Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Pseudo-structures

&pagelevel(5)&pagelevel

The pseudo-bases CURRENT and PARAMETER can be used to access operating data of the DAMP program.

The pseudo-base CURRENT

Diagnostic algorithms require not only the data of the object being diagnosed, but sometimes also the “operating data” of the DAMP program. This can be achieved by means of the pseudo-base “CURRENT.item”. The available items are explained below.

With the exception of CURRENT.ALET, CURRENT.ATYPE, CURRENT.ERROR, CURRENT.SPID and CURRENT.SEGMENT, the fields cannot be overwritten. Any attempt to assign a value to a read-only field will result in a compiler error.

CURRENT.ALET

When accessing data spaces (see CURRENT.ATYPE), CURRENT.ALET must be set to the required value for ALET (4-digit numeric value). The corresponding TID must be set using the standard procedure NEW_TASK (see "Standard procedures").

CURRENT.ATYPE

Unless otherwise specified, addresses are interpreted as virtual addresses in PRODAMP. However, it is also possible to address real memory, the hardware system area (HSA) or data spaces. This is done with the aid of the pseudo-symbol CURRENT.ATYPE and the pseudo-constants VIRTUAL, REAL, HSA, ABS_ADDRESSING, ALET and SPID, which can be assigned to this pseudo-symbol. Such an assignment defines which memory is to be addressed by the subsequent statements.

By assigning ABS_ADDRESSING to the pseudo symbol CURRENT.ATYPE, absolute memory can be addressed in the complete VM2000 SLED, e.g. to analyze the hypervisor.

Example 1 for CURRENT.ATYPE: Addressing the HSA

HSA_START  := CURRENT.HSA;
TEST_VALUE := 0;
ARRANGE
  .TEST_SYMBOL : TYPE=NUMERIC,LENGTH=1,RELATIVE=0;
END ARRANGE ;
CURRENT.ATYPE := HSA;
TEST_VALUE := HSA_START.TEST_SYMBOL;
IF CURRENT.ERROR <> 0 THEN
  MESSAGE ( 'Hardware system area is not addressable !!' );
ELSE
  ....
END IF;
CURRENT.ATYPE := VIRTUAL;

However, certain restrictions must be noted: the selected memory type applies only when addressing memory areas with the aid of symbols and is effective only locally within the current procedure. If called procedures are also to address real memory, the HSA, absolute memory or data spaces, then the memory type must also be set locally in these procedures. The only exception to this rule is the predefined procedure DUMP_MEMORY (see "Standard procedures"), which permits real memory, HSA memory, absolute memory or areas from data spaces to be output directly to a list.

If ALET and SPID are specified, the required values must be set before they are accessed using CURRENT. This is demonstrated in the following example:

Example 2 for CURRENT.ATYPE

ARRANGE
  .TEST.SYMBOL : TYPE = NUMERIC, LENGTH = 4, OFFSET = 0;
END ARRANGE;
CURRENT.ATYPE := ALET;
CURRENT.ALET := X'01010003';
PTR := 0;
OUT := PTR.TEST_SYMBOL;
IF CURRENT.ERROR <> 0 THEN
  MESSAGE ( 'Access error, ALET = '
          + HEX_STRING(CURRENT.ALET,8) + ', TID = '
          + HEX_STRING(CURRENT.TID,8) );
ELSE
...
END IF;
CURRENT.ATYPE := VIRTUAL;

If ALET is specified, the TID currently set is always used for access purposes. The TID can be reset as required using the standard procedure NEW_TASK (see "Standard procedures").

Furthermore, symbols which are localized automatically are always addressed virtually. Consequently, if you want to address real memory, absolute memory or the HSA, you must always specify a base address (as in the example above).

