Assembling, Compiling, Link-Editing, and Executing User-Written Programs

 

06/06/2024 Update:  The material on this page had not been updated for a long while, so I took the opportunity to read through and do some updates.  The material presented has not changed significantly, but I did find some areas where I believe clarification, and in some areas, just format update, has improved the presentation.  I also recompiled many of the coding examples to refresh the reproduced output and added some examples where there were none before.

The only assumption in this documentation is that you are working in a batch mode.  That is, you are entering/editing your source program using a Linux or Windows editor (vi, joe, jed, SPF/PC, whatever editor you use) and then the source, along with the appropriate JCL statements, are submitted to the reader device on the Hercules console.  If you are working under TSO, the procedures will be somewhat different and I have not covered those here, although you can easily adapt these instructions to achieve the same goal in the TSO (/RPF, /FSE, /RFE) environment.

This page was originally created as part of a group effort to document utilizing MVT (and later MVS) under the Hercules emulator, and was originally written sometime in late 2000.  So it was originally conceived as a page that would be read sequentially.  Over time the contents have been added to many times, so that the original serial organization has been somewhat lost, and the page serves more as a randomly organized reference.


Topics Covered Below (in alphabetical order)


I would suggest that you create a subdirectory under your main operating system subdirectory for each language you plan to write programs in.  This will result in a bit more typing when you "submit" a jobstream to the Hercules reader, but will result in better organization, especially as you write more programs.  My directory structure looks like:

hercules Top level for Hercules' related files
       mvs configuration and print/punch output are here
              jcl general jobstreams are here
              asm Assembler source programs are here
              cobol COBOL source programs are here
              rpg RPG source programs are here

After you have written a dozen or more programs, you will appreciate the few minutes you take now to institute some organization.  

If you have built an MVS system using my guide/tutorial (installMVS/iMVSintroV8.htm), this organization will not be a foreign concept to you.


 

Basic Job Submission

If you have MVS or MVT up and running under Hercules, you should already be familiar with basic job submission, but I will briefly go over the steps here before we get into assembler/compiler specifics.

A jobstream consists of several Job Control Statements (JCL) and may also contain embedded card image data statements.  These jobstream statements exist on the host operating system (Linux or Windows) as a text file.  It can be edited (created or modified) with your favorite text editor (vi, joe, jed, SPF/PC, whatever).

To submit a jobstream to the MVS or MVT system for processing, switch to the console window in which Hercules is executing and follow one of the two procedures below, depending upon whether you are using the semi-graphical control panel or the console window..  Reminder:  you can switch the Hercules control panel between the two modes by pressing the ESCape key.

 

Graphical Hercules Console

  1. type 'n'
  2. type the letter identifying the card reader device from the list on the right half of the display
  3. type the name of the text file containing the jobstream to be submitted (include the path if the file you are submitting does not reside in the subdirectory which was the current subdirectory when Hercules was started)

It is not necessary to press ENTER after steps 1 and 2, but it is necessary after step 3.

 

Text (Trace) Hercules Console

  1. type devinit <unit address number> <file name>

where <unit address number> is the hexadecimal address of the card reader device and <file name> is the name of the text file containing the jobstream to be submitted (include the path if the file you are submitting does not reside in the subdirectory which was the current subdirectory when Hercule was started)

Press the ENTER key after typing the <file name>.

Note: If you are running MVS (or MVT with HASP installed), you may need to include the parameter eof after the file name to prevent the Operating System from detecting an I/O error on the card reader and flushing the jobstream.  If you are running MVT without HASP, specify intrq instead of eof to leave the reader task running.  In recent versions of Hercules, the setting of either eof or intrq are persistent, and therefore do not need to be specified unless you wish to change the behavior of the emulated card reader device.

