By Marcel van der Veer
August 2018

Published in Computing history

More on Algol 68, Algol68C, Hercules, MVS, Mainframe, TK4-

As the author of Algol 68 Genie I am interested in having access to other Algol 68 compilers for reference purposes. Several years ago I wrote a post on installing Algol68C on MVS. In this post I would like to give an update.

Algol68C Release 1.3039 is derived from the compiler that was in service to the mid 1990's on IBM mainframes and runs on either MVT or MVS. MVT and MVS developed into today's z/OS that is backward compatible with its predecessors. I used Release 1.303 in the 1980's at the University of Nijmegen under VM/CMS.

Here I will discuss installing A68C on a mainframe emulated by the amazing Hercules S/370, ESA/390 and z/Architecture emulator. For a hobbyist like me, MVS 3.8J from the early 1980's is the "most recent" OS that can be used free of charge, and compilers are legacy, but since my goal is having a reference from the past for Algol 68 Genie, I am grateful to have this option. On the other hand, z/OS is essentially backward compatible with MVS - IBM are serious about protecting user investment in software, which is commendable.

On a side note - what performance can you expect from Hercules? A workstation could not have the tremendous throughput of a mainframe, but considering that I am a single user occasionally running legacy (scientific) software for reference purposes, MFLOPs rating might be an estimate and then Hercules compares well to the actual mainframes in university data centres when I worked on the real iron in the late 1980's. Of course, I cannot imagine a few hundred users working simultaneously on a virtual mainframe, while the real machines at the time dealt with such loads.

My previous post described Algol68C on a (nearly) vanilla MVS installation built using Jay Moseley's excellent instructions. This time I installed A68C on TK4- by Jürgen Winkelmann which is a very well made turnkey MVS distribution. Download the current distribution, install some readily available 3270 terminal emulator, and within ten minutes you will have a beautiful MVS installation at your fingertips.

If you would like more introduction to MVS on Hercules I would propose you browse YouTube. There are many video's to choose from, notably on TK4-.

Update on A68C installation

Below is a simple JCL job that installs A68C onto TK4-. Instructions on attaching the A68C distribution media to MVS are in my previous post so for clarity I will not repeat that information here. Before starting this job I made an alias A68CLIB relate to TK4- user catalog SYS1.UCAT.MVS.