More than a simple assignment is also possible. Since the pseudo-symbol CURRENT.ATYPE has, internally, the type numeric, you do not have to explicitly specify VIRTUAL, REAL, HSA, ABS_ADDRESSING, ALET or SPID. Instead, you could perform calculations with the value (although this is rather pointless), transfer the current value to another variable or, for example, pass the memory type as a parameter to another procedure. If an invalid value is assigned to CURRENT.ATYPE, this is not detected until runtime and causes the procedure to be aborted. The validity of the values is not checked at compilation time.

Example 3 for CURRENT.ATYPE

CURRENT.ATYPE:=35

This assignment is syntactically correct.

Example 4 for CURRENT.ATYPE transferring parameters

A procedure which returns the contents of the real address 0 as a printable string is called.

CALLER:
  VALUE := ' ';
  PRINTABLE_VALUE ( 0, REAL, VALUE );
PROCEDURE PRINTABLE=VALUE :
  LOC := 0;
  ARRANGE
    .ADDR   : TYPE=NUMERIC, LENGTH=4, RELATIV=0; 'PARAMETER 1'
    .MEMORY : TYPE=NUMERIC, LENGTH=4, RELATIV=4; 'PARAMETER 2'
    .TARGET : TYPE=STRING, LENGTH=8, RELATIV=8;  'PARAMETER 3'
    .CONTENTS : TYPE=NUMERIC, LENGTH=4, RELATIV=0;
  END ARRANGE
  CURRENT.ATYPE := PARAMETER.MEMORY;
  LOC := PARAMETER.ADDR;
  PARAMETER.TARGET := HEX_STRING ( LOC.CONTENTS, 8 );
  RETURN;

CURRENT.CPU

CURRENT.CPU contains the name of the CPU from the diagnosis object in the form of a string with a length of 8. If a file is opened as a PAM file, the CPU of the current system is displayed.

CURRENT.CONFIGURATION

CURRENT.CONFIGURATION contains the designation of the hardware configuration from the diagnosis object in the form of a string with a length of 21 (e.g.: 7.500- S210-60). The output corresponds to the designation in the /SHOW-SYSTEM-INFORMATION command. The configuration of the active system is output for a file opened as a PAM file.

CURRENT.CSMA

CURRENT.CSMA contains the (absolute) start address of the common shadow memory area (CSMA), i.e. a 4-digit numeric value.

CURRENT.DTYPE

CURRENT.DTYPE contains a 1-byte (8-bit) numeric value describing the opened medium. This value has the following format:

Medium

f

Dump








The following meanings apply:

Medium = 0 (B'0000') :   Medium not defined
Medium = 1 (B'0001') :   System
Medium = 2 (B'0010') :   Object can be selected
Medium = 3 (B'0011') :   Dump
Medium = 4 (B'0100') :   PAM file
Medium = 5 (B'0101') :   Self-loader

The Medium = 2 case can only occur in the dialog if the dump file contains multiple objects and if no subsequent selection (e.g. complete VM2000 SLED, SLED from a SLED) has been made in the INF screen as yet. In such cases, the program should therefore be aborted and a selection made in the INF screen. If no selection was made in the INF screen, access to the object (only a complete VM2000 SLED) with PRODAMP is only possible in the absolute addressing mode (CURRENT.ATYPE = ABS_ADDRESSING).

If Medium = 3 (0011), f and dump are both set. The following meanings apply:

Dump = 0 (B'000') :
Dump = 1 (B'001') :
Dump = 2 (B'010') :

SLED
System dump
User dump

If f is set to 1 (only for a SLED or user dump), the SLED is a snap file or the user dump is an area dump.

Example for CURRENT.DTYPE

The following query could be issued if you wish to check whether the opened medium is a user dump:

IF  CURRENT.DTYPE / 16 = 3  AND
    CURRENT.DTYPE MOD 8 = 2
THEN

CURRENT.DUMPTIME

CURRENT.DUMPTIME contains the date and time of the dump file in the format of a string 19 characters long: yyyy-mm-dd hh:mm:ss. The current date and time is supplied for the diagnosis of the active system.

CURRENT.ERROR