Using either method re-initializes (signals Hercules to close and re-open) the file associated with the simulated card reader.  The text file is opened by Hercules and read in, passing the card images to the MVS or MVT reader, which in turn writes them into the system job queue.  When the text file is completely read in, if the last card image contained a null statement (// in columns 1 and 2), the job is eligible for processing by an Initiator.  When an initiator becomes available, the job will be processed by MVS or MVT.

 

Submitting Jobs via Socket Reader

At some point in the evolution of the Hercules emulator, socket devices were introduced, which implements the emulator 'listening' on a particular port that is 'bound' to an underlying MVS device.  For an emulated card reader, this means that when a socket reader is defined for a card reader device address generated in MVS, card images on the host machine are sent to the bound port and are passed directly to the underlying MVS for immediate processing by JES2.  The use of a socket reader has been the standard for as far back as Turnkey 4, and now Turnkey 5.  MVS systems built following my guide have included them for a number of years.

To define a socket reader, the emulated card reader is definied in the Hercules configuration file as:

000C    3505    localhost:3505 sockdev autopad trunc ascii eof

In the definition above,

There are several methods for sending the contents of a text file - JCL statements - on the host operating system to the socket listening on port 3505; these are discussed in the Hercules reference manual - they include a PERL script, HercRdr (available from Fish at his site: http://www.softdevlabs.com/hercgui.html) or the netcat program.


 

Compile/Link-Edit/Execute Catalogued Procedures

The jobstream for an assembly or compile will consist of the JCL to invoke the assembler or compiler plus the source language statements that make up your program.  If you want to compile, link-edit, and execute the program in a single job, you will also need to include additional JCL for these steps. 

There is no reason you cannot include all of the DD statements required by the assembler or compiler in each text file along with your source program statements.  But there is always the requirement for one to three work files, usually a library file, input and one or more output files, compiler listing file, etc.  You can see it will rapidly get tedious typing in all of those DD statements for every program you write.  Fortunately, there is a set of catalogued procedures available for your use that will reduce the required JCL statements to a minimum.  And any shortcomings of the catalogued procedures can easily be overcome by submitting override JCL statements to modify the catalogued procedure to provide exactly the functionality you need for each individual program.

06/06/2024 Update:  This section was originally written to document the catalogued procedures for MVT, but it was subsequently updated to match the catalogued procedures for MVS (most likely an MVS generated from the Bekker distribution libraries).  There are now several MVS distributions in the Hercules' world, so you may need to do some investigating to determine exactly what is present in the distribution you are using ... look for the dataset SYS1.PROCLIB, or SYS2.PROCLIB, on your system.  Rather than attempting to document all possible distributions, this documentation refers to systems built following my instructions, which include the Compiler/Tools volume SYSCPK.  

Some of these compilers originated from sources other than IBM; compiler options documentation is provided only for IBM originated assembler/compilers.

Procedure Listing

Steps Included in Cataloged Procedure

Compiler
Options

ALGOFC ALGOL compile

ALGOL Options

ALGOFCG ALGOL compile and execute
ALGOFCL ALGOL compile and link-edit
ALGOFCLG ALGOL compile, link-edit and execute
ASMFC Assemble

Assembler Options

ASMFCG Assemble and execute
ASMFCL Assemble and link-edit
ASMFCLG Assemble, link-edit, and execute
ASM$C Assemble (with AFOX00, IFOX00 zapped for macro XREF)

Assembler Options

ASM$CG Assemble (with AFOX00, IFOX00 zapped for macro XREF) and execute
ASM$CL Assemble (with AFOX00, IFOX00 zapped for macro XREF) and link-edit
ASM$CLG Assemble (with AFOX00, IFOX00 zapped for macro XREF), link-edit, and execute
ASMGC Assemble (with Waterloo Assember G)
ASMGCG Assemble (with Waterloo Assember G) and execute
ASMGCL Assemble (with Waterloo Assember G) and link-edit
ASMGCLG Assemble (with Waterloo Assember G), link-edit, and execute
ASMXC Assemble

Assembler Options

ASMXCG Assemble and execute
ASMXCL Assemble and link-edit
ASMXCLG Assemble, link-edit, and execute
A68C ALGOL (Cambridge) compile
A68CG ALGOL (Cambridge) compile and execute
A68CL ALGOL (Cambridge) compile and link-edit
A68CLG ALGOL (Cambridge) compile, link-edit, and execute
A68LG ALGOL (Cambridge) link-edit and execute
A68XREF ALGOL (Cambridge) cross reference listing
BASICMON BASIC interpreter (multiple programs run in batch)
BASIC1UP BASIC interpreter (single program)
COBUC COBOL compile

COBOL Options

COBUCG COBOL compile and execute
COBUCL COBOL compile and link-edit
COBUCLG COBOL compile, link-edit, and execute
COBULG COBOL link-edit and execute
FORTGC FORTRAN G compile

FORTRAN Options

FORTGCL FORTRAN G compile and link-edit
FORTGCLD FORTRAN G compile, link-edit, and punch object deck
FORTGCLG FORTRAN G compile, link-edit, and execute
FORTGLG FORTRAN G link-edit and execute
FORTHC FORTRAN H compile
FORTHCL FORTRAN H compile and link-edit
FORTHCLD FORTRAN H compile, link-edit, and punch object deck
FORTHCLG FORTRAN H compile, link-edit, and execute
FORTHLG FORTRAN H link-edit and execute
LKED Link-edit

Link Editor Options

LKEDG Link-edit and execute
GCCC GCCMVS compile
GCCCL GCCMVS compile and link-edit
GCCCLG GCCMVS compile, link-edit, and execute
MORTGC MORTRAN (FORTRAN G) preprocess and compile
MORTGCG MORTRAN (FORTRAN G) preprocess, compile, and execute
MORTGCL MORTRAN (FORTRAN G) preprocess, compile and link-edit
MORTGCLG MORTRAN (FORTRAN G) preprocess, compile, link-edit, and execute
MORTHC MORTRAN (FORTRAN H) preprocess and compile
MORTHCG MORTRAN (FORTRAN H) preprocess, compile, and execute
MORTHCL MORTRAN (FORTRAN H) preprocess, compile and link-edit
MORTHCLG MORTRAN (FORTRAN H) preprocess, compile, link-edit, and execute
PASNC PASCAL (Stanford) compile
PASNCG PASCAL (Stanford) compile and execute
PASNCL PASCAL (Stanford)  compile and link-edit
PASNCLG PASCAL (Stanford)  compile, link-edit, and execute
PL1DFC PL/1 compile and punch object deck

PL/1 Options

PL1LFC PL/1 compile and produce object module
PL1LFCG PL/1 compile and execute
PL1LFCL PL/1 compile and link-edit
PL1LFCLG PL/1 compile, link-edit, and execute
PL1LFG PL/1 execute
PL1LFLG PL/1 link-edit and execute
PL360C PL360 compile
PL360CG PL360 compile and execute
PL360CL PL360 compile and link-edit
PL360CLG PL360 compile, link-edit, and execute
P8PASC PASCAL 8000 compile
P8PASCAL PASCAL 8000 compile and execute
P8PASCL PASCAL 8000 compile and link-edit
P8PASCLG PASCAL 8000 compile, link-edit, and execute
RPGEC RPG compile

RPG Options

RPGECL RPG compile and link-edit
RPGECLG RPG compile, link-edit, and execute
RPGELG RPG link-edit and execute
SIMC Simula compile
SIMCG Simula compile and execute
SIMCL Simula compile and link-edit
SIMCLG Simula compile, link-edit, and execute
SNOBOL4 SNOBOL4 compile and execute
SPIT370 SPITBOL/370 compile and execute
WATFIV Waterloo FORTRAN IV
XPLA XPL syntax analyzer
XPLC XPL analyze and compile
XPLCG XPL compile and execute
XPLLG XPL link-edit and execute a previously compiled program

The procedures that compile and execute utilize the loader to process the output of the compiler.  The loader resolves external references to produce an executable module, which is then executed.  The procedures that compile, link-edit, and execute utilize the link editor to process the output of the compiler.  The link editor also resolves external references to produce an executable module, but the executable module is written to an output file which may be saved so that the resulting module may be executed again without invoking the compiler and link editor.

Note for MVT users: Although the procedures for FORTRAN G are installed in the SYS1.PROCLIB of MVTRES during System Generation, the compiler load modules are not present.  If you want to use FORTRAN G under MVT rather than (or in addition to) FORTRAN H, you will need to load the FORTRAN G load modules and library using the procedure outlined under Fortran Compilers from MVT.


 

Compile/Assemble and Execute

The simplest procedures to use are those which invoke the assembler or compiler, pass the output of the compiler to the loader or link editor, and then execute the program.  Here is a jobstream which will assemble, link-edit, and execute a "Hello World" program written in assembler:      (The numbers to the left of the statements, shown in magenta, have been added for reference.)

 1 //ASMFCLG JOB  (001),'ASM HELLO WORLD',                     
 2 //             CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),REGION=128K
 3 //HELLO  EXEC ASMFCLG,PARM.ASM='OBJECT,NODECK,LIST,NOXREF'
 4 //ASM.SYSUT1 DD UNIT=SYSDA
 5 //ASM.SYSUT2 DD UNIT=SYSDA
 6 //ASM.SYSUT3 DD UNIT=SYSDA
 7 //ASM.SYSGO DD UNIT=SYSDA
 8 //ASM.SYSIN DD *
   HELLO    CSECT
            USING HELLO,15
            SAVE (14,12)
            WTO 'HELLO WORLD!'
            RETURN (14,12),RC=0
            END
15 //

Statement 1 (and continuation onto statement 2) is just a standard job card.  However, a REGION parameter has been specified which will allocate 128K to each step in the job.  The allocations provided by the REGION parameters in some of the catalogued procedures are inadequate and the jobs will terminate abnormally (abend) without adding a larger REGION on the job card.

Statement 3 invokes the catalogued procedure, ASMFCLG.  Note that the procedure name is specified alone instead of prefacing it with 'PGM=' as you would to execute a program.  This is how the scheduler knows that it needs to search a PROCedure LIBrary, frequently SYS1.PROCLIB, to locate a procedure instead of searching SYS1.LINKLIB to locate a program.  The PARM.ASM operand overrides the parameter supplied in the catalogued procedure, specifying that the assembler is to produce object code, but no deck; and a list, but no xref.

Statements 4 through 7 override specific operands on DD statements in the catalogued procedure.  They modify the content of the catalogued procedure by specifying replacement parameter values on four of the DD statements in the procedure.  If you look at the catalog procedure listing for ASMFCLG, you will see that the UNIT type for the three work datasets used by the assembler and the dataset to receive the output of the assembler are SYSSQ.  There is no real reason for these overrides, except as an illustration of the technique.

Notice that each override statement begins with the name of the step within the catalogued procedure where the statement occurs, followed by a period, followed by the name of the DD statement to which the override is to apply.  All of the overrides in this example apply to the ASM step, however if we wanted to override a DD statement in the link-edit step, we would preface the DD name with 'LKED.<ddname>'.

There is no SYSIN DD statement in the catalogued procedure.  That is because card image data may not be included inside of a catalogued procedure.  So, we must insert the SYSIN DD statement (statement 7), which is followed by the card image data that is the assembler source program.  The statement must begin with the name of the step within the catalogued procedure where the statement is to be inserted, followed by a period, followed by the DD name.  During the processing of the JCL, the inserted SYSIN DD statement, along with the card image data that is associated with it, will be merged with the statements from the catalogued procedure and will be processed as if all of the statements were present in the text file you originally edited.

Warning:  Statements in the input jobstream that are overriding statements in cataloged procedures must occur in the order in which they occur in the catalogued procedure.  Any statements that are to be appended to a particular step must immediately follow any overriding statements for that step.

In the example I have omitted the '/*' which could be used to indicate the end of the card image data since the system will assume the presence of the '/*' when it processes the null statement (//) which indicates the end of the jobstream.  Reminder:  if instream statements are preceded with a DD DATA statement, they must be followed by a '/*' statement.

The JCL listing produced when a catalogued procedure is utilized is also slightly different than which you might be used to seeing.  Here is a portion of the output from the jobstream shown above:      (The numbers to the left of the statements are generated by JES2 as it processes the merged input card stream and catalogued procedure statements.)

    2     //HELLO  EXEC ASMFCLG,PARM.ASM='OBJECT,NODECK,LIST,NOXREF'              00000200
    3     XXASMFCLG  PROC MAC='SYS1.MACLIB',MAC1='SYS1.MACLIB'                    00050000
    4     XXASM      EXEC PGM=IFOX00,PARM=OBJ,REGION=128K                         00100000
    5     XXSYSLIB   DD   DSN=&MAC,DISP=SHR                                       00150000
    6     XX         DD   DSN=&MAC1,DISP=SHR                                      00200000
    7     //ASM.SYSUT1 DD UNIT=SYSDA                                              00000300
          X/SYSUT1   DD   DSN=&&SYSUT1,UNIT=SYSSQ,SPACE=(1700,(600,100)),         00250000
          XX             SEP=(SYSLIB)                                             00300000
    8     //ASM.SYSUT2 DD UNIT=SYSDA                                              00000400
          X/SYSUT2   DD   DSN=&&SYSUT2,UNIT=SYSSQ,SPACE=(1700,(300,50)),          00350000
          XX             SEP=(SYSLIB,SYSUT1)                                      00400000
    9     //ASM.SYSUT3 DD UNIT=SYSDA                                              00000500
          X/SYSUT3   DD   DSN=&&SYSUT3,UNIT=SYSSQ,SPACE=(1700,(300,50))           00450000
   10     XXSYSPRINT DD   SYSOUT=A,DCB=BLKSIZE=1089                               00500000
   11     XXSYSPUNCH DD   SYSOUT=B                                                00550000
   12     //ASM.SYSGO DD UNIT=SYSDA                                               00000600
          X/SYSGO    DD   DSN=&&OBJSET,UNIT=SYSSQ,SPACE=(80,(200,50)),            00600000
          XX             DISP=(MOD,PASS)                                          00650000
   13     //ASM.SYSIN DD *                                                        00000700

The leading '//' in each statement read from the catalogued procedure has been changed to some other character in the listing.  If a statement in the procedure was modified by a statement in the text file, the '//' has been changed to 'X/'.  Notice that the parameter changed by the overriding statement is not actually altered on the listing.  The statements from the catalogued procedure that are not altered have their leading '//' changed to 'XX'.  Statements which are read from the jobstream (ie. the text file you created), are printed unchanged.

Statement 7, 8, 9, and 12 are the override statements and, in each case, the statement following, with X/ as the first two characters, indicate the original statement content prior to the override.


 

Compile/Assemble and Execute: Example Jobstreams / Output Listings

There are simple "Hello World" compile, link-edit, and execute jobstreams along with the resulting output listings available here for the following languages:

 

View Jobstream

View Listing

Assembler ASMFCLG.JCL ASMFCLG.output
COBOL COBUCLG.JCL COBUCLG.output
FORTRAN G FORTGCLG.JCL FORTGCLG.output
FORTRAN H FORTHCLG.JCL FORTHCLG.output
PL/1 PL1LFCLG.JCL PL1LFCLG.output
RPG RPGECLG.JCL RPGECLG.output

 

More Advanced Overrides

In addition to replacing a single parameter on a JCL statement in a catalogued procedure, you can substitute a complete replacement statement.  The possibilities are so limitless, that the compile procedures supplied in procedure libraries can be made to accomplish any task you need without ever having to completely type in all the JCL from scratch.

If you want to save the object code produced by a compiler, use either a compile or compile and link-edit procedure and override the dataset that receives the compiler output (usually the SYSLIN or SYSGO DD) to point to a disk dataset that is either catalogued or kept:

//******* ASSEMBLE CSECT TO CATALOGUED OBJECT LIBRARY
//ASTEP EXEC ASMFC
//ASM.SYSGO DD DSN=MY.OBJECT.LIBRARY(THISOBJ),DISP=MOD
//*
//****** COMPILE COBOL PROGRAM SAVING OBJECT OUTPUT
//CSTEP EXEC COBUCLG
//COB.SYSLIN DD DSN=MY.OBJECT,DISP=(NEW,KEEP)

In order to override a parameter on the EXEC statement (such as PARM, REGION, COND) in a catalogued procedure, specify the parameter name, followed by a period, followed by the name of the step within the catalogued procedure:

//HELOWRLD EXEC COBUCLG,PARM.LKED='MAP,LIST,LET'
//HELOWRLD EXEC FORTHCLG,REGION.FORT=384K

To nullify (remove) parameters, code the keyword followed by an equal sign by omitting the value.  To nullify an entire parameter that has subparameters, you must nullify each of the subparameters that have been coded; DCB= will not nullify a DCB parameter that has subparameters (RECFM=, LRECL=, etc) coded.


 

Parameter Options for Assembler, Compilers and Link Editor

A table showing the complete set of options for the Assembler, the language compilers and the linkage editor can be found at: Parameter Options

I have written a macro, jobstream, and instructions for changing the installed default options for the COBOL compiler (without regenerating the compiler via MVT System Generation). See: MVT COBOL Compiler Default Options


 

COBOL Source in Library and User Disk Datasets

Here I will use one example to illustrate two advanced situations.  The task is to compile and execute a COBOL program where the COBOL source statements are contained in a Partitioned Dataset.  The COBOL program reads input from a tape dataset and writes output to a disk dataset.      (The numbers to the left of the statements, shown in magenta, have been added for reference.)

 1  //COBUCLG  JOB CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1)
 2  //UPDATES  EXEC COBUCLG,CPARM1='LOAD,LIST,NODECK,DMAP,SUPMAP'
 3  //COB.SYSIN DD DSN=USER.COBOL.LIB(UPDATE1),DISP=SHR
 4  //LKED.SYSLIB DD DSNAME=SYS1.COBLIB,DISP=SHR
 5  //            DD DSNAME=SYS1.LINKLIB,DISP=SHR
 6  //GO.SYSPRINT DD SYSOUT=A
 7  //GO.TAPEIN DD DSN=TRANS,UNIT=TAPE,VOL=SER=001052,
 8  //             DISP=OLD,LABEL=2
 9  //GO.DISKUP DD DSN=QTD.MASTER,DISP=MOD
10  //GO.EXCEPTS DD SYSOUT=A
11  //

Statement 3 adds the SYSIN DD to the catalogued procedure to provide the input to the COBOL compiler, but rather than point to in-stream card images, the DD points to a member of a partitioned dataset.  Since there is no volume information included with the DD, you can deduce that the dataset is catalogued.

If there are no errors during the compilation and link-editing the program will be executed.

The tape dataset referenced by statements 7 and 8 will be read in by the program.  The disk dataset referenced by statement 9 will be extended (records added to the end).  And print records will be written to SYSOUT using the DD at statement 10.


 

Symbolic Variables

Another means of customizing catalogued procedures is through the use of symbolic variables.  The RPG procedures use symbolic variables extensively.  Here is a portion of the output from the sample jobstream using the RPGECLG procedure:      (The numbers to the left of the statements, shown in magenta, have been added for reference.)

 1  //HELOWRLD EXEC RPGECLG
 2  XXDEFAULT PROC RGREGN=52K,RGPARM='NODECK,LOAD,LIST,NOSEQN',
 3  XX             RGU3SPC='(600,(100,20))',RGU2SPC='(600,(100,20))',
 4  XX             RGU1SPC='(600,(100,20))',RGGOSPC='(80,(200,50))',
 5  XX             LKREGN=100K,LKPARM='XREF,LIST,LET',
 6  XX             LKMDSPC='(1024,(50,20,1))',LKU1SPC='(1024,(50,20))',
 7  XX             GOCOND='((9,LT,RPG),(5,LT,LKED))',GOPARM='DATE=000000'
 8  XXRPG     EXEC PGM=IESRPG,REGION=&RGREGN,PARM=(&RGPARM)
 9  IEF653I SUBSTITUTION JCL - PGM=IESRPG,REGION=52K,PARM=(NODECK,LOAD,LIST,NOSEQN)
10  XXSYSPRINT DD  SYSOUT=A
11  XXSYSPUNCH DD  SYSOUT=B
12  //RPG.SYSUT3 DD UNIT=SYSDA
13  X/SYSUT3   DD  DSNAME=&&SYSUT3,UNIT=SYSSQ,SPACE=&RGU3SPC
14  IEF653I SUBSTITUTION JCL - DSNAME=&&SYSUT3,UNIT=SYSSQ,SPACE=(600,(100,20))
15  //RPG.SYSUT2 DD UNIT=SYSDA
16  X/SYSUT2   DD  DSNAME=&&SYSUT2,UNIT=SYSSQ,SPACE=&RGU2SPC
17  IEF653I SUBSTITUTION JCL - DSNAME=&&SYSUT2,UNIT=SYSSQ,SPACE=(600,(100,20))
18  //RPG.SYSUT1 DD UNIT=SYSDA
19  X/SYSUT1   DD  DSNAME=&&SYSUT1,UNIT=SYSSQ,SPACE=&RGU1SPC
20  IEF653I SUBSTITUTION JCL - DSNAME=&&SYSUT1,UNIT=SYSSQ,SPACE=(600,(100,20))
21  //RPG.SYSGO DD  UNIT=SYSDA
22  X/SYSGO   DD  DSNAME=&&LOADSET,UNIT=(SYSSQ,SEP=SYSPUNCH),
23  XX             DISP=(MOD,PASS,DELETE),SPACE=&RGGOSPC
24 IEF653I SUBSTITUTION JCL - DISP=(MOD,PASS,DELETE),SPACE=(80,(200,50))

In statements 2 through 7, each of the pair of items separated by an equal sign (=) represent a symbolic variable name and its default value.  In the remainder of the procedure, each time a symbolic variable name is encountered, it is replaced by the value that was supplied on the right of the equal sign.  Statements 9, 14, 17, 20, and 24 indicate that substitution has been done and the JCL statements displayed on those lines are the statements as they appear after the substitution of the symbolic value in place of the symbolic variable name.

But you do not have to accept the default values supplied for the variables.  You may supply your own values which will override the defaults.  To supply a new value for a symbolic variable, you simply code the symbolic variable name, followed by an equal sign, followed by the value you want to substitute.  For example, if the first statement in the listing above had been coded as:

 1  //HELOWRLD EXEC RPGECLG,RGREGN=96K

the resulting statement nine would have been: 

 9  IEF653I SUBSTITUTION JCL - PGM=IESRPG,REGION=96K,PARM=(NODECK,LOAD,LIST,NOSEQN)

A much more subtle use of symbolic parameters can be found by looking closely at the DSN parameters in any of the catalogued procedures.  They are all specified as symbolic parameters.  Here is the SYSGO DD statement from the ASMFCLG procedure:

//SYSGO     DD DSNAME=&LOADSET,UNIT=SYSSQ,SPACE=(80,(200,50)),
//             DISP=(MOD,PASS)                                         

&LOADSET is actually a symbolic variable, but if no value is supplied for it, it will function as a temporary dataset name (as though &&LOADSET had actually been coded).  If you wanted to save the output from the assembler step, you could supply a value for the &LOADSET symbolic variable to point to a valid dataset name and then it would receive the output rather than a temporary dataset. 


 

A COBOL Note

The MVT COBOL compiler installs with a buffer default that is too small to handle blocked datasets for input (COBOL source read from the SYSIN DD) or output (object modules written to SYSLIN).  In order to read or write blocked datasets, or to copy source code from a library dataset, you will need to include a additional parameters to the compiler:

PARM='SIZE=2048K,BUF=1024K'

I would also recommend that you change the REGION to 4096K.  In February, 2002 I modified the procedures that are installed from the COBOL compiler installation tape to include these modifications.

On 8 November 2004, while helping someone resolve an error in a COBOL program I discovered that there is a catalogued procedure missing from the MVT system that is usually present - COBUCL.  I created this missing procedure and recreated the archive that contains the MVT COBOL compiler load modules, link library, and procedures.  I also made a small change to all of the procedures that execute the COBOL compiler that will make it easier to override the compiler options and always provide the two required options discussed here - SIZE and BUF.  Each catalogued procedure that invokes the compiler now contains a PROC header statement:

//COBUCG PROC CPARM1='LOAD', 
//            CPARM2='SIZE=2048K,BUF=1024K'

which supplies default values to two symbolic variables and the statement in the procedure containing the PARM keyword has been changed to:

// PARM='&CPARM1,&CPARM2' 

which concatenates the two values supplied by the symbolic variables into a single value to pass to the COBOL compiler as its parameter.  When executing one of these procedures, if you need to specify alternative compiler options, you may specify them by using the CPARM1 symbolic variable name.  You can see an example of this in the COBUCLG example above.  Of course, you can always override the value for SIZE and BUF by specifying your own value for the CPARM2 variable or by overriding the entire concatenated value by specifying PARM.COB in an override.

November 2004 - I have written a macro, jobstream, and instructions for changing the installed default options for the COBOL compiler (without regenerating the compiler via MVT System Generation).  See: MVT COBOL Compiler Default Options


 

Installing Compilers for MVS

Although performing a system generation to install the MVT 21.8f operating system will add the compilers documented here for that operating system, along with the procedures to invoke them, the only language processor that is installed with MVS 3.8 is the Assembler.  The MVT compilers may be installed under MVS and used with no problem and I have documented the process to accomplish that under the navigation tab:  Compilers for MVS.  There are also instructions there for installing additional compilers, such as WATFIV, PL360, PASCAL, etc.

Note:  If you have my Compilers/Tools volume, SYSCPK, installed on your system, you already have all the compilers available for MVS installed and ready for use.


 

VSAM Dataset Access for COBOL and PL/1

The MVT COBOL compiler pre-dates VSAM, so there is no support for VSAM datasets in this version of COBOL.  I have written an Assembler subroutine which can be called from COBOL programs compiled with the MVT compiler which will enable much of the functionality of a more recent COBOL compiler.  For information and to download, see:  VSAM File Access for COBOL

Likewise, the PL/1 compiler also predates VSAM, so I wrote a "wrapper" program to allow programs compiled under the MVT PL/1 compiler to call the routine as well.  For information and to download, see  VSAM File Access for PL/I

Note:  If you have my Compilers/Tools volume, SYSCPK, installed on your system, you already have these subroutines installed and available for use with your COBOL (and PL/1) main programs.

To view some examples of COBOL programs utilizing VSAMIO to load record into, and retrieve records from VSAM clusters, view ../isam_cobol/index.htm.  The relevant section begins at the heading:  Task Group #3: Access of VSAM Dataset via VSAMIO for COBOL.


 

Dynamic Subroutine Calls for MVT COBOL

The MVT COBOL Compiler predates the capability for dynamic subroutine calls (subroutine load module loaded at execution time rather than binding the subroutine code into the main program at compile/link edit time).  Ed Liss has written an assembler subprogram that will provide this functionality to COBOL programs compiled with the MVT COBOL compiler.  His archive containing his program and installation instructions is available for download from my site @  https://www.jaymoseley.com/hercules/downloads/archives/dynaload.zip (MD5: 22e13ce145153b1d4a3371f4b5df89e4  Size: 31 kB).

Note:  If you have my Compilers/Tools volume, SYSCPK, installed on your system, you already have the DYNALOAD subroutine installed and ready to call from your COBOL main program.

To illustrate how to use DYNALOAD, I have written a simple program.  The jobstream to compile/execute the program may be seen at testdyna.jcl.  The output from the job may be viewed at testdyna.pdf.  Note that the two called subprograms are not included in the link-editor map; they are loaded at execution time from SYSC.LINKLIB.


 

COBOL Identification/Environment/Data Divisions

The entries for the Identification and Environment Divisions are usually the most difficult to code, especially when dealing with a compiler as old as the one we have available, simply because there are very few manuals and/or textbooks available that match the compiler.  So, prompted by recent questions on one of the Hercules group lists about this area, I decided to add this section to assist others trying to solve this.

The Identification Division is relatively straight forward, with only the division header and the Program ID fields required.  Here are the entries in a syntax diagram format:

IDENTIFICATION DIVISION.
PROGRAM-ID. program-name.
[AUTHOR. comment. ]
[INSTALLATION. comment. ]
[DATE-WRITTEN. comment. ]
[DATE-COMPILED. comment. ]
[SECURITY. comment. ]
[REMARKS. comment. ]

The program name must consist of one word, contain one to eight characters, and begin with an alphabetic character.  The optional paragraphs following Program ID must appear in the order shown, if included.  Regardless of what is coded for DATE-COMPILED, the actual date compiled will be substituted by the compiler as the source is processed.


The Environment Division is more complex, and the entries required depend greatly upon the individual program.  Here are the entries in a syntax diagram format:

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. computer-name.
OBJECT-COMPUTER. computer-name.
SPECIAL-NAMES. 
  special-names-entries.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT [OPTIONAL] file-name-1
        ASSIGN TO system-name [FOR MULTIPLE {REEL | UNIT}]
        [RESERVE {NO | integer} ALTERNATE {AREA | AREAS}]
        [{FILE LIMIT IS | FILE LIMITS ARE} {data-name-1 | literal-1}
            THRU {data-name-2 | literal-2}]
        [ACCESS MODE IS {SEQUENTIAL | RANDOM}]
        [PROCESSING MODE IS SEQUENTIAL]
        [ACTUAL KEY IS data-name]
        [NOMINAL KEY IS data-name]
        [RECORD KEY IS data-name]
        [TRACK-AREA IS [data-name | integer} CHARACTERS]
        [TRACK-LIMIT IS integer {TRACK | TRACKS}].
I-O-CONTROL.
    SAME [RECORD] AREA FOR file-name-1 file-name-2 ... file-name-n.

The Environment Division entries are divided into two sections, the Configuration Section and the Input-Output Section.  The sections, and the paragraphs within, if used, must be coded in the order shown.  The Configuration Section may be omitted entirely unless there is a need for the Special-Names paragraph.  The Source-Computer and Object-Computer paragraphs are used to document the computer and memory size of the computer on which the program is developed (Source-Computer) and is intended to execute (Object-Computer).  The format of the entry for these fields is:

computer manufacturer - model group - memory size (as a letter designation) and model number

An example of this entry is:

SOURCE-COMPUTER. IBM-360-H65.

which identifies the source computer as an IBM 360/65 with 256k of memory.  The compiler will accept values in the range C through I for the memory size.  One table I have in my references lists these values for memory size:

F 64k
G 128k
H 256k
I 512k

I have a vague recollection of coding Source Computer and Object Computer entries when I first started writing production COBOL programs in the 1970's, but in most of my professional experience they have been omitted.

(Added November 2004) Now to completely contradict the last statement above:  I found an old (1981) OS Debugging for the COBOL Programmer in a used bookstore a few weeks ago, and it states that this compiler was used on both the 360 and 370 hardware.  If the object code was to be run on 360 hardware, additional instructions are placed in the generated object module to ensure proper boundary alignment.  These instructions are not required on 370 hardware, but if the OBJECT-COMPUTER entry incorrectly states IBM-360, the instructions will be produced and will increase the run time of the program.  So, for programs compiled and executed under Hercules it will probably be beneficial to have IBM-370 in the SOURCE- and OBJECT-COMPUTER entries.

The Special Names paragraph is used for assigning mnemonic names to functional names used in subsequent Procedure Division statements.  In my experience, this has most often been used to assign names to physical channel numbers in a printer carriage control tape.  For example:

SPECIAL-NAMES.
    C01 IS TO-TOP-OF-PAGE.

Thereby allowing a write statement used to print the first line on a new page of continuous form to be written as:

WRITE PRINT-RECORD FROM PRINT-LINE AFTER ADVANCING TO-TOP-OF-PAGE.

The section of the Environment Division which will be of the most interest will be the entries required for the Input-Output Section, since they are used to define the input and output datasets to be processed by the program, and will therefore be required in the majority of  programs written.  For each dataset to be processed, there must be a SELECT statement, which names the dataset for use of subsequent COBOL statements, with an ASSIGN clause with associates the dataset name with a physical dataset managed by MVS during the program's execution.  The format of the system-name in the ASSIGN clause is:

device class - device number - organization - DD name

The device class specifies the general category of device upon which the physical dataset resides, and must be one of these three entries:

UR to specify a Unit Record device
UT to specify a Utility device
DA to specify a Direct Access device

The device number is a four or five character designation of a specific hardware model, and more precisely defines the device upon which the dataset may reside.  Under MVS, the device number may, and should, be omitted.  If it is included, the MVT compiler will accept the following device numbers under the respective device classes:

UR 1403, 1404, 1443, 1442R, 1442P, 1445, 2501, 2520R, 2520P, 2540R, 2540P (R=reader and P=punch)
UT 2311, 2400
DA 2301, 2302, 2311, 2321, 2314, 7320

The organization is coded as either S, D, or I; where S designates sequential file organization, D designates files stored in a random organization where actual keys will be supplied to write and read the records, and I designates files stored using the Indexed Sequential Access Method.

The DDname portion of the system-name specifies the one to eight character name used on a DD JCL statement during execution to associate a physical dataset with the file defined in the COBOL program.  Here are some examples copied from programs I have compiled with the MVT compiler running under MVS 3.8j:

    SELECT CUSTOMER-MASTER
        ASSIGN TO UT-S-CUSTMAST.

    SELECT SORT-WORK
        ASSIGN TO DA-S-SORTFILE.

    SELECT REPORT-FILE
        ASSIGN TO UR-S-REPORT.

    SELECT ACCOUNT-FILE
        ASSIGN TO DA-I-ACCNT
        ACCESS IS SEQUENTIAL
        RECORD KEY IS ACCNT-KEY.

    SELECT MAINTENANCE-CARDS
        ASSIGN TO UT-2400-S-INDATA.

    SELECT PRIMARY-MASTER
        ASSIGN TO DA-2314-I-MASTER
        ACCESS IS SEQUENTIAL
        RECORD KEY IS PMR-ID-NUMBER.

    SELECT REPORT-FILE
        ASSIGN TO UR-1403-S-REPORT.

    SELECT TEST-DATA
        ASSIGN TO UR-2540R-S-SYSIN.

The remainder of the entries for the Input-Output Section will be interpreted as described in any contemporary COBOL textbook, with the possible exception of those for Indexed Sequential datasets.  However, if you don't already have some experience using Indexed Sequential datasets under MVS, it is probably not something you would attempt without having in your possession a textbook which covers it in depth.  If you have the need to process indexed datasets, I would recommend you consider using my VSAM I/O subroutine instead of having to deal with the idiosyncrasies and limitations of ISAM.

12/23/2021 Update:  I have created a page with example COBOL programs that demonstrate how to use the MVT COBOL compiler to write programs to load, update, and access indexed datasets that are:  1) native ISAM, 2) VSAM accessed with ISAM logic/code via the ISAM/VSAM Interface Program, and 3) VSAM accessed via my VSAMIO subroutine.  That page is available at COBOL Programs with ISAM and VSAM Datasets.

