Running Algol68C on MVS

Recently, Algol68C Release 1.3039 was made public for download. This release is derived from the compiler that was in service to the mid 1990's on IBM mainframes. The new release is meant to run on either MVT or MVS. This report documents the installation of the new release on emulated MVS/370.

The test system is my personal emulated MVS/370 system named BUFF, the TSO logon screen of which is depicted below.

                      Emulated SYSTEM/370 Mainframe Service
                 BB        BB  UU        UU  FF            FF
                BB        BB  UU        UU  FF            FF
               BB       BB   UU        UU  FF            FF
              BBBBBBBBBB    UU        UU  FFFFFFFF      FFFFFFFF
             BBBBBBBBBB    UU        UU  FFFFFFFF      FFFFFFFF
            BB       BB   UU        UU  FF            FF
           BB        BB  UU        UU  FF            FF
          BB        BB  UU        UU  FF            FF              _      _
         BBBBBBBBBBBB  UUUUUUUUUUUU  FF            FF            ." \\`.  (v)
        BBBBBBBBBBB    UUUUUUUUUU   FF            FF            ( \\ \\_\_ )\
                                                                 \\ _"  //\  )
                                                                  `/ // /// /
                                                                  (//  .__-"
                                                                    "-" \\
 Enter logon userid [reconnect]
                                                                 MVS/370 ONLINE 


Being the author of Algol 68 Genie I am interested in having access to other Algol 68 compilers for reference purposes. Of course we have algol68toc that descends from Algol68RS but there are also two versions of Algol68C available on the web, the oldest one being Version 247 and the most recent one being Algol68C Release 1.3039. These two compilers run on operating systems MVT 21.8F and MVS 3.8J that can be run free-of-charge on Hercules, the well-known IBM mainframe emulator. MVT and MVS developed into z/OS, which is backward compatible with its predecessors. The free-of-charge versions of MVT and MVS lack program products as ISPF, but TSO is available.

A68C Version 247 appeared in 1976, at about the same time as the Revised Report. In 1976, the language implemented by A68C still differed notably from the Revised Report language. The recent Release 1.3039 however is a much better approximation, and stems from Release 1.303 that I used under VM/CMS in the 1980's to do scientific calculations. The new release does however "preserve" idiosyncracies 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.

Since Algol68C and FLACC were an inspiration for me to write Algol 68 Genie, I installed Release 1.3039 on MVS. This page documents how to install this compiler.

What does running Algol68C look like?

For the moment I am content to run A68C programs in batch. Next JCL batch job is a typical example: the paradigm ZEROIN algorithm to search for roots of a function, which was also contained in the Mathematisch Centrum Algol 68 Test Set which is available for dowload onto MVS from this page as well. 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.

//A68.SYSIN DD *
  PROC zero in = (REF REAL x, y, PROC (REAL) REAL f, tol) BOOL:
      REAL a := x, b := y;
      REAL fa := f(a), fb := f(b);
      REAL c := a, fc := fa;
      WHILE (ABS fc < ABS fb | 
                (a := b, fa := fb); 
                (b := c, fb := fc); 
                (c := a, fc := fa));
            REAL tolb := tol(b), m := (c + b) * .5;
            ABS (m - b) > tolb
      DO REAL p := (b - a) * fb, q := fa - fb;
         (p < 0 | (p := - p, q := - q));
         (a := b, fa := fb);
         fb := f(b := IF p <= ABS q * tolb
                      THEN (c > b | b + tolb | b - tolb)
                      ELIF p < (m - b) * q
                      THEN p / q + b
                      ELSE m
         IF ABS (SIGN fb + SIGN fc) = 2
         THEN (c := a, fc := fa) 
      (x := b, y := c);
      ABS (SIGN fb + SIGN fc) < 2
  REAL eps = 3 * small real;
  PROC test = (REAL x0, y0, PROC (REAL) REAL f, STRING s) VOID:
      print((new line, "Expression: ", s, new line,
             "Zero to be found between ", x0, " and", 
             new line, y0, new line));
      IF REAL x, y;
         zero in(x := x0, y := y0, f, 
                 (REAL p) REAL: eps + eps * ABS p)
      THEN print(("f(", x, ") =", new line, f(x)))
      ELSE print("no solution found")
      print(new line)
  test(-10, 10, (REAL x) REAL: x ** 2 - 1, "x ** 2 - 1");
  test(-1, 0, (REAL x) REAL: exp(x) - x ** 2, "exp(x) - x ** 2");
  test(0, 1, (REAL x) REAL: cos(x) - x, "cos(x) - x")

I can issue batch jobs to the reader that on my emulated system sits on device number 00C. So if my batch job would be file jcl/zeroin.jcl, I would type at the Hercules console:

 Command ==> devinit 00c jcl/zeroin.jcl eof 

Alternatively, I can issue the batch job from TSO. I would log on as user marcel, hence my high level qualifier would also be MARCEL. Then if my batch job would be file MARCEL.ZEROIN.JCL, I would type at the TSO terminal:

 submit zeroin.jcl 

This job writes on the MVS console:

   - CCI001C A68     /A68C    /00:00:00.26/00:00:00/00000/1       /ZEROIN
   - CCI001C Z370    /Z370    /00:00:00.05/00:00:00/00000/1       /ZEROIN
   - CCI001C LKED    /IEWL    /00:00:00.09/00:00:00/00000/1       /ZEROIN
   - CCI001C GO      /PGM=*.DD/00:00:00.01/00:00:00/00000/1       /ZEROIN
     $HASP309    INIT  1 INACTIVE ******** C=A
     $HASP150 ZEROIN   ON PRINTER2       206 LINES

and produces on the printer:

Algol68C Release 1.3039
Unused space 25936
Z370 version 303.7
Program=1388 Data=248
Expression: x ** 2 - 1
Zero to be found between  -1.0000000000000000E +1 and
+1.0000000000000000E +1
f( -9.9999999999999999E -1) =
Expression: exp(x) - x ** 2
Zero to be found between  -1.0000000000000000E +0 and
+0.0000000000000000E +0
f( -7.0346742249839178E -1) =
Expression: cos(x) - x
Zero to be found between  +0.0000000000000000E +0 and
+1.0000000000000000E +0
f( +7.3908513321516066E -1) =

Note that the compiler's signature reveals its relation to the release 1.303 that I used on VM/CMS, as is apparent from next line printer listing from my 1987 MSc thesis:

Setting up a MVS/370 system

The question is whether you want a prebuilt turnkey-system or want to set up and tailor your own installation. Volker Bandke has posted a great ready-to-run Tur(n)key system. You can download this as an ISO image and be running MVS within minutes. For DIY people like me, Jay Moseley has written excellent instructions on how to set up your own system. This does not have you up and running within minutes, but setting it up yourself is a great learning experience. Note that Jay's system is not the same one as Volker's. The installation of Algol68C as described here was done on Jay's system, but should work equally well on Volker's offering.

Setting up a basic MVS system takes about one evening of entertaining work. I did borrow material from Volker's system to set up mine. For historic reasons I named my installation BUFF and devised a corresponding netsol logon screen as presented in the heading of this report (note that the turkey refers to the original MVS mascot). BUFF is a quite modest 8-DASD set up on which I installed memories of my computing past like FORTRAN H and DUCHESS, a strong 1970's chess program that competed with Chess, Kaissa and Belle. Of course I installed nice tools as Rob Prins's RPF and Greg Price's IMON370 and QUEUE. I ported Collosal Cave Adventure to Fortran H, so I am forever lost in a maze of twisty little passages, but that is another story.

Below screen shows how the A68C distribution files are installed on my particular MVS installation. Most MVS systems are set up such that third-party material is not mixed with IBM material. Hence SYS1 libraries (IBM material) sits for instance on volume MVSRES while SYS2 (third-party material) sits on SYSRES. I installed A68C using prefix SYS2 on volume called SYSRES; below is a view of this volume using RPF. I added SYS2.A68CLIB.MCRA68TS myself which is the Mathematisch Centrum Revised Algol 68 Test Set .

 Datasets starting with SYS2                 69---------------------------------
 Cmd =>                                                                         
 C Dataset name               Volume Ref.dt Org  RECFM RECL   BLK Ext  Size Free
   SYS2.ADVENT.LOAD           SYSRES 86.131 PO   U        0 19069   1     8    0
   SYS2.ADVENT.SRC            SYSRES 86.134 PO   FB      80  3120   1  1000  392
   SYS2.ALGOLF.ASM            SYSRES 86.134 PO   FB      80 19040   1   120   14
   SYS2.ALGOLF.CNTL           SYSRES 86.134 PO   FB      80 19040   1    30   21
   SYS2.ALGOLF.MACLIB         SYSRES 86.134 PO   FB      80 19040   1    30   21
   SYS2.ALGOLFRT.ASM          SYSRES 86.134 PO   FB      80 19040   1    90   36
   SYS2.ALGOLFRT.MACLIB       SYSRES 86.134 PO   FB      80 19040   1    30   27
   SYS2.A68C.VM.EXEC          SYSRES 86.128 PS   FB      80    80   1     3    1
   SYS2.A68CLIB.ALGOL68C.LANG SYSRES 86.135 PO   FB      80  2480   1   120   44
   SYS2.A68CLIB.LANGREF       SYSRES 85.241 PO   FB      80  2480   1    90   13
   SYS2.A68CLIB.MCRA68TS      SYSRES 86.134 PO   FB      80  3120   1    75    4
   SYS2.A68CLIB.MISC.DOC      SYSRES 86.135 PO   FB      80  2480   1    30   12
   SYS2.A68CLIB.MISC.JCL      SYSRES 86.135 PO   FB      80  2480   1    15    9
   SYS2.A68CLIB.MISC.SRC      SYSRES 86.135 PO   VB     136  2498   1    15    9
   SYS2.A68CLIB.MOD           SYSRES 86.135 PO   U        0 19069   1   120   59
   SYS2.A68CLIB.SYS           SYSRES 86.135 PO   VB     136  2498   1    15    5
   SYS2.A68CLIB.TEST.OUT3039  SYSRES 86.135 PS   VBA    137  2498   1    30   12
   SYS2.A68CLIB.TEST.TXT3039  SYSRES 86.135 PO   VB     136  2498   1   120   85
   SYS2.A68CLIB.USER.TXT3039  SYSRES 86.135 PO   VB     136  2498   1    30   22
   SYS2.A68CLIB.ZLIB.TXT3039  SYSRES 86.135 PO   FB      80  2480   1   120   82
   SYS2.CMDLIB                SYSRES 85.245 PO   U        0 19069   1   600  556 

Algol68C installation directions

The straightforward route is to install the prebuilt binaries from the DASD image. I downloaded the DASD image and did not use the AWS tape image. The disk is compressed, and I decompressed it since I do not use compressed disks on my system, and named it dasd/a68c01.3330. Mounting the disk was done by attaching it on the Hercules console:

 Command ==> attach 131 dasd/a68c01.3330 

Note that the device number, in my example 131, must be some free device number fit for a 3330, this depends on how your MVS system is configured. Once attached, on the MVS console I first put the disk online:

 v 131,online 

and then I mounted it from the MVS console:

 m 131,vol=(sl,a68c01),use=private 

Note that throughout this report I assume that MVS succesfully does what you ask it to do. Check this please, condition codes should typically be 0. I mounted the disk PRIVATE so MVS does not place data on it of its own accord. You can make the disk resident by adding it to member VATLST00 in SYS1.PARMLIB. The disk's VOLSER (label) is A68C01, but since it is not catalogued, there is no high-level qualifier - you don't need it anyway.

Now a JCL job can copy what you need. You can adapt and use the JCL job for my system to install A68C on your system. The job can be started by typing at the Hercules console:

 Command ==> devinit 00c a68c-load.jcl eof 

where you replace 00C with the device number of your reader. During the job, expect next messages to pass the MVS console:

    - CCI001C CLEAR   /IEFBR14 /00:00:00.00/00:00:00/00000/3       /A68CCOPY
    - CCI001C IEBCOP2 /IEBCOPY /00:00:00.11/00:00:00/00000/3       /A68CCOPY
    - CCI001C IEBCOP3 /IEBCOPY /00:00:00.02/00:00:00/00000/3       /A68CCOPY
    - CCI001C UPLOAD  /IEBGENER/00:00:00.01/00:00:00/00000/3       /A68CCOPY
    - CCI001C UPLOAD  /IEBGENER/00:00:00.01/00:00:00/00000/3       /A68CCOPY
      $HASP309    INIT  1 INACTIVE ******** C=A
      $HASP150 A68CCOPY ON PRINTER2       233 LINES
      $HASP250 A68CCOPY IS PURGED                                                

Now you are set to compose and run jobs as illustrated at the start of this page.