If the program detects an inconsistency which can be handled internally, i.e. which does not force the PRODAMP procedure to be aborted, then CURRENT.ERROR is set to a value other than 0. For example, if a requested page is missing from a dump file, this does not justify abortion of the procedure. But if, in contrast, a specified symbol cannot be found in the associated symbol file, PRODAMP aborts the procedure, as this problem can usually be traced to a typing error in the source code of the PRODAMP procedure, which will have to be corrected.

Theoretically, each access to a datum of the diagnosis object can result in an error. This should be checked by inspecting the contents of CURRENT.ERROR, since further execution of the PRODAMP procedure will be unpredictable if an error has occurred. To avoid impairing performance and to keep the procedure as simple as possible, this check can be restricted to a one-off query after the first access, albeit only if several objects within the same data structure are accessed one after the other and if you are sure that the data structure does not exceed the memory page.

The error code that may possibly be stored in CURRENT.ERROR is irrelevant for the diagnosis. You should therefore compare CURRENT.ERROR only against 0.

CURRENT.ERROR can be explicitly reset by assigning it the value 0 (CURRENT.ERROR := 0). This is not required in many cases, however, since PRODAMP automatically resets the CURRENT.ERROR in the following situations:

  • On entering a procedure (CURRENT.ERROR is maintained on a local procedure basis).

  • Following a successful read access on the data of the diagnosis object or the operating data of DAMP by means of a symbol (see section "Symbols").

    Example

    X:=.ETCBTID, Z:= CURRENT.DTYPE, Y:=PARAMETER .P1

    Exception: read access on CURRENT.ERROR.

  • On successfully using one of the standard functions of DAMP.
    Exception: the call to PATTERN does not change CURRENT.ERROR.

  • On successfully executing the standard procedures NEW_TASK or READ.

CURRENT.ERROR is not reset by any of the other standard procedures and assignments within PRODAMP.

Example for CURRENT.ERROR

TEST := P2_FCB.ID2CFLID ; "PSEUDO-HARDVALIDATION"
IF CURRENT.ERROR = 0 THEN
  "ACCESS POSSIBLE WITHOUT RISC"
  IF P2_FCB.ID2IND1 = ID2PRIVC THEN
    IF P2_FCB.ID2LOCK = ID2OUTL THEN
    "DO SOMETHING" 
    END IF ; 
  END IF ;
END IF ;

CURRENT.FILENAME

CURRENT.FILENAME contains the name of the currently open diagnosis object in the form of a string with a length of 54. If the diagnosis object is the active system, the string contains only blanks.

CURRENT.HSA

CURRENT.HSA contains, for SLED files, the (absolute) start address of the hardware system area. It is thus a numerical value with a length of 4. Since only SLED files have a hardware system area, CURRENT.HSA has the value 0 for other dump files.

CURRENT.ITN

See CURRENT.TID.

CURRENT.LEVEL

The pseudo-symbol CURRENT.LEVEL contains a numerical value with a length of 1 which shows the nesting depth of subroutine calls. A procedure in which RETURN would return control to the DAMP environment has CURRENT.LEVEL 0; a procedure called by this procedure has CURRENT LEVEL 1, and so on.

CURRENT.PCB

The pseudo-symbol CURRENT.PCB contains the address of the current PCB, which is set in diagnostic window 3. It is thus a numeric value with a length of 4. If no PCB has been set, CURRENT.PCB contains the value -1 (X'FFFFFFFF').

CURRENT.PTYPE

CURRENT.PTYPE contains a 1-byte numerical value indicating the DAMP execution mode.
The following values are possible:

CURRENT.PTYPE = 0 (B'00000000') : DAMP is running in interactive mode
CURRENT.PTYPE = 1 (B'00000001') : DAMP is running in procedure mode
CURRENT.PTYPE = 2 (B'00000010') : DAMP is running in batch mode

CURRENT.SEGMENT