Also, see Summary of Environment Division File Statements (Eleven page PDF)

COBOL Data Division

I am not going to cover all the specifics for the Data Division for the MVT compiler, but I thought it prudent to make a few statements about the File Description entries.  With modern COBOL compilers, we have come to expect that less is better and rely upon the DD statement and the data management subsystems of the Operating System to fill in whatever information is missing and required.  You probably should consider including the following clauses on your FD entries:


 

COBOL Source Program Library Facility

The Source Program Library Facility of the time period of the MVT COBOL compiler, otherwise known as the COPY statement, was much less flexible than for later compilers.  I have been most successful limiting my use to copying 01 level entries into Working-Storage, Linkage, and as Record Level descriptions beneath File Description (FD) entries in the Data Division.  Restrictions (limitations) I have encountered are:

From a COBOL textbook of the same time period as the MVT COBOL compiler:

Format -- Copy Statement -- REPLACING Option

    COPY library-name [SUPPRESS]

        [REPLACING word-1 BY {word-2 | literal-1 | identifier-1}

        [word-3 BY {word-4 | literal-2 | identifier-2}] ... ].

Some examples from the same textbook:

Option 1 (within the Configuration Section):

    SOURCE-COMPUTER. COPY statement.
    OBJECT-COMPUTER. COPY statement.
    SPECIAL-NAMES. COPY statement.