Note that (default) superuser credentials are in the job header, which looks a bit disturbing. TK4- has basic protection of data by RAKF (a basic RACF work-alike), and the superuser must consent to altering for instance SYS2.PROCLIB. Including credentials is only needed if the job is loaded onto the reader, from within the superuser's TSO account this is not needed.

 //A68CCOPY JOB 1,'A68CCOPY',CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
 //         USER=HERC01,PASSWORD=CUL8TR
 //*
 //* REMOVE EXISTING DATASETS
 //*
 //SCRATCH EXEC PGM=IEFBR14
 //LIBMOD  DD DSN=A68CLIB.MOD,DISP=(MOD,DELETE,DELETE),
 //           UNIT=3350,VOL=SER=PUB000
 //LIBSYS  DD DSN=A68CLIB.SYS,DISP=(MOD,DELETE,DELETE),
 //           UNIT=3350,VOL=SER=PUB000
 //*
 //* COPY A68C LIBRARIES
 //*
 //IEBCOP1 EXEC PGM=IEBCOPY
 //SYSPRINT DD SYSOUT=*
 //SYSUT1   DD DISP=OLD,DSN=A68CLIB.MOD,UNIT=3330,VOL=SER=A68C01
 //SYSUT2   DD DISP=(NEW,CATLG),DSN=A68CLIB.MOD,
 //         UNIT=3350,VOL=SER=PUB000,SPACE=(TRK,(120,120,20))
 //SYSIN    DD DUMMY
 //*
 //IEBCOP2 EXEC PGM=IEBCOPY
 //SYSPRINT DD SYSOUT=*
 //SYSUT1   DD DISP=OLD,DSN=A68CLIB.SYS,UNIT=3330,VOL=SER=A68C01
 //SYSUT2   DD DISP=(NEW,CATLG),DSN=A68CLIB.SYS,
 //         UNIT=3350,VOL=SER=PUB000,SPACE=(TRK,(10,10,20))
 //SYSIN    DD DUMMY
 //*
 //* COPY PROCEDURE A68CCG
 //*
 //UPLOAD EXEC PGM=IEBGENER
 //SYSPRINT DD SYSOUT=A
 //SYSIN    DD DUMMY
 //SYSUT2   DD UNIT=3350,DSN=SYS2.PROCLIB(A68CCG),DISP=OLD,
 //            VOL=SER=PUB000,SPACE=(TRK,(2,2))
 //SYSUT1   DD DATA,DLM=$$
 //* PROCEDURE TO RUN ALGOL68C ON MVS 3.8.
 //*
 //* 1. COMPILATION
 //A68     EXEC PGM=A68C,REGION=768K,PARM=F16K 
 //STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
 //INIT     DD DSN=A68CLIB.SYS(INIT),DISP=SHR
 //SYSENV   DD DSN=A68CLIB.SYS,DISP=SHR
 //CODE     DD UNIT=SYSDA,DISP=(NEW,PASS,DELETE),
 //            SPACE=(TRK,(58,8),RLSE)
 //SYSPRINT DD SYSOUT=*
 //PROGRAM  DD DDNAME=SYSIN
 //* 2. Z370 TRANSLATOR
 //Z370     EXEC PGM=Z370,REGION=192K,
 //  COND=(4,LT,A68),PARM=F16K
 //STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
 //ZCODE    DD DSN=*.A68.CODE,DISP=(OLD,DELETE,DELETE)
 //SYSGO    DD UNIT=SYSDA,DISP=(NEW,PASS,DELETE),
 //            SPACE=(TRK,(58,8),RLSE),
 //            DCB=(RECFM=FB,LRECL=80,BLKSIZE=2480)
 //SYSPRINT DD SYSOUT=*
 //* 3. GO EXECUTE
 //GO       EXEC PGM=LOADER,REGION=512K,
 //  COND=((4,LT,A68),(4,LT,Z370)),PARM='NOMAP,NOPRINT,CALL,LET'
 //STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
 //SYSLIB   DD DSN=A68CLIB.MOD,DISP=SHR
 //SYSLIN   DD DSN=*.Z370.SYSGO,DISP=(OLD,DELETE,DELETE)
 //SYSLOUT  DD SYSOUT=*
 //SYSPRINT DD SYSOUT=*
 $$
 // 

Update on the A68C compilation procedure

MVS is a batch oriented system, and I am content to run A68C programs in batch. It should however be possible to run A68C interactively, but you would have to write your own command procedure.

In my previous post I gave an example JCL batch job for ZEROIN. That used procedure A68CCLG (CLG for Compile, Link and Go) but over the years I have reduced that to a simpler procedure A68CCG (CG for Compile and Go) that fixes an occasional SC04 abend from MVS's linker IEWL. The installation JCL above embeds A68CCG so I will not present it separately.

Below I give the essentials of the new ZEROIN job. Note that in below listing, A68.SYSIN indicates that the following lines are read by job step A68 in A68CCLG as file SYSIN. Job step A68 is the actual compilation step in A68CCG.

//ZEROIN JOB 1,'ZEROIN',CLASS=A,MSGCLASS=H,MSGLEVEL=(1,1)
//ZEROIN EXEC A68CCG
//A68.SYSIN DD *
BEGIN 
  PROC zero in = (REF REAL x, y, PROC (REAL) REAL f, tol) BOOL:
    BEGIN   
      ...
    END;
   ...           