CURRENT.SEGMENT is required when the diagnosis object is to be accessed with very large addresses (i.e. with an address width of more than 32 bits). Two situations must be differentiated here:

  1. Access using large real or absolute addresses.

    The 4 GB segment to be automatically considered for every subsequent read access with CURRENT.ATYPE=REAL or =ABS_ADDRESSING, i.e. for a real or absolute address interpretation, must be passed in CURRENT.SEGMENT.

  2. PAM access on a large file.

    If the opened diagnosis object is a PAM file, absolute addresses must be specified for the localization of data. These addresses consist of the PAM page number P and the relative displacement D and are calculated using the following formula:

    A = (P - 1)*2048 + D                with 0 <= D <= 2047

    In the case of large PAM files (a maximum of 534 773 760 pages are possible), more than 4 bytes may be needed for A. A PAM file is therefore subdivided into a total of 256 segments of 2 097 152 pages each.

    In order to find data, you will always need to specify the 4 GB segment (in CURRENT.SEGMENT) and the relative address within that segment in a PRODAMP procedure.

    To calculate the segment for a specified PAM page, you should use unsigned arithmetic (UNSIGNED_ON ) as illustrated in the example given below.

    CURRENT.SEGMENT is maintained on a local procedure basis and is initially set to 0.

    In most cases (address < 4 GB), an explicit assignment is not needed. The provision of a negative value or a value greater than 255 always leads to a runtime error.

    Example 1 for CURRENT.SEGMENT: Conversion of PAM page number to segment and address

    UNSIGNED_ON;
       " The PAM page PAM_PAGE is to be converted to a 4 GB segment number
       - which is directly placed in CURRENT.SEGMENT - 
       and a 32-bit address 'BYTE_ADDRESS'"
    IF PAM_PAGE > X'1FE00000' THEN
       " Every BS2000 file has at most X'1FE00000' pages "
    MESSAGE ('** ERROR: PAM PAGE TO LARGE **');
    RETURN WINDOW=CURRENT.WNDNO;
    END IF;
    CURRENT.SEGMENT := (PAM_PAGE-1)/X'200000'; 
       "divided by 2 raised to (32-11)"
    BYTE_ADDRESS    := (PAM_PAGE-1)*X'800';
       "multiplied by 2 raised to 11"
    

    Example 2 for CURRENT.SEGMENT: Absolute read on the address X'1 8000 0000'

    CURRENT.A_TYPE  := ABS_ADDRESSING;
     CURRENT.SEGMENT := 1;
       A:=X'80000000';
       "Address in the 44 GB segment"
       ARRANGE .FULLWORD: LENGTH=4,TYPE=NUMERIC,OFFSET=0;
     Value := A.FULLWORD;
       "Access on a word at address X'000000'"
       IF CURRENT.ERROR = 0 THEN 
        "etc."
    

CURRENT.SPID

CURRENT.SPID must be set to the required value for SPID (8-character string) when data spaces are accessed (see CURRENT.ATYPE).

CURRENT.TIME

CURRENT.TIME contains the CPU time, in milliseconds, that has elapsed since LOGON in the form of a numeric value with a length of 4. If the maximum time (approx. 25 days) is exceeded, the maximum value is returned and CURRENT.ERROR is set to a value other than 0.

CURRENT.TID, CURRENT.TSN and CURRENT.ITN

The pseudo-symbols CURRENT.TID and CURRENT.TSN permit access to the current task. CURRENT.ITN refers to the rightmost halfword of the TID, which unambiguously identifies the task at diagnosis time.

In the case of system, user and area dumps, the current task is always the dump task and cannot be changed. For SLED and SNAP dumps or in the active system, the current task is determined either by selecting a task in the status window (W2), by entering a TID (or ITN) or TSN in the header line of a window or, in PRODAMP, by calling the procedure NEW_TASK. The current task can be addressed via CURRENT.TID, CURRENT.ITN or CURRENT.TSN. All accesses to task-specific tables (TCB, JCB, etc.) and to addresses in the user address space always refer to the current task.

CURRENT.TID and CURRENT.ITN are numeric, while CURRENT.TSN is a 4-character string.