Option 2 (within the Input-Output Section): 

    FILE-CONTROL. COPY statement.
    I-O-CONTROL. COPY statement.

Option 3 (within the FILE-CONTROL Paragraph):

    SELECT file-name COPY statement.

Option 4 (within the File Section):

    FD  file-name COPY statement.
    SD  sort-file-name COPY statement.

Option 5 (within the Report Section):

    RD  report-name [WITH CODE mnemonic-name] COPY statement.

Option 6 (within a File or Sort description entry, or within the Working-Storage Section or the Linkage Section):

    01  data-name COPY statement.

Option 7 (with a Report Group):

    01  [data-name] COPY statement.

Option 8 (within the Working-Storage Section or the Linkage Section):

    77  data-name COPY statement.

Option 9 (within the Procedure Division):

    section-name SECTION [priority-number]. COPY statement.
    paragraph-name. COPY statement.

As stated earlier above, if you utilize the COPY statement, the parameters for SIZE and BUFSIZE must be increased.  I usually run my COBOL compiler step with a REGION of 4096K, and specify: PARM='SIZE=2048K,BUF=1024K'.

December 2019 Update:  I had a question from someone who had been trying unsuccessfully to use the COPY statement in the MVT COBOL compiler.  I created a short COBOL program to demonstrate COPY statements that I have successfully used under MVS 3.8j and the MVT COBOL compiler.  I have not been able to successfully implement all the COPY statements that the COBOL textbook of the same era as the MVT COBOL compiler shows are possible. It is possible that this version of the MVT COBOL compiler does not implement the complete set of permissible COPY statements from the COBOL standards of that era.  My example program is not a functional program, but it does compile with no error messages: 

                                                J E S 2   J O B   L O G


 8.41.52 JOB  335  $HASP373 TESTCOPY STARTED - INIT  1 - CLASS A - SYS HMVS
 8.41.52 JOB  335  IEF403I TESTCOPY - STARTED - TIME=08.41.52
 8.41.52 JOB  335  IEC130I SYSLIN   DD STATEMENT MISSING
 8.41.52 JOB  335  IEC130I SYSLIN   DD STATEMENT MISSING
 8.41.52 JOB  335  IEFACTRT COB     /IKFCBL00/00:00:00.03/00:00:00.08/00000/TESTCOPY
 8.41.52 JOB  335  IEF404I TESTCOPY - ENDED - TIME=08.41.52
 8.41.52 JOB  335  $HASP395 TESTCOPY ENDED


