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...
None of our former students has worked on this exercise...
We suggested to investigate how a routine could test if it was called as a REXX function or as a CMS command (from the CMS command line). In the first case, it would then return a value to the caller, while in the second case, it would display a comment on the screen.
For example, if XACAP() would be called in a procedure (as a function call), it should return the value 1 or 0. If however, we would enter XACAP at the CMS command line, we should get a message such as: Your system is [not] XA capable, as the only way to return an information in this case, is to display it on the terminal.
When a REXX procedure is useful as a subroutine, it should determine whether it is invoked as a subroutine or as a normal procedure. When it is invoked as a subroutine, it has to return a result. No messages should be displayed then, as it would require a SET CMSTYPE HT/RT combination in the main procedure to hide these messages again.
To test how the program is called, use the parse source:
/* Procedure XACAP, can be used as-is or as subroutine */ parse upper source . how_called . xacap=(substr(diag(0),25,1)<'80'x) if how_called='COMMAND' then say 'Your machine is' word('not indeed',xacap+1) 'XA capable' else return xacap
When the procedure is called as a subroutine or as a function, then the variable how_called gets SUBROUTINE or FUNCTION respectively. In the other case, it gets the value COMMAND.
If the procedure is called as a COMMAND, then you can return to CMS via an exit nn or return nn, whereby nn is optional, must be numeric and represents the return code.
If it was called as a SUBROUTINE or FUNCTION, then you can return to the calling procedure with an exit or return statement, but a parameter is now required. The parameter does however not need to be numeric, it can be any character string.
You may be tempted to convert the system values to a human readable format before to test the values. This is not needed if you remember that you can use hexadecimal or binary notation in REXX. An hexadecimal number is coded for example as '4FD832'x, while '1001011'b is a valid binary representation.
To test a byte that contains '11110011'b, then these tests are possible:
if bitmap='F3'x if bitmap='1111011'b if bitmap=3
Next tests use an indirect method, and definitely require more system resources:
if c2x(bitmap)='F3' if c2b(bitmap)='1111011' if c2d(bitmap)=243
The very first one -using the hexadecimal notation - is of course to be preferred. The second one is tedious, especially if you have a lot of bytes, while for the third one implies that know your EBCDIC or ASCII codepage by heart.
This exercises requires that bits, not just bytes, are tested. These are the best techniques to test specific bits: they all use BITAND() or BITOR()):
/* Test if 4th bit (from the left) is on */ if bitand(byte,'10'x) = '10'x then ... /* Test if bit 4 OR bit 7 are on */ if bitand(byte,'12'x) > '00'x then ... /* Test if bit 4 AND bit 7 are on */ if bitand(byte,'12'x) = '12'x then ... /* Test if bit 4 is off */ if bitand(byte,'10'x) = '00'x then [ if bitor(byte,'EF'x) = 'EF'x then ] /* Test if bit 4 and bit 7 are off */ if bitand(byte,'12'x) = '00'x then
As no student produced a solution, we can only present ours:
/***********************************************************************/ /* Procedure LEVEL */ /* Function : XACAP() returns 1 if XA capable, else 0 */ /* VMREL(min_rel) returns 1 if minimum is installed */ /* MACHINE() returns 370, XA, XC or ESA */ /***********************************************************************/ address command say 'Your machine is' word('not indeed',xacap()+1) 'XA capable' say 'You have a' word('insufficient sufficient',esa11()+1) 'release' say 'Your machine is running in 'machine()' mode' exit /********************* Subroutines *************************************/ XACAP: /* Returns 1 if XA capable machine, else 0 */ /* XA capable if bit 1 of bitmap is 0 */ parse value diag(0) with 25 map 26 /* get program bit map */ return map<'80'x /***********************************************************************/ ESA11: /* Returns 1 if minimum ESA 1.1 is installed */ parse value diag(0) with 1 25 map 27 . if map>='7F80'x then return 1; else return 0 /***********************************************************************/ MACHINE: /* returns virtual machine mode */ parse value translate(diag(8,'Q SET'),' ','6B15'x) with 'MACHINE' mach . return mach
Use backward navigation to return to the assignments.