CURRENT.TSN

See CURRENT.TID.

CURRENT.VERSION

The pseudo-symbol CURRENT.VERSION contains the current BS2000 version of the diagnosis object in the form of a string with a length of 4. The format of the string is XX.X, for example 21.0. If a file is opened as an ordinary PAM file, the version in question is the version of the current operating system.

CURRENT.WNDNO

The pseudo-symbol CURRENT.WNDNO contains the number of the current diagnostic window, i.e. of the window which would appear at the top in a subsequent screen output. Since ARRANGE changes the order of the windows, CURRENT.WNDNO can be used, for example, to set the PRODAMP window as the current window again if an error occurs during window assignment.

The pseudo-base PARAMETER

Parameters can be transferred to PRODAMP procedures when calling from the DAMP program level or as a subprocedure of a PRODAMP procedure (see also section "Working with procedures (special window: PROC)").
During the call, a parameter area is generated from the parameters, and contains a list of the parameter values. In the parameter area, numeric data values and bit patterns are always entered right-justified in a 4-byte field.
The first static call from a PRODAMP procedure is used by the compiler to define the parameter area. The call consists of the name of the called procedure and a list of the current parameters enclosed in brackets.
PRODAMP also supports subprocedures with no parameters. Recursive calls are permitted.

In order to access the parameters, ARRANGE symbols must be defined with the PRODAMP statement. These symbols can then be addressed with the aid of the pseudobase PARAMETER. 

Example 1 for the pseudo-base PARAMETER

The GETOPC procedure is to return the operation code found at the address MOD + ADD in the symbol OPC.

Procedure GETOPC:

ARRANGE
.MOD : TYPE = STRING, RELATIVE = 0, LENGTH = 8;
.ADD : TYPE = NUMERIC,RELATIVE = 8, LENGTH = 4;
.OPC : TYPE = NUMERIC,RELATIVE =12, LENGTH = 4;
END ARRANGE ;
ARRANGE
.BYTE : TYPE=NUMERIC,RELATIVE=0,LENGTH=1;
END ARRANGE ;
A := ADDRESS ( PARAMETER.MOD,'CP' ) + PARAMETER.ADD ;
PARAMETER.OPC := A.BYTE ;

Procedure call:

MOD := 'DOPEN' ;
ADD := X'4ADC' ;
GETOPC ( MOD, ADD, OPC ) ;
IF OPC = X'47' THEN
.....

The structure variable PARAMETER.XX may be assigned a value. This value is assigned to the parameter variables used by the calling procedure at the same place.

At compilation time, the types and lengths of the parameter symbols and of all other structure variables are not known (see section "Working with procedures (specialwindow: PROC)").

Example 2 for the pseudo-base PARAMETER

The data is transferred with the default values “numeric” and “length 4”, even though other values were specified:

ARRANGE
   .DST:TYPE=STRING,RELATIVE=0,LENGTH=8;
   .SRC:TYPE=STRING,RELATIVE=8,LENGTH=8;
END ARRANGE
PARAMETER.DST:=PARAMETER.SRC;

The correct assignment can be ensured by using an auxiliary variable:

STR:=' ' * 8;
STR:=PARAMETER.SRC;
PARAMETER.DST:=STR;

In the case of a call from the DAMP program level, parameters are passed by means of the RESUME-PRODAMP-PROGRAM or START-PRODAMP-PROGRAM statement. However, results cannot be returned to the calling level in this case; results can be returned only if a procedure calls another procedure. It is nevertheless possible to write procedures which work correctly, regardless of whether they are called from the DAMP program level or from another procedure, by interrogating CURRENT.LEVEL in order to identify the level at which the procedure is running.

This means that all parameters are passed by the “call by reference” method, i.e. the address of the parameter is passed to the procedure. However, literals and expressions can also be passed directly as parameters. The corresponding structure variables can also be described in the called procedure, but they cannot be used to return values to the calling procedure.