END
/*
//

Note that in TK4-, message class H will hold your output so you can inspect it from TSO using REVOUT or OUTPUT.

Segmented compilation

A68C has idiosyncrasies like allocating three registers to address three 4kB code pages, by which an unsegmented program cannot exceed 12kB in length. All but small programs must still be segmented.

Here I want to describe the compilation of a larger program that I split in two parts, CLUSTER and CLUSTER1. This is a program I wrote in the late 1980's that could do calculations on heterogeneous transition metal clusters, when computational chemistry was emerging and we had to write our own scientific software - though I still do that up to this day.

CLUSTER1 defines procedures etcetera for use in CLUSTER. CLUSTER1 starts like this

TITLE cluster1
NAME "CLUSTER1"
ENVIRON CLUSTER1;

...

Program CLUSTER that applies the definitions in CLUSTER1 starts like this

TITLE cluster
NAME "CLUSTER"
USING CLUSTER1 FROM "ENVIN(CLUSTER1)"

...

Below is the JCL to tie it all together. Since this was a one-off I did not make a procedure like A68CCG for this.

//CLUSTER JOB (1),CLASS=A,MSGCLASS=H,MSGLEVEL=(1,1)
//SCRATCH EXEC PGM=IEFBR14
//CLUSTER DD DSN=MARCEL.CLUSTER.ENV,DISP=(MOD,DELETE,DELETE),
//           UNIT=3350,VOL=SER=MARCEL
//*
//* EXAMPLE OF RUNNING A SEGMENTED ALGOL68C PROGRAM.
//*
//* COMPILE ENVIRON
//A68ENV   EXEC PGM=A68C,REGION=768K
//STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
//INIT     DD DSN=A68CLIB.SYS(INIT),DISP=SHR
//SYSENV   DD DSN=A68CLIB.SYS,DISP=SHR
//CODE     DD UNIT=SYSDA,DISP=(NEW,PASS,DELETE),
//            SPACE=(CYL,(1,1),RLSE)
//ENVOUT   DD DSN=MARCEL.CLUSTER.ENV(CLUSTER1),DISP=(NEW,PASS,DELETE),
//            SPACE=(CYL,(1,1,1)),DCB=RECFM=VB,
//            UNIT=3350,VOL=SER=MARCEL
//SYSPRINT DD SYSOUT=*
//PROGRAM  DD DSN=MARCEL.A68C.CLUSTER(CLUSTER1),
//            UNIT=3350,VOL=SER=MARCEL,DISP=SHR
//Z370ENV  EXEC PGM=Z370,REGION=192K,
//  COND=(4,LT,A68ENV),PARM=F16K
//STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
//ZCODE    DD DSN=*.A68ENV.CODE,DISP=(OLD,DELETE,DELETE)
//SYSPRINT DD SYSOUT=H
//SYSGO    DD UNIT=SYSDA,DISP=(NEW,PASS,DELETE),
//            SPACE=(TRK,(58,8),RLSE),
//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=2480)
//* COMPILE MAIN
//A68      EXEC PGM=A68C,REGION=768K
//STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
//INIT     DD DSN=A68CLIB.SYS(INIT),DISP=SHR
//SYSENV   DD DSN=A68CLIB.SYS,DISP=SHR
//CODE     DD UNIT=SYSDA,DISP=(NEW,PASS,DELETE),
//            SPACE=(TRK,(58,8),RLSE)
//ENVIN    DD DSN=*.A68ENV.ENVOUT,DISP=SHR
//SYSPRINT DD SYSOUT=*
//PROGRAM  DD DSN=MARCEL.A68C.CLUSTER(CLUSTER),
//            UNIT=3350,VOL=SER=MARCEL,DISP=SHR 
//Z370     EXEC PGM=Z370,REGION=192K,
//  COND=(4,LT,A68ENV),PARM=F16K
//STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
//ZCODE    DD DSN=*.A68.CODE,DISP=(OLD,DELETE,DELETE)
//SYSPRINT DD SYSOUT=H
//SYSGO    DD UNIT=SYSDA,DISP=(NEW,PASS,DELETE),
//            SPACE=(TRK,(58,8),RLSE),
//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=2480)
//* LOAD (START NOMAP
//GO       EXEC PGM=LOADER,REGION=512K,
//  COND=((4,LT,A68),(4,LT,A68ENV),
//        (4,LT,Z370ENV),(4,LT,Z370)),
//  PARM='NOMAP,PRINT,CALL,LET'
//STEPLIB  DD DSN=A68CLIB.MOD,DISP=SHR
//SYSLIB   DD DSN=A68CLIB.MOD,DISP=SHR
//SYSLIN   DD DSN=*.Z370ENV.SYSGO,DISP=(OLD,DELETE,DELETE)
//         DD DSN=*.Z370.SYSGO,DISP=(OLD,DELETE,DELETE)
//SYSLOUT  DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CLUSTER  DD DSN=MARCEL.A68C.CLUSTER,DISP=SHR,
//            UNIT=3350,VOL=SER=MARCEL
//

Upon submitting above JCL, next lines will appear on the top of the output:


Algol68C Release 1.3039 compiling "cluster1" Unused space 21513
Z370 version 303.7 Program=6732 Data=606
Algol68C Release 1.3039 compiling "cluster" Unused space 21220
Z370 version 303.7 Program=10076 Data=872


All blog posts