------ JES2 JOB STATISTICS ------


 07 JUN 24 JOB EXECUTION DATE


        28 CARDS READ


       129 SYSOUT PRINT RECORDS


         0 SYSOUT PUNCH RECORDS


      0.00 MINUTES EXECUTION TIME
    1     //TESTCOPY JOB (1),'TEST COBOL COPY',CLASS=A,MSGCLASS=X                 JOB  335
    2     //COBUC EXEC COBUC,CPARM1='LIB,LIST,NOSEQ,NOLOAD'     <-- LIB option must be specified to use COPY
    3     XXCOBUC  PROC CPARM1='DECK,NOLOAD,SUPMAP',                             100010000
          XX            CPARM2='SIZE=2048K,BUF=1024K'                             00020000
    4     XXCOB  EXEC  PGM=IKFCBL00,REGION=4096K,                                 00040000
          XX           PARM='&CPARM1,&CPARM2'                                     00050000
    5     XXSTEPLIB  DD DSN=SYSC.LINKLIB,DISP=SHR                                 00051000
    6     XXSYSPRINT  DD SYSOUT=*                                                 00060000
    7     XXSYSPUNCH DD SYSOUT=B                                                  00070000
    8     XXSYSUT1 DD  UNIT=SYSDA,SPACE=(460,(700,100))                           00080000
    9     XXSYSUT2 DD  UNIT=SYSDA,SPACE=(460,(700,100))                           00090000
   10     XXSYSUT3 DD  UNIT=SYSDA,SPACE=(460,(700,100))                           00100000
   11     XXSYSUT4 DD  UNIT=SYSDA,SPACE=(460,(700,100))                           00110000
   12     //COB.SYSLIB DD DISP=SHR,DSN=JAY01.COPYLIB  <-- SYSLIB DD card must point to PDS containing copybooks 

   13     //COB.SYSIN DD *
 STMT NO. MESSAGE
