We have 3 exercises for you. For each, we have first to give an introduction that explains the situation.
A CMS MACLIB (Macro Library) has following internal structure:
+-----------------------+ +-! LIBPDS ! ! +-----------------------+ ! ! MACRO1 ! ! ! ! ! ! ! ! + - - - - - - - - - - - + ! ! MACRO2 ! ! ! ! ! ! ! ! ! ! ! + - - - - - - - - - - - + ! ! MACRO3 ! ! ! ! ! ! ! ! ! ! ! +-----------------------+ +>! MACRO1 --> MACRO2 -->! ! MACRO3 --> ! +-----------------------+
The first record has following layout:
1 2 3 1...+....0....+....0....+....0.... LIBPDSnnnnnnpppp....
where:
The index records contain one or more macro names (8 characters), followed by the record pointer (8 characters, binary notation) to the start of the macro definition.
The macros are separated from each other by a record starting with '61FFFF61'x.
This is enough information for you to let you code the procedure described below.
Write a procedure that extracts a specific macro from a MACLIB. Of course, you could do it with the aid of some CMS commands (like PUNCH or MACLIST), but this time we expect you to use REXX File I/O methods.
Your procedure can use any of the File I/O methods explained in the text. Maybe it's good to review the advantages and disadvantages of the different methods before to choose one for the exercise.
The command format should be:
GETMAC maclib_fn macro
where maclib_fn is the filename of the macro library, and macro is the name of the macro you want to extract.
Note
You can find plenty of MACLIB files on your S-disk. You should
'stress-test' your procedure on one of the largest ones (DMSOM MACLIB).
Your procedure should thus perform these logical steps:
When you have written yours, you may take the time to review our commented solutions.
by Steven L. Jones
This article was extracted from the IBM VM Software Newsletter of 1st Quarter 1991.
The article serves as introduction to the exercise, but contains valuable information on itself. You may be faced with the problem of determining the system on which you want to run your procedures.
The exercise mainly serves to teach you some less used REXX functions that do bit-manipulation. You will also be confronted with binary and hexadecimal notations, which may be a good review. This exercise is not too difficult.
In order to understand some terms in the article, let's review 2 machine instructions for those of you that don't know much about internal principles of operations.
Supervisor Call or SVC.
This instruction can be used by an application program to request services from the operating system (the supervisor). In most of our virtual machines, the supervisor is CMS.
The format of the SVC instruction is simple:
SVC nn
where nn is a number that applies to a convention for the supervisor. For example, SVC 204 is the instruction a program should use to ask CMS to execute another program or command.
The conventions are different for each operating system. SVC 06 asks an OS/390 system to call another program, while this same number means terminate processing when issued on a VSE/ESA system (or on CMS with SET DOS ON).
CMS also knows a bit about VSE/ESA and OS/390 and simulates these SVC routines. By default, CMS supposes you run OS/390 programs. If you want to run VSE programs, then you have to SET DOS ON.
SVC instructions are normally imbedded in assembler macros. So, for example, the CMS macro CMSCALL will prepare a parameter list and then issue the SVC 204.
Diagnose instruction
This instruction allows an operating system to request special services from the hardware. For a virtual machine, the hardware is CP, and thus, in VM, the diagnose instruction was selected to let a virtual machine request functions from CP.
The diagnose instruction has no mnemonic assembler code, so one has to code the operation code instead, such as:
DC X'83',Rx,Ry,nn
(this is a simplified format, you'll find a more complete example in the text). Rx and Ry are registers that provide or receive data and nn is again a convention for communication with CP.
For example, diagnose X'08' allows a program to issue CP commands, diagnose X'14' allows to manipulate spool data (such as reading a RDR file) and diagnose X'64' allows to load or purge shared segments.
The text talks about diagnose X'00' by which one can ask CP for the system level.
REXX provides the built-in functions DIAG() and DIAGRC(), which support many, but not all, diagnose code functions.
It is often necessary for an application to determine the availability or behavior of certain commands, Diagnose Codes, or architecture-sensitive information that affects its execution. There are several methods for obtaining this type of information. Some of the methods have however, the potential to break the application when it is ported to a new release or version of CP.
Note that some parts of the article are a bit obsolete now, as all VM systems should now at least run at VM/ESA level 2.2.0, as this is the first release that is Y2K compliant.
There are two common methods of determining CP functional information that should be avoided. These two methods are:
Here are some examples of the output returned by QUERY CPLEVEL on various versions of VM:
VM/SP RELEASE 6, SERVICE LEVEL 610 VM/XA SP Release 21, service level 0000 VM/ESA Release 1, Service Level 000 - 370 Feature VM/ESA Release 1, service level 0629 VM/ESA Release 2.1, service level 9404
The two pieces of information most commonly used from the output returned by QUERY CPLEVEL are:
The product name is normally compared to literal constants such as VM/XA or VM/SP so that different actions can be taken based on the result of the comparison. The release number is used to determine if an application is executing on a release that supports a specific function. Each release of CP adds new functions, so that applications that desire to exploit one, while still be able to work on earlier releases, need to determine the system level on which they execute. Programs may for example test for the availability of APPC/VM (was not on VM/XA), TSAF (was not on VM/XA), CMS Pipelines (was not on VM/ESA 1.0), specific Diagnose Codes, or new CP System Services.
| The product name returned by QUERY CPLEVEL should not be used for product determination because applications must recode whenever a new VM product name is introduced. |
For example, any application that coded a test of the product name returned by QUERY CPLEVEL such as the following:
Parse Value Diag(8,'QUERY CPLEVEL') With ProdName . If ProdName = 'VM/XA' /* Do we have XA-architecture? */ Then Call DOXA
is subject to breakage on VM/ESA because the product name will be VM/ESA, causing the test to fail. In most cases, however, the architectural considerations are the same for VM/ESA as they are for VM/XA, and you would want the test to succeed. Code similar to the above in applications prior to VM/ESA must now be recoded in order to support VM/ESA properly.
| This misuse of the QUERY CPLEVEL (or the Diagnose X'00' as explained later) is one of the main reasons why some program products fail to run on VM/ESA, and not because they are technically not able to run in that environment. |
The above is not an isolated case. There is a similar problem with VM/SP because of the VM/ESA-370 feature.
A test such as :
Parse Value Diag(8,'QUERY CPLEVEL') With ProdName . If ProdName = 'VM/SP' /* Do we have VM/SP system */ Then Call DOVMSP
will lead to incorrect results on the VM/ESA-370 feature because the system name returned by QUERY CPLEVEL will be VM/ESA. An additional problem with the VM/ESA 370 feature is that the product name for the 370 feature is the same as for the ESA feature. Both features are named VM/ESA. Returning to our output examples for VM/ESA:
VM/ESA Release 1, Service Level 000 - 370 Feature VM/ESA Release 1, service level 0629
you can see that in order to determine if you are executing on the 370 feature, an additional test must be made for the character string 370 Feature, which appears as the last two tokens of the output. This increases the complexity of the coding, particularly for assembler applications.
Similar breakages could occur in the future if new VM product names are introduced and applications are using hard coded character strings to identify products.
Diagnose X'00' returns following information:
System name | 8 bytes EBCDIC. See discussion below. |
Environment | 3 bytes HEXA. If bit 0 of first byte is '1' then VM runs in an LPAR. Other bits are reserved and zero. |
Version code | 1 byte HEXA, the version code from the CPUID. |
Reserved | 4 bytes with reserved bits or less important info |
Userid | 8 bytes EBCDIC, the userid issuing the diagnose. |
Product Bit Map | 8 bytes HEXA, see discussion below. |
Time Zone | 4 bytes HEXA, represent the time zone differential in seconds from GMT. |
Release Info | 4 bytes HEXA : byte 1 is release number, byte 2 is release modification level and bytes 3-4 are service level. |
The system name is the first eight bytes of the output returned by Diagnose X'00'. It will be one of the following: VM/SP, VM/XA SF, VM/XA SP, or VM/ESA. The system name returned by Diagnose X'00' is used for the same purpose as the product name returned by QUERY CPLEVEL: to determine whether the control program is 370 or XA (ESA), but the Diagnose X'00' system name is less informative than the QUERY CPLEVEL product name. For example, it is not possible to distinguish between VM/SP and VM/SP HPO, nor between the VM/ESA 370 Feature and the VM/ESA ESA Feature, using only the Diagnose X'00' system name.
The dangers of using the Diagnose X'00' system name are the same as for the QUERY CPLEVEL product name.
Breakage can also occur when the release number returned by Diagnose X'00' is used. For example, an APAR to VM/XA SP 2.1 changed the release number from 21 to 2.1. Either of these values may be returned, depending whether the APAR that made the change in the QUERY CPLEVEL output, is applied.
The previous discussion has demonstrated why you should not use QUERY CPLEVEL or the system name returned by Diagnose X'00' to determine the functional level of CP. Instead, use the Program Product Bit Map returned by Diagnose X'00'.
The Program Product Bit Map is an eight-byte field that starts at offset X'18' (24 decimal) in the data returned by Diagnose X'00'. The Program Product Bit Map has a unique bit for each functional enhancement to CP that affects externals or other major changes such as SPEs (Small Program Enhancements). Each release of VM will have a unique bit in the Program Product Bit Map.
In addition to the bit that designates the release of CP that an application is executing on, all previous release bits will also be on. Thus the Program Product Bit Map is cumulative. This means that for VM/SP 6, the bits for all previous releases of VM/SP (VM/SP 5 through BSEPP) are set to '1' as well as the bit for VM/SP 6. This point is significant in that once you have determined whether the control program is 370 or XA (ESA) a single bit can be tested to determine if you are executing on a specific release of CP or higher. This is usually the test that is done to determine if a particular function desired is available. An example of this will be discussed later.
The first bit (bit 0 of byte 0) of the Program Product Bit Map
is special in that it is
used to determine if the CP is 370 (VM/SP, HPO, VM/ESA-370) or XA (VM/XA,
VM/ESA-ESA). If this bit is "on" (1), the CP is 370 ; if it is
"off" (0), it is XA or ESA-ESA.
| Once the data has been captured from Diagnose X'00', bit 0 of byte 0 is all that is necessary to determine if the CP being executed on, has 370 or XA (ESA) capability. |
Therefore, unlike QUERY CPLEVEL or the system name contained in Diagnose X'00', the Program Product Bit Map is not subject to breakage due to changes in product names or format of the release level number. Once a particular bit is determined to be the initial indicator of a desired function and the application is coded to test that bit, the test will remain valid for future releases.
The definition of the bits that are contained in the Diagnose X'00' Program Product Bit Map is as follows:
Definition of the VM/SP (VM/ESA-370) Program Product Bit Map:
Program Product Bit Map : VM/SP, VM/SP HPO, VM/ESA-370 Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 ... 1111 1110 1111 1111 1111 1011 1111 1111 0000 0000 ... ^^^^ ^^^ ^^^^ ^^^^ ^^^^ ^ ^^ ^^^^ ^^^^ Byte 3 !!!! !!! !!!! !!!! !!!! ! !! !!!! !!!+-- X'01' VM/SP Secure Origin ID !!!! !!! !!!! !!!! !!!! ! !! !!!! !!+--- X'02' VM/SP in LPAR mode with monitor changes !!!! !!! !!!! !!!! !!!! ! !! !!!! !+---- X'04' Dispatcher Request Queue Changes (VM35119) !!!! !!! !!!! !!!! !!!! ! !! !!!! +----- X'10' VM/ESA Release 1.5 !!!! !!! !!!! !!!! !!!! ! !! !!!+------- X'10' VM/ESA Release 1 !!!! !!! !!!! !!!! !!!! ! !! !!+-------- X'20' VM/SP Release 6 !!!! !!! !!!! !!!! !!!! ! !! !+--------- X'40' VM/SP and HPO with 3380 Model K support !!!! !!! !!!! !!!! !!!! ! !! +---------- X'80' VM/SP and HPO with 3380 AD4/AE4 support !!!! !!! !!!! !!!! !!!! ! !! Byte 2 !!!! !!! !!!! !!!! !!!! ! !+--- X'01' Free Storage Enhance -SPE- running !!!! !!! !!!! !!!! !!!! ! +---- X'02' VM/SP HPO Release 6.0 !!!! !!! !!!! !!!! !!!! +------ X'08' VM/SP HPO Release 5.0 !!!! !!! !!!! !!!! !!!! !!!! !!! !!!! !!!! !!!+-------- X'10' HPO 3.4 Scheduler Monitor Changes !!!! !!! !!!! !!!! !!+--------- X'20' VM/SP HPO Release 4.2 !!!! !!! !!!! !!!! !+---------- X'40' VM/SP HPO Release 4.0 !!!! !!! !!!! !!!! +----------- X'80' VM/SP HPO VDLE Support !!!! !!! !!!! !!!! Byte 1 !!!! !!! !!!! !!!+--- X'01' VM/SP HPO 3880 Model 21 Support !!!! !!! !!!! !!+---- X'02' VM/SP HPO Release 3.6 !!!! !!! !!!! !+----- X'04' VM/SP HPO Release 3.4 !!!! !!! !!!! +------ X'08' VM/SP HPO Release 3.2 !!!! !!! !!!+-------- X'10' VM/SP HPO Release 3.0 !!!! !!! !!+--------- X'20' VM/SP HPO Release 2.5 !!!! !!! !+---------- X'40' VM/SP HPO Release 2.0 !!!! !!! +----------- X'80' VM/SP HPO Release 1.0 !!!! !!! Byte 0 !!!! !!+--- X'02' VM/SP Release 5.0 !!!! !+---- X'04' VM/SP Release 4.0 !!!! +----- X'08' VM/SP Release 3.0 !!!+------- X'10' VM/SP Release 2.0 !!+-------- X'20' VM/SP Release 1.0 !+--------- X'40' SEPP +---------- X'80' BSEPP 1.2 |
Notes:
Definition of the VM/XA (VM/ESA-ESA) Program Product Bit Map
Program Product Bit Map : VM/XA SF, VM/XA SP, VM/ESA-ESA Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 ... 0111 1111 1111 1111 0000 0000 0000 0000 ... ^^^ ^^^^ ^^^^ ^^^^ Byte 2 !!! !!!! !!!! !!!+ X'10' VM/ESA Version 2 Release 3.0 !!! !!!! !!!! !!+- X'20' VM/ESA Version 2 Release 2.0 !!! !!!! !!!! !+-- X'40' YEAR 2000 Support !!! !!!! !!!! +--- X'80' VM/ESA Version 2 Release 1.0 !!! !!!! !!!! Byte 1 !!! !!!! !!!+----- X'10' VM/ESA Version 1 Release 2.2 !!! !!!! !!+------ X'20' VM/ESA Version 1 Release 2.1 !!! !!!! !+------- X'40' VM/ESA Version 1 Release 2.0 !!! !!!! +-------- X'80' VM/ESA Version 1 Release 1.1 !!! !!!! !!! !!!! Byte 0 !!! !!!+----------- X'01' VM/ESA Version 1 Release 1.0 !!! !!+------------ X'02' Secure Origin ID SPE !!! !+------------- X'04' VM/XA SP Release 2.1 !!! +-------------- X'08' APSS SPE !!+---------------- X'10' VM/XA SP Release 2.0 !+----------------- X'20' VM/XA SP Release 1.0 +------------------ X'40' VM/XA SF Release 2.0 |
Notes:
VM/ESA 2.2.0 Cumulative bits = '7FFE000000000000'x VM/ESA Year 2000 Sup Cumulative bits = '7FFC000000000000'x VM/ESA 2.1.0 Cumulative bits = '7FF8000000000000'x VM/ESA 1.2.2 Cumulative bits = '7FF0000000000000'x VM/ESA 1.2.1 Cumulative bits = '7FE0000000000000'x VM/ESA 1.2.0 Cumulative bits = '7FC0000000000000'x VM/ESA 1.1.1 Cumulative bits = '7F80000000000000'x VM/ESA 1.1.0 Cumulative bits = '7F00000000000000'x Secure Origin ID SPE Cumulative bits = '7E00000000000000'x VM/XA SP Release 2.1 Cumulative bits = '7C00000000000000'x APSS SPE Cumulative bits = '7800000000000000'x VM/XA SP Release 2.0 Cumulative bits = '7000000000000000'x VM/XA SP Release 1.0 Cumulative bits = '6000000000000000'x VM/XA SF Release 2.0 Cumulative bits = '4000000000000000'x
It is therefore possible to determine a specific release of VM with two tests. The first test is to determine if CP is 370 or XA (ESA). The second one is to test the bit for the specific release where the function you desire was introduced.
Suppose you needed to determine if the CP you were executing on supported TSAF at a VM/SP 6 level of function. This would include:
A test similar to the following could be used:
************************************************************ * Determine if we have TSAF at the VM/SP 6 level or higher * ************************************************************ SPACE 1 LA R13,WORKAREA A(diag x'00' responsebuffer) LA R14,40 Length of Diagnose Response Buffer SPACE 1 DC 0H'0',X'83',AL.4(R13,R14),Y(X'00') Diagnose X'00' SPACE 1 TM 24(R13),X'80' Is this VM/XA or VM/ESA-ESA? BZ TRYXA Yes: check for VM/ESA 1.0 or later TM 27(R13),X'20' No: is it VM/SP 6 or later? BO GOTFUNC Yes: we have the desired function B NOFUNC No: the function is not available TRYXA EQU * TM 24(R13),X'01' Is this VM/ESA-ESA 1.0 or later? BZ NOFUNC No: VM/XA does not support TSAF GOTFUNC EQU * The function we want is available . . . WORKAREA DS XL40 Diagnose X'00' Response Buffer
Well, this is assembler. Many of you will not be able to understand
this. We kept the text as it was. But we will ask you to code a
similar thing in REXX at the end of this topic...
unless you now prefer to learn assembler...
This method is far superior to checking the output from QUERY CPLEVEL, which can have unexpected values such as VM/XA SP Release 21 for Release "2.1".
The functional level of CMS may be obtained through the QUERY CMSLEVEL command. The third token of the message contains the functional level. When used from an assembler application via CMSCALL, QUERY CMSLEVEL returns the functional level in bits 8-15 of General Register 1. This byte may be mapped with the CMSLEVEL macro.
Examples of the message returned by QUERY CMSLEVEL are:
VM/SP Release 5, Service Level 000 VM/XA CMS 5.5, Service Level 000 VM/XA CMS 5.6, Service Level 000 VM/SP Release 6, Service Level 000 CMS Level 7, Service Level 000 CMS Level 8, Service Level 000 CMS Level 10, Service Level 404
The data returned in GPR 0 and GPR 1 for QUERY CMSLEVEL when invoked via CMSCALL is as follows:
QUERY CMSLEVEL Loads R0 with the following: +----------------------------------------+ ! R0 is loaded with the fullword at ! R0 = ! USERLVL in NUCON. This field is ! ! Reserved for the user. ! +----------------------------------------+ 0 31 QUERY CMSLEVEL loads R1 with the following: +----------+---------+-------------------+ ! Reserved ! ! ! R1 = ! for ! Release ! Service Level ! ! future ! Number ! ! ! use ! ! ! +----------+---------+-------------------+ 0 8 16 31
Byte 1 (Release Number) returned in GPR 1 will have one of the following values, as mapped by the CMSLEVEL Macro:
VMR6 EQU X'00' - VM/370 RELEASE 6 VMBSEP EQU X'01' - VM/BSEP RELEASE 2 VMSEP EQU X'02' - VM/SEP RELEASE 2 VMSP1 EQU X'03' - VM/SP RELEASE 1 VMSP2 EQU X'04' - VM/SP RELEASE 2 VMSP3 EQU X'05' - VM/SP RELEASE 3 VMSP4 EQU X'06' - VM/SP RELEASE 4 VMSP5 EQU X'07' - VM/SP RELEASE 5 VMSP55 EQU X'08' - VM/SP RELEASE 5.5 VMSP56 EQU X'08' - VM/SP RELEASE 5.6 VMSP6 EQU X'09' - VM/SP RELEASE 6 CMS7 EQU X'0A' - VM/ESA 1.1.0; CMS level 7 CMS8 EQU X'0B' - VM/ESA 1.1.1; CMS level 8 CMS9 EQU X'0C' - VM/ESA 1.2.0; CMS level 9 CMS10 EQU X'0D' - VM/ESA 1.2.1; CMS level 10 CMS11 EQU X'0E' - VM/ESA 1.2.2; CMS level 11 CMS12 EQU X'0F' - VM/ESA 2.1.0; CMS level 12 CMS13 EQU X'10' - VM/ESA 2.2.0; CMS level 13 CMS14 EQU X'11' - VM/ESA 2.3.0; CMS level 14 CMS14 EQU X'12' - VM/ESA 2.4.0; CMS level 15
An example of an assembler program obtaining the Release Number from R1 is:
******************************************************************** * R5 Contains the address of a work area * ******************************************************************** SPACE 1 LA R1,LVLPLIST CMSLEVEL Tokenized plist CMSCALL PLIST=(1),ERROR=CMSERR QUERY CMSLEVEL STCM R1,B'0100',KEEPLVL Save CMSLEVEL for later LR R1,R5 Location for LINERD plist MVC 0(LINRDSIZ,R1),LRPLIST Initialize LINERD plist LA R5,LINRDSIZ(R5) Location of response buffer LA R6,80 Size of the buffer SPACE 1 LINERD DATA=((R5),(R6)),ERROR=CMSERR,MF=(E,(R1)) SPACE 1 ... LVLPLIST DC CL8'QUERY' DC CL8'CMSLEVEL' DC CL8' (STACK' DC XL8'FFFFFFFFFFFFFFFF' SPACE 1 LRPLIST LINERD MF=L LINRDSIZ EQU *-LRPLIST
Notes:
Applications should not use the first token of the message text from QUERY CMSLEVEL, as it is not reliable with respect to CP or VM product determination. For example, CMS 5.5 running on VM/SP 5 gives a first token of "VM/XA". In addition, VM/ESA 1.0 changed the first token to "CMS" from "VM/ESA."
Also, REXX applications parsing output from QUERY CMSLEVEL with a template such as:
Address Command 'QUERY CMSLEVEL (STACK' Parse Pull . 'Release' Lvl ',' .
are subject to breakage on releases other than VM/SP 5 or VM/SP 6 because the trigger 'Release' does not appear in the output for other releases of CMS.
A good example of a REXX program using the message output is:
Address Command 'QUERY CMSLEVEL (STACK' Parse Pull . . LvlNum ',' .
In summary, use the Program Product Bit Map returned by Diagnose X'00' to determine the functional characteristics of the CP you are executing on. Do not use CP QUERY CPLEVEL as a programming interface and do not use the first 8 bytes returned by Diagnose 'X00' to determine the system name.
QUERY CMSLEVEL will return the functional level of CMS in GPR 1, which may be mapped by the CMSLEVEL macro. A REXX EXEC will need to use the third token of the output returned by QUERY CMSLEVEL via the STACK option.
Don't use QUERY CPLEVEL for determining the CMS level, as VM/ESA now allows to run back level CMS releases under CP, so, CP is not aware of the exact CMS release.
Write a procedure LEVEL EXEC that can accept 3 different
parameters:
XACAP | returns 1 if your CP is XA capable (31 bit support), else it should return 0. |
ESA220 | returns 1 if your system is at least at the VM/ESA Version 2, Release 2.0 level (hence Y2K support). If not, it returns 0. |
MACHINE | returns the virtual machine mode (370, XA, XC or ESA). Note that 370 is no longer possible with latest releases of VM/ESA. |
The returned values 1 or 0 are for when your procedure is called as a subroutine. If your procedure is executed from the CMS command line, then an explicit message should be displayed at the terminal.
Example
> level machine Your virtual machine runs in XC mode.
If used as functions, then you could have code such as:
if level('XACAP') then 'CP XAUTOLOG EREP' ; else 'CP AUTOLOG EREP' if level('ESA220') & level('MACHINE')='XC' then...
When you are ready, you can have a look at the commented solution.
This last exercise is a bit more challenging. It not only lets you practice File I/O, but also advanced use of REXX arrays. We suggest you take at least a few minutes to read the following text, and to think about the problems posed by the exercise.
In general, disks are organized in cylinders (CKD) or blocks (FBA). We'll concentrate only on CKD here.
Each cylinder contains a number of tracks (equal to the number of surfaces in a cylinder). The tracks have a specific byte capacity depending on the DASD type or architecture.
Note: with the most recent DASD technology, the physical organization of cylinders and tracks may be totally different. From the users' point of view, however, things remain the same.
The tracks are in turn subdivided in physical blocks. In CMS, those blocks are created via the FORMAT command.
The image of a track becomes thus something like:
+--------------+---+--------------+---+--------------+---+---------- !block 1 !gap!block 2 !gap!block 3 !gap! ..... +--------------+---+--------------+---+--------------+---+----------
The CMS FORMAT command lets you choose between block sizes of 512 bytes, 1K, 2K or 4K. All blocks have the same size on a CMS minidisk. Between the physical blocks there are so called inter-record-gaps. The more blocks you define on a track, the more gaps there will be, and hence, less space is available for storing data. For this reason, we tend to choose for large block sizes.
On the other hand, as a CMS file does not share its blocks with another file - the last block is not necessarily filled with data - we tend to choose for smaller block sizes for this second reason. For example, 2 CMS files of 1 byte each will together consume 2 blocks, or, on a minidisk formatted with 4K blocks, they'll consume 8K, while on a minidisk formatted with 1K blocks, they'll consume only 2K.
In VM we count with cylinders (on CKD device types), not with tracks, and to make life easier, VM provides the $DASD$ CONSTS S file that tells for each type, how many CMS blocks can fit on a cylinder, and how many cylinders are available on the DASD. For the 3390 type of DASD, the statements look like these:
blocks4k.3390 = 180 /* 3390 */ blocks2k.3390 = 315 blocks1k.3390 = 495 blocks512.3390 = 735 cylinders.3390 = 10017 dasd_type.3390 = 'CKD'
This means that for a 3390 cylinder it is possible to create 180 blocks of 4K, or 495 blocks of 1K. And there are 10017 cylinders on the largest model of this type DASD (model 3).
Write a procedure that uses the information provided in the $DASD$ CONSTS S file and calculates the cylinder capacities for the various DASD types when formatted with different block sizes. The output should look like this:
devtype ! 1K ! 2K ! 4K ! ------------+---------+---------+---------+ 3330 Bl/cyl ! 209 ! 114 ! 57 ! 3330 KB/cyl ! 209 ! 228 ! 228 ! 3330 KB/vol ! 168872 ! 184224 ! 184224 ! ------------+---------+---------+---------+ ..... 3390 Bl/cyl ! 495 ! 315 ! 180 ! 3390 KB/cyl ! 495 ! 630 ! 720 ! 3390 KB/vol ! 4958415 ! 6310710 ! 7212240 ! ------------+---------+---------+---------+
We want to have, for each type, and for each block size (you can ignore the 512 bytes size):
These are the logical steps for your procedure :
When you are ready, you can have a look at the commented solution.
This was the last exercise for lesson 4.