Intel MCS-8 Microcomputer Programming Guide
PDF
Dokument
Werbung
Werbung
a
INICS-8
A Guide to
PL/M Programming
PL/M is a new high level programming language designed specifically for Intel s8
bit microcomputers The new language gives the microcomputer systems program-
mer the same advantages of high level language programming currently available in
the mini and large computer fields. Designed to meet the special needs of systems
programming, the new language will drastically cut microcomputer programming
time and costs without sacrifice of program efficiency. In addition, training, docu-
mentation, program maintenance and the inclusion of library subroutines will all be
made correspondingly easier. PL/M is well suited for all microcomputer program-
ming applications, retaining the control and efficiency of assembly language, while
greatly reducing programming effort The PL/M compiler is written in ANSI stand-
ard Fortran IV and thus will execute on most machines without alteration.
SEPTEMBER 1973
REV. 1
© Intel Corporation 1973
INTEL CORP. 3065 Bowers Avenue, Santa Clara, California 95051 + (408) 246-7501
Section
I. INTRODUCTION TO PL/M eee eee ee eee
IT. A TUTORIAL APPROACH TO PL/M ........Ñ.. e... 0... 00aroeceo,
1. The Organization ofa PL/M Program .........................
2. Basic Constituents of a PL/M Program ........................
2.1. PL/M Character Set ............. 0...
2.2. Identifiers and Reserved Words ........................
2.3. Comments ........_ooeeresscooacdornecacorarareroroo
3. PL/M Statement Organization ...............................
4. PL/M Data Elements ............. iin
4.1. Variable Declarations ............... cio...
4.2. Byte and Double Byte Constants . . .....................
5. Well-Formed Expressions and Assignments .....................
6. ASimple Example ........... ee aa a 0
7. РО-Стопре ............ 5..2... 5 RR RR RR RR RR a ee
7.1. The DO-WHILE Group ee 4 a Lea ae»
7.2. The Петайуе ОО-Стопр .............................
7.3. The DO-CASE .........eameaaraoareovoocoreararasoo.
8. Subscripted Variables and the INITIAL Attribute ............o...
8.1. Subscript Declarations and Value References .............
8.2. The INITIAL Attribute ..................... ... .. ....
9. ASorting Program .............. iii eee,
10. Procedure Definitions and Procedure Calls .....................
10.1. Procedure Declarations ..............................
10.2. Procedure Calis .............oo rese0r0orereoroeoaan.
11. Based Variables ........e_.oor_ecoaoorarraroorerdroorercrerdeera
12. Long Constants .........o_eeeeeaearorerreorerdororerdeoaeaca,
13. бсоре о? МапаЫе8................... 2..5... 02...52... .......
14. Statement Labels and GO TO’s ue...
14.1. Label Names ................... PA RR
14.2. GOTO Statements .............c. iin...
14.3. Scopeof Labels ................... 0.0...
15. Compile-Time Macro РгосевыШ@ .............................
16. Predeclared Variables and Procedures .........................
16.1. Condition Code Variables ............................
16.2. The MEMORY Vector. ............ inno.
16.3. The TIME Procedure .......22011 00020 4 ea ea ae a La
16.4. Type Transfer Functions .............................
16.5. Bit Manipulation Procedures ..........................
16.6. I/O Processing ......... imi titties
Ш. THE FORMAL DEFINITION OF PL/M ...........................
IV. COMPILING AND DEBUGGING PL/M PROGRAMS ................
1. PLM1 Operating Procedures........2102020000 104 Lea aa aa Lane
2. PLM2 Operating Procedures. ............ee_e00aerorooorerac
3. Program Check-Out ................. iin...
4. Implementation-Dependent Operating Procedures ...............
V. PL/M RUN-TIME CONVENTIONS FOR THE 8008CPU ..............
1. Storage Allocation ............ iin.
2. Subroutine Linkage Conventions .............................
3. Use of Assembler Language Subroutines with PL/M ..............
TABLE OF CONTENTS
Page
© I AN x x NN
A GUIDE TO PL/M PROGRAMMING
I. INTRODUCTION TO PL/H.
fa,
oO
e ес
к
- 1 -
n language desig
i sp
for the INTEL MCS-8 Microcomputer. Th a
q
jou
is
=
LQ
c
o
Te
M
structurally similar to PL/I (in particular, PL/M closely
resembles XPL), with data types and primitive operations
which reflect the architecture of the MCS-8 CPU. Thus, the
systems designer can use PL/M to quickly and easily express
programs which execute on the MCS-8 CPU, with little or no
loss in execution efficiency when compared to assembly
language programming. In addition, programs written in PL/M
are somewhat self-documenting, are easily altered and
maintained, and provide upward software compatibility in the
INTEL 8000 CPU series. That is, programs written in PL/M
for the 8008 CPU can be recompiled for the 8080 CPU with no
alteration of the source program. In each case, the
resulting object code takes advantage of the particular
target CPU architecture.
The discussion of PL/M given here is in two main
sections. Section II provides a tutorial description of
PL/M; only a minimal amount of programming experience is
assumed, and the discussion is mainly expository. Section
III presents a more formal approach to PL/M, providing the
exact syntactic structure and corresponding actions of each
statement in PL/M. Section III is intended as a reference
manual, but may be used as an introduction to PL/H by
readers who are familiar with block structured languages
similar tc PL/I or XPL.
The remaining sections provide system notes on the use
of PL/M, including compiler error messages, control toggles,
and execution controls and commands. Appendix A contains
sample PL/M programs; it may be useful for the reader to
refer occassionally to this appendix to find instances of
the various statements as they are discussed in Sections IT
and III.
IT. A TUTORIAL APPROACH TO PL/M.
As mentioned above, this section describes the PL/M
programming language from a tutorial viewpoint. The various
structures of PL/M are introduced at various levels of
complexity. Examples of each of the constructs are also
given. The overall structure of a PL/M program is given
first.
1. The Organization of a PL/M Program.
A PL/H program is arranged as a sequence of
declarations and statements separated by semicolons. The
declarations allow the programmer to control allocation of
storage, define simple macros, and define procedures.
Procedures are subroutines which are invoked through certain
statements in PL/M. These procedures may contain further
declarations which control storage allocation and define
nested procedures. The procedure definition capabilities of
PL/M allow modular programming; that 15, a particular
program can be divided into a number of subtasks, such as
processing teletype input, converting from binary to decimal
forms, and printing output messages. Each of these subtasks
is written as a procedure in PL/M. These procedures are
conceptually simple, are easy to formulate and debug, are
easily incorporated into a large program, and form a basis
for library subroutine facilities when writing a number of
similar prograns.
In addition to the procedure declaration facilities,
PL/M allows a number of data types to be declared and used
in a program. The two basic data types are Byte and
Address. A Byte variable or constant is one which can be
represented in an eight-bit word, while an Address variable
or constant requires sixteen bits (double byte). The
programmer can declare variable names in a PL/M program to
represent Byte and Address values. PL/M also allows the
vectors of Byte or Address variables to be declared.
A number of arithmetic, logical, and relational
operations are defined in PL/M on Byte and Address variables
and constants. These operators and values are combined to
form expressions which resemble elementary algebraic
expressions. The PL/M expression
X* (Y-3) /R
represents the calculation of the value of X times the
quantity Y-3 divided by the value of В. When values in
expressions are both Byte and Address type, PL/M
automatically converts the Byte value to an Address value.
Expressions are the major components of most PL/M
statements. A simple statement form is the PL/M assignment
statement which allows the programmer to compute a result
and store it in a location defined by a variable name.
Thus, the assignment |
о = Хх * (У - 3) / В
first causes the computation of the expression to the right
of the equal sign. The result of this computation is then
saved in the memory location represented by the variable
name ©.
Additional statements are provided in PL/M for
conditional tests and branching, iteration control, and
procedure invocation with parameter passing.
Input and output statements in PL/M allow the
programmer to read the eight-bit value latched into a
particular MCS-8 input port, or set the value of an
eight-bit output port. Procedures can be defined which use
these basic input and output statements to perform more
complicated I/O functions.
A compile-time macro processing facility is also
provided in PL/M. This facility allows the programmer to
define a name in the program to represent an arbitrary
seguence of characters. Each time the name is encountered,
the corresponding character sequence is substituted into the
source program.
The section which follows provides a detailed
description of the format of a PL/M program.
2. Basic Constituents of a PL/M Program.
PL/M programs are written in free-form. That is, the
input lines are column independent and blanks can be freely
inserted between the elements of the program. The only
requirement is that the declarations and statements are all
terminated with a semicolon. The characters recognized by
PL/M are given below. These characters can be combined to
form identifiers and reserved words.
2.1. PL/M Character Set. The character set recognized
by PL/M is a subset of both the ASCII and EBCDIC character
sets. The valid PL/M characters consist of the alphanumerics
012 3 456 72839
ABCDEFGHIJKILMNOPOQRSTUV UW XYZ
along with the special characters
$=. / () +- "*, <>:
all other characters are ignored by PL/M (a blank is
substituted for an unrecognized character).
Special characters and combinations of special
characters have particular meanings in a PL/M program, as
shown below.
Symbol Name Use
doiiar
“i
sign
= equal
:= assign
. dot
/ slash
() parens
+ plus
- minus
compiier controis, number
and identifier spacer
relational test and assignments
imbedded assignments
address indicator
division symbol and comment delimiter
list and subscript delimiter
addition
subtraction
' apostrophe string delimiter
asterisk
< less
greater
<= less or
equal
>= greater
Or equal
<> not equal
multiplication and comment delimiter
relational tests
: colon label delimiter
; semicolon declaration and statement delimiter
2.2. Identifiers and Reserved Words. A PL/M
identifier is used
to represent names of variables,
procedure names, macro names, and statement label names.
Identifiers can be up to 31 characters in length; the first
character must be
alphabetic, and the remaining characters
can be alphaketic or numeric. Imbedded dollar signs ($) are
ignored by PL/M, and can be used to improve readability of a
name. Thus, valid identifiers are
Note, however,
X
GAMMA
LONGIDENTIFIER
INPUT$COUNT
that there are a number of reserved
words in PL/M which cannot be used as names in a PL/M
program. These reserved words are shown below
Reserved Word Use
IF conditional tests and branching
THEN
ELSE
DO statement grouping
PROCEDURE and procedure definition
END
DECLARE data declarations
BYTE
ADDRESS
LABEL
INITIAL
DATA
LITERALLY
BASED
GO unconditional branching
TO and iteration control
BY
GOTO
CASE
WHILE
CALL subroutine call
RETURN subroutine return
HALT machine stop
OR logical or
AND logical and
XOR logical xor
NOT logical not
MOD remainder after division
PLUS add with carry
MINUS subtract with carry
EOF end-of-file
Blanks may be inserted freely around identifiers and
special characters. Blanks are not necessary, however, when
two identifiers are separated by a special character. Thus,
the expression
X * (Y- 3) /R
is equivalent to
X* (Y-3)/R
in PL/M.
2.3. Comments. Explanatory remarks can be used
throughout a PL/M program to improve readability and provide
a measure of self-documentation. Comments are sequences of
symbols from the character set of PL/M bounded by the symbol
pairs /* and */. Thus, the sequence
/*THIS IS A COMMENT ABOUT COMMENTS*/
is completely ignored by the PL/M compiler, and has no
effect on the program. Comments may be freely interspersed
in a PL/M program, and may appear anywhere a blank is valid.
2 PL/M Statement Organization.
The statements found in PL/M programs are one of three
basic types: simple statements, conditional statements, and
groups.
An example of a simple statement is the PL/M assignment
À = B + C * D;
Note that simple statements are always followed by a
semicolon. Other forms of simple statements are defined in
later sections.
Conditional statements are preceded by the reserved
word IF and contain one or more other statements as a part
of the statement body. A conditional statement could be
written in PL/M as
IF A > B THEN & = В;
which assigns the value of B to the variable A only if A's
value is greater than B's value.
A more complicated conditional statement involves an
alternative, denoted by the reserved word ELSE. The
conditional
IF À > B THEN C = A; ELSE C = Bj;
assigns the larger of the two values A and B to the variable
C.
Statements can be collected together in groups which are
delimited by the reserved words DO and END. These groups of
statements are then treated as a single statement in the
flow of ccntrol. The group could, for example, become a
part of a conditional statement:
IF A > B THEN
DO; A = В; В = С;
END;
which would perform the two assignments to A and B only if
A is greater then B.
Simple statements, conditional statements, and groups
can be labelled for control flow purposes. The label may be
a PL/M identifier, which precedes the statement, and is
separated from the statement by a colon (:). Thus,
LAB1: A = B + C * D;
is an example of a simple statement labelled by LAB1.
The exact details of the various simple, conditional,
and statement groups are discussed in following sections.
4. PL/M Data Elements.
PL/M data elements represent single bytes, double
bytes, and strings corresponding to 8-bit values, 16-bit
values, and ASCII character strings of length greater than
two. Data elements can be either variables or constants.
Variables are PL/M identifiers corresponding to values which
can change during execution of a PL/M program, while
constants have a value which is fixed. The expression
X * (Y- 3) /R
involves the variables X, Y, and R, and the constant 3.
variables must declared in PL/M programs before they
are used in expressions. The declaration tells the PL/M
compiler how to handle expressions and assignments which
involve the variable.
4.1. Variable Declarations. A declaration for a
variable or set of variables is headed by the reserved word
DECLARE and followed by either a single identifier or a list
of identifiers enclosed in parenthesis, and terminated by
one of the data types BYTE or ADDRESS. Thus, valid PL/M
declarations are:
DECLARE X BYTE;
DECLARE (Q,R,S) BYTE;
DECLARE (U,V,W) ADDRESS;
Thus, expressions involving only the variables X, 0, R, and
S produce single byte operations, while expressions
involving U, V, or W would produce double byte operations
and results.
Additional facilities are present in PL/M for declaring
vectors, macros, and data lists. These facilities are
discussed in later sections.
4.2. Byte and Double Byte Constants. Constants
representing single and double byte values can be expressed
in several different ways in PL/M. First, PL/M accepts
constants in the binary, octal, decimal, and hexadecimal
bases. In addition, ASCII strings of length one or twc are
translated tc single and double byte constants.
In general, the base of a constant is represented by
one of the letters
B OQ DH
following a sequence of digits. The letter B represents a
binary constant, while the letters 0 and Q denote octal
constants. The letter D optionally follows decimal numbers.
Hexadecimal numbers consist of sequences of hexadecimal
digits (0,1, -.. ,9,A,B,C,D,E,F) followed by the letter H.
Note that the leading digit of a hexadecimal number must be
a decimal digit to avoid confusion with a PL/M identifier (a
leading 0 is always sufficient). Any number not followed by
one of the letters B, 0, 0, D, or H is assumed to be
decimal. The numbers must always be capable of
representation as a single or double byte value (a maximum
of 16 bits). Thus, the following are valid constants in
PL/M
2 330 110B 33FH 55D 55 OBF3H 65535
The dollar sign symbol may be freely inserted within
constants to improve readability. Thus, the binary constant
1111011001418
could be expressed as
111$1011$0011B
ASCII strings are represented by PL/M characters
enclosed within apostrophe symbols ('). Strings of length
one or two translate to byte and double byte values as
mentioned previously. Thus, the string
TATE
10
is the same as 65 decimal. A pair of apostrophes ('')
within a string results in a single apostrophe in the
internal representation of the string. Thus, the string
1110" becomes a single apostrophe followed by the character
Qe.
5. HNKell-Formed Expressions and Assignments.
PL/M expressions can now be more completely defined. А
weli-formed expression consists of basic data elements
combined through the various arithmetic, logical, and
relational operators, in accordance with the usual algebraic
notation. Thus, an expression consists of a simple data
element, such as a number or variable, or an expression can
be two (sub) expressions separated by an operator:
eXxpression1 operator expression2
Examples are
А + В
А+ В - С
A ** B + C/D
Operators in expressions have an assumed precedence which
determines the order in which the operations in the
expression are evaluated. The valid PL/M operators are
listed below from highest to lowest precedence. Orerators
listed on the same line are of equal precedence and are
evaluated from left-to-right when they occur in an
expression.
* / MOD
+ - PLUS MINUS
< <= <> = >= >
NOT
AND
OR XOR
The expression
А+ В * С
for example, results first in the computation of B times С
11
since the multiplication (*) has a higher precedence than
the addition (+). The result of this computation 1s then
added to the value of A.
Parenthesis can be used to override the assumed
precedence Ly enclosing subexpressions which are to be
computed first. The expression
(A + B ) * C
causes A + B to be evaluated first. The result is then
multiplied by C's value. Following are a number of
well-formed PL/M expressions
A + B- Cx D
A- (B+ C) =D
A / (B+ C) *D
A/ (Bt+C)
A OR B AND OFH
А + B> C- D
Each expression results in either a single or double
byte value. The number of bytes in the result is determined
by the number of bytes required by the subexpressions in the
result. Generally, if both operands in an expression are
byte values, the result is a byte value. If either operand,
however, is a double byte, the result is a double byte
value. In this case, the shorter operand 1s padded with
high-order zeroes.
Two exceptions to these rules occur in PL/M. The first
is in the case of the *, /, and MOD operations. These
operators always result in a double byte value. The second
exception is the case of relational operators. A relational
test results in either a true or false condition. A true
condition is represented in PL/M by a byte value equal to
255 (all bits are 1's), and a false condition is represented
by the byte value 0.
12
Suppose the variables X, Y, and Z have been declared as
follows:
DECLARE X BYTE ;
DECLARE (Y,Z) ADDRESS;
given these declarations, the expressions below yield
results with the precision shown to the right of the
expression:
X + 5 single byte result
X + 300 double byte result
X + Y double byte result
Y + Z double byte result
X / 5 double byte result
X + ( Y > Z ) single byte result
The NOT operator is a unary operator, and thus PL/m
expressions involving NOT take the form
NOT expression
The effect of the NOT operator is that all the bits of the
expression are inverted (1,s become 0's, and 0's become
1's). In particular, true conditions change to false
conditions, and false conditions revert to true. Examples
of the use of the NOT operator are
NOT A
NOT (4 > B)
NOT A OR B
For convenience, a unary minus sign is also allowed in
PL/M expressions. The form of the unary minus in an
expression is
- expression
The effect is exactly the same as the expression
0 - expression
where the "-“ in this last case is the subtract operator.
The expression -1, for example, is equivalent to 0-1,
resulting in the byte value 255.
13
Recall that the assignment statement 1s used to store
the result of an expression into a variable. The declared
precision of the assigned variable affects the resulting
store operation. If the assigned variable is a single byte
variable, and the expression is a double byte result, the
high order byte is omitted in the store. Similarly, if the
expression yields a single byte result, and the receiving
variable is declared as type ADDRESS, the high order byte is
set to zero.
It is often convenient to assign the same expression to
several variables. This is accomplished in PL/M by listing
all the variables to the left of the equal sign, separated
by commas. The variables A, B, and C could ail be set to
the expression X + Y with the single assignment
A, B, C= X + Y
A special form of the assignment is allowed within
expressions in PL/M. The form of an imbedded assignment is
(variable := expression)
and may appear anywhere an expression is allowed in PL/M.
The expression to the right of the assign symbol (:= is
evaluated and then stored into the variable on the left.
The value of the imbedded assignment is the same as the
expression on the right. The expression
A + (B := C + D ) - ( E := F / G)
results in exactly the same value as
A + (C+ D) - (F/G)
except that the intermediate results C+D and F/C are stored
into B and E, respectively. These intermediate computations
can then be used at a later point in the program without
recomputation.
Note that the form
A = ( B := (C := X + Y })
has exactly the same effect as the multiple assignment to A,
14
B, and C given previously.
It is now possible to construct a simpie program based
upon these expressions and assignments.
6. A Simple Example.
The following PL/M sample program reads data from input
ports 0 and 1, and writes the larger of these two values at
output port 0. Note that the two pseudo-variables INPUT(0),
and INPUT(1) act like PL/M single byte variables, but have
the effect of reading the values latched into input ports 0
and 1, respectively. Similarly, the pseudo-variable
OUTPUT {0) can be used in an assignment statement in order to
write values to output port 0.
The complete PL/M program for performing this simple
function is shown below
DECLARE (I,J,MAX) BYTE;
/* READ INPUT PORT 0 AND SAVE IN VARIABLE I */
LOOP: |
I = INPUT (0);
/* NOW READ INPUT PORT 1 AND SAVE IN VARIABLE J */
Jd = INPUT (1) ;
/* SET MAX TO THE LARGER OF THESE TWO VALUES */
IF I > J THEN MAX = I; ELSE MAX = J;
/* WRITE THE VALUE OF MAX AT OUTPUT PORT 0 */
OUTPUT (0) = MAX;
/* GO BACK AND READ THE INPUT PORTS AGAIN */
GO TO LOOP;
EQF
The symbol EOF (end-of-file) is required in PL/M to
indicate the end of the program. Note also that the GO TO
Statement causes program control to restart at the point
labelled 'LOOP:' where input values are read again.
15
In crder to effectively construct more comprehensive
PL/M programs, it is necessary to consider the structure of
PL/M statement groups, including the loop control groups.
7. DO Groups.
As mentioned previously, statements can be grouped
together within the bracketing reserved words DO and END as
a DO-group. Recall that the simplest DO-group is of the
form
DO;
statement-1;
statement-2;
statement-n;
END;
Several additional DO-groups are defined in PL/M which
control program flow. These groups are shown below.
7.1. The DO-WHILE Group. One form of the DO-grcup 1s
called a DO-WHILE. The DO-WHILE has the form
DO WHILE expression;
statement-1;
statement-2;
statement-n;
END;
In this case, the expression following the reserved word
WHILE is evaluated before the statements within the group
are executed. If the expression evaluates to true (i.e.,
the rightmost bit of the result is 1), the statements up to
the corresponding END are executed. At the end of the
group, program control is transferred to the top of the
DO-group and the expression is evaluated again. The group
is executed over and over until the expression results in a
16
false condition (the rightmost bit 15 0). Consider the
following example:
A = 1;
DO WHILE A <= 3;
A = А + 1;
END;
The statement A = A + 1 will be executed exactly three
times. The value of A at the end of execution of the group
is four.
7.2. The Iterative DO-group. An Iterative DO-group
allows a group of statements to be executed a fixed number
of times. The simplest form of the Iterative DO-group is
DO variable = expression1 TO expression2:
statement-1;
statement-2;
statement-n;
END;
The effect of this group is to first store. expressicn1 into
the variatle following the DO. The group is executed with
this initial value once, and control returns to the top of
the DO. The value of the variable is incremented by 1 and
tested against expression2. If the incremented value
exceeds expression2, control transfers to the statement
following the END; otherwise, the group is executed once
again. An example is
DO I = 1 TO 10;
A A + I;
END;
Note that this DO-group has exactly the same effect as the
following DO-WHILE:
I = 4;
DO WHILE I <= 10:
À = А + I;
Ll = I + 1;
17
END;
A slightly more complicated form of an Iterative
DO-group allows a stepping value other than 1. This second
form is
DO variable = expr1 TO expr2 BY expr3;
statement-1;
statement-2;
statement-n ;
END; |
In this case, the variable following the DO 15 stepped by
the value expr3 instead of by 1.
7.3. The DO-CASE. Another form of the DO-group is the
DO-CASE statement. The form of a DO-CASE group is
DO CASE expression;
statement- 1;
statement-2;
statement-n;
END;
The effect of this group is the following. Upon entry to
the DO-CASE, the expression following the CASE is evaluated.
The result of this expression is a value k which must be
between 0 and n-1. This value k is used to select one of
the n statements of the DO-CASE to execute. The first case
corresponds to k = 0 (statement-1), the second case
corresponds to k = 1 (statement-2), and so-forth. Control
transfers to the selected statement, the statement 15
executed, and control then passes to the statenent following
the END.
An example of the DO-CASE is:
DO CASE X - 5;
X= X + 5; /% CASE 0 */
18
DO; /* CASE 1 */
X = X + 10; Y = X - 3;
№;
/¥ CASE 2 */ |
DC I = 3 TO 10; A = А + I:
END;
END /* OF CASES */ ;
{
Before giving more comprehensive examples, it is useful
to define the notion of a subscripted variable and its use
in a PL/M program.
8. Subscripted Variables and the INITIAL Attribute.
It is often useful in PL/M to reference memory
locations with an "offset" from some base address. This
feature is allowed in PL/M through subscripting.
8.1. Subscript Declarations and Value References. A
subscripted variable is similar to a simple variable with
the addition of an expression enclosed within parentheses
following the variable name. The location referenced by the
subscripted variable is the sum of the base address of the
variable and the subscript expression. Any variable name
can be subscripted in PL/M.
suppose a PL/M programmer declares the variables X, Y,
and Z as follows |
DECLARE (X,Y,Z) BYTE;
The first memory location can be referenced simply as X or
as the subscripted variable X (0). Similarly, X(1) refers to
the location Y, and X (2) references Z's location.
PL/M also allows a fixed number of locations to be set
aside in the declaration statement. These fixed locations
start at the variable name specified in the declare
19
statement. For example, the statement
DECLARE X (100) BYTE;
provides a memory area of 100 bytes starting at X. In this
case, X is called a vector. Note that the size of a vector
must always be a constant.
Several vectors of the same length can be declared in
the same declare statement. The statement
DECLARE (U,V,W) (50) ADDRESS;
causes three vectors of length 50 (each) to be allocated in
contiquous memory locations. Note, however, that these
vectors are of type ADDRESS, and thus each element requires
two bytes; hence, U takes up the first 50 two-byte
locations, requiring 100 bytes altogether. The storage for
the second vector starts at V and requires the next 100
bytes. Similarly, W occupies the 100 byte area following V.
As mentioned previously, a subscript can be thought of
as a displacement from a base address. This displacement,
however, is affected by the declared precision of the
variable. That is, if the declared precision is BYTE, then
the displacement is measured in single bytes. If, however,
the variable is type ADDRESS, the displacement 1s measured
in double bytes. Thus, given the declaration of U, V, and W
above, the first element of U is U(0), and the last element
is U(49). The first element of V is V(0), or U(50).
Storage is always arranged so that double byte variables are
at memory addresses which are even numbers; hence, there 15
sometimes one extra word allocated between contigous byte
and double byte variables.
Before continuing, it should be noted that the
subscripts can be complicated expressions, and not
necessarily just the simple constants shown above. Note
also that subscripted variables can occur everywhere a
=
simple variable is allowed, including expressions and
20
assignments. A single excepticn to this rule is that a
subscripted variable cannot be used as the indexing variable
in an Iterative DC group.
Two built in functions are provided in PL/M which are
based upon the declared size of a vector. These functions
take the forms
LENGTH (identifier) and LAST(identifier)
where the identitifers correspond to variables declared
previously. These forms can appear anywhere an expression
is allowed in PL/M, and result in the declared length and
last element number of the specified variable, respectively.
The following program, for example, uses the LAST function
to set all the elements of a vector v to the constant 5.
DECLARE V (100) BYTE;
DECLARE I BYTE;
DO I = 0 TO LAST (V) ;
V(I) = 5;
END;
EOF
8.2. The INITIAL Attribute. The values of variables
can be initialized in a declaration statement using the
INITIAL attribute. This attribute takes the forn
INITIAL (constant-1,constant-2,...,COnSstant-n);
and must directly follow the type (BYTE or ADDRESS) in the
declare statement.
The purpose of the INITIAL attribute is to preset the
values of memory iccations starting at the location named in
the declarations. The constants given in the INITIAL
attribute are placed into memory before the program starts
(these constants become a part of the object code and must
be loaded into random-access memory). The following are
valid variable declarations which use the INITIAL attribute.
DECLARE X BYTE INITIAL(10);
21
DECLARE Y(10) BYTE INITIAL (1,2,3,4,5,6,7,8,9,10);
DECLARE Z (100) BYTE INITIAL
(* SHORT', 'STRING',0FH,33) ;
DECLARE U (100) ADDRESS INITIAL (3,4,333Q);
DECLARE (Q,R,S) BYTE INITIAL (0,1,2);
Note that the number of bytes required to hold the
constants given in the INITIAL attribute need not correspond
to the length deciared for the variable. The constants are
placed into memory without truncation starting at the first
byte allocated in the declare statement.
The use of subscripted variables is shown in the
example which follows.
9. A Sorting Program.
It is now possible to construct a more complicated
program, given the expressions, DO-groups, and subscripted
variables which have been presented. In the program which
follows, a vector A is initialized to a set of constants in
unsorted order. The program below sorts the values of A
into ascending order.
/* FIRST DECLARE A VECTOR TO HOLD THE
VALUES TO SORT.
ASSUME THERE ARE NO MORE THAN 10 ELEMENTS TO BE
SORTED. EACH ELEMENT IS BETWEEN O AND 65535 */
DECLARE A(10) ADDRESS INITIAL
(33, 10,2000,400,410,3,3,33,500,1999) ;
/* START THE 'BUBBLE SORT' AT THIS POINT
EXAMINE ADJACENT ELEMENTS OF 'A' AND SWITCH INTO
ASCENDING SEQUENCE. RECYCLE UNTIL NO MORE
SWITCHING OCCURS */
DECLARE (I,SWITCHED) BYTE,
TEMP ADDRESS;
SWITCHED = 1;
DO WHILE SWITCHED; SWITCHED = 0;
/* GO THROUGH 'A' ONCE AND LOOK FOR A PAIR
WHICH KEEDS TO BE REVERSED */
DO I = 0 TO 8;
IF A(I) > A(I+1) THEN
DO; SWITCHED = 1;
TEMP = A(I); A(I) = A(1+1);
A(I+1) = TEMP;
END;
END;
END;
/¥ THE VALUES IN 'A' ARE NOW IN ASCENDING ORDER */
EOF
1C. Procedure Definitions and Procedure Calls.
The procedure capabilities of PL/M are discussed in
this section. A procedure, or subroutine, is a section of
PL/M source code which is declared, but not executed
immediately. Instead, the procedure is called from various
parts of the progran. The call amounts to a transfer of
program ccntrol from the calling point to the procedure.
The procedure executes, and, upon completicn, returns to the
statement following the cali.
The use of procedures in PL/M allows construction of
modular programs, allows construction and use of subroutine
libraries, eases programming and documentation, and reduces
generated code when similar program segments are used at
several points in the program.
Procedures are described in two parts: how to define
them, and how to use then.
10.1. Procedure Declarations. A procedure declaration
consists of four main parts: the procedure name,
specification of values which are sent to the procedure, the
23
type of the returned value (i.e., BYTE, ADDRESS, or no
returned value), and the description of the actions of the
procedure, called the procedure body. The procedure may be
invoked anywhere in the program after it is declared. The
form of a procedure declaration is
procedure-name: PROCEDURE argument-list procedure-type;
statement-1;
statement-2;
statement-n;
END procedure-name;
The procedure-name is any valid PL/M identifier, and 15
used to name the procedure so that it can be called at a
later point in the progran.
The argument-list takes the form
(argument-1,argument-2,...,argument-n)
where argument-1 through argument-n are valid PL/M
identifiers. These identifiers are called formal parameters
and are used to hold particular values which are sent to the
procedure from the point of invocation, Each of these
parameters must also appear in a declarations statement
within the procedure body (before the corresponding END).
Note that the argqument-list can be omitted altogether if no
parameters are passed to the procedure.
The procedure-type is either BYTE, ADDRESS, Or can be
omitted if the procedure does not return a value to the
calling point. The procedure-type defines the precisicn of
the value returned so that proper type conversion takes
place when the procedure is invoked as a part of an
expression.
The execution of a procedure is terminated with a
RETURN statement in the procedure body. The RETURN
24
statement takes the form
RETURN;
or
RETURN expression;
The first form is used if the procedure-type is omitted (no
value is returned to the calling point). The second form is
used if the procedure-type is BYTE or ADDRESS. The
expression following the RETURN is brought back to the
calling point in this case.
The statements within the procedure body can be any
valid PL/M statements, including nested procedure
definitions and invocations. A number of valid PL/M
procedure declarations are listed below.
NULL: PROCEDURE;
RETURN;
END NULL;
SUM: PROCEDURE (X,Y) ;
DECLARE (X,Y) ADDRESS:
/* ASSUME U IS PREVIOUSLY DECLARED */
U = X + Y;
RETURN;
END SUM;
ZERO: PROCEDURE BYTE;
RETURN 0;
END ZERO;
IDENTITY: PROCEDURE (X) ADDRESS;
DECLARE X ADDRESS;
RETURN X;
END IDENTITY;
PLUSXY: PROCEDURE (X,Y) BYTE;
DECLARE (I,X,Y) BYTE;
I = X - Y;
RETURN X + Y;
END PLUSXY;
25
10.2. Procedure Calls. Procedures can be invoked
anywhere after their declaration. There are two pessible
forms of the call, depending upon whether the procedure-type
is present or omitted in the procedure declaration.
If the procedure-type is omitted, then the procedure
does not return a value to the point of invocation. In this
case, the form of the call is
CALL procedure-name argument-list
where the procedure-name and argument-list correspond to
those defined above. The effect in PL/M is to assign the
actual values in the argument-list at the call to the
identifiers given in the argument-list in the procedure
declaration. The elements of the argument-list in the call
are called actual parameters, and are not restricted to
simple PL/nm identifiers. In fact, any valid PL/M expression
can be placed in the argument-list. These expressicns are
all evaluated in the actual parameter list before they are
assigned to the corresponding identifiers in the formal
parameter list. If the procedure is declared with an empty
formal parameter list then the actual parameter list is also
omitted. Control is then transferred to the beginning of
the procedure named by the procedure-name.
Thus, given the procedure definitions above, the
following are all valid procedure calls
CALL NULL;
CALL SUM (5,3);
CALL SUM(Q,R + Z);
In the last case, for example, the value of Q is first
placed into X in the procedure SUM. The value of R + Z is
then computed and stored into the formal parameter Y.
Control then passes to the procedure SUM where the variable
U is set to the sum of these two values (it is assumed that
U has been declared ahead of the procedure SUM). Note that
automatic type conversion occurs between BYTE and ADDRESS
26
values when the actual parameters are assigned to the formal
parameters.
The second form of a procedure call occurs when the
procedure is declared with а procedure-type of BYTE or
ADDRESS. In this case, the procedure call results in a
value which can be used in an expression. The form of the
call is
procedure-name argument-list;
and may appear anywhere a PL/M expression is allowed. The
following calls demonstrate a number of valid PL/M procedure
invocations
I = IDENTITY (I);
X = PLUSXY(X,Y) ;
X = Q-PLUSXY (X+Y,0) / (X-Y) ;
DO I=PLUSXY (Q,R) TO PLUSXY (Z+R,Q) +10; END:
As an example of a procedure declaration and call,
consider the sorting program given earlier. The segment of
the program which performs the sort can be redefined as a
procedure. Assume the procedure has a single formal
parameter which gives the upper bound of the sort loop. The
value returned by the procedure is the number of switches
required to sort the vector.
DECLARE A (10) ADDRESS INITIAL
(33,10,2000,400,410,3,3,33,500,1999) ;
SORT: PROCEDURE (N) ADDRESS;
/* SCRT THE VECTOR AT 'A' OF LENGTH
N + 2. RETURN THE NUMBER OF SWITCHES
REQUIRED TO PERFORM THE SORT */
DECLARE (N,I,SWITCHED) BYTE,
(T1,T2,COUNT) ADDRESS;
SWITCHED = 1; COUNT = 0;
DO WHILE SWITCHED; SWITCHED=0;
DO I = 0 TO N;
T1 = A(I); T2=A(I+1);
27
IF T1 > T2 THEN
DO; A(I+1) = T1;
A(I) = T2; SWITCHED = 1;
COUNT = COUNT + 1;
END;
END;
END;
RETURN COUNT;
END SORT;
/* THE SORT PROCEDURE IS DECLARED ABOVE.
CALL SORT WITH N -2 = 10 - 2 = 8 */
DECLARE NSWITCHES ADDRESS;
NSWITCHES = SORT (8) ;
EOF
The program shown above illustrates a difficulty in
parameter passing which has not yet been considered. IN
particular, the SORT procedure would be much more useful as
a library subroutine if several different vectors cculd be
processed by the same subroutine. As shown, the SORT
procedure is only capable of sorting the particular vector
А.
The next section introduces the notion of based
variables which overcome this difficulty.
11. Based Variables.
Based variable features of PL/M allow computation of
variable addresses during execution of a program. A based
variable is similar to the variables discussed previously,
except that no storage is allocated for the variable.
Instead, corresponding to each based variable is an address
variable, called the base, which determines the memory
address for the based variable during execution.
28
Based variables are declared using the BASED attribute
which specifies the base. The form of the BASED attribute
is
BASED identifier
where the identifier is a previously declared ADDRESS
variable name. The BASED attribute must immediately follow
the name cf the based variable in the declaration statement.
The following are examples of PL/M based variable
declaraticns
DECLARE X BASED A BYTE;
DECLARE (X BASED XA, Y BASED YA) ADDRESS:
DECLARE (Q BASED QA) (100) BYTE:
In the first case, a byte variable called X is declared.
The declaration implies that X will be found at the location
given by the address variable A (which must be declared as
an ADDRESS variable elsewhere).
The second declaration above defines two based
variables X and Y both of type ADDRESS which are located at
XA and YA, respectively.
The third declaration defines a vector based variable
called Q based at QA. Note that the vector size need not be
stated, however, since no storage is allocated to Q by the
PL/M compiler. The only use for the vector size is to
provide values for the LENGTH(Q) and LAST(Q) built-in
functions described previously.
In order to make effective use of based variables, it
1s necessary to allow programmatic reference to the assigned
address of a non-based variable. The memory location
assigned to a variable is designated by preceding the
variable name with a dot symbol (.). Thus, the expressions
.A and .A (5)
yield the address of A and the address of A(5),
respectively. If A is a BYTE variable, the value of .A+5 is
the same as .A(5). Similarly, if A is of type ADDRESS, then
.A+10 is the same as .A (5). The address reference to a
based variable 15 allow and results simply in the value of
the base.
An address reference using the dot symbol can be used
anywhere an expression is valid in PL/M.
As an illustration of the use of based variables,
consider the following loop which initializes the elements
of a vector to their respective element numbers
DECLARE A (100) ADDRESS;
CECLARE I BYTE;
DO I = 0 TO LAST (4);
А (1) = I;
END;
EOF
This same function can be performed (rather
inefficiently) with the following loop using based variables
DECLARE A (100) ADDRESS,
QA ADDRESS, Q BASED QA ADDRESS;
/* SET QA TO THE BASE ADDRESS OF A*/
QA = À;
DECLARE I BYTE;
DO I = 0 TO 99;
О = I; QA = QA + 2;
END;
EGF
Note that QA starts at the base of A and moves up by
two bytes on each iteration since each element of A occupies
two bytes.
Based variables are. most commonly found in procedure
parameter passing. It is often necessary to return more
30
than one value from a procedure. In this case, the address
of an actual parameter can be passed to the procedure
instead of the value of the actual parameter. The
corresponding formal parameter is declared within the called
procedure as an address variable. This formal parameter is
then used as a base for a based variable whithin the
procedure. Any changes to the based variable then alter the
corresponding actual parameter.
In the case of the SORT procedure, for example, the
address of a vector to be sorted can be sent as an actual
parameter. The SORT procedure then operates upon a locally
defined based variable. The revised SORT procedure is shown
below
SORT: PROCEDURE (Q,N) ADDRESS;
DECLARE (N,I,SWITCHED) BYTE,
(Q,T1,T2,COUNT) ADDRESS:
/* AND THEN SET UP THE BASED
VARIABLE TO SORT */
DECLARE A BASED Q ADDRESS:
SWITCHED = 1; COUNT = 0;
DO WHILE SWITCHED; SWITCHED=0;
DO I = 0 TO N;
T1 À (I) ; Т2=А (1+1);
IF T1 > T2 THEN
DO; A(I+1) = T1:
A(I) = T2; SWITCHED = 1:
COUNT = COUNT + 1;
END; END;END;
RETURN COUNT;
END SORT;
DECLARE B (10) ADDRESS INITIAL
(33,10,2000,400,410,3,3,33,500,1999) ;
DECLARE C (5) ADDRESS
INITIAL('A',32,0FFFH,220,2D);
/* NOW SORT THE VECTORS B AND C x /
31
DECLARE (N1,N2) ADDRESS;
N1 = SORT (.B,LAST (8) -1);
N2 = SORT (.C,LENGTH(C)-2);
EOF
The SORT procedure has two formal parameters Q and №.
0 is an ADDRESS variable which gives the base address of the
vector to be sorted. The parameter N gives the upper bound
in the sort loop, as before. The variable A is declared
inside SORT as an ADDRESS variable based at 0. Thus,
references to A inside SORT are actually references to
memory locations starting at the value of 0.
The SORT procedure is called twice. First, the vector
B is sorted by sending the base address of B. The second
call sorts C by passing the base address of C as the first
actual parameter.
The section which follows introduces the concept of a
long constant. These long constants allow manipulation of
data which exceed two bytes in length.
12. Long Constants.
Recall that PL/M allows direct representaticn of
numeric and string constants which require a single or
double byte internal representation. It is often useful,
however, to manipulate constants of indefinite length. This
facility is provided in PL/M through the use of long
constants.
A PL/M long constant is a set of contiguous memory
locations represented by the address of the first byte. The
memory locations for long constants are allocated in the
same area as the program storage, and are initialized to the
string and numeric values specified in the constant (progran
32
steps and long constants are normally a part of the Read
Only Memcry portion of Storage, and thus cannot be altered
during execution). The first form of a long constant is
simply
«. Constant
where the constant is a string or numeric value. The result
of this expression is an address value providing the
location of the constant. The second form allows several
constants to be gathered together and based at the sane
address. This form is
. (constant-1,constant-2,...,constant-n)
Again, the result of this expression is an address value
giving the starting position of the constants in memory.
Valid PI/M long constants are
. 335
- 'THIS IS A LONG CONSTANT STRING"
* ("THREE', ' STRING ' , 'CONSTANTS')
« (3, 'CONSTANTS', OFFE2H)
These long constants can appear anywhere a PL/M expression
is allowed.
Another form of a long constant allows the constant to
be named and accessed as a subscripted variable. This
second form is a particular case of the declare statement
Called a DATA declaration. The form is
DECLARE identifier DATA (constant-1,...,constant-n);
The following are valid PL/M DATA declarations
DECLARE X DATA ("LONG STRING"):
DECLARE Y DATA (0,1,2,3,'STRING',4);
These two declarations have an effect similar to INITIAL
declarations except that new values cannot generally be
assigned to the elements of X and Y. In addition, there is
an automatic vector size assigned to elements declared in a
DATA declaration which is the number of bytes required to
hold the constants listed in the DATA attribute. In the
33
above case, both X and Y are treated as BYTE variables with
vector size 11. As a result, the LENGTH and LAST built-in
procedures can be applied to DATA variables to determine the
length of the constant string.
Given the above DATA declaration, the expressions below
evaluate to the result shown on the right
X (0) = 'L'
X(10) = 'G'
Y (3) = 3
LENGTH(Y) = 11
As an example, consider the following PL/M procedure,
called EQUAL, which compares two long constants for
equality. EQUAL has two formal parameters which give the
hase addresses of two long constants. The last byte of each
constant is Offh. EQUAL returns a 1 if the constants match,
and 0 if not.
EQUAL: PROCEDURE (AS1,AS2) BYTE;
DECLARE (AS1,AS2,I) ADDRESS,
(S1 BASED AS1, S2 BASED AS2) BYTE,
(J1,J2) BYTE;
/* COMPARE UNTIL A MISMATCH OR OFFH
IS FOUND IN BOTH STRINGS */
Jil, J2, I = 0;
DO WHILE J1 = J2;
IF J1 = OFFH THEN RETURN 1;
J1 = S1(I); J2 = S2 (I);
I = I + 1;
END;
RETURN 0;
END EQUAL;
Assume that the following declarations occur in the
program
DECLARE X DATA ('WALLAWALLAWASH', OFFH);
DECLAKE Y DATA ('WALLAWASH',OQFFH);
The EQUAL procedure can be called by
I = EQUAL (.X,. ("WALLAWALLAWASH',OFFH)) ;
As a result, I is set to 1. The value of I in the case
I = EQUAL (.X,.Y)
is zero since the strings X and Y differ.
As a final comment, one should note that the
fundamental difference between DATA variables and BYTE
variabies with the INITIAL attribute is in the allocation
of storage. DATA variables are stored in the same area as
program code, as mentioned previously, and cannot generally
be altered through a PL/M assignment. BYTE variables, on
the other hand, are allocated in alterable program stcrage.
The INITIAL attribute provides data which is preloaded into
these locations before the program executes (and hence is
volatile storage). In this case, these initial values can
always be changed with assignment statements during
execution.
13. Scope of Variables.
An important concept in any block-structured language,
such as PL/M, is the notion of variable scope. The scope of
a variable in PL/M is the range of statements where the
variabie can be used in expressions and assignments. The
scope of variables is controlled by the arrangement of
DO-groups and DECLARE statements. A variable is available
for use only within the DO-END statements in which the
DECLARE statement for the variable occurs. This range is
called the scope of the declared variable.
Consider the following PL/M program, for example:
1 DECLARE (A,B,C,D) BYTE;
2 EB,C = 10:
3 A =B + C;
4 DO;
5 DECLARE (Q,R,S) BYTE;
6 Q, R = 20;
7 5 = А + 0 + В;
8 END;
9 D = 2 + A;
10 EOF
The declaration on line 1 defines four variables A, B,
C, and D which can be used throughout the program. The
DO-group between lines 4 and 8 contains a declaration of
three variables Q, R, and S which are defined only within
the group; that 15, although A, B, C, and D can be used
anywhere in the program, the variables Q, R, and S cannot be
referenced outside the range of statements beginning on line
4 and ending on line 8. These lines delimit the scope of Q,
R, and S.
A more complicated structure is given by the following
skeletal Pi/M program
DECLARE (A,B,C,D) BYTE; /* BLOCK 1 */
DO; /* BLOCK 2 */
DECLARE (A, E,F,G) BYTE;
DO; /* BLOCK 3 */
DECLARE (B,H,I,J) BYTE;
END; /* OF BLOCK 3 */
END; /* OF BLOCK 2 */
DO; /* BLOCK 4 */
DECLARE (A,E,K,L) BYTE;
END; /* OF BLOCK 4 */
36
/* BLOCK 1 IS COMPLETED */
ECF
The declaration of A, B, C, and D at the top of block 1
makes these variables global to any nested inner blocks in
the program. That is, they can be referenced anywhere in
the program where there is no conflicting declaration.
The variables A, E, F, and G at the top of block 2 are
said to be local to block 2 and global to block 3. These
variables cannot be referenced outside block 2. Note that
the variable A in block 2 conflicts with the declaration of
A in block 1. In this case, any reference to A within block
2 refers to the innermost declaration of A. Similarly, the
variables B, H, I, and J declared at the top of blcck 3
cannot be accessed outside block 3. Again, the declaration
of B in block 3 overrides the outer block declaration of
this variable name.
Block 4 is parallel to block 2 in this program. The
variables А, E, K, and L are local to block 4. Thus, the
variables E, K, and L are undefined outside block 4, and
references to A outside block 4 affect the variable A
declared on the first line.
The notion of scope of variable names extends to
procedure names and to formal parameters declared within
procedures. A procedure declaration is treated the same as
a DO-group in defining scope of variables. As an example,
consider the following program
/* BLOCK 1 */
DECLARE (I,J,K) BYTE:
P1: PROCEDURE (I,Q) BYTE:
/* BLOCK 2 */
DECLARE (I,Q,J,R) ADDRESS:
37
END P1 /* AND BLOCK 2 */;
E2: PROCEDURE (J,Q,R) ADDRESS;
/* BLOCK 3 */
DECLARE (J,0,R,S,T) BYTE;
END P2 /* AND ALSO BLOCK 3 */
/* BLOCK 1 IS FINISHED */
EOF
The variables I, J, and K are global to both the P1 and
Р2 procedures. The procedures P1 and P2 constitute
independent parallel blocks, each with their own local
variables. Note that the local variable I declared in
procedure P1 is used in all references to I within block 2,
instead of the global variable declared in line |. Note
also that the variable Q defined in P1 15 completely
independent of the Q declared in P2.
The principal advantage to the scope of variable
concept in PL/M is that subroutines are independent of the
program in which they are imbedded, with no problems arising
from conflicting declarations. In particular, library
subroutines can be written as completely modular subprograms
with no dependence upon the names used outside the
procedure.
14. Statement Labels and GO TO's.
PL/M allows program statements to be identified with a
statement label, and allows unconditional transfer of
program control to these labelled statements.
14.1. Label Names. A PL/M labelled statement takes
the form
label-1: label-2: ... label-n: statement;
where label-1 through label-n are valid PL/M identifiers or
constants. Any number of labels may precede a PL/M
statement. Valid labelled statements are
L1: X = X + 1;
LOOP: Y = 3;
L1: LOOP: X Y + 5;
30: Y = X -5;
LOOP: 30: 11: Q = 5 + Y:
The function of numeric labels is to specify an crigin
for code generation. The statement "30: Y = X - 5:" for
example, specifies that the object code for this statement
is to begin at location 30 in memory. The identifier form
of a statement label has no effect on the origin of the
code, but does provide a destination for GO TO statements.
14.2. GO TO Statements. PL/M allows three distinct
forms of an unconditional transfer. The first is
GO TO label;
In this case, the label is an identifier which appears as a
label in a labelled statement. Program control transfers
directly to the statement with this label.
The second form of a GO TO is
GO TO constant;
The constant is any valid PL/M single or double byte number.
Program ccntrol transfers to the absolute location in memory
given by this number.
The last form is
GO TO variable;
where the variable contains a computed memory address.
Control transfers directly to this computed absolute
address.
39
The following program illustrates the use of latelled
statements and GO TO's.
DECLARE X ADDRESS;
10: GO TO KEYIN;
t+
O
©
го
KO
i
Lo
+
33
IF Q > Z GO TO LOOP;
GO TO EXIT:
/* COMPUTE AN ADDRESS AND BRANCH */
X = .MEMORY + 13;
GO TO X;
GO TO 30;
EXIT: HALT;
EOF
14.3. Scope of Labels. It should be noted that the
identifier fcrm of a label has an implied scope, similar to
variables and procedures. This implied scope can be made
explicit through the PL/M label declaration. The form of
the label declaration is
DECLARE identifier LABEL;
or
DECLARE (identifier-1,...,identifier-n) LABEL;
The label declaration informs the compiler that a label or
set of labels will occur at the same block level as the
declaration. The label declaration is only necessary,
however, when the implied declaration does not correspond to
the programmer's intention. In particular, any occurrence
of an undeclared label in either a GO TO statement, or as a
statement label results in an inmediate automatic
declaration cf the label. This implied declaration is most
40
easily seen by example. The programs to the left below
contain undeclared labels. The implied declarations
resulting from these labels are shown in the corresponding
programs to the right.
PROGRAM 1
. eo o | DECLARE LOOP LABEL;
LOOP: X =X + 1; | LOOP: X = X + 1;
GO TO LOOP; | GO TO LOOP:
EOF | EOF
PROGRAM 2
. . o | DECLARE LOOP LABEL;
LOCP: X=X+1; | LOOP: X=X+1:
DO; | DO;
DECLARE EXIT LABEL;
ое = e DECLARE Q1 LABEL;
GO TO Q1; | GO TO Q1;
01: Y=Y+1;: | Q1: Y = Y+1;
GO TO LOOP: | GO TO LOOP;
END; | END;
|
GO TC EXIT; | GO TO EXIT;
EXIT: HALT; | EXIT: HALT;
EOF | EOF —
PROGRAM 3
X=X+1; | X=X+1;
DO: | DO;
о. = | DECLARE L11 LABEL;
GO TO L1; | GO TO L1;
11: Y=Y+1: | 11: Y=Y+1;
END; | END;
. e. e | DECLARE L1 LABEL;
L1: Q=Q+3; | L1: Q=Q+3;
GO TO L1; | GO TO L1;
EOF | EOF
The only instance which requires explicit declaration
of a label is when a GO TO statement in an inner nested
41
block references a label in an outer block, and the label
follows the GO TO statement. Consider the fcllowing
program, for example.
/% BLOCK 1 */
X = X + 1;
DO; /* BLOCK 2 */
GO TO EXIT;
END /* OF BLOCK 2 */;
EXIT: HALT;
EOF
The implied label declaration created by the PL/M compiler
for the label EXIT results in the program
X =X + 1;
DO;
DECLARE EXIT LABEL;
GO TO EXIT;
DECLARE EXIT LABEL;
EXIT: HALT;
EOF
Note that the resulting program is in error since the
implied declaration of EXIT in block 2 indicates that the
scope of EXIT is only block 2, conflicting with its
occurrence in block 1. Thus, the label declaration can be
used to remedy the situation. The programmer overrides the
implied declaration with
DECLARE EXIT LABEL;
42
EXIT: HALT;
EOF
As a final note, the PL/M programmer is encouraged to
use the IF-THEN-ELSE and DO-group constructs in the place of
labelled statements and GO TO's whenever possible. The
effect in most cases is better object code and improved
readability of the source program.
15. Compile-Time Macro Processing.
PL/M allows declaration and expansion of simple macros
at compile time. The LITERALLY declaration in PL/M allows
the programmer to define an identifier to represent a
sequence of arbitrary characters. The PL/M compiler
automatically substitutes the defining string at each
occurrence of the defined identifier. The form of the
LITERALLY declaration is
DECLARE identifier LITERALLY string;
where the identifier is any valid PL/M name which does not
conflict with previous declarations, and the string is an
arbitrary PL/M string, not exceeding 255 characters in
length.
The following program illustrates the use of the PL/M
macro facility
DECLARE TRUE LITERALLY '1!,
FALSE LITERALLY "0';
43
CECLARE DCL LITERALLY 'DECLARE?!,
LIT LITERALLY 'LITERALLY';
DCL FOREVER LIT 'WHILE TRUE';
DCL (X,Y,Z) BYTE;
X = TRUE;
DO FOREVER; Y=Y+1;
IF Y > 10 THEN HALT;
END;
EOF
The declarations on lines 1 and 2 allow the programmer to
use the symbols TRUE and FALSE instead of 0 and 1, which
often makes the program more readable. The declarations for
DCL and LIT define abbreviations for DECLARE and LITERALLY,
respectively.
The DC FOREVER statement on line 8 first expands to DO
WHILE TRUE. The macro expansion of TRUE then results in a
loop headed by DO WHILE 1 (which executes indefinitely,
until the HALT statement is executed).
The LITERALLY declaration is also useful for declaring
fixed parameters for the particular compilation, but which
may change from one compilation to the next. Consider the
program below, for example:
DECLARE ASIZE LITERALLY '300',
PBASE LITERALLY '4000°,
SUPERVISOR LITERALLY '200';
DECLARE (A (ASIZE) ,I) ADDRESS;
PBASE: A (ASIZE-10) = 50;
GO TO SUPERVISOR;
EOF
44
In this case, ASIZE defines the size of the vector A. The
value of ASIZE can be altered in the LITERALLY declaration
without affecting the remainder cf the program. Similarly,
the value of PBASE defines the starting location of the
program since it expands to a numeric label. The expansion
of the PBASE macro results in the statement
4000: A (ASIZE-1) = 50;
In the case of the SUPERVISOR macro, the statement "GO TO
SUPERVISOR" 1s replaced by "GO TO 200" resulting in a
transfer to absolute address 200 in memory.
16. Predeclared Variables and Procedures.
The LENGTH and LAST forms described previously are
called built in procedures. A number of additional
predeciared variables and procedures are described in this
section, which are intended to ease the programming task.
It should be noted that these variables and procedures
are assumed to be declared at an outer encompassing block
level which 1s invisible to the programmer. Thus,
declarations of variables and procedures with identical
names within the program override the predeclared names.
16.1. Condition Code Variables. There are four
variable names in PL/M which can be used to test the
condition codes in the MCS-8 CPU. These names are
CARRY ZERO SIGN PARITY
Any occurrence of one of these variables generates an
immediate test of the corresponding condition code flip-flop
for a true condition (value is 1). The use of these
variables is somewhat implementation-dependent, and 15
described more completely in the section cn PL/M system
notes. In any case, these variables cannot be used as the
destination cf an assignment.
45
16.2. The MEMORY Vector. It is often useful to
address the area cf memory following the last variable
allocated in a particular program. PL/M provides this
facility by automatically inserting the declaration
DECLARE MEMORY (0) BYTE;
as the last declaration in every program.
As an example, consider the following program. This
program assumes it will execute on a machine with 10 pages
(2560 bytes) of memory. The program initializes all
remaining space after the program variable storage to 1's.
DECLARE SIZE LITERALLY '2559°¢',
I ADDRESS;
DO I = MEMORY TO SIZE;
MEMORY (I - .MEMORY) = 1;
END;
EOF
16.3. The TIME Procedure. A built-in procedure,
called TIME, is provided in PL/M for waiting a fixed amount
of time at a particular point in the program. The form of
the call is
CALL TIME (expression) ;
where the expression evaluates to a byte quantity n between
1 and 255. The wait time is measured in increments of 100
usec; hence, the total time-out for a value n is
n(100 usec).
Thus, the call to TIME shown below results in a 4500 usec
(4.5 msec) time-out
CALL TIME (45) ;
Since the maximum time-out is 255*%100 usec = 25500 usec
= 25.5 msec, longer wait periods are affected by enclosing
the call in a loop. The following loop, for example, takes
1 second to execute
DO I = 1 TO 40;
46
CALL TIME (250);
END;
16.4. Ty pe Transfer Procedures. Two built-in
procedures are provided in PL/M to convert ADDRESS values to
BYTE values. The procedure calls take the forms
LOW (expression) and HIGH (expression)
The LOW procedure returns the low-order byte of a double
byte value, while the HIGH procedure returns the high-order
byte. Either call can be used wherever a byte expression is
vaiid in PL/M.
16.5. Bit Manipulation Procedures. Four procedures
are provided in PL/M for shifting and rotating expressions.
These procedure calls take the forms )
SHL(expression1, expression2);
SHR (expression1,expression2);
ROL (expression3,expression2);
ROR (expression3, expression2);
In these cases, expression1 can be either byte or double
byte, but expression2 and expression3 must be single byte
values.
The SEL and SHR procedures shift expression] to the
left or right by an amount given by expression2,
respectively. The precision of the result is the same as
that of expression. Note that the value of expression?
must be greater than zero.
The value of SHL(1000$0011B,2), for example, is the
byte value 00001100B. The call SHR(1$0000$1100B,1) results
in the double byte value 0$1000$01108B.
The ROL and ROR procedures rotate the value of the byte
expressicn3 to the right or left by an amount given by
expression2, respectively. Again, expression2 must be
47
greater than zero. Both procedures always return a byte
value. The value of ROL(1011$000B,2) is 1100$0010B, and the
value of ROR (1111$0000B,8) is 1111$0000B.
The SHL, SHR, ROL, and ROR calls can appear anywhere a
PL/M expression is allowed.
16.6. 1/0 Processing. The built-in procedure INPUT
and built-in variable OUTPUT were introduced earlier. In
general, the input call takes the form
INPUT (constant)
where the constant is in the range 0 to 7. The effect of
the call is to read the input port designated by the
constant. The result of the call is the byte value latched
into the port. The call to INPUT can appear as a part of
any valid PL/M expression.
The pseudo-variable OUTPUT can only be used as the
destination cf an assignment. The form is
OUTPUT (constant) = expression;
where the constant is in the range 0 to 23. The value of
the expression is latched into the output port designated by
the constant.
This section completes the tutorial introduction to
PL/M. The section which follows provides more detailed
discussion of the individual statements and constructs of
PL/M.
48
III. A FORMAL APPROACH TO PL/M.
(Section III is currently incomplete. The BNF description of PL/M is included, however, for reference purposes.)
1 <PROGRAM> ::= <STATEMENT LIST>
2 <KSTATEMENT LIST> ::= <STATEMENT>
3 | <STATEMENT LIST> <STATEMENT>
4 <STATEMENT> ::= <BASIC STATEMENT>
5 | <IF STATEMENTS
6 <BASIC STATEMENT> ::= <ASSIGNMENT> 3
7 <GROUP> y;
8 <PROCEDURE DEFINITION> 5:
9 {RETURN STATEMENT> :
10 CCALL STATEMENT :
11 <GO TO STATEMENT> :
12 <DECLARATION STATEMENT> :
13 HAUT 3
15 <LABEL DEFINITION> <BASIC STATEMENT>
16 <IF STATEMENT> ::= <IF CLAUSE> <STATEMENT>
17 <IF CLAUSE> <TRUE PARTS <STATEMENT>
18 <LABEL DEFINITION> <IF STATEMENT>
19 <IF CLAUSE> ::= IF <EXPRESSION> THEN
20 <TRUE PART> ::= <BASIC STATEMENT> ELSE
21 <GROUP> ::= <GROUP HEAD> <ENDING>
22 <GROUP HEAD> ::= DO:
23 DO <STEP DEFINITION> ;
24 DO <WHILE CLAUSE> 3
25 DO <CASE SELECTOR> :
26 <GROUP HEAD> <STATEMENT>
27 <STEP DEFINITION> ::= <VARIABLE> <REPLACE> <EXPRESSION> <ITERATION CONTROL>
28 <ITERATICN CENTROL> ::= <TO> <EXPRESSION>
29 | <TO> <EXPRESSION> <BY> <EXPRESSION>
<WHILE CLAUSE> ::= <WHILE> <EXPRESSION>
31 <CASE SELECTOR> ::= CASE <EXPRESSION>
32 «PROCEDURE DEFINTION> ::= <PROCEDURE HEAD> <STATEMENT LIST> <ENDING>
33 <PROCECURE HEAD> ::= <PROCEDURE NAME> ;
34 <PROCEDURE NAME> <TYPE>
35 <PROCEDURE NAME> <PARAMETER LIST> ;
36 <PROCEDURE NAME> <PARAMETER LIST> <TYPE> :
37 <PROCEDURE NAME> ::= <LABEL DEFINITION> PROCEDURE
38 <PARAMETER LIST> ::= <PARAMETER HEAD> <IDENTIFIER> )
39 <PARAMETER HEAD> ::= (
40 | <PARAMETER HEAD> <IDENTIFIER> ,
41 <ENDING> ::= ENC
42 END <IDENTIFIER>
43 <LABEL DEF INITION> <ENDING>
44 <LABEL DEFINITION> ::= <IDENTIFIER> :
45 | <NUMBER> :
46 <RETURN STATEMENT> ::= RETURN
47 | RETURN <EXPRESSION>
48 <CALL STATEMENT> ::= CALL <VARIABLE>
49 <GO TO STATEMENT> ::= <GO TO> <IDENTIFIER>
50 | <<GO TO> <NUMBER>
51 <GO TO> ::= GO TO
52 | GOTC
53 <DECLARATION STATEMENT> ::= DECLARE <DECLARATION ELEMENT>
54 | <DECLARATION STATEMENT> , <CECLARATION ELEMENTS
55 <DECLARATION ELEMENT> ::= <TYPE DECLARATION>
56 <IDENTIFIER> LITERALLY <STRINC>
57 <IDENTIFIER> <DATA LIST>
58 <DATA LIST> ::= <DATA HEAD> <CONSTANT> )
59 <DATA HEAD> ::= DATA ({
60 | <DATA HEAD> <CONSTANT>
61 <TYPE DECLARATION> ::= <IDENTIFIER SPECIFICATION> <TYPE>
62 <BOUND HEAD> <NUMBER> |] <TYPE>
63 <TYPE DECLARATION> <INITIAL LIST>
49
alm a O
WN —O 00
~~
Nn
Y
Où do ‘Л
o
©
O 00060 00000 DD OO DO mo om Co Y
OD OYE PUNO ONU NA O0 01 CUL WN m
N Nr a pa a
+ OU OY MCU Sno
pa = ps pe ны | венце poa AA pet pes pe
NNN
е8 LU D N
nll
J
un
+
<TYPE> 3:=
<BOUND HEAD> ::= <IDENTIFIER SPECIFICATIONZ (
<IDENTIFIER SPECIFICATION> ::= <VARITABLE NAME>
| <IDENTIFIER LIST> <VARIABLE NAME> }
<IDENTIFIER LIST> <= { |
{ <IDENTIFIER LIST> <VARIABLE NAME> ,
= <IDENTIFIER>
| <BASED VARIABLE> <IDENTIFIER>
<BASED VARIABLE> 2: <IDENTIFIER> BASED
<VARIABLE NAME> -:
INITIAL LIST> ::= <INITIAL HEAD> <CONSTANT> )
<INITIAL HEAD> ::= INITIAL |
{| <INITIAL HEAD> <CONSTANT> y»
<ASSIGNMENT> ::= <VARIABLE> <REPLACE> <EXPRESSION>
| <LEFT PART> <ASSIGNMENT>
<REPLACE> ::= =
CLEFT PARTY> ::= <VARIABLE> ,
<EXPRESSION> ::= <LOGICAL EXPRESSION>
| <VARIABLE> : = <LOGICAL EXPRESSION>
<LOGICAL EXPRESSION> ::= <LOGICAL FACTOR>
<LOGICAL EXPRESSION> DR <LOGICAL FACTOR>
<LOGICAL EXPRESSION> XOR <LOGICAL FACTOR>
<LOGICAL FACTOR> ::= <LOGICAL SECONDARY>
| <LOGICAL FACTOR> AND <LOGICAL SECONCDARY>
<LOGICAL SECONCARY> ::= <LOGICAL PRIMARY>
| NOT <LOGICAL PRIMARY>
<LOGICAL PRIMARY> ::= <ARITHMETIC EXPRESSION>
{ <ARITHMETIC EXPRESSION> <RELATION> <ARITHMETIC EXPRESSICN>
<RELATION> ::= =
>
<>
=
> =
<ARITHMETIC EXPRESSIONS ::= <TERM>
| ZARITHMETIC EXPRESSION> + <TERM>D
| CARITHMÉTIC EXPRESSIONS - <TERMD
<ARITHMETIC EXPRESSION> PLUS <TERM>
| <ARITHMETIC EXPRESSION> MINUS <TERM>
- <TERM>
<TERM> ::= <PRIMARY>
<TERM> * <PRIMARY>
<TERM> / <PRIMARY>
<TERM> MOD <PRIMARY>
<PRIMARY> =::= <CONSTANT>
» <CONSTANT> .
CONSTANT HEAD> <CONSTANT> ]
<VARIABLE>
. <VARIABLED>
( <EXPRESSION> )
<CONSTANT HEAD> :2:= e. |
| <CONSTANT HEAD> <CONSTANT> +
<VARIABLE> <2:= <IDENTIFIER>
| <SUBSCRIPT HEAD> <EXPRESSION> )
<SUBSCRIPT HEAC> 3:= <IDENTIFIER> ( |
| <SUBSCRIPT HEAD> <EXPRESSION> ,
<CONSTANT> ::= <STRING>
| <NUMBER>
<TO> ::= TO
<BY> t= BY
<WHILE> ::= WHILE
50
IVe COMPIIING AND DEBUGGING PL/M PROGRAMS®
This section discusses procedures for compiling and
debugging PL/M programs. A complete compilation of a PL/NM
program is performed in two distinct parts: the first
phase, referred to as PLM1, scans the source program, and
produces an intermediate form. The second phase, called
PLM2, accepts this intermediate form and produces the
machine code for the MCS-8 CPU. All errors in rrogram
syntax are detected in PLMI.
The debugging process begins following successful
compilation of a PL/M program. This debugging phase
consists of an execution of INTERP/8 which accepts the
machine code produced by PLM2 and simuiates the acticns of
the MCS-8 CPU. INTERP/8 has a number of facilities which
aliow monitoring of CPU action, allowing symbolic and
absolute reference to machine code and variable storage
locations (see Appendix III of the INTEL publication "MCS-8
Micro Computer Set 8008 Users Manual") These three phases
are described in detail in the sections which follow.
1. PLM1 Operating Procedures.
The first pass of the PL/M compiler scans the source
program, and detects improperly formed declarations and
statements. A listing of the source program can be obtained
during this pass. Errors are listed by line number whether
the source listing is produced or not. An error message
produced Бу PLM1 takes the form:
(nnnnn) ERROR m NEAR S
The number nnnnn corresponds to the line where the error
occurred, s is a symbol on the line near the error, and m
corresponds to the particular error message as given in
51
rij
|!
te
£i
H
UM
Hd
«<
i
mam
®
Before discussing the files referenced by PLM1, it is
necessary to present the file naming scheme used thrcughout
the three programs PLM1, PLM2, and INTERP/8. These three
programs are written in ANSI standard FORTEAN with the
intention of being as independent from the host computer as
possible. Thus, only a few assumptions can be made about
the physical input and output devices or FORTRAN logical
unit numbers and corresponding file names used in any
particular implementation. Instead, these three programs
use an internal file numbering scheme which is consistent
between the three programs, but which may differ in terms of
FORTRAN logical units from installation to installation.
The machine-independent approach here is to give the file
numbering in terms of devices types, and allow any
particular implementation to assign the most convenient
FORTRAN units.
The file numbers used throughout PLM1, PLM2, and
INTERP/8, along with the corresponding device types, are
shown in Figure IV-2. Two examples of FORTRAN unit number
assignments for the PDP-10 and IBM System/360 computers are
shown in Figure IV-3.
A number of compiler control switches are used during
the execution of pPLM1 to control I/O based upon this file
numbering scheme. Additional switches are provided to
control other compile-time functions during this pass, as
given below. Compiler control switches come in two forms:
compiler toggles, and compiler parameters. Compiler toggles
can take on only the values 0 and 1 (generally specifying an
"on" or "off" condition), while compiler parameters can be
any non-negative value.
A compiler switch is specified to PLM1 by typing a line
52
ERROR
NUMRER
4
11
12
14
15
16
17
19
28
21
22
Figure IV-1.
MESSAGE
pr wm an mm == зе TR = GE a Wr am ER EE Wee GUE Se oar GF AE UP UE mewn TE AE Ar me = EF Mp ae м o
THE SYMBOLS PRINTED BELOW HAVE BEEN USED IN THE CURRENT 3LNCK
BUT DO NOT APPEAR IN A DECLARE STATEMENT, OR LASEL APPEARS [У
A GO TO STATEMENT BUT DOES NOT APPEAR IN THE BLOCK,
PASS-1 COMPILER SYMBOL TABLE OVERFLOW, TNO MANY SYMBOLS IN
THE SOURCE PROGRAM. EITHER REDUCE THE NUMBER OF VARIARLES Ia
THE PROGRAM, OR RE-COMPILE PASS-1 WITH A LARGER SYM3IL TA3Le.
INVALID PL/M STATEMENT. THE PAIR SF SYMBOLS PRINTEN 3FLOA4
CANNOT APPEAR TOGETHER IN A VALID PL/M STATEMENT (THIS ERROR
MAY HAVE BEEN CAUSED BE A PREVIOUS ERROR IN THE PROG:2A%),
INVALID PL/M STATEMENT. THE STATEMENT IS IMPROPERLY FOR E D--
THE PARSE TO THIS POINT FOLLOWS (THIS MAY HAVE OCTUIRTD ЭЕ-
CAUSE OF A PREVIOUS PROGRAM ERROR).
PASS-1 PARSE STACK OVERFLOW. THE FROGRAM STATEMEMTS ARF
RECURSIVELY NESTEN TOO DEEPLY: EITHER SIMPLIFY THE PRASGHAN
STRUCTURE, OR RE-COMPILF PASS-1 WITH A LARGIR PARSE STAUK.
NUMBER CONVERSION ERROR. THE NUMBER EITHER EXCEEDS 65535 OP
CONTAINS DIGITS WHICH CONFLICT WITH THE RADIX INDICATOR,
PASS-1 TABLE OVERFLOW. PROBABLE CAUSE 15 a CCHSTAMT 57-1050
WHICH tS TOO LONG. IF SOC, THE STRING SHY ND RE WITTEN 45 #
SEQUENCE OF SHORTER STRINGS, SEPARATED ry COMMAS, QTUCINTSE,
RE-COMPILE PASS-1 WITH A LARGER VARC TARLZ,
MACRO TASLE OVERFLOW. TOO MANY LITERALLY DECLARAT(0'JS,
EITHER REDUCE THE NUMBER IF LITERALLY DOFCILARATIONS, 9P RE-
CAMPILE PASS-1 WITH A LARGER "MACROS TARMI E.
INVALID CONSTANT IN INITIAL, DATA, NR InN-L TIE CONSTANT,
PRECISION OF CONSTANT EXCEEDS TWO BYTES (MAY BF INTERNAL
PASS-1 pOMPILER ERROR).
INVALID PROGRAM, PROGRAM SYNTAX INCORRECT FOR TERMINATION
OF PROGRAM. MAY BE DUE TO PREVIOUS ERRORS wHICH OCo PET
WITHIN THE PROGRAM,
INVALIO PLACEMENT OF A PROCEDURE DECLARATION WITHIN THE PL/M
PROGRAM, PROCEDURES MAY ONLY BE DECLARED IN THE QUTER BLOCK
(MAIN PART OF THE PROGRAM} OR WITHIN DO-END GROUPS (NOT
ITERATIVE DO'S, DO-WHILE'S, OR DO-CASE'S).
IMPROPER USE OF IDENTIFIER FOLLOWING AN END STATEMENT,
IDENTIFJERS CAN ONLY BE USED IN THIS Way TN CLOSE A PROCEDURE
DEFINITION.
iNENTIFIER FOLLOWING AN END STATEMENT DOES NOT MATCH THE NAME
NF THE PRCCFDURE WHICH IT CLOSES.
DUPLICATE FORMAL PARAMETER NAME IN a PROCEDURE HEAGING,
IDENTIFIER FOLLOWING AN END STATEMENT CANNOT BE FOUND IN THE
PROGRAM,
PUPLICATE LABEL DEFINITION AT THE SAME BLOCK LEVEL.
NUMERIC LABEL EXCEEDS CPU ADDRESSING SPACE,
INVALID CALL STATEMENT. THE NAME FCLLOWING THE CALL IS NOT
A PROCEDURE.
INVALID DESTINATION IN A GO TO, THE VALUE MUST BE A LABEL
OR SIMPLE VARIABLE,
MACRO TABLE OVERFLOW (SEE ERROR E& ABOVE).
DUPLICATE VARIABLE OR LABEL DEFINITION,
VARIABLE WHICH APPEARS IN A DATA DECLARATION HAS BEEN PRE-
VIOUSLY DECLARED IN THIS BLOCK
PLM1 error messages issued during the first
pass.
53
23
24
25
26
27
28
29
3p
31
32
33
34
35
37
38
PASS-1 SYMBOL TABLE OVERFLOW (SEE ERROP 2 ABOVE).
INVALID USE OF AN IDENTIFIER AS A VARIABLE NAME,
PASS-1 SYMBOL TABLE OVERFLOW (SEE ERROR 2 ABNYE),
IMPROPERLY FORMED BASED VARIABLE DECLARATION. THE FORM IS
I BASED J» WHERE 1 IS AN IDENTIFIER NOT PREVIOUSLY DECLARED
IN THIS BLOCK, AND J IS AN ADDRESS VARIABLE,
SYMBOL TABLE OVERFLOW IN PASS-1 (SEE ERROR 2 ABOVE).
INVALID ADDRESS REFERENCE, THE DOT OPERATOR MAY ONLY
PRECEDE SIMPLE AND SUBSCRIPTED VARIABLES IN THIS CONTEXT,
UNDECLARED VARIABLE, THE VARIABLE MUST APPEAR IN A DECLARE
STATEMENT BEFORE ITS USE,
SURSCRIPTED VARIABLE OR PROCEDURE CALL REFERENCES AN UN-
DECLARED IDENTIFIER, THE VARIABLE OR PROCEDURE MUST BE
DECLARED BEFORE IT IS USED,
THE IDENTIFIER 1S IMPROPERLY USED AS A PROCEOURE OR SUa-
SCRIPTEN VARIABLE,
TOO MANY SUBSCRIPTS IN A SUBSCRIPTEM VAR'ABLE REFERENCE,
PL/M ALLOWS ONLY CNE SUBSCRIPT,
ITERATIVE DO INDEX IS INVALID, [N THE FORM ‘DO ] = El TO E?!
THE VARIABLE I MUST BE SIMPLE (UNSUBSCRIFTED).
ATTEMPT TO COMPLEMENT A $ CONTROL TOGGLE WHERE THE TOGGLE
CURRENTLY HAS A VALUE OTHER THAN % OR 1, USE THE '= Nt
OPTION FOLLOWING THE TOGGLE TO AVOID THIS FRROF,
INPUT FILE NUMBER STACK OVERFLOW. RE-COMPILE PASS-1 WITH
A LARGER INSTK TABLE.
TOO MANY BLOCK LEVELS IN THE PL/M PROGRAM. El THER SIMPLIFY
YOUR PROGRAM (37 BLOCK LEVELS ARE CURRENTLY ALLOWED) OR
RE-COMPILE PASS-1 WITH A LARGER BLOCK TABLE,
THE NUMBER OF ACTUAL PARAMETERS IN THE CALLING SEQUENCE
IS GREATER THAN THE NUMBER OF FORMAL PARAMETERS DECLARED
FOR THIS PROCEDURE.
THE NUMBER OF ACTUAL PARAMETERS IN THE CALLING SEQUENCE
IS LESS THAN THE NUMBER OF FORMAL PARAMFTEX3 DECLARED
FOR THIS PROCEDURE,
Figure IV-1 (Con't)
54
Input
Internal File Number Input Device
Interactive Console
Card Reader
Paper Tape
Magnetic Tape A
Magnetic Tape B
Sequential Disk A
Sequential Disk B
= СО UTE WNH
Output
Internal File Number Output Device
Interactive Console
Line Printer
Paper Tape
Magnetic Tape C
Magnetic Tape D
Sequential Disk C
Sequential Disk D
3 OUI A OO ND HA
Figure IV-2. Symbolic Device Assignments for PLM1, PLMZ,
and INTERP/8.
55
PASS-1 FILE DEFINITICNS
POP-10
INPUT OUTPUT
AIM DEVICE UNIT NUM DEVICE UNIT
1 TTY 5 1 TTY 5
2 CDR 2 2 PTR 3
3 PAP 6 3 PAP 7
4 MAG 1€ 4 MAG 17
5 DEC 9 5 GEC 12
6 DISK 2¢ 6 DISK 22
7 DISK 21 7 DISK 23
IRM S/362 (CP/CMS)
INPUT QUTPUT
MUM NEY ICE UNTT NUM DEVICE UNIT
1 TTY 39 5 1 TTY 127 6
2 COR $ 19 2 PTR 133 6
3 TAP 38 11 3 PUN BO 7
4 TAP 140 9 4 TAF 133 12
5 nEK R2-Li 13 5 Sk EZ-13 13
6 nsk 8% 1 6 Dix BB 3
7 DSK 849 2 7 DSK 82 4
PASS-2 FILE DEFINITIONS
POR-18
INPUT QUTPUT
NUM DEVICE UNTT MUM DEVICE UNIT
1 TTY 5 i TTY 5
2 COR 2 2 PTR 3
3 PA? 6 3 PAP 7
4 MAG 16 4 MAG 17
5 DEN 9 5 DEC 3,2
6 DISK 2¢ 6 DISK 22
7 DISK 23 7 DISK 21
IRM S/36%9 (CCP/CMS)
INPUT OUTPUT
NUM DEVICE UNIT NUM DEVICE UNIT
1. TTY 80 5 1 TTY 127 5
2 CHR aß 19 2 PTR 133 8
3 TAP 80 il 3 Plis 80 7
4 TAP 140 9 4 TAP 133 12
5 nSK 84-18 13 5 nSx 82-12 13
6 DSK 89 2 6 DSK 82 1
7 DSK 82 4 7 DSK 82 ?
ALL INPUT RECORDS ARE 82 CHARACTERS OR LESS. ALL
QUTPUT RECORDS ARE 128 CHARACTERS OR LESS.
THE FORTRAN UNIT NUMBERS CAN BF CHANGED IN THE
SUBROUTINES GNC AND WRITEL (THESE ARE THE ONLY OC-
CURRENCES OF REFERENCES TO THESE UNITS),
Figure IV-3. PDP-10 and IBM System/360 real device assignment.
56
of input with a "$" in column 1, and a switch name starting
in column 2 (only the first character of the switch name is
significant, and the remaining characters may be omitted).
In the case of compiler parameters (and, optionally compiler
toggles), the switch name is followed by an equal sign (=)
and an integer value. A compiler toggle with the equal sign
and number omitted is complemented (a 0 becomes a 1, and a 1
changes to a 0). Compiler switches are not printed in the
source listing.
The most commonly used compiler switches for PLM1 are
listed in Figure IV-4, along with their default values.
Note that compiler toggles are listed in Figure IV-4 without
the "= n" option although it is understood that either "= 1"
or "= 0" is acceptable. Compiler parameters are listed in
the Figure with the "= n" part following the switch name.
The value of n is assumed to be in the proper range.
Finally, note that the default values shown here are those
provided by INTEL in the distribution version of the system
and assume a batch processing environment. Any particular
implementation may have differing default values (e-g.,
values may assume a time-sharing mode of processing), and
thus the local installation should be consulted.
The operation of the first pass can now be described.
PLM1 begins by reading the input file number which is
defaulted by the $INPUT switch. Normally, this switch
defaults to the card reader if operating in batch mode, and
to the terminal af operating in interactive mode.
Subsequent switches in the primary file can be used to
change these default values, if necessary (e.g., reset the
left or right margin, or change to an alternate input file).
The first pass normally creates a listing file on output
file number 2, an intermediate symbol table on file 6, and
an intermediate code file on file 7.
57
Switch Name
SANALYZE
SCOUNT = n
$DELETE = n
SEOF
SGENERATE
SINPUT = n
SLEFTMARGIN=n
SMEMORY
SOUTPUT = n
SPRINT
SRIGHTMARGIN=n
SEYMBOLS
STERMINAL
SWIDTH = n
NOTE:
Use Default
Controls the PL/M syntax analysis 0
trace.
Start the line numbering at line n. 0
Delete all trailing characters in 120
the output after position n.
End-of-file on this unit. 0
Interlist the intermediate language
generated by Pass 1.
Switch to file n for subsequent 1
input (see PL/M file numbering).
Ignore all characters before column 1
n in the input lines.
Include a symbol table in the ENPF 0
tape produced by Pass 2 showing the
memory address assignments for
variables, labels, and procedures.
Write subsequent output lines to 1
file n (see PL/M file numbering).
Print output lines (batch mode). 1
Ignore all characters in the input 72
lines beyond position n.
Print a symbol table dump at the end 0
of Pass 1.
Interactive processing mode.
Set output line width to n charac- 72
ters.
The input lines are a maximum of 80 characters,
and the output lines cannot exceed 120 characters.
Figure IV-4.
PLM1 "$" compiler switches.
58
It should be noted that in an interactive mode, PLM1
starts by reading the progammer's console. At this point,
the programmer could type the program directly at the
console into PLM1. It is usually the case, however, that
the programmer first composes his program using the
time-sharing system's text editor. When PLM1 reads the
console for the first line of input, the programmer
redirects the PLM1 input to the disk file containing the
edited program using the $INPUT = n compiler switch, where n
‘is one of the input file numbers correspinding externally to
the edited program.
The output from PLMI can be directed to the
programmer's console, or to another device such as a disk
file or line printer using the $OUTPUT compiler switch
placed in the input stream. If the programmer selects the
console as an output device, it is often useful to set
$TERMINAL = 1 which automatically lists only the error
nessages at the terminal. The programmer then uses the line
numbers, along with the time-sharing system editor to locate
the errors and change the source program in preparation for
recompilation. In this way, a source listing of the program
need never be generated during the first pass. The program
is listed as the compilation proceeds if the STERMINAL
toggle 1s zero.
A practical approach to development of large PL/I
programs is to write the program in terms of a number of
independent procedures. Each of these procedures can be
compiled and debugged separately, and, after all procedures
are checked-out, the entire program can be compiled.
As an example, consider the program shown in Figure
IV-5. In this case, a procedure is shown, called INDEX,
which performs a cemparison of two character strings to
determine if the second string occurs as a substring in the
$MEMORY = 1
/ * THE INDEX PROCEDURE SEARCHES THE STRING STARTING AT
A!" FOR AN OCCURRENCE OF THE STRING STARTING AT 'B',
INDEX RETURNS A ZERO IF THE SECOND STRING IS NOT A SUB-
STRING OF THE FIRST; OTHERWISE, THE POSITION OF THE
SECOND STRING 1S RETURNED. THE CHARACTER POSITIONS ARF
COUNTED STARTING FROM 1 AND ENDING AT 255. */
DECLARE EOS LITERALLY 'OFFH':
/* THE LABELS LO ... L5 AND C1 ... C3 ARE PRESENT FOR DERUCCINC
PURPOSES ONLY, AND CAN BE REMOVED WITHOUT AFFECTING THE PROCPAM
EXECUTION */
INDEX: PROCEDURE (A,B) BYTE;
LO: DECLARE (A,B) ADDRESS,
(SA BASED A, SB BASED B, J,K,L,M) BYTE;
J = 0;
Li: DO WHILE SA(J) <> EOS:
K = 0;
L2: DO WHILE (L:=SA(J+K)) = (M:=SB(K)):
L3: IF L = EOS THEN RETURN J+1:
K = K + 1;
END;
J = J + 1;
Ly: IF M = EOS THEN RETURN J:
END;
LS: RETURN 0;
END INDEX;
/* TEST THE INDEX FUNCTION */
DECLARE Q DATA ('WALLAWALLAWASH', EOS),
(1,J) BYTE;
PO WHILE 1:
Cl: | INDEX(.0,.('WALLA',EOS));
C2: | = INDEX(.('WALLA',E0S),.Q);
C3: | = INDEX(.0,.("WASH',E0S));
END;
EOF
Figure IV-5. A card-image listing of the INDEX procedure.
60
first string, as described in the comment preceding the
procedure declaration. The last part of the program
(Following the declaration of Q) is present only to test the
INDEX procedure and will be removed when INDEX is imkedded
within a larger program. Note that this test section
includes three sample calls on INDEX which are regeated
indefinitely. The labels LO through LS within INDEX are
used only during the debugging phase, and have no effect
upon program execution. In fact, these labels may be
removed after the INDEX procedure is checked-out to avoid
later confusion as to the purpose of the labels.
Figure IV-6 shows a sample execution of PLM1 using the
above source program as input. The exact manner in which
PLM1 is started on any particular computer is, of course,
implementation dependent. A number of particular systems
are considered, however, in Section IV-4. The particular
example shown in Figure IV-6 resulted from execution of PLMI
on an IBM System/360 under the CP/CMS time-sharing system
using a 2741 console. Thus, all lines shown in lower case
in this example, and examples which follow, are typed by the
programmer, while upper case lines are output from the
program keing executed. The PLM1 output shown in this
figure indicates that the program is syntactically correct,
the intermediate files have been written, and the second
pass can te initiated.
2. PLM2 Operating Procedures.
As mentioned previously, PLM2 performs the second pass
of the PL/M compilation by reading the intermediate files
produced through execution of PLMI. PLM2 then generates
machine code for the MCS-8 CPU.
Error messages produced by PLM2 are of the form
(nannn) ERROR m
61
PASS-1
$i=2 (could use $0=2 for printer listing, $t=1 for no listing)
00001 2 /* THE INDFX PROCENURE SEARCHES THE STRING STAPTIMR AT
00002 2 'A' FOR AN OCCURRENCE OF THE STRING STARTING AT ‘rt,
00003 2 INDEX RETURNS A ZERO PF THE SECOND STRINC 15 MOT A SUPR-
00008 2 STRING OF THE FIRST; OTHERWISE, THE POSITIOM OF THF
00005 2 SECOND STRING IS RETURNED. THF CHARACTER POSITIOMS ARE
00006 2 COUNTED STARTING FROM 1 AND ENDING AT 255, */
00007 2 DECLARE EOS LITERALLY '"OFFH';
00008 2 /* THE LABELS LO ... L5 AND C1 ... C3 ARF PRESENT FOR NEBUCGI
00009 2 PURPOSES ONLY, AND CAN BE REMOVED WITHOUT AFFECTING THE PROG
00010 2 EXECUTION */
00011 2 INDEX: PROCEDURE (A,B) BYTE;
00012 3 LO: DECLARE (A,B) ADDRESS,
00013 3 (SA BASED A, SB BASED B, J,K,L,M) BYTE;
00014 3 J = 0;
00015 3 Lil: DO WHILE SA(J) <> EOS;
00016 3 K = 0;
00017 & 12: DO WHILE (L:=SA(J+K)) = (M:=SR(K));
00018 4 13: IF L = EOS THEN RETURN J+1;
00019 5 K = K + 1;
00020 5 END;
00021 4 J= J + 1;
00022 % Lu: IF M = EOS THEN RETURN J;
00023 4 END;
00024 3 L5: RETURN 0;
00025 3 END INDEX;
00026 2
00027 ? /* TEST THE INDEX FUNCTION =/
00028 2 DECLARE Q DATA C'WALLAWALLAWASH',EOS),
00029 2 (1,J) BYTE;
00030 2 DO WHILE 1;
00031 2 Cl: 1 = INDEX(.Q,.('WALLA',E0S));
00032 3 C2: 1 = INDFX(.('WALLA',EO0S),.Q);.
00033 3 C3: | = INDEX(.0,.("WASH', EOS));
00034 3 END;
00035 2 ECF
NO PROGRAM ERRORS
Figure IV-6. Listing produced by PLM1 for the INDEX procedure.
62
where nnnnn references the line in the source prograr where
the error occurs, and m is an error message number,
corresponding to those given in Figure IV-7.
Operation of the second pass is particularily simple.
PLM2 begins by reading the card reader (batch mode) or
console (time-sharing mode) and will accept any number of
"$11 syitches as input. These switches set the second pass
compiling parameters shown in Figure IV-8. PLM2 continues
to read these switches until one blank line is encountered.
At this point, PLM2 reads the intermediate files produced by
PLM1 and generates the MCS-8 machine code.
As in the case of PLM1, the exact manner in which the
PLM2 program is initiated is implementation dependent, and
will be discussed for some particular systems in Section
TIV-4.
Figure IV-9 shows the execution of PLHZ using the
intermediate files produced by PLM1 for the INDEX procedure
given previously. Figure IV-10 lists the BNPY machine code
file which results from this execution of PLH2. Note that
the machine code file is headed by a symbol table (caused by
the $MEMCRY=1 entry during PLM1) which will be used by
INTERP/8 during the debugging phase which follows.
3. Program Check-Out.
Program verification is accomplished through the use of
the MCS-8 CPU software simulator, called INTERP/8. The
various commands available in INTERP/8 are described fully
in the MCS-8 Users Manual. The PL/M program being
checked-out is first compiled using PLM1 and PILM2, as
previously described. In order to quickly locate errors in
the source program, it is helpful to include the $MEMORY=1
toggle in PLM1 so that a symbol table is produced for the
63
ERRQR
NUMBER
184
195
196
197
108
199
114
115
124
125
126
127
128
MESSAGE
ii Lee rr ee mr me rr tm rr, me tn, — —— ——
REFERENCE TO STCRAGE LOCATIONS OUTSIDE THE VIRTUAL MEMORY
IF PASS-2. RE-COMPILE PASS-2 WITH LARGER 'MEMORY' ARRAY,
"
VIRTUAL MEMORY OVERFLOW, PROGRA” IS TOO LARGE TO COMPILE
WITH PRESENT SIZE OF 'MEMORY.' EITHER SHORTEN PROGRAM OR
RECOMPILE PASS-2 WITH A LARGER VIRTUAL MEMORY,
{SAME AS 183),
STOGGLE USED IMPROPERLY IN PASS-2. ATTEMPT TO COMPLEMENT
A TOGGLE WHICH HAS A VALUE OTHER THAN ß OR 1,
REGISTER ALLOCATION TABLE UNDERFLOW, MAY BE DUE TO A PRE-
REGISTER ALLOCATION ERROR. NO REGISTERS AVAILABLE, MAY
BE CAUSED BY A PREVIOUS £RROR, OR PaSS-2 COMPILER ERROR,
PASS-2 SYMBOL TABLE OVERFLOW. PEDUCE NUMBER OF
SYMBOLS, OR RE-COMPILE PASS-2 WITH LARGER SYMBOL TABLE,
SYMBOL TABLE OVERFLOW (SEE ERROR 108).
MEMORY ALLOCATION ERROR, TOO MUCH STORAGE SPECIFIED IN
THE SOURCE PROGRAM (16K MAX ON 8808), REDUCE SOURCE PROGRAM
MEMORY REQUIREMENTS,
INLINE DATA FORMAT ERROR, MAY BE DUE TO IMPROPER
RECORD SIZE IN SYMBOL TABLE FILE PASSED TO PASS=2,
(SAME AS ERROR 197).
REGISTER ALLOCATION STACK OVERFLOW, EITHER SIMPLIFY THE
PROGRAM OR INCREASE THE SIZE OF THE ALLOCATION STACKS,
PASS-2 COMPILER ERROR IN 'LITADO! -e MAY BE DUE TO A
PREVIOUS ERROR,
(SAME AS 114),
(SAME AS 114),
LINE WIDTH SET TOO NARROK FOR CODE DIIMP (USE SWIDTHEN)
(SAME AS 187),
(SAME AS 118),
(SAME AS 119, BUT MAY BE A PASS-2? COMPILER ERROR),
(SAME AS 188),
PROGRAM REQUIRES TOO MUCH PROGRAM ANN VARIABLE STORAGE,
(PROGRAM AND VARIABLES EXCEED 16K),
INITIALIZED STORAGE OVERLAPS PREVIOUSLY (INITIALIZE) STORAGE,
INITIALIZATION TABLE FORMAT ERROR. (SES ERPNF 111),
INLINE DATA ERROR, MAY HAVE BEEN CAUSED ВУ PREVIOQUS ERROR,
BUILT-IN FUNCTION IMPROPERLY CALLED.
INVALID INTERMENTATE LANGUAGE FORMAT, (SEE ERPOR 111).
(SAME AS ERROR 113).
Figure IV-7. PLM2 error messages issued during the
second pass.
64
141
142
143
INVALID USE OF BUILT-IN FUNCTION IN AN ASSIGMMENT,
PASS-2 COMPILER ERROR, INVALID VARTABLE PRECISION (ET
SINGLE BYTE OR DOUBLE BYTE), MAY BE DUE TO PREVISIUS ERROR,
LABEL RESOLUTION ERROR IN PASS-2 (MAY BE COMPILER ERROR).
(SAME AS 108).
(SAME AS 113),
INVALID PROGRAM TRANSFER (ONLY COMPUTEL JUMPS ARE ALLOWED
WITH A "GO TO"),
(SAME AS 134),
ERROR IN BUILT-IN FUNCTION CALL.
(NOT USED)
(SAME AS 187),
ERROR IN CHANGING VARIABLE TO ADDRESS REFERENCE. MAY
ВЕ A PASS-2 COMPILER ERROR. OR MAY BE CAUSED BY PRE-
VOUS ERROR.
(SAME AS 187).
INVALID ORIGIN, CODE HAS ALREADY BEFN GENERATED IN THE
SPECIFIED LOCATIONS,
A SYMBOL TABLE DUMP HAS BEEN SPECIFIED (USING THE $МЕМОВУ
TOGGLE IN PASS-1), BUT NO FILE HAS RFEN SPECIFIED TC kE-
CEIVE THE BNPF TAPE (USE THE SENPF=N CONTROL).
INVALID FORMAT FOR THE SIMULATOR SYMBOL TABLE DUMP (SEE
FRROR 111).
Figure IV-7. (Con't)
65
Switch Name Use | | Default
SANALYZE = n Print a trace of the register allcca- 0
tion stack if п=1. Include assigned
registers if n = 2.
SBNPF = n Do not write a BNPF tape if n=0. Other- 0
wise, write a BNPF tape to file n (see
PL/M file numbering).
SCOUNT = n (Same as Pass 1)
SDELETE = n (Same as Pass 1)
SEOF (Same as Pass 1)
SFINISH Print a decoded dump of the generated 0
machine code at the finish of Pass 2.
SGENERATE = n Print a cross reference of source line 0
numbers verses machine code locations
if n=1. If n = 2, print a trace of
the intermediate language as it is read,
as well.
SHEADER = n Start machine code generation at loca- C
tion n when producing a code dump or
BNPF tape.
SINPUT = n (same as Pass 1)
SLEFTMARGIN=n (same as Pass 1)
SMAP | Print a memory map showing symbol num- 0
bers and address assignments at the end
of Pass 2.
SOUTPUT = n (same as Pass 1)
SPRINT (same as Pass 1)
SRIGETMARGIN=n (same as Pass 1)
STERMINAL (same as Pass 1, default value suppresses 0
the listing of the intermediate files as
they are read)
SVARIABLES = n The first page of Random-access Memory 0
(RAM) is page n (numbering 0, 1,...,63)
SWIDTH = n (same as Pass 1)
Figure IV-8. PLM2 "$" compiler switches.
66
PASS-2
¿generate =
Sbnpf = 6
12=0003H
19=0067H
25=0089H
35=00E6H
Figure IV-9.
1 (cross reference line numbers and locations in code)
(write bnpf tape to internal file number 6)
13=000EH 15=0011H 16=001EH 17=0026H 18=0043H
20=006DH 21=0071H 22=0077H 23=0084H 24=0087H
26=008AH 29=009CH 32=00A5H 3>=00BEH 34=00E1H
Sample output from PLM2 corresponding to the
INDEX procedure.
67
1 CARPY 00362
2 ZERO 00363
3 SIGN 0036
L PARITY 00365
6 МЕМОРУ 00800
19 INDFX 00003
20 A 00366
21 B 00370
23 LO 00016
26 J 00372
27 K 00373
28 L 00374
29 M 00375
31 L1 00021
35 L2 00054
38 L3 00132
41 LU 00170
43 L5 00207
44 0 00215
46 1 00376
47 J 00377
50 C1 00234
52 C2 00265
53 C3 00316
Figure IV-10.
ME EEE EEE dd EEE dad add EEE GE add EB EEE EEE
ЖЕ + * * * * *
GE EEE dei Ed kh kk RARE kh RA ARERR AAR kh hd kkk
tA RE XX KX
0
8
16
32
40
48
56
64
72
80
88
96
104
112
120
128
136
24h
152
160
168
176
184
19.2
200
208
216
224
232
BNPNHNPNNF
BUNENNENNE
PNNPPNHNNF
BHNPPNNNNF
BNNNNNNNNE
BPPPPPNPNF
RPHNMNPPPE
BNNNNNNNNF
BPPNNNPPPF
BPNNNNPPPF
BNNPPNPPNF
BNNPNPPPNF
BPPNNNPPPF
BPPPPNPPNF
BNNNNNPPNF
BPPPNPNNNE
BNNPPNPPNF
BPPNNPHNNF
BPNNNNPPPF
BNNNNNHNNE
BPPNNNPPPF
BPPPPPPNPF
BNPPPMNNPF
BNNNPNPNNF
BMNNNNNMNF
BNNNNPNNNF
BNNNNNNNNE
BNNNNPNNNF
BMNNNNNNNF
BPPPPPNPNF
BMNPPNPPNF
BPPPPPPPPF
BNNPPNPPNF
BNPNNNPNNF
BNNNNNPPPF
BNNNMMNNNF
BNPNNPPNNF
BNPNNPPNNF
BNPNNNNNPF
BNPNNNPNNF
BNPNNNNNPF
BPPPPPPPPF
BNNNNNNNNF
BNNNNNNNNE
BNNPNPPPNF
BPPPPPNNNF
BNPNPNPPPF
BNFHNNNNPF
BNNNPNPPNF
BNNPNNPPHF
ENNNNNNNNF
BPPPPPPPNF
ENNNNNNNNF
BMPNNPNNNF
BNNNPNPPNF
ENNPNNPPNE
BNNNNNNNNF
BPPPPPPPNF
ENNNNNNNNE
BPNNNPNPHF
PENPPHPPNF
RPPPPPHPME
BPPPPPPNNF
BENPNPPPNF
BPPNINPPPE
ENNPP MENT
BPNNNPPPPF
ENHNPNPNNEF
BNNNNNNNHE
BPPPPPNPPF
EMMNNNNNNF
BNNPPNNNNF
BPNNNNPPPE
BANNNNNNNE
ВРРЫММРРРЕ
BPPPPPPNNE
BPPNNNPPPF
BNNPPNNNNF
RPNNNPPPPE
BNNPNPPPNF
BPPPPPNNNF
BNNNNNNNNEF
BPPPPPPPPF
BNNPPNPPNF
BPPNNNNNPF
ENNPPNPPNF
BPPPPPNNPF
BNNPNPPPMF
BPPNNPPPPF
BPPPPPPNPF
BMPNNPMNNEF
BPPPPPNPNF
BNNNPNNNPF
BMHNMNPPPE
BNPNPNPPPF
BMPHMNNNPF
ВМРММРРММЕ
BNPNPNNPPF
BPNPNNPNPF
BNPNNPPNNE
BNNNNPPPNF
BNNNPPPPHEF
BMPNNNPPNEF
BNNNNMNNNE
BNPNNNPNNE
BNPNNNNNPF
BPPPPPPPPF
ENNNNNNNNF
BMNNNNNNNE
BMNPNPPENF
EPPPPPNNNF
BNPNPNPPPE
BPPPPPPPPF
BNNNNNNKNF
BNNNNNNNNE
PNNPNPPPNF
BPPPPPENNE
EPPPPPPPPF
ENNNNNNNNF
BPPPPHPPNF
BMNPPMNNNF
BENPPNNNHF
BMHNNMMMNF
DHNPPHPPME
PPPANPENNE
EPPPPMENPF
BPPPPPPPPF
BNYNPNPPPNF
ВИНРРРРРМЕ
BMMPPMPPNF
EPNMMNPPPF
BNNPPNNENE
BPHNNPPPPF
BNNPNPPPHE
ВРРРРРМММЕ
BNNPPNPPNE
BPPMPNNNNFE
BPPPPMMPNE
BNNNNNNANF
BPNNPNNNPF
ENNPPNNNPE
BNPNNPNNNEF
BPPPPPNPNE
BNNNNNPPPF
BPPPPPNPPF
BMPMNMNPNNF
BNNNNNNNNME
BNNNNPNNEF
BFPNNNPPPF
BPNNNNPNNF
BPPMMNPPPE
BNNNANNNNE
BNPNANPNNE
BNPANNNNPE
RHPNPHPPPE
ENPENNNNPE
BNPNNPNNNE
BHHMNMMMMNE
EMPNNPPNNEF
EPNNNPPNPF
RPMNPPPPPE
BYENNNNPPF
BNNPPMNPPMEF
BPMPPPPPNF
S"PENDPNNF
BMHMNPPPNF
BMNMPPPPMF
BHPMNNNPPNF
EANNNNNNNF
BNPMMNPNNF
ENPANENNPE
BNNNNPPPNE
BNNNPPPPNF
EN PANNNPPNE
BENNNMNNNE
EHPNNNPNNE
B'INPNPPPNF
ВРРРРРММРЕ
BPPPPPNPPF
RNNPPPPPNE
DINPANDPNF
BPPPPNPPHF
BNENENPPNF
EPPPHPENNE
BNPPNPANNE
BHNNMNNNNF
BNFNNNNNNE
EPPPPPNPNF
BNNPPNPPNF
BPPENPNNNE
ВРРРРМММРЕ
BNNNMMNMNE
RMNPPMMMPF
BPPPPPNNNF
BENNNNPPNF
BPPPHPHNNE
BNNPPNPPNF
BNPNNPNENF
BPPNNNPPPF
BNPPMNPPPF
BPPNNPPPPF
BHNPNPPPNF
BPPNNPPPPF
BNNPNPPNNF
BNNPPNPPNF
BPPPPPNNPF
BNNNPNPNNF
BNNNNENNNE
BNNNNNPPPF
BPNPNPNNNF
BPNNPPPNNF
BNPENPPANE
EMPNNNNNPF
BMPNPNPPPF
EFPPPPPPPF
BHPNPNPPPF
BNPNNNNNPF
ENNNENDPNE
BNNPANPPNE
BNNHNNNNNF
ВРРРРРРРМЕ
PHHNNNNNNF
BEPHNPPNNE
BPNPPPHNNE
BPHNNPPNPE
EMNNHNNPPF
BENPPHPPNF
BPPHPNPPNF
BNPNPHNPPF
EPNNNPPNPF
BPPNPNNNPF
BNNNNNNPPF
BNNPPNPPNF
EPNNPPPNNE
Symbol table and BNPF tape produced by PLM2
for the INDEX procedure.
68
simulation. In addition, key statements in the source
program should be labelled so that important points can be
referenced symbolically during program check-out (see the
use of the labels LO, ... L5, and C1, C2, and C3 in Figure
IV-6, for example).
The generated symbol table and compiled object ccde 1s
loaded into INTERP/8. Simulated program execution can then
be monitored, the values of memory locations can be examined
and altered, and program errors are readily detected.
Program check-out is usually more effective if debugging is
carried-out at the symbolic rather than absolute level.
That is, INTERP/8 allows reference to memory through both
symbtolic locations (using the generated symbol table) and
absolute addresses. As a result, it 1s generally much
easier to follow the execution using the symbolic features
of INTERP/8 than it is to trace the execution using absolute
memory addresses. Thus, it is well worth the effort to
become familiar with INTERP/8 symbolic debugging facilities.
A number of features have been added to the INTERP/8
program which enhances its use in debugging PL/M programs.
These features augment the commands described in Appendix
III of the MCS-8 Users Manual. These additions are given
below.
First, note that symbolic names can be duplicated in a
PL/M program. That is, a programmer could declare variables
with the same name in block levels which do not conflict
with one another. Consider the two procedures below, for
example
P1: PROCEDURE (A) BYTE;
DECLARE (A,B) ADDRESS;
END Pl;
P2: PROCEDURE (0) ADDRESS;
62
DECLARE (Q,A,B) BYTE;
END P2;
Recall that although there are variables in procedures P1
and P2 which have the same names (i.e., A and B), these
variables are all given separate storage locations. In
order to distinguish these variables, a construct cf the
form
S1/ 52 / «.. Sn
is allowed as a symbolic reference in INTERP/S. The
interpretation of this construct is as follows: INTERP/8
first searches for the symbol S1, then looks further to S2,
and so-forth until Sn is found. This new construct can
appear anywhere a "symbolic name" is allowed in the current
INTERP/8 command structure. Note that in particular, the
definition of a "range element" is extended to include this
new form. Thus, the command
DISPLAY MEMORY A TO B+1.
is the same as
DISP MEM P1/A TO P1/B+1.
The seccnd cccurrences of A and B can only be located by
first searching for the name P2. Thus, these two variables
could be displayed using the command
DI MEM P2/A TO P2/B.
A second change to the INTERP/8 commands allows
reference to a symbolic location when setting the value of
the program stack (PC, PS O, ... PS 7) or the value of the
memory address register (HL). With this addition, the
following are valid commands
SET PC = P2, PS 5 = P1.
SET HL = B.
SET HL = P2 / A + 1.
Two additional $ switches have been added to INTERP/8.
The first is of the form
70
$MAXCYCLE = n
When this switch has a non-zero value, the CPU simulation is
prevented from running more than n cycles fkefore returning
to the card reader or console for more input (n is initially
zero). The toggle
| $GENLABELS
was added to cause INTERP/8 to print the closest symbolic
name to the current program counter whenever a break point
is encountered. INTERP/8 prints
break AT n = label displacement
where "break" is one of the break point types: CYCLE,
ALTER, or REFER, and n is an absolute location. The value
of "label" is the closest symbolic name in the program,
while the displacement is a positive or negative distance
from the name to the location counter.
The last change to INTERP/8 allows imbedded dollar
signs within numbers and identifiers, as in PI/M.
These features are demonstrated in the example
described below. Figure IV-11 gives a sample run of
INTERP/8 using the symbol table and machine code produced by
PLM2 corresponding to the program containing the INDEX
procedure given previously. Again, the initiation of
INTERE/8 is system dependent and thus is not shown here.
The symbol table is first loaded from file 6, followed by
the machine code, also from file 6. Note that these file
numbers must correspond to the BNPF tape file written by
PLM2 (see the $BNPF switch in PLM2). The listing produced
by PLM1 is used, along with the symbolic reference features
of INTERP/8 to follow the program execution.
71
INTERP/8 VERS 1.0
/* first load the symbol table and bnpf tape from internal
file number 6 (corresponding to the $bnpf=6 i'n pass2) */
load 6 6.
234 LOAD OK
/* then look at the symbol table */
display
0003620
0003630
0003640
0003650
0004000
0000030
0003660
0003709
0600150
0003720
0003730
0003740
0003750
0000210
00005450
0001320
0001700
0002070
0002150
00037608
0003770
0002340
0002650
0003160
symbols,
00242
00253
00244
00245
00256
00003
00246
00248
00014
00250
00251
00252
00253
00017
00048
00090
00120
00135
00141
00254
00255
00156
00181
00206
00F24
OOF 3H
00F4H
OOF5H
0100H
OCO3H
COFEH
O0F 3H
000 EH
OOFAH
OOFBH
00FCH
00FDH
0011H
002CH
005AH
0078H
0087H
008DH
OOFEH
OCFFH
CO9CH
0OP5H
ООСЕН
CARRY
ZERO
SIGN
PARITY
MEMORY
INDEX
A
B
LO
cl
C2
C3
Figure IV-1ll.
/* set break points at places in the index procedures
iabelled by 10, ,15 */
11, . ..
refer 10,11,12,13,14,15,
REFER OK
/* it will probably be useful to examine the program
to index, so...*/
at the beginning and end of each call
ref cl,c2,c3.
REFER OK
/* now run the program to the first reference variable */
go 1000.
GO OK
REFER AT 156=C1
/* we are at location 156 decimal, or equivalentiy, label cl */
base hex.
HEX BASE OK
display symb *.
Cl
/* look at cpu registers ...*/
di cpu. i
CYZSP A 3 C D E H L HL SP PSS
#0000C+00H+COH*00H*00CH+0CH*00H#00H=00C0H*0CH=00SCH
di sym 9ch.
ci
Sample execution of INTERP/8.
12
di memory q to а+10.
008DH 57H 414 4CH 4CH 41H S7H L1H ECH LCH 41H 57H
/* that must be the hex representation of WALLAWALLAW */
di sy a.
0002150 00141 OO8DH
/* now run the program to entry of the subroutine */
go 1000.
GO OK
REFER AT EH=LO
/* now at label LO, so examine the value of a */
di mem a.
DOF65H 8DH
di mem a to a+l.
00F6H 8DH OOH
/* the first string is based at a, so look at it..*/
di mem 8dh to 90h.
008DH 57H 41H HCH SCH
/* looks good, now examine b's value */
di mem b to b+1.
OOF8H 9FH 00H
conv 9fh.
100111118 2370 159 9FH
di mem 159 to 165.
O0SFH 57H 41H 4CH LCH 41H FFH OEH
/* looks good too, so run the index procedure down to
label 12 (also, to save tYping go 1000, we can set maxcycle
to 1000 so the simulation will never run more than 1000 cycles
before stopping) */
$maxcycle = 1000
go.
REFER AT 11H=L1
go.
REFER AT 2CH=L2
/* examine the values of the local variables */
di mem index/j to index/m dec.
COFAH 000 000 000 000
di mem j to m.
COFAH DOM OOH OOH 00H
di sy Ofah.
J
/* run the procedure to label 15 +/
go.
REFER AT SAH=L3
/* both 1 and m should contain a 'w' */
di mem 1 to m.
QOFCH 57H 57H
73
/* we should get a match on characters W ALLA
and then return with the matching position 1 */
go. di m 1 tom.
REFER AT 2CH=L2
OOFCH 57H 57H
go. di m1 tom.
REFER AT SAH=L3
OOFCH L1H 41H
go . go. di m 1 to m.
REFER AT 2CH=12
REFER AT SAHEL3
OOFCH 4CH 4CH
/* so far we have matched W A | */
go. go. di m1 tom.
REFER AT 2CH=L2
REFER AT SAH=L3
OOFCH ECH &CH
/* turn off the break point at L2 since it is getting
in the way */
noref 12.
REFER OK
go. di ml tom.
REFER AT SAH=L3
OOFCH L1H 41H
/* this time we should return */
go.
REFER AT 78H=LL
di mem m.
COFDH РЕН
/* m = eos, so we should end up at label c2 */
ref 12. go.
REFER OK
REFER AT B5H=C2
/* the value of i should be 1 #/
di mi.
OOFEH 01H
di mi dec.
OOFEH 001
/* now try the second call */
go.
REFER AT EN=LO
di mem a to b+1.
COFOH REIT 004 80! ON
base dec.
NEC BASE OK
di mem a to b+1l.
00246 184 000 181 000
74
di mem 184 to 190, mem 181 to 147.
00124 0287 065 076 076 065 255 014
00141 087 065 076 076 065 087 065
/* strings are being sent properly, so we can continue,
we should return a 0 this time since the larger string
is not a substring of the smaller, so set reference
breakpoint only at 15 */
noref 10,11,12,13,14, go.
REFER OK
REFER AT 135=L5
/* looks good, so let the subroutine return */
O.
REFER AT 206=C3
di mem 1.
00254 000
noref 15. /* let the subroutine run, and see if
REFER OK
it returns the proper value */
go.
CYCLE AT 50=L2+6
/* we just ran over 1000 cycles, so let it continue */
go 5000.
GO CK
REFER AT 156=C1
/* we are now back around the loop. i will be an 11
if all is well */
di mem |.
0025 011
/* everything looks good, so we can now do a little
fooling around to show some of the other debugging
features -- first we will look at the operand break
point */
noref 0 to 256.
REFER OK
/* all reference break points are reset. we will now
set a break point so that program execution stops when
the variables local to index are referenced. */
refer j to k.
REFER OK
go.
REFER AT 15=L0+1
/* we stopped at the first instruction in index...
look to see what instructions are there */
75
di mem * to *+10 code.
00015 LM!,00H LHI,00H LLI,FAH LAN LLI F6H ADM INL
di hl,
HL = 250
di sy 250,
J
/* thus program execution has stopped because there
was an attempt to store a zero into a variable set
in the refer command run the program further...*/
go.
REFER AT 21=L1+4
di hl. dí mem * code.
HL = 250
00021 LAM
di sy 250.
J
/* breakpoint now occurs because of the reference to
the variable j. reset the break points, and
break only if the variable is being altered */
noref j tom. alter j tom.
REFER OK
ALTER OK
go.
ALTER AT 42=12-2
di hl, di m * code.
HL = 251
00042 LM!
di sy 251.
K
/* now stopped because of attempt to alter variable k=/
go.
ALTER AT 66=L2+22
di hl.
HL = 252
di sy 252.
L
di me * to * + 10 code.
00066 LMA DCL LBA LAM LL!,F8H ADM INL LCA LAI,OOH
di a.
A = 87
/* we are about to store the accumulator into the
variable 1. look to see what is currently in 1, and
then run one cycle, examine again. */
di mem 1.
00252 255
go 1.
GO OK
CYCLE AT 67=L2+23
76
di mem |.
00252 087
/* stored ok now reset all operand breakpoints,
and go back and try the call over again */
noalter j to m.
ALTER OK
di sy cl.
0002340 00156 009CH
di cpu.
CYZSP A B C Nn E H L HL SP PSO PS1
*«0101+087*141 000*159 000 000+252+00252+001*00176*00067
set pc = cl. di cpu,
SET OK
CYZSP A B С D E H L HL SP PSO PS1
0101 087 141 000 159 000 000 252 00252 001 001760*00156
/* we had better get out of the subroutine
call, so .... */
set sp = 0. set pc=cl., di cpu.
SET OK
SET OK
CYZS
P A B C D E H L HL SP PSO
0101 087 141 000 159 000 000 252 00252+000%0015
6
/* that looks a lot better. now try the call again */
go.
CYCLE AT 62=L2+18
go.
CYCLE AT 64=L2+20
ref cl,c2,c3.
REFER OK
go.
REFER AT 181=C2
di mem i.
00254 001
/* same as before. now try some selective
program execution and tracing. we will set the
values of some local variables and execute only
the code between 12 and 13 */
set cpu. di cpu.
SET OK
CYZSP A B С D E H L HL SP PSO
*0O00*+000+000 ONO*000 000 000+000+00000 000*00000
/* display the code between 12 and 13 */
di mem 12 to 13 cod.
00044 LHI,OOH LLI,FAH LAM INL ADM LLI,FOH ADM INL LBA LAN, OOH ACM LLR
00060 LHA LAM LH!,004 LLI,FCH LMA DCL LBA LAM LLI,F8H ADM INL LCA LAI
00076, 00H ACM LLC LHA LAM LHI,OOH LLI,FDH LMA SUB JFZ,71H,00H DCL
set mem j tom = 9. di mem j tom.
SET OK
00250 000 000 000 000
77
/* set the address pointers for a and b up in memory
somewhere */
set mem a to b+1 = 0 1h 10h 1h. di ma to b+1,
SET OK
00246 000 001 016 001
/* now place data into these locations */
set mem 100h to 120h =1 2 3 4 5 6 7.
SET OK
di mem 100h to 120h.
00256 001 002 003 004 005 006 007 001 002 003 004 005 006 007 001 00?
00272 005 004 005 006 007 001 002 003 004 005 006 007 001 002 003 004
/* set j to 3 and k to 2 */
set mem j=3, mem k=2. di m j tk.
SET OK
00250 003 002
/* now trace this section of code */
trace 12-3 to 13+5,
TRACE OK
go 5.
GO OK
REFER AT 156=C1
/* move the program counter up to this section */
di
PC
SP
c, SP.
156
0
NU
di b.
B = 0
di cpu.
CYZSP A B С D E H L HL SP PSO
0000 000 000 000 000 000 000 000 00000 00000156
set ps 0 = 12. /* same as set pc=12+/
SET OK
go 5.
GO OK
0000 000 000 000 000 000 000 000 00000 000x000L4
LHI O
0000 000 000 090 000 000 000 000 00000 000*x000Q46
LLI 250
0000 COO 000 000 000 000 000*250*x00250 000*00048
LAM
0000*003 000 000 000 000 000 250 00250 000*00049
INL
* 0010 003 000 000 000 000 000*x251*00251 000*x00050
ADM
CYCLE AT 51=L2+7
base hex.
HEX BASE OK
go 30
GO OK
78
*0001+05H 00H
LLI F6H
0001 05H
ADM
0001 05H OOH
INL
+0010 OSH 00H
LBA
CYZSP A В
0010 O5H+05H
LAI OH
0010+00H
ACM
*0000+01H
LLB
0000 01H
LHA
0000 01H
LAM
0000+06H
LHI OH
0000 06H
LLI FCH
0000 06H
LMA
0000 06H
DCL
+0010 06H
LBA
CYZSP A В
0010 06H+06H
LAM
0010+02H
LLI F8H
0010 02H
ADN
*0001#12"!
INL
£0011 12H
LCA
0011 12H
LAT OH
0011+0CH
ACH
*0000+01H
LLC
6000 O1H
LHA
0000 01H
LAM
CYZSP A B
0000+05H 06H
LH! OH
0000 05H
LLI FDH
0000 05Н
LMA
0000 05H
SUB
«1011+*FFH 06H
JFZ 71H
00H
05H
05H
05H
05H
05H
05H
05H
05H
OSH
06H
06H
06H
06H
06H
06H
GEH
06H
06H
06H
06H
CYCLE AT 73H=LL~5H
/* that should be enough of a check-out,
$eof
00H
00H
00H
00H
С
00H
00H
00H
00H
00H
00H
00H
00H
00H
00H
С
00H
00H
00H
00H
00H
0bH*12H
12H
12H
12H
12H
C
12H
12H
12H
12H
12H
00H
00H
00H
00H
D.
00H
00H
00H
00H
00H
00H
00H
DOH
00H
00H
D
00H
00H
ОСН
00H
00H
CoH
00H
CO!
CNH
DOH
D
00H
00H
00H
00H
00H
00H
00H
00H
00H
E
00H
00H
00H
00H
00H FRH OOFEH
OOH*F6H*DOFBH
00H F6H OOF6H
O0H»+F 7H*00F7H
H L HL
OOH F7H OOF7H
00H F7H O0F7H
00H F7H O0F7H
O0H+05H+0005H
OOH*+01H OSH*C1O5H
00H
01H O5H O1O5H
O0H*00H O5H*0005H
00H
00H
00H
E
00H
00H
00H
00H
00H
OCH
OOH*FCH*QOFCH
00H FCH OOFCH
OOH*+FBH*OOFBH
HL HL
00H FBH OOFRH
OOH FBH OOFBH
O0OH*F8H*00F8H
ООН F8H OGF8H
ONH*F9H*00F 9H
COH F9H OCF9H
CCH FSH COF9H
DON F9H COFSH
00Н*12Н* 0012Н
00Н*01Н 12H+0112H
Е
00H
H L HL
01H 12H 0112H
004*00H 12H*0012H
00H
00H
00H
OOH«FDH+#00FDF
00H FDH OOFDH
OOH FDH OOFDH
79
O0H*0033H
OOH*0035H
00H*0036H
O0H*0037H
Sp PSO
COH*0038H
ONH*003AH
00Hx003BH
O0H*+003CH
00H*003DH
00H*003EH
00H* 005 0H
OOH*0042H
00H*0043H
00H*00LL4H
SP PSO
ООН * 004 5Н
O0H*00L6H
O0Hx0048H
COH*OOLOH
OOH* OOGAH
COH*00LB"!
OOH*004D'!
OCH*OCLE!N
OOH*0O04FH
OCH*0050H
SP PSO
OOH*+0051H
00H*0053H
00H#0055H
00H*0056H
00H*0057H
so retire...
As mentioned previously, the exact manner in which PLM1
and PLM2 are initiated on any particular computer is
implementation-dependent. Several sample implementations
are given, however, in Figures IV-12 through IV-15. These
figures rrovide a sample execution of both passes for the
INTEL PDF-10, and the commercial time-sharing services
Tymshare, Applied Logic, and General Electric, respectively.
In each case, the FORTRAN unit names are specified for each
of the major files accessed by PLM1 and PLM2.
When using the Tymshare version (Figure 1IV-13), for
example, the programmer places the PL/M source program into
a file named FOR20.DAT, which corresponds to the internal
file number 6. This file is read when the $I=6 switch is
encountered during the PLM1 execution. PLM1 produces the
intermediate files FOR22.DAT and FOR23.DAT, along with an
optional listing in FORO3.DAT (under control of the $C=2 and
$T=0 or $T=1 switches). |
PLM2 is then initiated and automatically reads the
intermediate files produced by PLM1. Output can be directed
to the disk file FOR07. DAT using the $0=3 switch during the
PLM2 execution. The $B=7 switch in PLM2 produces a BNPF
machine code tape during this second pass.
INTERP/8 can then be intiated for the debugging run,
and the "IOAL 7 7." command can be used to read this tape.
80
SAMPLE RUN ON INTEL PDP-18
COPY FORZA .DAT=MYPROG.PLM
‚SFT SPOOL LPT
‚В Pimi
$1=6
PASS 1 OF COMPILER IS INVOKED HERE
.R PLM?
$B=7
(SPACE -CARRIAGF RETURN)
PASS 2 NF COMPILER IS INVOKED HERE
PRINT #.LPT
INPUT
FILE (FOR28.DAT)
Г
OPTIONAL N
PLMI LISTING (*.LPT)
i
(FOR22.DAT) (FOR23.DAT)
roy
PTI
OPTIONAL | (om)
LISTING
(FOR21.. AT)
Figure IV-]2. The INTEL implementation of PLMl1 and PLM2.
81
SAMPLE RUN ON TYMSHARE PDP-10
‚ СОРУ MYPROG.PLM,[email protected]
e KUN (JPL) PIMA
n=?
SM=i
$5 =!
$ Еее
PASS 1 9° COMPILER IS INVOKED HERE
‚RUN (UPL) PLM2
ФЕ =).
Gal
ER =7
FMm=t
Ф0 =
(SPACE .CARRITAGE RETURN)
PASS 2 OF COMPILER IS INVOKED HERE
INPUT
FILE (FOR2@ .DAT)
f
OPTIONAL
PLM1 LISTINC (FORZ3.DAT)
(FOR22.DAT) (FOR23.DAT)
OPTIONAL
„DAT
LISTING (FOR#7.DAT)
PLM2
(FOR21.DAT)
Figure IV-13. The Tymshare implementation of PLMl and PLM2.
82
TYMSHARE FILE DEFINITIONS
83
PASS 1
INTERNAL
FILE INPUT FORTRAN
NUMBER DEVICE FILENAME UNIT
1 TTY FOR@S . DAT 5
2 CDR [email protected] 2
3 PTR FORP6 . DAT 6
4 МТАЙ FOR16.DAT 16
5 DTA1 FORß9.DAT 9
6 DSK FOR2f . DAT 29
7 DSK1 FOR21.DAT 21
INTERNAL
FILE OUTPUT FORTRAN
NUMBER DEVICE FILENAME UNIT
1 TTY FORPS . DAT 5
2 LPT FOR(3.DAT 3
3 PTP FOR@7 . DAT 7
4 MTA1 FOR17.DAT 17
5 DTA2 FOR18.DAT 19
6 DSK2 FOR22.DAT 22
7 DSK3 FOR23.DAT 23
PASS 2
INTERNAL
FILE INPUT FORTRAN
NUMBER DEVICE FILENAME UNIT
1 TTY [email protected] 5
2 CDR FOR@P2. DAT 2
3 PTR FOR@6 . DAT 6
4 МТАЙ FOR16.DAT 16
5 DTA1 FOR(9 .DAT 9
6 DSK2 FOR22.DAT 22
7 DSK3 FOR23.DAT 23
INTERNAL
FILE OUTPUT FORTRAN
NUMBER DEVICE FILENAME UNIT
1 TTY FOR@S . DAT 5
2 LPT [email protected] 3
3 PTP FORG7.DAT 7
4 MTA1 FOR17.DAT 17
5 DTA2 FOR18.DAT 1
6 DSK FOR2@ . DAT 29
7 DSK1 FOR21.DAT 21
SAMPLE RUN ON AL/COM POP-18
». COPY FILEL18, DAT=MYPROG,PLM
APPLY PLM1
$032
$Mz)
$5:
1 = 5
PASS 1 OF COMPILER IS INVOKED HERE
+APPLY PLM2
$F=i
$Ся!
$8=7
$M=i
$0=3
(SPACE,CARRIAGE RETURN)
PASS 2 OF COMPILER IS INVOKED HERE
INPUT
FILE (FILE{L .DAT)
r
OPTIONAL
PLMI LISTING CALE 13. DAT)
—
INTER
2117, вату! MECIATE
(Ев? PAT) LANG AGE
¿ FILE
(FILEt® .DAT)
OPTIONAL (FILE[4, DAT)
LISTING
(FILE12.DAT)
Figure IV-14. The ALCOM implementation of PLM1 and PLM2.
84
INTERNAL
FILE
NUMBER
1 ON UT $5 CA DO Hs
INTERNAL
FILE
NUMBER
1 ÓN U1 FE Uy N FH
INTERNAL
FILE
NUMBER
1 ON UI > UY Y HH
INTERNAL
FILE
NUMBER
+ СО сло Сл PY HH
AL/COM FILE DEFINITIONS
INPUT
DEVICE
TTY
DSK
DSK
DSK
DSK
DSK
DSK
OUTPUT
DEVICE
TTY
DSK
DSK
DSK
DSK
DSK
DSK
INPUT
DEVICE
TTY
DSK
DSK
DSK
DSK
DSK
DSK
OUTPUT
DEVICE
TTY
DSK
DSK
DSK
DSK
DSK
DSK
PASS 1
PASS 2
85
FILENAME
FILES .DAT
FILE7 .DAT
FILES .DAT
FILE9.DAT
FILE1ÿ.DAT
FILE11.DAT
FILE12.DAT
FILENAME
FILE6.DAT
FILE13.DAT
FILE14.DAT
FILE15.DAT
FILE16.DAT
FILE17.DAT
FILE18.DAT
FILENAME
FILES.DAT
FILE7.DAT
FILE8.DAT
FILE9.DAT
FILE1ÿ.DAT
FILE17.DAT
FILE18.DAT
FILENAME
FILE6.DAT
FILE13.DAT
FILE14.DAT
FILE15.DAT
FILE16.DAT
FILE11.DAT
FILE12.DAT
FORTRAN
UNIT
5
7
8
9
19
11
12
FORTRAN
UNIT
6
13
14
15
16
17
18
FORTRAN
UNIT
5
7
8
9
12
17
18
FORTRAN
UNIT
6
13
14
15
16
11
12
SAMPLE RUN ON GENERAL ELECTRIC TIMESHARE
OLD MYPROG
SAVE FILEIN
OLD PLM1
RUN
PASS 1 OF COMPILER IS INVOKED HERE
OLD PLM2
RUN
SF
$6
$8=7
SM
$0=2
(SPACE »CARRIAGE RETURN)
PASS 2 OF COMPILER IS INVOKED HERE
INPUT
FILEIN
FILE
Г
OPTIONAL (PTR 1)
PLMI LISTING
{
SYMBOL |
(INTFIL) LANGUAGE TABLE (SYMFIL)
FILE
|
OPTIONAL |
PLM2 LISTING (PTR 2)
(LOGBIN)
Figure IV-15. The General Electric implementation of PLM1
and PLM2.
86
GENERAL ELECTRIC FILE DEFINITIONS
37
PASS 1
INTERNAL
FILE INPUT
NUMBER DEVICE FILENAME
1 TERMINAL __-
2 DISK CDR
3 DISK PAPI
4 DISK MAGI1
5 DISK DECI1
6 DISK FILEIN
7 DISK LOGBIN
INTERNAL
FILE OUTPUT
NUMBER DEVICE FILENAME
1 TERMINAL en
2 DISK РТВ
3 DISK PAPO | oY
4 DISK MAGO PO to titel
5 DISK DECO
6 DISK DISKO1
7 DISK DISKO2
PASS 2
INTERNAL
FILE INPUT
NUMBER DEVICE FILENAME
1 TERMINAL __-
2 DISK CDR
3 DISK PAPI
4 DISK MAGI1
5 DISK DECI1
6 DISK DISKO1 | ай ft, Ae
7 DISK DISKO2 )
INTERNAL
FILE OUTPUT
NUMBER DEVICE FILENAME
1 TERMINAL ---
2 DISK PTR2
3 DISK PAPO
4 DISK MAGO
5 DISK DECO
6 DISK LOGOUT
7 DISK LOGBIN
У. PL/M RUN-TIME CONVENTIONS FOR THE 8C08 CEU.
This section presents the run-time organization of PL/M
programs, including storage allocation and subroutine
linkage. The discussion below assumes an 8008 CPU
environment, and thus programs which are intended to be
independent cf CPU architecture should not depend upon the
conventions presented here.
1. Storage Allocation.
The overall organization of memory for the INTEL 8008
CPU is shown in Figure V-1. Memory is allocated in three
maln sections: the Instruction Storage Area (ISA), the
Variatle Storage Area (VSA), and the Free Storage Area
(FSA). The beginning of the ISA is determined ky the
numeric label of the first statement within the PL/M
program. If no numeric label is specified, the origin of
the ISA defaults to zero, and the segment marked "unused" in
Figure V-1 is empty. The "square root! program given in
Appendix A contains a numeric label on the first statement
to force the ISA to start at location 2048.
All ccde generated by the PL/M compiler is "pure."
That is, no object code modifications are made at run-time.
Thus, the ISA memory portion can be implemented in either
RAM (Random-Access Memory) or ROM (Read-Oniy Memory).
The VSA portion of memory holds values of variables
declared within the PL/M program in address-order. The
first variable declared in the source program is at the
lowest address in the VSA, while the last variable declared
is at the highest address. It should Бе noted that
douEle-byte (ADDRESS) variables are always aligned on an
88
16383
e MEMORY —»
FIRST
VARIABLE
DECLARED —&~
PROGRAM
ORIGIN —
00000
Figure V-1.
MCS-8 MEMORY
FREE
STORAGE
AREA
(FSA)
VARIABLE
STORAGE
AREA
(VSA)
INSTRUCTION
STORAGE
AREA
(ISA)
ДИ
89
MEMORY
VECTOR
/
— LAST
VARIABLE
DECLARED
Run-Time Storage Organization for the 8008 CPU.
even address boundary; thus, contiguous BYTE and ArDRESS
declarations in the source program may or may not lead to
contiguous aliccation of these variables in the ЗА. in
addition, note that deciarations with the DATA attribute
cause allocation of the corresponding value in the ISA, not
the VSA. Hence, DATA variables cannot be altered if the ISA
is implemented in ROM.
The VSA is placed after the ISA, but never tktegins
befcre the page indicated by the $VARIABLES compiler switch
in PLM2 (the default value of this switch is zero).
Suppose, for example, that pages 0, 1, and 2 cí memory are
irplemented in unalterabie ROM (recall that there are 256
bytes per page). The programmer would then set the switch
$VARIABLES = 3
during PLM2 to indicate that page number 3 is the first page
in which variables can be allocated. If the ISA is
contained within pages 0, 1, and 2 then the VSA begins in
page 3. If the ISA extends past the first three pages into
RAM then the length of the ISA determines the beginning of
the VSA. The end of the VSA is always at an even page
boundary.
Recall that there is one predeclared BYTE vector,
called "MEMORY," which is automatically included in every
PL/M program. The MEMORY vector 1s started after the last
variable in the VSA, and thus represents the last area of
memory, called the FSA, shown in Figure V-1. The length of
the MEMORY vector is, of course, dependent upon the amount
of memory physically attached to the rarticular 8008 CPU
being used, and the length of the ISA and VSA. The length
of MEMORY can be effectively computed at run-time, however,
by attempting to read and write the first location in each
page of the FSA. A subroutine for this purpose is shown in
Figure V-2.
90
00001 2 /* THE MEM$LENGTH PRCCEDURE RETURNS THE NUMBER OF
00002 2 BYTES IN THE FREE STORAGE AREA (FSA) +/
00003 2 DECLARE TEST$VALUE LITERALLY '1010$1010B';
00004 2 MEMSLENGTH: PROCEDURE ADDRESS;
00005 3 DECLARE (I,MAX) ADDRESS;
00006 3 | = 0; MAX = 4000H - ‚MEMORY;
00007 3 /* MAX !S THE LARGEST POSSIPLE SIZF FOR THF FSA
00008 3 IM A FULL 1EK 8008 SYSTEM */
00009 3 IF .MFMORY <> O THEM /* AT LFAST ONE FRFE PAGE */
00010 3 LOOP: DO WHILE 1 < MAX;
00011 3 /* WRITE THE TEST VALUE INTO THE FIPST WOPD OF
00012 3 THE PAGE */
00013 3 MEMOPYCI) = TEST$VALUE;
00018 4 IF MEMORYCI) = TESTSVALUE THEN
00015 Ц | = 1 + 256; ELSE MAX = 0;
00016 4 END;
00017 3 RETURN 1;
00018 3 END MENSLENCTH;
00019 2
00020 2 /* TEST THE ABOVE PROCENUPE */
00021 2 RECLARE RESULT ARDRESS;
00022 2 START: RESULT = MEM$SLENCGTH;
00023 2 FINISH: CO TO START;
00024 2 EOF
NO PROGRAM ERRORS
Figure V-2. A PL/M Procedure for Determining MEMORY Length.
91
4. Subroutine Linkage Conventions.
The methods used for activating procedures and binding
actual parameters to formal parameters in PL/M is given
below. Again, note that the conventions given here are
dependent upon the 8008 CPU environment.
Subroutine parameter passing is performed as follows.
First, note that formal parameters declared in the grccedure
definiticn are treated the same as locally defined
variables. That is, each parameter is allocated storage
sequentially in memory as if it were a variable local to the
procedure. Formal parameters, however, are initialized to
their ccrresronding evaluated actual parameters at the time
the procedure is invoked. Thus, all parameters are "call by
value" in PL/M. This initialization of formal parameters is
performed in two different ways, depending ugon the number
of argusents declared in the procedure. If there is only
one parameter, the low-order byte is passed in CPU register
B, while. the high-order byte is sent in register C. If
there are two parameters, the first is passed as abcve, and
the second is passed in CPU registers D (low-crder byte) and
E (high-crder byte). When there are more than two
parameters, the last two are sent as described abcve, and
the others are sent by generating implied assignment
statements at the «calling point which store the evaluated
actual parameters into the variables representing the formal
parameters.
The CPU registers are also used to hold values on
return frcm procedures which have tae BYTE or ALDRESS
attribute. In the case of a BYTE procedure, the value
returned is in the A register, while an ADDRESS procedure
returns the low-order byte in register A, and the high-crder
byte in register C.
92
The eight-level program counter stack mechanism cf the
8008 CPU is used to hold return addresses when subroutines
are called. Although this stack size is sufficient fcr most
PL/M programming applications, the user should be aware that
the 8008 stack size limits nesting of subroutine calls to
seven levels at run-time.
3. Use of Assembler language Subroutines with PL/M.
T— la is" a eb wikis aie is
Assembler language subroutines can he incorporated into
PL/M programs if these subroutines account for the PL/M
procedure conventions discussed previously.
The assembly language subroutines are first assembled
into absolute locations, usually starting at low addresses
in memory, as shown in Figure V-3. Each subroutine should
end with a RET (return) operation code. The beginning
address of each subroutine is obtained after assembly,
dencted by S1, S2, ... ‚Sn in Figure V-3.
For each subroutine S1, 52, ... ,Sn, write dummy PL/M
interface procedures P11, P2, ... ,Pn where each Pi is a
procedure containing the single statement
GO TO Si;
The procedure Pi can have Zero, one, Or two parameters of
type BYTE or ADDRESS, and can return either a BYTE or
ADDRESS value, or simply return with no value at all. Note
that if more than two parameters are to be sent, or if more
than one value is to be returned, ADDRESS variables can be
used tc "rcint to" parameters or results.
The subroutine Si then obtains parameters from the CPU
registers E, C, D, and E, as given in the conventions abcve,
and returns values through registers A and C.
93
MCS-8 MEMORY
FSA
VS A
I SA
Containing Procedures
Pi, Poy ... BP
SUBROUTINE п
SUBROUTINE 2
SUBROUTINE 1
JMP to Origin
Figure V-3. Including Assembly Language Subroutines in
PL/M Programs.
94
Suppose, for example, a programmer codes three
subroutines in assembly language for handling teletype I/0.
The subroutine S1 sends a line-feed-carriage-return, and is
found at location 50 in memory. The subroutine S2 writes a
single character at the teletype and returns. Assume 52
assembles starting at location 75. The subroutine S3 reads
one character from the teletype, and 1s located Letween
addresses 1206 and 150 in memory. The foilowing PL/¥ program
then provides interface procedures for these assembly
language subroutines.
150: DECLARE CRLFS LITERALLY '50"',
TTYOUTS LITERALLY "75",
TTYINS LITERALLY '120 ';
CRLF: PROCEDURE;
GO TO CRLFS;
END CRLF;
TTYOUT: PROCEDURE (CHAR):
DECLARE CHAR BYTE;
GO TO TTYOUTS ;
END TTYOUT;
TTYIN: PROCEDURE EYTE;
GO TO TTYINS;
END TTYIN;
The CRLF, ITYOUT, and TTYIN procedures can then be called
in the same manner as any internally-defined rrocedure.
If the assembly language subroutines are not fully
checked-out and thus are undergoing revisions, it may be
worthwhile constructing a "jump vector" at the beginning of
memory. The jump vector contains jump instructions to
addresses of the currently assembled subroutines S1 through
Sn in ilcwer memory. The corresponding PL/M interface
procedures then branch indirectly through this jump vector.
If the subroutines are reassembled at different lccaticns,
only the jump vector need be changed, since it is not
necessary to recompile the PL/M program.
95
As a final note, the programmer is reminded that
assembly language subroutines should be used only when
absolutely necessary. Changes to the PL/M system for future
machine architecture will necessitate changes in sukroutine
conventions, resulting in loss of upward software
compatibility in all programs which depend upon these
conventions.
96
PASS-1
gang,
22002
00033
09024
02805
200086
09987
20008
20009
8981
90011
209812
80913
27914
22015
97016
90817
09718
82919
908928
9802:
33022
20623
20024
080025
00026
28827
00028
98029
00230
08951
9095?
30033
000934
РОЗ
00336
araz7
20938
90739
00040
28041
809042
00043
20044
00045
00046
2047
fanag
7049
[47]
075:
0057
62853
Bagsa
00055
28856
20057
29058
APASq
996
9061
8062
096%
29964
29065
92966
00767
92968
29069
70272
70071
90077
A Al A Al A AIN A AA AAN NA NR
PO MI DC A DAN PN NN NINN ON NG DE AA E E NWN NNW LNW WWM Cl AA AAA A
Appendix A
A Sample Program in PL/M
2048: /* IS THE ORIGIN OF THIS PROGRAM #/
DECLARE TTO LITERALLY '2', CR LITERALLY '15Q'; LF LITERALLY 'BAH',
TRUE LITERALLY *1°*, FALSE LITERALLY '2';
SQUARESROOT: PROCEDURE (X) BYTEJ
DECLARE (X,Y,Z) ADDRESS;
Y = Xi Z = SHRCX+#1,1);
DO WHILE У <> &;
Y = 2; 2 = SHR(X/Y + Y + 1, 1);
END:
RETURN Y:
END SQUAREROOT:
PRINTSCHAR: PROCEDURE (CHAR);
NECLARE BITSCELL LITERALLY '91',
(СНАЯ, 1) ВУТЕ;
OUTPUT (TTO) = @:
CALL TIME (BITSCELL);
DO I = 2 TO 7;
OUTPUT(TTO) = CHAR; /# DATA PULSES »/
CHAR = ROR(CHAR,1):
CALL TIME(BITSCELL);
END:
QUTEUT (T10) = 1:
CALL TIME (BITSCELL+BITCELL):
7% AUTOMATIS RETURN IS GENERATED =/
END PRINTSCHAR:
PRINTSSTRING: PROCEDURE (NAME, LENGTH);
DECLARE NAME ADDRESS,
(LENGTH, I1,CHAR BASED NAME) BYTE;
90 I = @ TO LENGTH - 1;
CALL PRINTECHARCCHARCT));
END:
END PRINTESTR ING:
PRINTENUMBER: PROCEDURE (NUMBER, BASE,CHARS, ZEROSSUPPRESS);
DECLARE NUMBER ADDRESS, (RASE,CHARS, ZEROSSUPPRESS, 1.) BYTE:
DECLARE TEMP (16) AYTE:
IF CHARS > LAST(TEMP) THEN CHARS = LAST(TEMP) 3;
DO I = 1 TO CHARS:
J = NUMBER MOD BASE + '@';
IF J > '9" THEN J = J + 7;
IF ZEROSSUPPRESS AND I <> € AND NUMBER = 2 THEN
= "o":
TEMPCLENGTE CTEMP)-1) = J;
NUMBER = NUMBER / BASE;
END:
CALL PRINTESTRING(.TEMP + LENGTH(TEMP) = CHARS. CHARS):
END PRINTENUMBER;
NECLARE | ADDRESS,
CRLF LITERALLY 'CR,LF",
HEADING DATA (CRLF ,LF.LF,
' TARLE ОР SQUARE ROOTS', CRLF,LF,
* VALUE ROOT VALUE ROOT VALUE ROOT VALUE RONT VALUE ROOT*,
CRLF LF);
7% SILENCE TTY AND PRINT COMPUTED VALUES #/
OUTPUT(TTO) = 13
30 1 =1 TO 19808:
IF I MOD 5 = 1 THEN
DO; IF ! MOD 250 = 1 THEN
CALL PRINTSSTRING(.HÉEADING,LENGTHCHEADING)) 3
END: ELSE
CALL PRINTSTRING{,(CR,LF),2);
CALL PRINTENUMBERCI, 12,6,TRUE /e TRUE SUPPRESSES LEADING ZERDES +/);
CALL PRINTSNUMBERISQUARESROOTI), 10,6. TRUE):
END;
DECLARE MONITORSUSES (10) BYTE:
EOF
NO PROGRAM ERRORS
Ke)
I
PASS-1 SYMBOL TABLE
Fw we ow точ Tae we rows
SYMRAL
580078» 2326
502077 00322
500976 9319
5009075 0316
590074 B31?
509098973 2399
59990972 9385
500871 #392
590070 0298
500069 #295
500065 9289
502067 0268
Seas 9264
5092065 0269
SO/A64# 0255
50963 9251
590262 8247
SEAL 0244
S986 0241
SOAR59 #257
5090058 0233
“20057 00230
SOPB56 #227
500055 0224
5S007P54= 8273
SA9753= 8216
SOPB52?s= A212
599й51 07279
sSaMNa56= 6233
SB9B45+ #199
SdGAA48+ 0195
SP2047+= 8199
SOVn46# B18B4
592945 9181
SOBAB44 0178
500043# 9173
S8AB42« 0169
500241 09166
S09247* 0161
5090039# 0157
S338» 8151
S208z7 9148
500036 0144
502035 0141
SPagı4 8137
509773 9133
597032 179
590312 #125
SOBRIA 9127?
500079» £118
500080278 P1413
500077 Pin
590726 89187
500025 8103
50024 9099
590027 BOYS
SaMA2 8092
Sepp21» 2888
SB. JAI
S@Ag19 9979
502018 30874
590217 0079
S0ÿ016 2566
S2G2615 0961
50074 0756
SARI 007572
59012 08048
500211 02844
52020210 0906482
saneos 0800936
SOnP278a 0032
Sonar? 2828
Sépere 2024
5090025 0819
500074 0914
S0073 Peg
520002 009096
50001 POR?
pb
ANF WE 2 RAILCAR 5 о) не ва оО ГО 8 ео ох об м са бо не См
неон оне ого О 8 a RE A VN SH UR OR RR A DRE RS a A RA RW NRE RS
On
H
HOT SE UNNA AS SUSE
[A
NA DD A AU ALA AAA LD A ADBPROARRHE REL. DA HRAINORHEBGRH ACNR ASDaoO
O DON DIDIUIDSIOIUUOUIODIUZOUUOUDOOOUUUONOUOUOOO
О 60 20 VU DO 20 20 О 70) 30 20 20 20 20 20 20 20 10 20 О СЮ 0 10 О 10 50 10 20 20 ТО 20 0 20 20 20 О 20 20 по р го
LENGTH PR TY
200010
072206
700008
Ве 8090
208257
2000008
200005
070008
81000
020000
#000
2000099
000018
PBEP13
200115
200001
gong3e
peaoee
20060900
260057
000048
208
200777
вр ОЙ
200716
207001
angeai
Bcpagg
Aepeei
eoppoi
eapgg1
ве 091
62084
ggegee
PAPA
272981
РВС
279777
207071
800821
922082
20 20 В
000907
000000
A00LI1
azpeee
200987
920081
020006
OPE
229001
ТАВДА,
Вей
9001
000701
002201
COBRA
220081
gape
ир20 48
gacenl
270703
2900701
ВОЙ,
¢agea1
#200:
PDA:
COBUR1
29001
20060?
002282
COBRAR?
TNA
ДЕ
ДДД
790581
220801
022001
QQ PORRA ALA AA e ANG ON ANA A AA 5
HPA RPhpAL HOP Pia: ONNHENANNDH.A.SsShHhHAR-=- H>H AHH AN HAHPH on
AAA ARA ANUN AAEAUH HO OUT VU A CO a OA nm О AE
Bo 2 2 AO AMP ГО РО NUN VO WF BE HONE DW BEE ONO OD OB HE Bs
MONI TORUSES
6
250
5
1908
' VALUE ROOT VALUE
'
DA
15
HEADING
I
то’
‘pe
TEMP
J
1
ZERCSUPPRESS
CHARS
BASE
NUMBER
PRINTNUMBER
CHAR @P20A027H
I
LENGTH
NAME
PRINTSTRING
“М
91
2
2
i
CHAR
PRINTCHAR
=< ry A
X
SQUARERDOT
2046
DOUBLE
MOVE
LAST
LENGTH
OUTPUT
INPUT
LOW
HIGH
TIME
SHR
SHL
ROR
ROL
MEMORY
PARITY
SIGN
ZERO
CARRY
LO
со
ROOT VALUE ROOT VALUE RI
TABLE OF SQUARE ROOTS
PASS=.2
LINE NUMBER ~ ADDRESS CORRESPONDENCE
2=0800M 6=8803H 7=B8BAH 8=981DH 9=0838H 19=2890H
11=08A9H 12=BBB1H 13=08B2H 16=28B5H 17: 28BAH 18=08BCH
19-G8C5H 29=-288C8H 21=08D2H 22=08D7H 23=28D8H 24=28E8H
°5-08EBH 26=08EFH 27=08F7H 28=28F 8H 30=98FBH 31509748
32=-09807H 33=250DH 34=0923H 36=892DH 37=892EH 38:8931H
39-0938H 49=893CH 41=093FH 42=0952H 43=096FH 4480972H
45=0999K 4 6=2990H 47=09AFH 48=89CCH 49=9901H SixGGFS5H
52=09F6H
509864 82553 115
20H BAH BAH BAH 29H 20H 20H 28H 28H 20H 20H 20H 28H 28H 20H 20H 20H
20H 24H 28H 20H 28H 29H 20H 20H 29H 20H 20H 54H 41H 42H ACH 45H 29H áFH
46H 20H 534 51H SSH 41H 52H 45H 28H 52H 4FH 4FH 54H 33H BDH BAH ВАН 20H
26H 41H 4CH 554 45H 20H 28H 52H 4FH 4FH 54H 29H 56H 41H 4CH 55H 45H 28H
20H 52H 4FH 4FH 544 20H 56H 41H 4CH 55H 45H 20H 20H 52H 4FH 4FH 54H 20H
26H 41H 4CH 554 45H 29H 20H 52H 4FH 4FH 54H 28H 56H 41H 4CH 55H 45H 22H
28H 52H 4FH 4FH 544 GDH ВАН OAH
60=20A6CH 61=0A6FH 62=0A78H 63=0AA4H 64=/AC3H
65=@AC6H 66=DACFH
SE@A81 #2773 2
GDH BAH
67=2/A0D7H 68=0AF 7H 69=08B89H 70-2B28H
SA72A1 B9BCCH SOVUG2 BABCON SA0003 GIBCEH SHAIG4 OOBCFH
5262975 20C0BH 508021 APBDOH S0B023 BUBD24 500924 BOBD4H
598929 OBBN6H 502031 BBBD7H S00939 2969BD8H SA0840 COBDAH
586042 BGOBDBH SP0047 OPBDCH 500048 OGBDFH 500949 SOBRE PH
500050 SBRriH 508852 BOBRE2H 59000535 AABEIH SADU54 PUBE4H
SERBES BOBF4H 500878 OBBroH 500079 OOBCAH SOBALD POBCBH
BBMBH HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT HLT
GENERATED OBJECT CODE
B888H JMP,B2H.B8H LHI, 88H
0819H INL
9829H LAB RAR LLI:.D4H LMA
B839H INL LBA LAC SBM ORB
B848H LMC DCL LBM INL LCM
B85AH,CAH LMB INL LMC JMP,BAH,B8H LEM DCL LOM
B86PH RAL LDA LAE RAL LEM DCE LME LEA RTZ LAB
B878H DCL
88884 LAC
2890H ADM
B8ABH LAD
@8BAH RET
LAB SUM LBA INL LAC SBM LCA JFC,B3H,
ACM LCA INL SBA SBI,88H UMP,S5FH,B8H CAL.,S57H,@8H LAD
INL LDA LAE ACM LEA LAD ADI,21H LDA LAE ACI,@BH ORA
RAR INL LMA INL LME JMP,27H,@8H LHI, 23H LLI,D2H САМ
RET JMP,FB8H,88H LHI,@BH LLI,D6K LMB XRA 010 LBI.5B8H
B8COH,C5MH, 8H JUMP,BEH.B8H INL LMI,GGH LAI.Q7H LHI,B8H LLI,D7H
@8DOH,EBH,@8H DCL LAM 019 LAM RRC LMA LBI»58H OCB JTE:E1H
PGEBH,OBH INL LBM INE LMB JMP,C8H, gEH CAL, 81H 018 LAl,58H
LMI >11H
RAL LBA
@8H DCL
INL LCM
INL
LMB
LCM
LCA
LBA
RAR
INL
DCB
SUM
AD1,58H
B8FAH DCB JTZ,F7H,@8H JMP.FOH,9BH RET UMP,2FEH,@9H LHI, BBM LL 1,D8H
@90@8H INL LMC INL LMD INL LMI,@8H LHI,®BH LLI.DAH LBM DCB LAB INL SUM
8918H JTC, 20H,29H LAM LLI.D8H ADM
LLI,
» 08H JUMP,
ЦТ, ВОН LMB INL LMC DCL LBM INL LCM INL LMB
LMC LLI.DOH LAM INL LCM ADI.@1H LBA LAC ACI,88H ORA RAR LCA
INL LMC LHI, 88H LLI.D2H LAM
JTZ,A9H,@8H DCL LBM INL LCM LLI.D2H
LLI,C8H [MB INL LMC LLI.,DEBH LBM INL
LBI,0GH
LAC RAL
LAB AOM
SUM
INL
LLI
LC8 LAD
OCL
INL
D2H
LEA
LCM
JT2
JTC
DAH
LBA
í ad
ur
INL LBA LAI.AAH ACM LLB LHA {AM LBA
@92@H CAL,B%H,B88H LHI,@B8H LLI,DBM LBM INB LMB JMP,B7H, 89H RET JMP,FEN
@938H,B9H LHI,BBH LLI.EBH LMB INL LMD LAL,BFH
DCL SUM
JFC41H,09H LM]
B940H,BFH LHI.,BBH LLI,E24 LMI,S1H LHI,JBH LLI-EOH LAM LLI,E2H SUM JTC
@950H,D9H, 39H LLI,DFH LBM LLI,C8H LMB
@960H LLI,CAH LMB INL LMC CAL,57H,08H
O97AH,ESH LMB LAI,39H SUM JFC,7CH,A9H LAM ADI,
A9RAR LOM LLB LHA LMD LHI.GBH
B9CAH,DCH LBM INL LCM LLI.CAH
LLIL.DFH LBM LLI,
LMB INL LMC CAL,S57H,B8H СЕТ, ОСН LMD
INL LMI,@@H LLI,DCH LBM INL LCM
LAB ADI,39H [ВА LAC АСТ, ЙЙН (1
A7H LMA ЦНТ, йВН LLI,E2H
2960H LAM SUL,AMH ADI,FFN SBA DCL NDM LLI,DCH LBA LAM INL LDM SUI ,@@H
0990H LCA LAD SBI,GBH ORC SUI, A1H SRA NDB RRC JFC,A1H,B9H LLI,E3H LMI
BIABH, 28H LAI,19H LHI,BBH LLI,E2H SUM LLI,E4H ADL LBA LAH ACI, ABH DCL
CRH LMB
INL LMI .6BH LLI
NL
O9DAH LME LLT,E2H LBM INB LMB UMP, 47H,89H LHI,9BH LLI,E4H LCH LAL ADI
B9EBH, 10M LBA LAC ACI,P@H LCA
B9FAH LDM LCA CAL FBH,B8H RET JMP,6CH,BAH REi
BABBH INE INE INE INE INE INE INE INE INE INE
AALZH TINE INE INE INE INE JUMP,41M, 424 JMP, 45H
PAZOH 019 198 CFS, 45H,20H CFS, 4FH,4FH JMP,53H,
» 20H
RRC
INE
AnH
INE INE
LAB LLI,E@H SUM LBA LAC SBI,20H LLI,ERH
RRC RRC INE INE
INE INE
107 CAL,270H,53H OPA
RRC RPC INE CAL, 41H
INE
INE
ZA3BY,4CH 012 192 INE INF CFS,4FH,4FH JMP.,2?8H,56H 106 JUMP ,55H, 45H INE
DA4OH INE CFS,4FH,4FH JMP,28H,56H 18@ JUMP,55H,
45H
INE INE CFS, 4FH,4FH
BASOH UMP, 20H,S6H 188 JUMP,55H,45H [NE INE CFS:4FH,4FH JMP,20H,56H 180
ВАбИН UMP,55H, 45H INE INE CFS, 4FH,4FH UMP, PH, AAH RRC LALI,@1H 012 LHI
BDA70H,BBH LLI,F4H LMI,A1H INL LMI.ADH LAL,ERH LCI,@3H LHI, BH LLI,F4H
ВАЗОН SUM INL LBA LAC SBM JTC, 28H, DBH LLI,Ceh LMI, 95H INL LMI, BH LLI
GAQAH,F4H LBM INL LCM LLI,CAH LMB INL LMC CAL:57H,88H LAB SUI,@1H LBA
BAABH LAC SEI, 80H ORB JFZ,D2H,0AH LLI,CBH LMI,FAH INL СМТ, ЯН LLI,F4H
2ABOH LBM INL LCM LLI,CAH LMB INL LMC CAL,57H,78H LAB SUl,B1H LBA LAC
BACH SBI,ZON ORB JFZ,CFH,.BAH LBI,F9H LCI, Z9H LDI,73H CAL,FBH.B8H ‘UMP
ВАОЙН, ЕЙН, РАН JMP,D7H,GAH ROL RRC LBI.OSH LCI,GAH LCI1, 92H CAL,FAH,g8H
BAEZH LHI, P8H LL!,F4H LBM INL LCM LLI,DCH LMB INL LMC LLI.DFH LMI, BAH
BAFAH LBTI, 86H LO!I,91H CAL,I1H,99H LHI,GBH LLI,F4H LBM INL LCM CAL,ESH
OBEBH, UBH LHI, BH LLI-OCH LMA INL СМТ, ВОН LLI,DFH LMI, BAH LBI,B6H LD!
BB1OH, B1H CAL, 31H, B9H LMI, BBH LLI,F4H LAM INL LCM ADI, @1KH LBA LAC AC!
BU20H,BBH DCL LMB INL LMA JUMP, 78H, BAH HLT
99
UT A AO
20
21
23
24
28
29
31
38
39
4p
42
46
47
48
49
5g
52
53
54
63
64
78
2748
2756
2864
207?
2080
2088
CARRY 05714
ZERO 05715
SIGN 05716
PARITY 05717
MEMORY 24230
SQUAREROOT 28217
x 85729
Y 8572?
2 257724
PRINTCHAR 21327
CHAR 95726
[ 057727
PRINTSTRING 21757
NAME 95738
LENGTH 25732
1 05733
PRINTNUMBER 22387
NUMBER 25754
BASE 95737
CHARS 05748
ZEROSUPPRESS #5741
1 95742
J 95743
TEMP (15744
1 95764
HEADING 34771
MONI TORUSES 85766
ARES NG TR BR RNP RRR ARNE RE CRAB HAAR BR Ep RED RERO ENDO TA RY
BNPNNNPNNF
BNNNNPNPPF
BNNPPNNNNF
BNNPPNNNNF
BNNPPNNNNF
BPPNNNPPPF
ENNNNNNNPF
BNMNNNNNNF
BPPNNNNNPF
BPPPPPNNNF
ENNNNPNPPF
BNNPPNNNNF
BPNPPNNPNF
BNNPONPPNF
BPPPPPNPNF
BPPNPNPPPF
BPPPPPNPNF
ENNPPNNNNF
BPPNNPNNNF
BPNPPNNNNF
BNNNPPNPNF
BNNPPNNNNF
BNNPPNPPNF
BPPNPNOPPF
BNNNNPNNNF
BPPNPNNNNF
BNNPPNNNPF
BNNPPNNNNF
ANNPPNPPNF
APPNPNPPPF
BPONNNNPNF
BNNNPPNPNF
BNNPPNPPNF
BPPPPPNPNF
BPPNPNNPNF
BNNPPNNNNF
ENNPNPOPNE
RPPPPPNNDSF
RPPNNPPPD9F
EPPPPENNPF
BPPNONNNNEF
BN NNNNPNNF
RNNNMPPNNF
DEPNENNNNE
RPPNONPENE
BNNFNPPPNF
PPPNNNPPPF
RPNNPNPPPF
2096
2194
2112
2120
2128
2136
2144
2152
2160
2168
2840
2848
2856
ENNPPNNNNF
BPNPPNNNPF
BNNPPNNNPF
BNNPPNPPNF
BPPPPPNPNF
BPPNPNPPPF
3N NP PNANNF
BPPNNPPPOF
BPPNNPNPNF
BNPNNNPNNF
BNNPPNANPF
ENNNNPPPNF
BNMNPNNP NF
BPPPNNPPPF
BNNPNPNPPF
BPPNNNNPNF
ENNPPNNNPF
ENNPPNNNNF
ENPNNNNNNF
BPPNNNNNPF
BNPNPNPNNF
ENNNNNPPNF
BNNNNPNPPF
BNNNNNNNPF
3ENNNNNPPNF
RNNPNPPPNF
BPNNPNPPPF
BPNNPPPPPF
ENNPPNPPNF
RNNPPNMNNF
BPPPPNPNNF
BNNPPNPPNF
BPPPPPNPNF
BPPNNNNNPF
BPPNNNNPNF
BNPNNPNNNF
BPPNNPNNNF
BNNPPPEPNF
ВРРММРРРРЕ
RPPNNPNPNF
BNPNNNPPNF
BNNNPNPNNF
8 NANPOPNNE
RPPNMPPPPF
BNNNPNOPNF
BNPNNNPPNF
BPPPNNNNNF
BNNNNPNPNF
BPPNPNPNPF
BNNNNNNPNF
ENNPNPPPNE
BPPNNPBPPF
BPPNPPPNNF
ENNPPNPPNF
BNNNNPPPNF
ENPNNNPPNF
BNNNNPNPPF
RNMPPNNNNF
BNNNNPNNNE
BPPNPPPNNF
BNNNNNNNNF
ENNNNPNPNF
2? BNNNNNNNPF
BNNPNPPPNF
BPPNNNPPPF
BNNNNNNNPF
ENNNNNNNNF
BPPPPENNNF
BNNNNANNNF
$
NO PROGRAM ERRORS
100
BPPNNPNNNF
BNPPNPNNNF
BPPNNPPPPF
BPPNPNNPNF
BNNPPNNNPF
BNNPPNPPNF
BPPPPPNPNF
BNNPPNNNNF
BPPPPENNPF
BPNNNPNPNF
BPPNPPPPPF
BNNNNNNNNF
BPPNPPNNNF
ENNPNNNNPF
BPPNNNNNPF
ENNNPNNPNF
BPPNNNNNPF
BPPNNNNPNF
BPNNNNNPPF
BP NNNNPPPF
BNNNNPPNPF
BNNNNNNNPF
BNNPPNPPNF
BNNPPNNNNF
BPPPNPNNNF
ENNNNPNPPF
BNNPPNNNNF
BNPPNNNNNF
BP PN NP NN NF
BNNPPPPENF
BPPNNPPPPF
BPPNNPNPNF
BNPNNNPPNF
BNNNPNPNNF
BNNNPPPNNF
BPPNPNNPNF
ENNPPPPPNF
SNNNNNNNNF
ENNPPNNNNF
BPPPPPNNPF
BNPNPNPPPF
BNNNNNNNPF
SNNNNNNNNF
BNNNNPNPNF
SNNNNPNNPF
RPPPPPNPPF
BNNNNPNPNF
BNNNNPPNPF
BNNNPNPPNF
BNPNNNPPNF
BNNNNPNPPF
BNNPPNNNNF
BPPPPPNNPF
BPPNPPPPPF
BNNNNNPPNF
ENNPPNNNPF
BNNPPNPPNF
BPPNPNPPPF
BNNPNPPPNF
RPPPPPNNNF
BNNPPNPPNF
ENNNNPPPNF
BNPNNNPPNF
ENNNNPNPPF
BNNPPNNNNF
BPPNNPNNNF
BNNPPNNNPF
BNPNNNPNNF
3PPNNNNPNF
RPNPNPNNPF
BNNPPNNNNF
BPPPPPNNPF
BPPNNPPPPF
BPPNNPNNNF
RN NP PN PP NF
3PPNPNPPPF
ANNPPNNNNF
BNNNNPNNNF
BNNPPPPPNF
APPNPNNNPF
RP PNNNPNNF
BPPPPPPNNF
'ENNNPNNPNF
BPPNPNNNNF
8P NN PNPP PF
SPNNPPPREF
BNNNNPNNNF
BPP NNPNNNF
BNNNNPNPNF
BNPNPNPNPF
BPPPPNPNNF
ENNPPPPPNF
BNNNPNPPNF
BNNPPNPPNF
BPPNNPNNNF
BNNPNPNNNF
RNNPPPPPNF
ENNNNNNNNF
BNNPPNNNNF
BPPPPPNNPF
BNPNPNPPPF
BNNNNNNNPF
BNNNNNNNNF
BNNNNPNPNF
ВРРРРРМРМР
BNNPPNPPNF
BPPNPNPPPF
ANNPENNNNF
BNNNNPNNNF
BPPNNPNNNF
RPNPPNNNPF
BNNNNPPPNF
BNNNPPPPNF
BNNNNPNNNF
BNPNNNPNNF
BNNNNPNPNF
2NNNNPNPNF
BPPPPPNPPF
BNNPPNPPNF
BPPNPNPPPF
BNNPPNNNNF
BNNPPPPPNF
SNNNPPPPNF
BNNNNPNNPF
BPPOPNPNNF
RNONNNPPNF
BNNNNPNPPF
BNNPPNNNNF
BPPNPPPPPF
BNNNNNPPNF
ENNPPNNNPF
BNNPPNPPNF
BPPNPNPPPF
BPPNNNNPNF
BPPPPPNNPF
BNPPPPNNNF
RPNNPPPPRF
RMNNMPNNNF
BPPNPNPPPF
ENNPPNNNNF
ENNPPNNNNF
EPPPPPNNPF
BPPNPNNNNF
ENNPPNPPNF
RPPPPPNPNF
EPPPNNPPPF
ENNNPNNNPF
BPPNNNNPOF
ENNNPNNPNF
BPPPNNNNNF
BPPNNPINNF
ENNPPNNNPF
BPPNNPNNNF
BPPNPNNNNF
RNNPPNNNPF
BN NP PN NN NF
BNNNNPNPNF
RNNPNPPPNF
BNNPPPPPNF
BNNNNNNNNF
ENNNNNNPPF
RPPPPNPNNF
BPPNNNNPNF
BNNNNPNPPF
BN NN NN PN PF
BNNPPNPPNF
RPPNPNPPPF
BNNPPNNNNF
BNNANPNNNF
BPPNNPNNNF
BPNPPNNNPF
BNNPPNPPNF
ENNPPNNNNF
3PPPENPNNF
BNNPPNPPNF
ВРРРРРМРМЕ
BPP NNNNNPF
BPPNNNNPNF
BHPNNPNNNF
RPPPPPNNPF
RNPPPNNPPF
RNPNNNPNNF
BPPNPNPPPF
BNNNNPPPNF
RNNNPP PP NF
SNNNNPNNNF
BPPPPNPNNF
BNNPPNPPNF
BPPPPPNPNF
BNNNNPNPNF
BNNNNNNNPE
ENNPNPPPNF
BPPNNPPPPF
BNNNNNNP PF
BNNPPNPPNF
BNNPPPPPNF
BNNPPPPPNF
BNNNPPPPNF
BNNNNPNNPF
BPPPPNPNNF
ENNNNNPNNF
BNNNNPPNNF
BNNPPNNNNF
ENNNNPNPNF
">
/
Herunterladen
Nur eine freundliche Erinnerung. Sie können das Dokument direkt hier ansehen. Aber was am wichtigsten ist, unsere KI hat es bereits gelesen. Sie kann komplexe Dinge einfach erklären, Ihre Fragen in jeder Sprache beantworten und Ihnen helfen, auch in den längsten oder kompliziertesten Dokumenten schnell zu navigieren.
Werbung