-
    4     IEF653I SUBSTITUTION JCL - PARM='LIB,LIST,NOSEQ,NOLOAD,SIZE=2048K,BUF=1024K'
IEF236I ALLOC. FOR TESTCOPY COB COBUC
IEF237I 253  ALLOCATED TO STEPLIB
IEF237I 253  ALLOCATED TO SYS00079
IEF237I JES2 ALLOCATED TO SYSPRINT
IEF237I JES2 ALLOCATED TO SYSPUNCH
IEF237I 390  ALLOCATED TO SYSUT1
IEF237I 252  ALLOCATED TO SYSUT2
IEF237I 280  ALLOCATED TO SYSUT3
IEF237I 251  ALLOCATED TO SYSUT4
IEF237I 180  ALLOCATED TO SYSLIB
IEF237I 180  ALLOCATED TO SYS00081
IEF237I JES2 ALLOCATED TO SYSIN
IEC130I SYSLIN   DD STATEMENT MISSING
IEC130I SYSLIN   DD STATEMENT MISSING
IEF142I TESTCOPY COB COBUC - STEP WAS EXECUTED - COND CODE 0000
IEF285I   SYSC.LINKLIB                                 KEPT          *--------0
IEF285I   VOL SER NOS= SYSCPK.
IEF285I   UCSYSCPK                                     KEPT          *--------0
IEF285I   VOL SER NOS= SYSCPK.
IEF285I   JES2.JOB00335.SO0102                         SYSOUT
IEF285I   JES2.JOB00335.SO0103                         SYSOUT
IEF285I   SYS24159.T084152.RA000.TESTCOPY.R0000001     DELETED       *--------4
IEF285I   VOL SER NOS= WORK03.
IEF285I   SYS24159.T084152.RA000.TESTCOPY.R0000002     DELETED       *--------6
IEF285I   VOL SER NOS= WORK01.
IEF285I   SYS24159.T084152.RA000.TESTCOPY.R0000003     DELETED       *--------7
IEF285I   VOL SER NOS= MVS380.
IEF285I   SYS24159.T084152.RA000.TESTCOPY.R0000004     DELETED       *--------4
IEF285I   VOL SER NOS= WORK00.
IEF285I   JAY01.COPYLIB                                KEPT          *-------12
IEF285I   VOL SER NOS= PUB000.
IEF285I   UCPUB000                                     KEPT          *--------0
IEF285I   VOL SER NOS= PUB000.
IEF285I   JES2.JOB00335.SI0101                         SYSIN
IEF373I STEP /COB     / START 24159.0841
IEF374I STEP /COB     / STOP  24159.0841 CPU    0MIN 00.02SEC SRB    0MIN 00.01SEC VIRT  2076K SYS   228K
**** JOB NAME: TESTCOPY JOBCARD READ 2024/159 08:41:52 370/148 VS2 R03.8 HMVS ******************************************************
*                                                                                                                                  *
*  STEP NUMBER:          1  USER CORE:       2076K  START TIME:   08:41:52     CPU TIME:    00:00:00.03  ACTIVE TIME:  00:00:00.05 *
*  STEP NAME:     COB       SYSTEM CORE:      228K  STOP TIME:    08:41:52     SRB TIME:    00:00:00.01  ALLOC TIME:   08:41:52    *
*  PROGRAM NAME:  IKFCBL00  REGION SIZE:     4096K  ELAPSED TIME: 00:00:00.08  TCB TIME:    00:00:00.02  PROGRAM LOAD: 08:41:52    *
*  CONDITION CODE:   00000  PERFORMANCE GROUP: 004                                                                                 *
*                           JES2 CARDS:          2       SERVICE UNITS  PAGES IN/OUT  # SWAPS  PAGES SWAP IN/OUT  VIO PAGES IN/OUT *
*                                                                  223      0 /    0        0           0 /    0          0 /    0 *
*                                                                                                                                  *
*   ADDR/UNIT I/O COUNT  ADDR/UNIT I/O COUNT  ADDR/UNIT I/O COUNT  ADDR/UNIT I/O COUNT  ADDR/UNIT I/O COUNT  ADDR/UNIT I/O COUNT   *
*   253/D3350         0  253/D3350         0  390/D3390         4  252/D3350         6  280/D3380         7  251/D3350         4   *
*   180/D3380        12  180/D3380         0                                                                                       *
************************************************************************************************************************************
IEF375I  JOB /TESTCOPY/ START 24159.0841
IEF376I  JOB /TESTCOPY/ STOP  24159.0841 CPU    0MIN 00.02SEC SRB    0MIN 00.01SEC
  CB545 V2 LVL78 01MAY72                 IBM OS AMERICAN NATIONAL STANDARD COBOL                      DATE JUN  7, 2024


   1


00001          IDENTIFICATION DIVISION.
00002          PROGRAM-ID. COPY-BOOKS.
00003          DATE-WRITTEN. DECEMBER 25, 2019.
00004          DATE-COMPILED. JUN  7, 2024.
00005          REMARKS. EXAMPLES OF COPY STATEMENTS.
00006          ENVIRONMENT DIVISION.
00007          CONFIGURATION SECTION.
00008          INPUT-OUTPUT SECTION.
00009          FILE-CONTROL.
00010              SELECT MASTER-FILE
00011                  ASSIGN TO UT-S-INMAST.
00012          DATA DIVISION.
00013          FILE SECTION.
00014          FD  MASTER-FILE COPY FDMAST.
00015 C            LABEL RECORDS ARE STANDARD
00016 C            BLOCK CONTAINS 0 RECORDS
00017 C            DATA RECORD IS MASTER-RECORD.
00018          01  MASTER-RECORD COPY RDMAST.
00019 C        01  MASTER-RECORD.
00020 C            05  ITEM-CODE               PIC X(3).
00021 C            05  ITEM-NAME               PIC X(29).
00022 C            05  STOCK-ON-HAND           PIC S9(6).
00023 C            05  UNIT-PRICE              PIC S999V99 COMP-3.
00024 C            05  STOCK-VALUE             PIC S9(9)V99 COMP-3.
00025 C            05  ORDER-POINT             PIC S9(3).
00026          WORKING-STORAGE SECTION.
00027          01  WORK-RECORD COPY WRMAST.
00028 C        01  WORK-RECORD.
00029 C            05  WORK-ITEM-CODE          PIC X(3).
00030 C            05  WORK-ITEM-NAME          PIC X(29).
00031 C            05  WORK-STOCK-ON-HAND      PIC S9(6).
00032 C            05  WORK-UNIT-PRICE         PIC S999V99 COMP-3.
00033 C            05  WORK-STOCK-VALUE        PIC S9(9)V99 COMP-3.
00034 C            05  WORK-ORDER-POINT        PIC S9(3).
00035          PROCEDURE DIVISION.
00036          SETUP-OPEN.
00037              OPEN INPUT MASTER-FILE.
00038          COMPUTE-VALUE. COPY PDCALC.
00039 C            COMPUTE WORK-STOCK-VALUE =
00040 C                    WORK-STOCK-ON-HAND * WORK-UNIT-PRICE.
00041          CLOSE-AND-END.
00042              CLOSE MASTER-FILE.
00043              STOP RUN.
   2


*STATISTICS*     SOURCE RECORDS =    43     DATA DIVISION STATEMENTS =    17     PROCEDURE DIVISION STATEMENTS =     4
*OPTIONS IN EFFECT*     SIZE = 2097152  BUF = 1048576  LINECNT = 57  SPACE1, FLAGW, NOSEQ,   SOURCE
*OPTIONS IN EFFECT*     NODMAP, NOPMAP, NOCLIST,   SUPMAP, NOXREF, NOLOAD, NODECK, APOST, NOTRUNC,   LIB, NOVERB
*OPTIONS IN EFFECT*       ZWB

 

COBOL Report Writer Feature

In answer to a question posted to the IBM-Main discussion group ... yes, the MVT COBOL compiler does include the Report Writer Feature.  I have written a tutorial covering the basics of using the Report Writer Feature, with examples at:  COBOL Report Writer


 

Extended Assembler Mnemonics

If you are attempting to assemble a program written for a more recent version of MVS (or OS/390 or z/OS), you may want to take a look at Jan Jaeger's extended mnemonic macros -  Extended Mnemonics


 

Extended Machine Instruction Macro Library                 (Added January 2008)

Stephen Powell has made available the macro library he developed.  It may be used under either VM/CMS or MVS.  For more information and to download the installation files -  Stephen Powel Macros


 

ALGOL Datasets and the SYSACT Control Procedure

Datasets