Various parameter lists can be defined by means of ARRANGE and subsequently overlaid on the pseudo-base PARAMETER after an INTERRUPT statement. Admittedly, in a later RESUME statement it is necessary to specify all the parameters which are evaluated after the associated INTERRUPT statement, but this method makes it possible to program a “guided dialog”.

Example 3 for the pseudo-base PARAMETER

ARRANGE
.TSN : TYPE=STRING,LENGTH=4, RELATIVE=0;
END ARRANGE;
MESSAGE ( 'Please enter TSN. (RESUME window,''tsn'')' ) ;
INTERRUPT;
TASK := PARAMETER.TSN ;
ARRANGE
.NUM : TYPE=NUMERIC,LENGTH=4,RELATIVE=0;
END ARRANGE;
MESSAGE ( 'Please enter number of passes. (RESUME window,num)');
INTERRUPT;
PASSES := PARAMETER.NUM ;

In a case of a symbolic access with the pseudo-base PARAMETER, it is only checked whether the datum to be accessed lies within the parameter area supplied by the caller, and if this is not the case, the program aborts with a corresponding runtime error message (see Examples 4 and 5).

Other errors - e.g. when the types of the call parameters do not match the fields defined with ARRANGE in the called procedure - cannot be detected by DAMP and can thus result in unpredictable side-effects at runtime.

You can query the overall length of the parameter area in the called procedure with the standard function LENGTH. This allows you to respond to missing parameters in the called procedure, for example.

Example 4 for the pseudo-base PARAMETER: Checking the length of the parameter area

The following PRODAMP program is to be called with two parameters, an address and an optional counter to be specified. If the second parameter is not supplied, a default value is to be used for the calculation instead.

"Layout of the parameter block (the 2nd. parameter may be missing )"
ARRANGE .ADDR_OF_STRUCT : OFFSET=0,LENGTH=4,TYPE=NUMERIC; "1st.parameter"
  .COUNTER : OFFSET=4,LENGTH=4,TYPE=NUMERIC; "2nd. parameter"
END ARRANGE;
" Transfer of parameters to the variables ADDR_OF_STRUCT and COUNTER."
" If counter is not specified, set COUNTER=100."
L:=LENGTH('*PARAMETER','DS');
IF CURRENT.ERROR <> 0 THEN
MESSAGE (' Program aborted. DAMP Version V4.2 or later required ');
RETURN WINDOW=CURRENT.WNDNO;
ELSIF L=4 THEN
ADDR_OF_STRUCT:= PARAMETER.ADDR_OF_STRUCT; 
COUNTER       := 100;
ELSIF L=8 THEN
ADDR_OF_STRUCT:=PARAMETER.ADDR_OF_STRUCT;
COUNTER:=PARAMETER.COUNTER;
ELSE
MESSAGE ('Program aborted. Invalid parameter supplied');
END IF;
" etc. ( ADDR_OF_STRUCT and COUNTER are now supplied )"

Example 5 for the pseudo-base PARAMETER: Artificial parameter area

In some cases, it is useful to provide a special work area in the parameter area for a PRODAMP program, which can then be “freely” accessed. This can very easily be implemented by calling the program a second time, but now with an extended parameter area:

PROZEDUR XY 
"Parameter layout"
ARRANGE :
.ADDR_IN: TYPE=NUMERIC,LENGTH=4,OFFSET=0;
.WORKAREA: TYPE=STRING,LENGTH=128,OFFSET=4;
END ARRANGE; 
"Only ADDR_IN should be supplied for a direct call"
L:=LENGTH('*PARAMETER','DS');
WORKAREA := #'00'*64;
IF L = 4 THEN
   XY(PARAMETER.ADDR_IN,WORKAREA);  "Recursive call"
ELSIF L <> 4+64 THEN
   MESSAGE(' Invalid parameter supplied or DAMP prior to V4.2 ');
END IF;
"A work area initialized with binary zero is now available to the program 
XY in the parameter area."