# PL360 - Introduction and a hypotenuse program

In this single part post, we’ll take a quick look at PL360, a low level programming language targeted at the System/360.

## PL360

PL360 was initially designed by Niklaus Wirth at Stanford in the late 1960s. He was working on a successor to ALGOL and was unsatisfied with the choices of implementation languages: assembler or FORTRAN. Quoting from his original paper, he wanted a tool which would:

(1) allow full use of the facilities provided by the 360 hardware, (2) provide convenience in writing and correcting programs, and (3) encourage the user to write in a clear and comprehensible style.

As a result, he and his team came up with PL360. As the name suggests, the language is tied to the architecture of the System/360, providing direct access to opcodes like `STC`

and the need to specify which registers to use. It also contains high level features like `IF ... THEN`

conditionals and `WHILE ... DO`

loops, plus syntax to make common tasks easier, eg `R1 := R1 + R2 + R3`

.

## PL360 on MTS

PL360 on MTS seems to date back to at least distribution 1.0. The version was have on the latest distribution 6.0 has the following note in the drive file listing under component 108:

This version of PL360 is based on one received from Stanford in late 1977 and installed at UM in January, 1978. The latest versions are distributed by UBC as part of the SPIRES distribution.

PL360 is installed on MTS as `*PL360`

. The compiler takes input from `SCARDS`

and writes an object file to `SPUNCH`

. For example:

```
$RUN *PL360 SCARDS=input SPUNCH=object
```

At run time, to use the standard I/O library you need to add `*PL360LIB`

to the `$RUN`

command, ie:

```
$RUN object+*PL360LIB
```

Note that documentation linked below mentions that some procedures in the standard library are not available on MTS, such as `VALTOBCD`

which converts a number to an EBCDIC representation.

## Prerequisites

No special installation instructions to get this language running - just do the standard D6.0 setup as described in this guide and then sign on as a regular user such as `ST01`

.

## Hypotenuse program

Our sample program will calculate the hypotenuse of a right angled triangle: this is taken from the PL360 textbook linked below. The original version used `VALTOBCD`

etc which is not available, so we’ll supply the input values in the main program and use the MTS debugger to view the results.

The program uses Newton’s methods to take square roots `R'' = ((X/R') + R')/2`

:

where R’ is an approximation for the root of X, and R’’ is the next approximation. When the difference between R’ and R’’ becomes very small, R’’ is the assumed root of X. The first approximation of R’ is taken to be X with its exponent cut in half. Thus, the first approximation for the root of 128 would be 8. Likewise, 1/8 would be the approximation for 1/128. (128 = #80)

The procedure to calculate square roots looks like below. The format is mostly unchanged; I’ve added line numbers in the first two columns which would not be present in the actual program text.

```
1 PROCEDURE SQRT (R14); IF F01 > 0L THEN
2 |-- THIS PROCEDURE TAKES THE SQUARE ROOT OF THE VALUE IN F01 --|
3 BEGIN LONG REAL TEMPCELL; |-- TEMPORARY STORAGE --|
4 LONG REAL REGISTER DIFF SYN F67, |-- TEMPORARY --|
5 APROX1 SYN F23, APROX2 SYN F45; |-- REGISTERS --|
6 TEMPCELL := F01; R1 := R1-R1;
7 |-- COMPUTE HALF THE ORIGINAL EXPONENT, EXCESS 64 NOTATION --|
8 IC(R1,TEMPCELL); R1 := R1 - #40S SHRA 1 + #40S;
9 STC(R1,TEMPCELL); APROX2 := TEMPCELL; DIFF := 2L;
10 WHILE DIFF > 10'_6L DO |-- FIND SQRT OF F01 --|
11 BEGIN APROX1 := APROX2; |-- NEW APPROXIMATION FROM OLD --|
12 APROX2 := F01/APROX1 + APROX1 / 2L;
13 DIFF := APROX2 - APROX1; DIFF := ABS DIFF;
14 END; F01 := APROX2; |-- REPLACE F01 BY SQRT OF F01 --|
15 END;
```

The procedure implicitly takes its input and returns output to floating point register 0. R14 is used to denote the register containing the address to jump to on return.

The `IF`

statement will guard against negative input values, skipping the whole procedure unless the input is positive.

The body of the `iF`

starts on line 3 with `BEGIN`

. It creates temporary storage `TEMPCELL`

and provides synonyms for floating point registers to make the code clearer.

Cutting the exponent is done by taking the byte containing the exponent (the ‘characteristic’ in IBM’s language) out of the floating point value (with `IC`

), shifting it right one bit (which divides it by two) and then storing it back into the floating point value. Why is `#40S`

subtracted before the shift and then added back again? I had to look at the ‘Principles of Operation’ for this: turns out characteristic is biased by +64, ie hex 40.

We then use a `WHILE ... DO`

statement to loop the approximation calculation until the difference is less then 10^-6. Note that precedence is strictly left to right, so we can write the approximation calculation on line 12 in that way.

To calculate the hypotenuse, we need to sum the squares of the two sides and call `SQRT`

. This can be easily done:

```
BEGIN
F01 := 3.0 * 3.0;
F23 := 4.0 * 4.0;
F01 := F01 + F23;
SQRT;
END.
```

Note the `END`

is terminated with a period to denote this is the main program.

## Compiling and running the program

We compile the program as follows:

```
$run *PL360 SCARDS=hyp.pl3 SPUNCH=hyp.l
```

The output shows a listing and a cross-reference table, and ends with `NO ERRORS DETECTED`

so we are good.

To test, we run this under the debugger and print out the floating point registers at the end with `DUMP FRS`

:

```
$debug hyp.l
Ready
run
User program return.
Ready
dump frs
Floating Point Registers
Hex Decimal
FR0 : 41500000 00000000 5.
FR2 : 41500000 02C4F885 5.00000001031688268
FR4 : 41500000 00000000 5.
FR6 : 3A2C4F88 50000000 .103168826814936665E-07
stop
```

FR0 contains 5, so it looks like it worked!

## Final thoughts

PL360 occupies a unique slot in the set of languages on the System/360: tied closely to the architecture but operating at a higher level then assembler. Apart from Wirth’s work, it did enjoy some use for other applications, eg the SPIRES database system, but was not widely adopted on MTS or other systems.

## Further information

The original paper Wirth wrote on PL360, PL360, a Programming Language for the 360 Computers gives background on why it was developed and an overview of the language.

MTS CCMEMO 75 has an overview of the language and its implementation on MTS.

Copies of the “PL360 Reference Manual” formerly distributed by Stanford can be found on the Internet, eg here. A textbook based on this manual can be found here.

Full source code for this program can be found on github.