Up to sixteen datasets may be used during execution of an ALGOL program; each dataset is referred to in the ALGOL procedure by a dataset number, the value of which may range from 0 through 15 and corresponds to the following DD names:

Dataset number DD name Dataset number DD name
0 SYSIN 8 ALGLDD08
1 ALGLDD01 9 ALGLDD09
2 ALGLDD02 10 ALGLDD10
3 ALGLDD03 11 ALGLDD11
4 ALGLDD04 12 ALGLDD12
5 ALGLDD05 13 ALGLDD13
6 ALGLDD06 14 ALGLDD14
7 ALGLDD07 15 ALGLDD15


SYSACT Control Procedure

The SYSACT control procedure (included in the ALGOL library installed with the compiler) may be used to gain access to parameters that influence the characteristics of a dataset, specifically those characteristics which control the sequential order of data transfer.  The parameters available to interrogation/modification are:  the character pointer (position within current record), the record pointer, the record length, the number of record per section (page), the number of blanks serving as a delimiter, and the state of the dataset (open, closed, or exhausted).

The declaration of the SYSACT control procedure is implied as:

'PROCEDURE' SYSACT (<dataset number>, <function>, <integer argument>);

The value of the <dataset number> argument determines to which dataset the action of the SYSACT procedure will apply.  The value of the <function> argument determines the action taken by the procedure.  The value of <integer argument> is a variable of the function which either sets or returns the value of a particular dataset characteristic.  The value of <function> may be specified as an integer in the range of 1 through 15 and has the following action associated with each value:

Function Argument is Action
1 variable Returns the value of the character pointer
2 variable / literal Sets the value of the character pointer (within current record) 
3 variable Returns the value of the record pointer
4 variable / literal Sets the value of the record pointer (within current section)
5 variable Returns the value of the record length
6 variable / literal Sets the value of the record length
7 variable  Returns the value the number of records per section
8 variable / literal Sets the value of the number of records per section
9 variable Returns the value of number of blank spaces serving as a delimiter
10 variable / literal Sets the value of number of blank spaces serving as a delimiter
11 variable Returns a value corresponding to the dataset status: 1 if open; 0 if closed; -1 if exhausted
12 variable / literal If the argument value is 1 and the dataset is closed, the dataset is opened.  If the argument value is 0 and the dataset is open, the dataset is closed.
13 variable Returns the value of the record pointer and also stores the value in an internal index for the dataset (for subsequent use by SYSACT)
14 variable / literal Increments the record pointer by the value of the argument (skips records)
15 variable / literal Skips to the next section and sets the record pointer to the value of the argument

Some basic examples of the use of SYSACT may be viewed at ALGOL test.


 

ASSIST - Assembler System for Student Instruction & Systems Teaching

ASSIST is a small, high-speed, low-overhead assembler/interpreter system especially designed for use by students learning assembler language.  The assembler program accepts a large subset of the standard Assembler Language under OS/360, and includes most common features.  The execution-time interpreter simulates the full 360 instruction set, with complete checking for errors, meaningful diagnostics, and completion dumps of much smaller size than the normal system dumps. 

