Miscellaneous Programs

Even before I created this site for Hercules, I had been maintaining a site which included programs I had written in the past, either in connection with my employment or just playing around.  After I had MVT (and later MVS) running on my own computer under Hercules, I began finding reasons to pull some of these programs over and compile them under Hercules.  It has occurred to me that some of them might be of interest to others, either for their intended function or as coding examples.  So, I have added this page to contain them.  I don't plan any grand scheme of organization for this page; I will just add programs as I get the time and the urge moves me.  And now I find that there are useful programs written by other people that I have collected and have nowhere else on my site to place, so I have added another segment to this page to contain this type of program, properly attributed to the source.

    Programs included on this page:

Access PDS Members from COBOL 
Calculate CRC32 for MVS Datasets
Comb Sort in COBOL   
Date Routines 
Dynamically Load Subprograms in MVT COBOL
Field Edit Routines 
Generate DD Statements for Online DASD Devices 
Issue Console Commands and Display Messages at Predefined Times 
Prime VSAM Cluster 
Pseudo-Random Number Generator 
Report Step Completion Codes
Reset Dataset(s) to Empty 
Retrieve JOB Card Information
Translate 3270 Buffer Addresses 
UCB Scan Routine
Verify load module available and return library where it was found


Pseudo-Random Number Generator

