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.
(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.
The installation/verification jobstream is in y2k$load.tgz
[MD5: DF1ACC3172DD4A42CB0D5F8CF34BDACB].
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.Y2K.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.Y2K.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: Y2K$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: 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.
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 not been completed.
No other functionality is changed.
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:
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:
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
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.
When I tracked down the macros required to assemble the program, I
found that it was necessary to change the name used to call one of them in order
to match the version of the macro included. The three cards changed may be
recognized by my initials (JLM) in column 65.
I made an additional change in the open request code - if the member
parameter is non-blank, the contents of the member parameter are moved to the DD
Name of the PDS DCB before it is opened. Again my changes may be
identified by my initials (JLM) in column 65.
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: 8DC1D00F45A407B8CAF7D0DA65F2D97A].
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
I cannot recall the original path through which this archive
came to me, but according to the date stamps I obtained it in May 2007 and the
files within the archive were created in January 2007. The web address
given in the source of the program is no longer valid, so I am adding the
archive here as it provides an extremely desirable and needed function to
programs compiled with the MVT COBOL compiler we have available.
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
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:
jobcrd$ - assembles the subroutine
jobcrd@ - compiles a simple COBOL program to verify the subroutine and
demonstrate its use
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.