The ASSIST package has been available from several Internet sites for some time.  In fact, I had acquired an AWS tape image containing the package sometime in 2001, but my pursuit of installing it was interrupted by a hard drive crash and I just did not get back to it until recently.  The package, as found on the CBT tape (file #085 on the overflow tape) and at least a couple of other locations I checked, seems to have been last updated in March, 1975.  Part of the struggle in getting ASSIST into an easily installable package for Hercules/MVS 3.8 was dealing with some strange spurious hex characters appearing in some of the distribution members where only display characters should have been.  I am extremely grateful for the help of Mike Stack at NIU in attempting to help me track down the source of these errors.  Eventually, I scrapped the CBT tape copy and used the source from Mike's site at NIU, as well as using his installation jobstream as the model for what I built for Hercules/MVS 3.8.  [Mike subsequently moved his ASSIST material to his personal site: https://kcats.org/]  Following this route greatly reduced the problems with the source and, with a single exception, the source is exactly what is contained on Mike's site.  By building SYSIN jobstreams for the installation reduced the size of the files to download and hopefully prevents introduction of further errors by translation of compressed data from ASCII/EBCIDIC and back repeatedly.

The installation archive @ https://www.jaymoseley.com/hercules/download/archives/assist.tgz [MD5: 79D3361EF4ADAAD1FC1284C144E98C32  Size: 661 kB] - contains six jobstreams:

assist$.jcl This large jobstream installs the ASSIST load module, the macros ASSIST needs during execution, and a procedure to execute ASSIST.
astest00.jcl
astest01.jcl
astest02.jcl
astest03.jcl
astest04.jcl
astest05.jcl
These six jobs may be submitted to verify successful installation of ASSIST.  They contain many actual programs submitted by students, some with errors still intact.

Following Mike's example, the assist$.jcl. jobstream copies all the original source statements from SYSIN statements in the jobstream to two temporary datasets.  Updates are then applied to the datasets using statements also read from SYSIN.  All of ASSISTs default options are controlled by settings of symbolic variables in the ASSYSGEN macro.  As supplied, pretty much everything is "turned on" and it should be suitable for most folks, as is.  If you want to make changes, you should make them in the update statements, not in the original.  With a little rearranging, IFOX00 is suitable for assembling ASSIST, so after the updates are made to the temporary datasets, ASSIST is assembled and link-edited to SYS2.LINKLIB.  As always, if you don't use SYS2.LINKLIB, simply change the DSN for the target library.  The last two steps of the jobstream add the ASSIST macros to SYS1.MACLIB and the catalogued procedure to SYS2.PROCLIB.  Again, change as required for your system.  The completion codes for all steps of this job should be 0000.

Submit one or all of the test jobs to verify successful installation.  Completion codes for all of these jobs should be 0000, even though there will be errors listed for some of the programs in the SYSOUT.

The ASSIST documentation included formatting control characters and were best when processed with the included copyed program (which I have not included here).  I have processed the members with the program and subsequently placed the output into PDF files.  PDF compression greatly reduces the size of the files and the text in the PDF is 100% searchable.  You may chose which, if any, of the documentation members to download and use:

PDF File (Original Member)

Pages / Download Size

Contents

asmintro (ASASSIGN) 247 / 660kb Pennsylvania State University introductory information for beginning students of assembler
logic (ASPLMXXX) 181 / 403kb ASSIST System Program Logic Manual
usergd (ASUSERGD) 72 / 205kb ASSIST User's Guide
xmsysgen (XMSYSGEN) 7 / 24kb Summary of the XMacro package
xmwrites (XMWRITES) 22 / 61.2kb XMacro Usage

The first document - asmintro - contains actual assignments given to students and a fair amount of basic information about OS and good assembler programming methods.  Likewise, the ASSIST User's Guide - usergd - includes much basic assembler information.  The xmsysgen document will probably only be of interest to someone seeking to write additional X macros for the ASSIST system.

A good textbook that incorporates the use of ASSIST in learning 370 Assembler is IBM Assembly Language with ASSIST; Structured Concepts and Advanced Topics by Charles J. Kacmar.  As I write this, there are 4 copies listed for sale at www.abebooks.com

Note:  If you have my Compilers/Tools volume, SYSCPK, installed on your system, you already have the ASSIST load module and catalogued procedure to execute it installed and available.  The first IVP jobstream, astest00, is available from astest00.jcl and the output from the jobstream is available to view at astest00.pdf.


 

SYS1.APVTMACS

While applying a recent VS2 Modification from Greg Price, the job required a macro library that I had not previously encountered - SYS1.APVTMACS.  Researching the origin of this library I found the following post on the Hercules' MVS group:

Mar 04, 2019; 8:46am
Re: SYS1.APVTMACS
pricgren@yahoo.com

In reply to this post by kerravon86
On 2019-03-04 8:06 PM, [hidden email] [H390-MVS] wrote:
> Were these "optional
> material tapes" present anywhere in TK3, just
> needing some extra steps to make them
> available?

On my system I loaded up the source and called the data set
MVS370.SYM1.VOL1.PDS01
which was created in "1973" - check which early 21st century year has
the same week day alignment to determine the real year - obviously it
was before we got game enough to use the real year when IPLing TK3.

This would correspond to data set
MVSSRC.SYM101.F01
if you have that one. The first member is named AMDDATA.

In later levels, some members eventually moved into SYS1.MACLIB, while
others when to MODGEN, and others became defunct or morphed into OCO
versions.

Cheers,
Greg

I obtained a copy of the Optional Materials tape images in June, 2000, so I have downloaded them to my MVS system and then created a 3380-K DASD image with the files on it. That is documented and available from MVS 3.8 Optional Materials.  The contents of SYS1.APVTMACS originated in the library MVSSRC.SYM1-1 on that volume, although there are some additional members in MVSSRC.SYM1-1 that do not appear in SYS1.APVTMACS.  I attribute the discrepancy to the final paragraph of the post above.

A quick solution to making the SYS1.APVTMACS library available on your system is to install the library from the Turnkey system, which is the process I describe here.

After installing the library on my system using XMIT370/RECV370, I used the Review OFFLOAD command to extract the contents of the library in an IEBUPDTE format.  I then created a jobstream to reload the library to any system.  The jobstream is available for download from install.apvtmacs.tgz (1.1 MB)  [MD5: 23451a358d3c6a784b6d2958a0c99d6e].  Unpack the jobstream - IAPVTMACS.JCL - (tar, unzip, winzip or other application of your choice).  Be aware that the text file was created on a linux system, so it will not have carriage returns at the end of each line.  The jobstream installs the library on the volume MVS000, which corresponds to the system generated with my MVS 3.8 installation tutorial.  If you need the library installed on a different volume, edit the JCL to match what is on your system.  Submit the jobstream to MVS to create the dataset SYS1.APVTMACS and you are done.

Note:  If you have built your MVS system using my guide, you should already have this library available in the dataset: SYS1.APVTMACS.


 

COBOL IBM Manuals

November 2020: I downloaded pdf copies of these manuals some time ago, but a recent discussion on the forums has prompted me to add the links for where you may download them.  These editions of the IBM manuals were published close to the time period when the OS/360 MVT COBOL compiler that we have available was in commercial use, so the information provided in them will match the compiler.

GC28-6396-5 IBM OS Full American National Standard COBOL (June 1975) http://www.bitsavers.org/pdf/ibm/360/os/cobol/GC28-6396-5_IBM_OS_Full_American_National_Standard_COBOL_Jun75.pdf 
GC28-6399-2 IBM OS Pull American National Standard COBOL Programmer's Guide (July 1972) http://www.bitsavers.org/pdf/ibm/360/os/cobol/GC28-6399-2_COBOL_Compiler_and_Library_Version_2_Programmers_Guide_Jul72.pdf 

And also of use to the MVS COBOL programmer:

GC26-4061-1 MVS/370 Linkage Editor and Loader User's Guide (December 1985) http://bitsavers.org/pdf/ibm/370/MVS/GC26-4061-1_MVS_370_Linkage_Editor_Users_Guide_Dec85.pdf 


 

COBOL DD Names

November 2020: Prompted by the same forum discussion mentioned above, this is a summary of the DD Names required for COBOL compile, link-edit (or loader), and execution steps.  Most of this information can be found in the Programmer's Guide above, pages 57 through 84.

Although the heading is COBOL DD Names, these are actually the DD Names which are either required or optional for the COBOL compiler, the Link Editor, the Loader, or a compiled COBOL user program execution.

Compiler (EXEC PGM=IKFCBL00)
SYSIN Required, LRECL=80, in-stream (JES2) or from sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  COBOL source program statements.
SYSLIB Optional, LRECL=80, one or more Partitioned Datasets.  Additional COBOL source statements referenced by COPY or BASIS statements in the source program (SYSIN).  Additional information about the Source Program Library Facililty (COPY statements) is available at:  COBOL Source Program Library Facility.
SYSLIN Optional, LRECL=80, sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  Object code generated from COBOL source program statements.  Most often this will be a temporary DASD dataset that is passed to the next step (either Link Editor or Loader) and will be deleted at the conclusion of the job.
SYSPRINT Required, LRECL=121, print output (JES2) or sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  Listings and diagnostic messages produced by the compiler.
SYSPUNCH Optional, LRECL=80, punch output (JES2) or sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  Object code generated from COBOL source program statements.
SYSUT1 Required, sequential dataset (DASD required).  Utility dataset for compiler use during source program analysis and translation.  Temporary dataset deleted at the conclusion of the job step.
SYSUT2 Required, sequential dataset (TAPE or DASD).  Utility dataset for compiler use during source program analysis and translation.  Temporary dataset deleted at the conclusion of the job step.
SYSUT3 Required, sequential dataset (TAPE or DASD).  Utility dataset for compiler use during source program analysis and translation.  Temporary dataset deleted at the conclusion of the job step.
SYSUT4 Required, sequential dataset (TAPE or DASD).  Utility dataset for compiler use during source program analysis and translation.  Temporary dataset deleted at the conclusion of the job step.
Link Editor (EXEC PGM=IEWL)
SYSIN Optional, in-stream (JES2) or from sequential dataset (TAPE or DASD) or member of Partioned Dataset.  Contains directives to the link editor.
SYSLIB Required, Partitioned Dataset.  Automatic call library, where required routines called by the COBOL main program or subprograms may be located.  SYS1.COBLIB (or SYSC.COBLIB, depending upon your MVS system) contains the library of modules supplied with the COBOL compiler.  Depending upon your COBOL program, it may be necessary to concatenate other libraries (or explicitly include modules - see User defined datasets below) to successfully link your compiled program.
SYSLIN Required, primary input to the link editor, sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  Object code generated from COBOL source program statements; may also contain, by concatenation, other object code datasets.
SYSLMOD Required, member of Partitioned Dataset.  The load module to be executed will be written here.  The name under which the load module will be stored in the Partitioned Dataset may be supplied by a NAME parameter read from SYSIN; if not supplied, the load module will be stored as TEMPNAME.
SYSPRINT Required, print output (JES2) or sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  Diagnostic and informational messages, load module map, and cross reference list.
SYSUT1 Required, sequential dataset (DASD required).  Utility dataset for link editor use.    Temporary dataset deleted at the conclusion of the job step.
User defined datasets Optional, sequential dataset (TAPE or DASD) or Partitioned Datasets.  Additional object modules and/or load modules referenced by statements contained in SYSIN to satisfy references in the COBOL main program or subprograms.
Loader (EXEC PGM=LOADER)
SYSLIB Required, Partitioned Dataset.  Automatic call library, where required routines called by the COBOL main program or subprograms may be located.  SYS1.COBLIB (or SYSC.COBLIB, depending upon your MVS system) contains the library of modules supplied with the COBOL compiler.  Depending upon your COBOL program, it may be necessary to concatenate other libraries to successfully link your compiled program.  Although indicated in IBM documentation for the Loader as Optional, in the case of object code produced by the COBOL compiler, it is rare that library modules from COBLIB will not be necessary, making this a required DD statement.
SYSLIN Required, primary input to the loader, sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  Object code generated from COBOL source program statements; may also contain, by concatenation, other object code datasets.
SYSLOUT Optional, print output (JES2).  Diagnostic and informational messages, optional map of external references.
Additional datasets required during execution (requirements are identical to User defined datasets described below) These DD statements define datasets required by the logic of the main COBOL program and any external programs called by the COBOL main program.
Execution (EXEC PGM=*.LKED.SYSLMOD or EXEC PGM={load module name})
SYSABEND or SYSUDUMP Optional, print output (JES2) or sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  To obtain a diagnostic dump in the case the job is abnormally terminated, include either SYSABEND or SYSUDUMP DD statements.  If SYSABEND is used, the dump will include the system nucleus, the program storage area, and a trace table, if the trace table option was requested at system generation.  If SYSUDUMP is used, the dump will only inlucde the program storage area.
SYSIN Optional, in-stream (JES2) or from sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  If the ACCEPT verb is included in a COBOL program and either the FROM option is omitted or references a mnemonic-name associated with SYSIN, a DD statement for SYSIN is required.  If it is omitted, when the ACCEPT is executed, the message "UNSUCCESSFUL OPEN FOR SYSIN" is issued.
SYSOUT Optional, print output (JES2) or to sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  If the DISPLAY verb is included in a COBOL program and either the UPON option is omitted or references a mnemonic-name associated with SYSOUT, a DD statement for SYSOUT is required.  A SYSOUT DD is also required if the EXHIBIT or TRACE statements are included in a COBOL program.
SYSPUNCH Optional, punch output (JES2) or to sequential dataset (TAPE or DASD) or member of Partitioned Dataset.  If the DISPLAY verb is included in a COBOL program and the UPON option specifies SYSPUNCH or references a mnemonic-name associated with SYSPUNCH, a DD statement for SYSPUNCH is required.
User defined datasets A DD statement is required for any datasets named in a COBOL SELECT statement in the FILE-CONTROL paragraph of the INPUT-OUTPUT SECTION.  The DD statements will be processed when the OPEN statement is executed for the file.  All sequential (JES2, TAPE, DASD), indexed-sequential (DASD), direct (DASD) datasets, or VSAM indexed clusters processed with the ISAM Interface Program will require a DD statement.  You will also need a DD statement if you use my VSAM I/O routines to process a VSAM object (examples of jobstreams using VSAM I/O may be found at ../vsam_io/vscobol.htm). 

I hope this has provided you with the information you need to get started assembling, compiling, link-editing, and executing programs on your own.  If I can answer any questions about using catalogued procedures for the compilers or if you find errors in these instructions, please don't hesitate to send them to me:


Return to Site Home Page 


This page was last modified on June 08, 2024.