(Assembler)  I recently decided to try consolidating some programs I use to generate test data into a single run unit.  The first hurdle was finding a suitable random number generator that I could implement under MVS 3.8.  Unfortunately, the COBOL compiler we have available to us lacks those handy intrinsic functions, including RANDOM.  I also found that there are not many solutions available in Assembler or COBOL.  And those few I found (well, actually only a couple and they were very old) failed to built very random sets of numbers.  I came up with a subroutine, written in Assembler, based on the Linear Congruential method (described in Knuth, Sedgewick, and in many places on the 'net).  It isn't cryptographic quality, but will do for simulation and ad hoc sets of test numbers.  I also wrote a COBOL program to do some analysis on the generated number sets.  The jobstream contained in random.tgz [MD5: 2194283AC0C57ECCA347B1074E8788A7] will run the analysis program and illustrates how to link the Assembler routine to your own programs.

I recently had an inquiry regarding modifying this program to return the value in a format other than floating point.  As a result, I have added instructions to the assembler routine to return the generated number in both the original floating point format and also the extracted fractional portion of the number as a fullword binary value.  This version of the program is contained in random2.tgz [MD5: C0D8AECEDA0B3F08FA2A063D6575314B].


Date Routines

(Assembler)  Back when Y2k was the buzzword of the day and everyone was doing remediation, I gathered together a lot of date manipulation routines I had written in prior years.  They were originally written in COBOL, BASIC, and even Microsoft MASM.  From this hodgepodge collection, I believe that I have put together a set of routines that will do just about anything one could want to do with a date.  And when I rewrote them, they ended up in 370 Assembler.  

I updated the installation procedure on September 2, 2003.  So if you have an earlier version, and have checked back here and are worried that the version you got on an earlier date needs updating, relax.  There have been no significant changes to the routines themselves, just an update to the jobstreams that load them onto your system.

(Note:  If you have the SYSCPK volume installed on your system, you already have the latest version.) The installation/verification jobstream is in y2k$load.tgz [MD5: db09102e2ebac2dc18cea859c41edb71].  This is an IEBUPDTE job that will create a PDS containing the assembler and COBOL source and three jobstreams, plus an index member ($INDEX).  As configured for my system, the source/jobstream PDS is on a 3350, VOL=SER=SYSCPK, and is named SYSC.Y2K.SOURCE.  You will probably want to change all of those parameters for your system.  When the installation job runs, it will place the load modules into SYSC.LINKLIB (UNIT=3350,VOL=SER=SYSCPK). The source PDS and load library are referenced in a number of DD cards in the jobstreams, so it would probably be easiest for you to use a text editor on your host OS (Linux/Windows/???) and make all the changes in the "reload" jobstream before you submit it to MVS.

Once the changes above are correct for your system, and you have created the source/JCL PDS, submit the jobstream:  Y2K$ASM from the source/JCL PDS.  This job assembles and link-edits all fourteen of the routines to the load library PDS.  If you want to run the installation verification program, submit the jobstream:  Y2K$IVP.  This will compile and run a COBOL program which calls all the routines with a test data value.

With two calls from your program, you can get a formatted current date.  Here are all the possible formats you can request:

MAJ MIN LEN OUTPUT
 1   1  08  06082024
 1   2  10  06 08 2024
 1   3  10  06/08/2024
 1   4  10  06-08-2024
 1   5  10  06.08.2024
 2   1  08  08062024
 2   2  10  08 06 2024
 2   3  10  08/06/2024
 2   4  10  08-06-2024
 2   5  10  08.06.2024
 3   1  08  20240608
 3   2  10  2024 06 08
 3   3  10  2024/06/08
 3   4  10  2024-06-08
 3   5  10  2024.06.08
 4   1  12  JUNE 8, 2024
 4   2  11  8 JUNE 2024
 5   1  11  JUN 8, 2024
 5   2  10  8 JUN 2024
 6   1  22  SATURDAY, JUNE 8, 2024
 6   2  21  SATURDAY, 8 JUNE 2024
 7   1  21  SATURDAY, JUN 8, 2024
 7   2  20  SATURDAY, 8 JUN 2024
 8   1  17  SAT, JUNE 8, 2024
 8   2  16  SAT, 8 JUNE 2024
 9   1  16  SAT, JUN 8, 2024
 9   2  15  SAT, 8 JUN 2024

And the program that produced the list above is testdfmt.jcl.

Updated 04/2008 - I received a suggestion from Angel Luis Dominguez of slightly different code in the three places where I am determining a leap year.  His code utilizes TM instructions on a binary field containing the four digit year instead of the original series of packed decimal divide instructions.  On my Hercules' emulated system, 500,000 iterations saves 3.13 seconds of CPU time, so it could add up to some savings and is certainly cooler code.  I am embarrassed to admit how long it took to update the source for the three programs affected, but it has now been completed.  No other functionality is changed.

Update 04/2016 - I was working on COBOL versions of these programs for use on a Linux system (compiled with GNUCOBOL) and I needed to add code to the Installation Verification program to call Y2KESTR. While there I also updated the data file for the program to include the expected output in the input datastream to make verification of the results easier; then fed both changes back into this archive. Since I have modified my system to incorporate the source and load modules for these routines into SYSCPK, I did modify the jobstreams to reflect that environment.

Update 05/2024 - There was a recent discussion regarding retrieving the system date and time from MVT COBOL.  Although I believe it was eventually resolved that even in this very old COBOL compiler, you can retrieve at least the basic time of day (clock time) and date with native COBOL syntax.  However, as a result of that conversation, I have added code to return the system time with the Y2KGETD program.  I also updated the Y2KIVP program to show the fields returned.  Here is the page which includes that line from the output of Y2KIVP:

 

DATE: 05/06/24                                YEAR 2000 COMPLIANT DATE SUBROUTINES                                   PROGRAM: Y2KIVP
TIME: 10:37                                    INSTALLATION VERIFICATION PROGRAM                                        PAGE:      3

TEST DATA INPUT RECORD                                           ROUTINE  R/C
DOWN 02061997          3 (THURSDAY)                          Y2KDOWN   0   DAY OF WEEK NUMBER IS: 3 (THURSDAY)
DOWN 02071997          4 (FRIDAY)                            Y2KDOWN   0   DAY OF WEEK NUMBER IS: 4 (FRIDAY)
DOWN 07041997          4 (FRIDAY)                            Y2KDOWN   0   DAY OF WEEK NUMBER IS: 4 (FRIDAY)
DOWN 12251997          3 (THURSDAY)                          Y2KDOWN   0   DAY OF WEEK NUMBER IS: 3 (THURSDAY)
DOWN 12311997          2 (WEDNESDAY)                         Y2KDOWN   0   DAY OF WEEK NUMBER IS: 2 (WEDNESDAY)
DOWN 04151997          1 (TUESDAY)                           Y2KDOWN   0   DAY OF WEEK NUMBER IS: 1 (TUESDAY)
ESTR 2016              03/27/2016                            Y2KESTR   0   EASTER FALLS ON:  3/27/2016
ESTR X039              INVALID CHARACTERS (ZD)               Y2KESTR  *2*  INVALID ZONED-DECIMAL DATA
ESTR 4000              INVALID VALUE (YEAR)                  Y2KESTR  *4*  INVALID VALUE (YEAR)
ESTR 1600              INVALID VALUE (YEAR)                  Y2KESTR  *4*  INVALID VALUE (YEAR)
ESTR 2017              04/16/2017                            Y2KESTR   0   EASTER FALLS ON:  4/16/2017
GETD                                                         Y2KGETD       05062024    2024127   2,460,437  10.37.25.3.3

The values returned for system time are: HH.MM.SS.t.h, where HH=current hour, MM=current minute, SS=current second, t=tenths of second, h=hundredths of second.  The field returned does not contain the periods, they are added during editing for print by Y2KIVP.


Comb Sort

(COBOL)  The comb sort algorithm is an extended bubble sort that outperforms the basic bubble sort and is very simple to implement.  This program reads in 10,000 records from SYSIN, sorts them, and prints the sort time and sorted records on SYSOUT.  Under Hercules the times I saw were around 5/100ths of a second to sort the 10,000 randomly generated test records.  The link to download the COBOL source is:  combsort.tgz [MD5: 5501BBFD3B35AC4B49AE666D30663836].  (A slightly cleaner implementation with inline perform statements can be downloaded this link:  combsort.cbl, but of course it will not compile with the MVT compiler).

 


Input/Output Field Editing Routines

(Assembler)  I first started putting together this collection when I discovered BIF DEDIT didn't do much for fields entered into my CICS programs.  But the collection first became a set, and also became re-entrant, back in 1993 when I had some spare time.  The logic for the numbers to words routine (OFMTMONY) was originally in written in COBOL back in 1976 when another programmer told me I couldn't write the routine in COBOL efficiently enough to run in production.

I updated the installation procedure on September 3, 2003.  So if you have an earlier version, and have checked back here and are worried that the version you got on an earlier date needs updating, relax.  There have been no significant changes to the routines themselves, just an update to the jobstreams that load them onto your system.  And I made a minor change to the Installation Verification COBOL program's report (the output for IFMTLJST was not printing the field returned from the assembler routine).

The installation/verification jobstream is in fmt$load.tgz [MD5: DF68D84AB0B125FB0797D25DCEF4254D].  This is an IEBUPDTE job that will create a PDS containing the assembler and COBOL source and three jobstreams, plus an index member ($INDEX).  As configured for my system, the source/jobstream PDS is on a 3330, VOL=SER=JAY001, and is named JAY01.FORMAT.SOURCE.  You will probably want to change all of those parameters for your system.  When the installation jobs run, they will create a PDS load library.  Again, on my system it is configured to reside on the same 3330 as the source library and is named JAY01.FORMAT.LOADLIB.  These two datasets are referenced in a number of DD cards in the jobstreams, so it would probably be easiest for you to use a text editor on your host OS (Linux/Windows/???) and make all the changes in the "reload" jobstream before you submit it to MVS.

Once the changes above are correct for your system, and you have created the source/JCL PDS, submit the jobstream:  FMT$INST from the source/JCL PDS.  The first step of this job deletes the target load library so you can resubmit this job if you need to restart it or want to recreate the load library for any reason.  The second step simply submits the jobstream:  FMT$ASM from the source/JCL PDS.  This job assembles and link-edits all eight of the routines to the load library PDS.  If you want to run the installation verification program, submit the jobstream:  FMT$IVP.  This will compile and run a COBOL program which calls all the routines with a test data value.


Translate 3270 Buffer Addresses

(Assembler) I have been investigating 3270 Data Streams and wrote these two small programs that will translate a row and column to the equivalent 3270 Buffer Address (BA3270) and translate a 3270 Buffer Address to the equivalent row and column (BA3270R).  They are quite simple to use:

To call from COBOL:
000100 01  ROW-VALUE                   PIC 9(2).
000200 01  COLUMN-VALUE                PIC 9(2).
000300 01  BUFFER-ADDRESS              PIC X(2).
000400
000500     CALL 'BA3270' USING ROW-VALUE, COLUMN-VALUE, BUFFER-ADDRESS.
000600     CALL 'BA3270R' USING BUFFER-ADDRESS, ROW-VALUE, COLUMN-VALUE.
000700
To call from Assembler:
         CALL BA3270,(ROW,COL,ADDRS)     
         CALL BA3270R,(ADDRS,ROW,COL)    
                                         
ROW      DS    CL2                       
COL      DS    CL2                       
ADDRS    DS    CL2                       
                                         

Both programs are in the single archive: ba3270.tgz [MD5: E7D5242A949DA1BAE22EBA22545C77E3].


Generate DD JCL Statements for Online DASD

There are a number of utility programs that require a DD statement to be included for any DASD volume on which an action is to be performed - IEHPROGM and IEHDASDR are good examples.  I stumbled upon a program that would do this on the Internet, but it would not work under MVS 3.8j.  So I wrote a program that would provide this function for MVS 3.8j.  The program scans the UCB table and generates a DD statement in the format:

//PUB002 DD UNIT=SYSDA,DISP=OLD,VOL=SER=PUB002 * DDDASD GENERATED 

for each DASD type device that is mounted, placing the Volume Serial Number in the name field for the statement and in the VOL=SER= field.

The jobstream in dddasd.tgz [MD5: 549DD3CADC9449719A49AFA95F593D4C] will assemble/link the program into SYS2.LINKLIB.  To execute the program, use the JCL:

// EXEC PGM=DDDASD
//SYSUT1 DD DSN=<dataset to receive generated statements>,
            DCB=(RECFM=FB,LRECL=80,BLKSIZE=800),
            <other statements as required>


The following programs were not written by me, but lacking another existing page on which to include them and not wanting to create individual pages for a lot of miscellaneous programs, I am placing them here.  I have been revisiting archives as I clean out a storage facility and some of the programs I have found there are too good not to share here.  Perhaps someone else will find exactly the solution they have been searching for in this eclectic collection.


Prime VSAM Cluster

This assembler program was written by Steve Wentworth and solves the problem of opening an empty (newly created) VSAM cluster with a COBOL program for input/output.  You will experience this even if you are using my VSAM I/O routines to open a newly created VSAM cluster as Input-Output and attempt to add a new record -- the write will fail because the HIGH-USED-RBA is 0.  Steve's program will work with any KSDS cluster without modification; he uses SHOWCB/MODCB macros to tailor the key and record length to whatever is defined for the file pointed to by the DS DD at execution.  

An installation jobstream with the source program and an execution jobstream are included in the archive:  primevs.tgz [MD5: 57D64F0637EAD81DD2C132762FE6C0B8]. 


Reset Dataset(s) to Empty

This assembler program will reset (empty) partitioned or sequential datasets in preparation for a reload.  Datasets processed by this program will appear as though they have been deleted and re-allocated, however, the overhead of scratch/allocate and uncatalog/catalog is avoided.  Additionally, datasets will still reside in the original location on the volume, which cannot be assured with scratch/allocate.  This allows for permanent placement of datasets even though they may require reloading.  Datasets to be reset are specified by one or more DD cards beginning RESET (the final three characters may be any legal DSName characters), so multiple datasets may be reset with each execution.  No additional DD cards are required and no parameter information is necessary.

An installation jobstream with the source program and an execution jobstream are included in the archive: resetds.tgz [MD5: FABA6900B29CD15B992CF67938EEC0AC].


Access PDS Members from COBOL Updated 07/22/2014

This assembler program allows high level access to PDS members from languages that may not have native means (COBOL, PL/I, etc).  The source of the program is file #12 of the CBT Overflow tape.  This file originated from UK GUIDE and the routine itself came from Smith International (North Sea) Ltd.  

Update:  It was reported to me by Vincent Coen that this routine abends with a S0C4 (addressing exception) when attempting to retrieve all records of a member when the member occupies more than a single block on the PDS. I had not personally used the routine to do more than read a few parameter card image records from a single member, so I had not experienced this, nor had I had this reported to me previously.  Just prior to heading off into a dump to attempt to resolve it, I thought to check CBT to see if anyone else had already fixed the problem.  Fortunately, Harold Zbiegien has fixed the problem and uploaded his corrected version to file #152 of the current CBT tape (#488).  I have updated my installation jobstream, replacing the original version with Harold's version.  Harold's version includes the addition of an additional parameter to facilitate modifying the DDNAME for the dataset to be utilized prior to opening the dataset, so I have modified my example program to match Harold's version of the subprogram.

I have also included a very simple example program in COBOL to illustrate the use of the program and to verify correct installation.  Note that the documentation for the routine, embedded in the assembler source, is incorrect with regards to the return code obtained upon reaching the end of a member on a read command; the actual value returned is 4 rather than 8.

The installation jobstream - install.jcl - and the sample program - ivp.jcl - are contained in the archive:  ncz93205.tgz [MD5: 884ab95523b30bf7fa78a40e93a3f436].  My jobstream installs the routine into SYS2.LINKLIB, which may be changed to suit your environment.


Issue Console Commands and Display Messages at Predefined Times

This assembler program runs as a started task, initially executed at IPL time.  It automatically schedules itself to start every two hours, or at the time of the next scheduled event, if an event is scheduled to occur sooner than the next two hour "window".  The scheduled events are read from a parameter member and may be either a message to display on the console or an MVS console command to be executed.  A field in the event table designates the table entry as relevant to any machine or a specific machine based upon the System IDentification string.

I prefer to have automatically issued commands "echoed" to the console as well as executed so that there is a record of commands executed.  The display code in the original version of this program placed displayed messages with DESC=(2) by default, which made them non-rollable.  This is probably a desirable feature for critical messages, but not necessary to "echo" commands.  So I duplicated the WTO code to provide both a high intensity, non-rollable message and regular intensity, rollable message facility, selectable by DSH or DSN on the schedule table entry.  My installation jobstream creates both a procedure and parameter member for the program and there is an example of automatic commands with low-intensity displays in the jobstream.

I have also modified the code to retrieve the System IDentification from control blocks rather than scanning the SMF parameters every execution.  The overhead saved by eliminating the file access is probably minimal, especially on the Hercules' platform, but it simply seems more efficient to me.

All of my modifications may be identified by the presence of the string '*JLM*' in the right margin of the line.

The jobstream to assemble and link-edit the program, plus install the procedure and parameter member is in ztimer.tgz [MD5: 4018FA80ED50877E45168CD2FEDAF4E1].  The program must be in an authorized library and the jobstream is set up with SYS2.LINKLIB as a target.  SYS1.LINKLIB may be used if you do not have a SYS2.LINKLIB set up as an authorized library.  The target for the procedure is SYS2.PROCLIB, but SYS1.PROCLIB may be substituted.  The target for the parameter is SYS2.CONTROL, but SYS1.PARMLIB may be substituted (don't forget to change the procedure if you are not using SYS2.CONTROL).  Also, you should place a START command for the program in your COMMAND member so that it will be started after each IPL.


Dynamically Load Subprograms in MVT COBOL

DYNALOAD is one of several utilities written by Ed Liss.  His website is no longer available, but I will continue to provide DYNALOAD on this page and it will be included on the Compiler/Language/Tools Volume that I maintain as it provides an extremely desirable and needed function to programs compiled with the MVT COBOL compiler available for use under MVS 3.8.

In later versions of IBM COBOL compilers, depending upon compile time options and/or method of coding the CALL verb, execution of the called subprogram could be either Static or Dynamic.  

In the Static case, the object code for the called subprogram was bound to the main program by the Link Editor at compile time.  If the subprogram was later changed and recompiled, it was necessary to re-link the calling program in order to utilize the updated subprogram.  In the case of large applications, where there might be many shared subprograms, a change to even a single subprogram might result in much re-linking and a huge system management task.

When Dynamic subprogram calling became available, subprograms were no longer bound to the main program by the Link Editor, but were compiled as separate load modules.  At execution time, when a CALL statement was executed, the load module for the subprogram was loaded into memory and executed.  It was no longer necessary to re-link every main program that called a subroutine when the subroutine was modified.

The MVT COBOL compiler predates the ability to have Dynamic CALLs.  Ed Liss' DYNALOAD subprogram provides that functionality.  His archive contains installation instructions, the Assembler DYNALOAD subprogram, and a couple of COBOL programs to demonstrate its use.  Download the archive - dynaload.zip [MD5: 22E13CE145153B1D4A3371F4B5DF89E4] - from this site and follow the installation instructions in the readme file contained therein.


Retrieve JOB Card Information  Updated 03/08/2023

This subroutine will traverse MVS control blocks to extract information contained in fields on the JOB card and return them to the caller.  The original program code is located in File #65 of the CBT overflow tape and is part of a collection from the Los Angeles User Group tape.  I found that the JES Job Number field was not returned using the program as supplied and I believe that the reason is that the program is coded to retrieve the JES Job Number from a field maintained under JES3.  So I left the original code intact and added code following it to retrieve the JES2 Job Number.  My added lines are identified by *jlm* beginning in column 67 of each line.

Download the archive - jobcrd.zip [MD5: 858D14DEB322E0637D1AD7BED39635B6] - from this site.  The archive contains two jobstreams:

The jobcrd$ jobstream places the load module for the subroutine in SYS2.OBJLIB, which is defined on my system to contain this type of module which is to be subsequently linked or called by another program.  You will probably need to change the target to a library that is defined on your system.  Likewise, the jobcrd@ jobstream uses an override in the link step to allow the link editor to access the subroutine from this library; you will need to change this override to match whatever change you make in the first jobstream.

Note:  This archive and the jobstreams contained within were created on a Windows system.  Each line is terminated by x'0d0a'.  If you download them to a Linux system you will need to strip the x'0d' using a utility such as fromdos. 

Updated 03/8/2023:

Ed Liss submitted a wrapper program so that the subprogram may be called from a PL/I program.  Download the archive - jobcrdp.tar.gz [21 kB MD5: c9f767b15d48f4ca21ca13b901166e4b] - from this site. The archive contains two jobstreams and the output from those jobstreams in two PDFs:

The two jobstreams were created by Ed Liss.  The only modifications I have made was to install the wrapper subroutine into SYSC.LINKLIB.


Report Step Completion Codes

This program is executed as the final step of any batch job to send a report of the completion codes for all the preceding steps of the job to a dataset (SYSPRINT DD statement), one or more consoles (via ROUT parameter), and/or one or more TSO User IDs (via SEND).  I found this on an old NASPA CD and I believe the originator of the program was Don Frasier at Western Atlas International in Houston, TX, but there is no attribution in the source and I have made this inference from other programs contained in the same location.  As provided, there were some problems that prevented the program from assembling, which I have corrected.  You can find my corrections by searching for *JLM* in column 67 of the source.  The instructions are simple and stated well in the comments from the source:

THIS PROGRAM IS DESIGNED TO REPORT STEP COMPLETION CODES FOR BATCH JOBS. 
WHAT AND WHERE IT WRITES IS DETERMINED BY A PARAMETER LIST AND A DD STATEMENT. 
THE PROGRAM IS TO BE RUN AS ITS OWN JOBSTEP FOLLOWING ANY JOBSTEPS THAT IT 
IS TO REPORT ON. FOLLOWING IS A JCL EXAMPLE: 

    //* 
    //COMPCODE EXEC PGM=COMPCODE,COND=EVEN,
    // PARM='USER=(RWGV3),ROUT=(2,3,11),STEP=(ASMFCL.*,TESTER)'
    //SYSPRINT DD DSN=RWGV3.SYSPRINT,DISP=MOD
    //* 

(1) COND=EVEN SHOULD ALWAYS BE SPECIFIED SO THAT THE STEP WILL EXECUTE EVEN 
    IF A PREVIOUS STEP HAS ABENDED.

(2) VALID PARMS ARE AS FOLLOWS:

    (A) USER= SPECIFIES WHICH USER(S) ARE TO BE NOTIFIED BY COMPCODE.
        THIS PARAMETER IS OPTIONAL.  THE USER LIST MUST BE ENCLOSED IN 
        PARENTHESIS EVEN IF ONLY ONE USER IS SPECIFIED.  EX. USER=(S001,S002) 
        OR USER=(S001).  THE MAXIMUM NUMBER OF USERS IS THREE.  IF NO USERS 
        ARE SPECIFIED, NO USERS WILL BE NOTIFIED.

    (B) ROUT= SPECIFIES THE ROUTE CODES THAT THE MESSAGE(S) ARE TO BE SENT TO. 
        THIS PARAMETER IS OPTIONAL.  THE ROUTCDE LIST MUST BE ENCLOSED IN 
        PARENTHESIS EVEN IF ONLY ONE ROUTE CODE IS SPECIFIED.  EX. ROUT=(1,2,3) 
        OR ROUT=(3).  VALID ROUTE CODES ARE 1-16.  IF NO ROUTE CODES ARE 
        SPECIFIED, NO MESSAGES WILL BE SENT TO OPERATOR CONSOLES. 

    (C) STEP= SPECIFIES THE STEP(S) THAT COMPCODE IS TO REPORT ON.  THIS 
        PARAMETER IS OPTIONAL.  IF OMITTED, ALL STEPS WILL BE REPORTED ON 
        (EXCEPT FOR STEPS THAT HAVE NOT YET EXECUTED OR THE "COMPCODE" STEP, 
        BOTH OF WHICH ARE NEVER LISTED).  THE STEP LIST MUST BE ENCLOSED IN 
        PARENTHESIS EVEN IF ONLY ONE STEP IS SPECIFIED.  STEPS MUST BE INDICATED 
        IN ONE OF THREE WAYS: 

            (1) PROGRAM EXECUTION - WHERE THE EXEC CARD SPECIFIES PGM=.
                FOR //STEP1 DD PGM=IEBGENER, THE STEP PARM WOULD READ: 
                STEP=(STEP1,ETC,ETC) 

            (2) PROC EXECUTION(SINGLE STEP) - WHERE THE EXEC CARD SPECIFIES A 
                PROC AND ONLY ONE STEP OF THE PROC IS TO BE REPORTED ON. 
                FOR //ASMNLINK EXEC ASMFCL, TO GET ONLY THE LKED STEP, THE 
                STEP PARM WOULD READ:  STEP=(ASMNLINK.LKED,ETC,ETC) 

            (3) PROC EXECUTION(ALL STEPS) - WHERE THE EXEC CARD SPECIFIES 
                A PROC AND ALL STEPS FOR THE PROC ARE TO BE REPORTED ON.
                FOR //ASMNLINK EXEC ASMFCL, TO GET ALL STEPS, THE STEP 
                PARM WOULD READ:  STEP=(ASMNLINK.*,ETC,ETC) 

(3) SYSPRINT DD STATEMENT - IF A SYSPRINT DD STATEMENT IS INCLUDED, THE MESSAGE 
    WILL BE WRITTEN INTO THE DATASET SPECIFIED IN ADDITION TO THE USER= AND 
    ROUT= REPORTING.  IF THE DATASET EXISTS AND HAS DCB ATTRIBUTES, THEY ARE NOT
    CHANGED.  IF NO DCB ATTRIBUTES ARE SPECIFIED, THE DATA IS WRITTEN AS 
    RECFM=FB,LRECL=133,BLKSIZE=6118. 

(4) SNAPDUMP DD STATEMENT - THIS DD STATEMENT IS TO BE USED FOR DIAGNOSTIC 
    PURPOSES ONLY.  IF INCLUDED, A SNAPDUMP OF THE PERTINENT CONTROL BLOCKS WILL 
    BE DONE.  NOTE THAT THE DCB ATTRIBUTES FOR THIS DCB ARE HARD-CODED TO 
    RECFM=VBA,LRECL=125,BLKSIZE=1632, A RESTRICTION IMPOSED BY THE SNAP FACILITY.

* NOTE: THAT THIS PROGRAM MUST RUN APF-AUTHORIZED IF THE "USER=" PARAMETER IS 
  SPECIFIED.

Download the archive - compcode.tar.gz [MD5: 9d2afb728b05c7c667300608ccf53a02] - from this site.  The archive contains the single jobstream to assemble and link the load module.  The target load library is SYS2.LINKLIB; if you do not have a SYS2.LINKLIB, the load module may be placed in SYS1.LINKLIB.  The load module must be executed from an authorized load library if the USER= parameter is employed.


UCB Scan Routine

Recently I was looking back at my saved messages from the Hercules' forums and found a January 2021 thread (re)discussing this thread from the old Yahoo H390-MVS forum.  The original posts on the Yahoo forum were from April 27,  2016.  Because I was familiar with the occasional need for this capability in MVS 3.8j, I had saved the original archive back in 2016, but had never done anything further with it.  Instructions, both in 2016 and the recent repost, included very little in the way of instruction about how to utilize the programs, so I have packaged them, and made few minimal changes in the naming, and am placing them here on my 'miscellaneous' page.

In MVS/SP and later versions of MVS there is a routine in the Operating System that will scan the Unit Control Block table, which contains an entry for every device generated (during System Generation) for the Operating System.  The address of the routine is located at offset x'434' in the Communication Vector Table.  Unfortunately, MVS 3.8j has no equivalent.  I have run into it with several of the programs I have installed from the CBT archive, which I have solved by commenting out the call to the resident scan routine and coding a scan routine inside each of the programs.  The discussions on the MVS forums, both in 2016 and 2021, were in regard to running the IBM program TRSMAIN, which is distributed in object code only, so a solution of 'coding your own routine' will not work.  Back in 2016 someone, who apparently wished to remain anonymous, coded this solution to implement the scan routine in MVS 3.8j.  somitcw posted the five files required to implement the routine in the forum files, and that is where I obtained the copy I have.

The steps required to implement the routine in MVS 3.8j are:

  1. Assemble the scan routine code and link-edit into SYS1.LPALIB;
  2. Re-IPL with CLPA to rebuild the Link Pack Area, which places the routine in memory;
  3. Assemble and link-edit a program to acquire the address of the routine and ZAP it into the CVT at x'434'.

It is necessary to repeat step #3 following each IPL.

The original collection of programs also included a simple assembler program to test the functionality of the scan routine.  

I have combined the three assembler jobstreams into a single jobstream, and added a step to place a procedure into SYS2.PROCLIB that will execute the ZAP program to place the scan routine address into CBT+x'434'.  The archive containing the installation jobstream and the test jobstream is available from ../downloads/archives/iosvcucb.tar.gz  (Size: 9 kB MD5: 95b9f3a3267d953d2d70ec53b3fa89b1).

The scan routine must be linked into SYS1.LPALIB.  Currently the two other programs in the jobstream are linked into SYS2.LINKLIB, which may be changed, but the target load library must be an authorized library in the Link List.  The procedure - IOSVSUCB - will be created in SYS2.PROCLIB.  Tailor the installation jobstream - IOSVSUCB.jcl - if required for your system and submit it to install the three programs and the procedure.  Edit your SYS1.PARMLIB member that contains commands automatically issued following IPL - on my system that is SYS1.PARMLIB(COMMND00) - and add a line at the end:  COM='START IOSVSUCB'.  Shut down MVS and re-IPL, specifying CLPA to rebuild the Link Pack Area.

To verify that the scan routine is installed and functioning, submit the test program jobstream - UCBSCANT.  The output from that job on my system is included at ucbscant.pdf.


Verify Load Module Available (and return library where it was found)

I recently needed to be able to verify that a load module was available, then set a return code in order to determine subsequent steps to run in a batch job.  After searching for a while, I concluded that particular solution had not yet been coded, although I found some code in a Xephon article that did some of the work toward what I needed.  Initially I was not interested in producing any output other than the step return code, but the design expanded, because, well I could; so if you supply a SYSPRINT DD statement, a single line of output is produced that identifies the library where the load module was found.  Of course, if the load module is not found, the information line is not produced.  All current programs on CBT that do something similar to this rely upon the LLA pointer in CVT, which is not available for MVS 3.8j.  If the load module is located, I use dynamic allocation to read the Link List member from SYS1.PARMLIB to provide the dataset name of the library and the volume serial where it resides.

As for the original purpose for which I wrote the program, if the load module is found, the step return code is 0000; if it is not found, the step return code is 0001.

The source is available in a jobstream to assemble it at ../downloads/archives/whichlib.tar.gz.  The program will be included in the next update of SYSCPK.

Update 05/25/2024:  John Bos pointed out to me that in TK5, and perhaps in other installations of MVS, parameter statements in SYS1.PARMLIB have blanks (or at least one) preceding the value in the record.  Also, I just assumed that the values I was reading SYS1.PARMLIB members would be present, so I had not coded to allow reading past the end of the member while looking for the data I was after.  So I have now corrected the program to allow for these situations.  The updated version will be in the next update of SYSCPK, but if you need it immediately, download the jobstream above to assemble/link WHICHLIB into SYSC.LINKLIB (or any other library on your system).

Example jobstream:

//WHICHLIB JOB 1,'WHICHLIB',CLASS=A,MSGCLASS=X
//WHICHLIB EXEC PGM=WHICHLIB,PARM=SORT  <-- name of load module to be found is provided in PARM
//SYSPRINT DD SYSOUT=*                  <-- totally optional SYSPRINT DD

Produces information output:

SORT     WAS FOUND IN LINKLIST LIB(05) SYSC.LINKLIB ON SYSCPK

Calculate CRC32 for MVS Datasets

I have had this on my 'to do' list for a while.  I found this program in a Xephon article and thought it would be of interest to people who transfer a lot of datasets into and out of MVS 3.8j.  Being able to verify that a dataset was not altered during transfer can save a lot of lost time tracking down errors.  There were minimal changes required for assembly with IFOX00, although it did require a macro that is not distributed with MVS 3.8j, which I satisfied by using the identical macro from OS/VS1, which was not an original idea, as I knew that Gerhard Postpischill had done this previously.  I included the macro, along with YREGS in front of the source, so to eliminate the need for another macro library.  The jobstream to assemble and install it to SYS2.CMDLIB, along with a simple help member for SYS2.HELP is available at ../downloads/archives/crc32.install.tar.gz.


Return to Site Home Page 



This page was last updated on June 08, 2024.