Customizing functions and translation tables

From m204wiki
Jump to navigation Jump to search


User-written SOUL functions are stored in the user function module FUNU. The FUNU module is distributed as a skeletal module containing a table for functions and arguments, and the assembler code for one function. You can list the contents of FUNU using the procedures given in the Rocket Model 204 Installation Guide for your operating system.

The Encoding/Decoding facility uses the translation tables contained in the distributed CDTB module. The $Code and $Decode functions access the translation tables to allow the use of both coded and string values of fields. The contents of the translation tables can be listed by using the procedures listed in the Rocket Model 204 Installation Guide for your operating system.

You can store messages and return codes for user-written functions in the MSGU module.

This page gives the procedures for adding user-written functions to the FUNU module, customizing the translation tables contained in the CDTB module, and adding messages to MSGU.

If you are migrating to 31-bit or multiprocessing environments, review the conversion considerations summarized in Converting user-written functions.

For general directions on assembly and link-editing, see the Rocket Model 204 Installation Guide for your operating system.

Adding functions to the FUNU module

You can add user-written functions to the FUNU module before FUNU is assembled and linked into Model 204. Reassembly and relinking is required whenever you migrate to another release of Model 204.

To add functions to the FUNU module:

  1. Label the function table in the FUNU source code FUNUTAB.
  2. End the function table in the FUNU source code with DC X'FFFF'.

    The location of the function table in the code is not significant.

  3. Make the new function available to the Model 204 SOUL compiler by adding an entry to the function table using the FN macro:

    FN function-name, R-type, (A-type [, A-type]...), ROUTINE=


    • function-name specifies a unique 1- to 7-character name of the function without the leading $. Spaces or special characters are not allowed.

      User-written functions must not duplicate the name of Rocket Software functions. A list of Rocket Software functions is given in SOUL $functions.

    • R-type represents the type of value returned from the function. Only one value can be returned. S represents a string value. N represents a numeric value.
    • A-type describes the type of argument value. More than one argument can be specified. S represents a string value. N represents a numeric value.
    • In the following example, $SEP receives three string arguments and returns a string value:

      FN SEP,S,(S,S,S)

    • ROUTINE= identifies the name on the ENTER macro of the routine that actually implements the function. This allows the name of the $function (the name on the FN macro) to be more than seven characters.

      For example, one of the MQ/204 $functions, $MQ_FIND_QUEUE_ENTITY, has these two entries (not in FUNU) for FN and ENTER:

      FN MQ_FIND_QUEUE_ENTITY,S,(S,S),MP=OK,ROUTINE=$MQFNDQ ... $MQFNDQ ENTER ZMODE=64 assembly language code for the function LEAVESTR

  4. Code the function (as described in Coding a function).

Coding a function

Coding conventions

The following conventions are required for coding a user-written function:

  • Begin the function code with:

    $name ENTER

  • End the function code with:


  • Observe the following register conventions (correspondence between Rocket Software mnemonic names and IBM general registers is printed at the beginning of the module in the expansion of the STARTS macro):
    • Registers RC, R6, PD, and RL must not be modified.
    • Registers T1 through T5 and R1 through R5 can be used as work registers.
    • Registers R1 through R5 are somewhat more permanent.
    • Use BUF1 and BUF2 (260 bytes each) as buffers (doubleword aligned).
    • Use string, numeric, or omitted arguments.

String arguments

If the nth argument is type S, you can move the argument into a work area by using the following code. Registers R1 through R4 are used by this sequence:


  • The ARG macro returns the VTBL pointer to the nth argument in X1.
  • The RTSTRL routine sets R2 to the length of the string, and it sets R1 to address-1 of the string.
  • The length of the string is given by register R2.
  • The string is moved to BUF1, starting at location BUF1 + 1.
  • The string length is moved to location BUF1.

Numeric arguments

If the nth argument of a function is type N, you can obtain the argument in floating-point form or binary integer form (truncated or rounded) using registers R1 through R3, as follows:



  • x = 0, if a truncated value is required.
  • x = value, if a rounded value is required.

After this sequence, F0 contains the original floating-point value. If the number is valid, R1 contains the integer portion of the number as a binary value and R2 is zero. If the number is invalid, R1 is zero and R2 is nonzero.

Omitted arguments

When writing a call to a function, you can omit an argument, as follows:

$Read( ) $Substr(NAME,,5)


  • If the omitted argument is type S, the value of the argument defaults to a null string.
  • If the argument is type N, the value defaults to zero.

NOARG option

You can specify the NOARG option on the ARG macro in the event that an argument is omitted. When NOARG is used, the code branches to the location indicated by the NOARG option. For example:


You can also specify the following, which returns control to the next sequential instruction after the ARG statement:


Using the ENTER macro to allocate working storage

You can use the VARS argument of the ENTER macro to define stack variables for working storage unique to each user-written function. This method of allocating storage is preferable to STORAGE, GETMAIN, and FREEMAIN instructions. Using the ENTER macro avoids the possibility of causing Online waits or having all users share the same storage.

Syntax for ENTER VARS

ENTER VARS = (, X (varname1, varlength1), comments X (varname2, varlength2), comments X (varname3, varlength3), comments X . . . ), AMODE=n

You must initialize each of these variables.

Routines available for user written $functions

There are CCALL entry points for: DATE, DATE3, and DATE4. All routines must be called with T1 pointing to a 26-byte answer area. Rocket Software recommends that you allocate the answer area using the VARS=(name, len) pushdown list variable of the ENTER macro. The following table lists how the current date and time is stored in the area with this format:

Formats used to store the date routines
Code entry point Format used for storing...







All registers are returned intact with the exception of the DATE call. The DATE call changes only the T4 register, returning the number representing the current month (1-12).

Note that there are double SPACEs before and after the "MON DD".

Return values

Functions can return a string or a numeric value. The following coding considerations apply:

  • To return a string value, end the function routine by doing the following:
    1. Load R1 with a pointer to the location of the result string minus one.
    2. Load R2 with the length of the result string.
    3. Issue the LEAVESTR macro at the end of the code, just before POOL or LTORG to drop local addressability.
  • To return a numeric value, end the function routine in one of the following ways, depending on how the result is computed:
    • For an integer result, end the code end with the following:
      1. Load the binary integer into R1.
      2. Zero R2.
      3. Issue the LEAVENUM macro just before POOL or LTORG.
    • For a floating-point result, end the code with the following:
      1. Load F0 with the long floating-point number.
      2. Issue the LEAVEF0 macro just before POOL or LTORG.
  • To return a Longstring value, end the function routine by doing the following:
    1. Code LSTR=YES on the end of the FN macro, along with the S for string output.
    2. Load R1 with a pointer to the location of the result longstring minus one. If very long it will have to be above the bar.
    3. Load R2 with the length of the result longstring.
    4. Issue the LEAVELST macro at the end of the code, just before POOL or LTORG to drop local addressability.
  • To avoid affecting the performance of Model 204 multithreading operations, ensure that a SOUL function does not invoke any kind of synchronous operating system service that could result in a wait.

Coding messages

You can add messages and codes specific to user-written functions by adding EDEF message lines to the MSGU module. These are referenced in your functions by invoking the ERROR macro.

To code and activate messages and return codes:

  1. Add EDEF statements to MSGU as needed in place of the dummy EDEF in the distributed module.
  2. Add ERROR macros to your functions, referring to messages in MSGU by message number as follows:

    ERROR errnum,OPT=USER

  3. Reassemble MSGU and FUNU.
  4. Relink the Model 204 modules (for example BATCH204, ONLINE) in which MSGU and FUNU are included.

EDEF statements in MSGU

Each EDEF statement defines a message.

EDEF statement syntax

EDEF msgno, aaaa, class, batchrc, ssss, text


  • msgno denotes message number.
  • aaaa denotes action bits controlling output, snap generation, register pointers, and so on.
  • class (E, I, or P) specifies batch and Online return code requirements.
  • batchrc specifies batch return code.
  • ssss denotes snap bits controlling contents of snaps and dumps.
  • text contains message text, which can contain %variables passed by invocation of the ERROR macro.

For complete details on these EDEF arguments, refer to the internal documentation in the MSGU listing.

Encoding/Decoding facility

The Model 204 SOUL $Code and $Decode functions provide the capacity to operate with both coded and string values of fields.

CDTB module

Define code tables in the CDTB module, which you must include in any load module needed to support the $Code and $Decode functions (usually with BATCH204 and ONLINE configurations).

CDTB is an assembly language program consisting of:

  • Three macros used to define each table distributed in source code form
  • Comments explaining the macros
  • CSECT statement
  • Three sample tables
  • END statement

The macros contained in the CDTB module are:


    CODETABL id, length


    • id is a 1- to 8-character string, not enclosed in quotation marks, used to identify the table.
    • length is the length of the longest code found in the table.

    The CODETABL macro builds a table header that consists of a pointer to the next table, the table identifier, the number of entries in the table, and the length of the longest code. Each table defined must specify one CODETABL macro.

  • CODE

    CODE code, 'string'


    • code is the code not enclosed in quotation marks and not longer than the length specified in the previous CODETABL macro.
    • string is the string associated with the code and is enclosed in quotation marks. The string can have up to 255 characters.

    The CODE macro builds one entry that consists of the code, the string length, and the string value. The CODE macro must be used individually for each entry in the table.



    ENDTAB requires no operands and indicates the end of the current table. One ENDTAB macro is required for each table. ENDTAB completes the definition of the table by:

    • Returning to the header created by the previous CODETABL macro
    • Updating the information about the pointer to the next table
    • Updating the number of entries in the table just defined
    • Setting up information to start the next table or to mark the end of all tables

Customizing the sample translation tables

To modify the distributed sample translation tables (refer also to the Rocket Model 204 Installation Guide for your operating system):

  1. List CDTB with its sequence numbers.
  2. Replace the sample tables by using an appropriate operating system utility program.
  3. Assemble the program.
  4. Link the object modules into the appropriate Model 204 load modules.

Modifying translation tables

To make additions, deletions, or changes to translation tables (refer also to the Rocket Model 204 Installation Guide for your operating system):

  1. Modify the source code.
  2. Assemble the source code.
  3. Link-edit the new CDTB module into the appropriate Model 204 load modules.

Sizing the CDTB module

The size of the CDTB module depends on the tables defined. If tables are very large, CDTB might require a significant amount of storage, resulting in an adjustment to the REGION size.

Each table entry requires:

Number of bytes in longest code + 1 (for string length) + number of bytes in string + 1

32 bytes per table is required overhead for header information.

Converting user-written functions

User-written $functions may need to be modified if you are migrating to 31-bit or multi-processing environment. While Rocket Software generally discourages customers from coding $functions that have extensive dependencies on Model 204 internal data structures and algorithms, some customers have found it necessary to do so. These conversion notes describe the changes required for the conversion of most $functions.

Note: These sections do not provide complete descriptions of all internal data structure and algorithm changes that have been made to Model 204; nor are they to be construed as official sanction on Rocket Software's part of the use of any specific interfaces or of the dependency on any specific data structure or algorithm. All such interfaces, data structures, and algorithms remain subject to change without notice.

Coding requirements for all operating systems

Observe the following coding requirements for all operating systems:

  • Model 204 runs in 64-bit mode and requires all registers to be saved and restored using the grande versions of the assembly instructions STM (Store Multiple) and LM (Load Multiple). All user-written functions must be reviewed and modified to use STMG and LMG instructions.
  • Change $functions that refer to KX or KY as follows:
    • Remove X,Y arguments from the KOMMS macro.
    • Code the new FSA macro with the same X,Y arguments that were present on the KOMMS macro.
    • Modify references to fields in KX or KY to use a different base register from the KOMM base register as follows:

      L reg,KJFLKX USING KX,reg refer to KX or KY fields DROP reg

  • From the CCALL MOVEIN routine, remove CCALL. This places the code inline. By expanding the code, efficiency is improved. The input and output are the same as before. However, you might have to add pool statements to the macro, since the offset points to a pool.
  • Some KOMM fields have been moved from KA-KD to KZ. While user-written $functions should not generally reference these fields, those that do need to address KZ as follows:

    L reg, KBPKZ USING KZ,reg refer to KZ fields DROP reg

  • As of version 7.7, KU is no longer 4K addressable from KOMM. It has been relocated to KOMM+1100 and must be addressed using grande (‘G’) instructions. In addition, all KUP… fields have been removed and replaced by their 64-bit equivalent KUG… fields.
    For example, before 7.7, VTBL might be addressed by using L R1,KUPVT. As of version 7.7, that reference would require LG R1,KUGVT.
  • The CSAVE or IOSAVE macros replace the SETAMODE macro in the MACLIB.
  • The AMODE parameter of the ENTER macro is ignored. The CCALL, ENTER, and KARTN sequences no longer cause switches in addressing mode.
  • The XAMODE macros are now obsolete and have been deleted from Rocket Software-delivered MACLIBs. Consequently, it is no longer necessary to maintain XAMODE$U.
  • Reassemble FUNU and FUNUUG.

Additional requirements for systems using 31-bit architecture

All code receives control in 31-bit mode. See IBM z/OS/XA Principles of Operation for differences between 24-bit and 31-bit mode operation:

  • Nearly all Model 204 data structures (servers and PCBs, for example) are in 31-bit storage. Pointers to such data structures must be 31-bit addresses. Three-byte address constants, for example AL3(xyz), cannot be used as pointers.
  • Code that explicitly manipulates Model 204 four-byte string codes must be modified to remove the high-order byte from the string code before adding:
    KUPVT or KUPST (version 7.6 and lower)
    KUGVT or KUGST (version 7.7 and higher)
  • If you invoke a z/OS service that must receive control in 24-bit mode (such as BSAM) use CSAVE or IOSAVE with the AMODE=24 parameter. Code CRSTR or IORSTR with the AMODE=31 parameter. You cannot reference KOMM or the pushdown list between AMODE=24 and AMODE=31 brackets.
  • The NOARG parameter (described in NOARG option) is required for ARG statements in 31-bit mode.
  • You cannot use the CCALL macro in 24-bit mode.
  • For users of the multiple KOMM feature:
    • If the $function switches to z/OS register conventions, RC might at some point no longer be equal to KOMM. Use the following code to locate KOMM:


    • In ESA systems, each user's KOMM is allocated in 31-bit storage.

      (See the discussion of MP system parameters in Performance monitoring and tuning).

Additional requirements for MP/204 (multiprocessing)

  • The FN macro has an MP argument, which defaults to NO. Other legal values are OK and YES. When the FN macro specifies MP=NO, the $function is guaranteed to execute in the maintask.
  • When a $function is invoked that specifies MP=OK, that $function might execute in one of the MP subtasks, depending on whether Model 204 is running in parallel a section of code that contains it. If so, the $function is eligible to execute in a subtask.
  • When a $function is invoked that specifies MP=YES, that $function executes in one of the MP subtasks, regardless of whether the section of code within which it is contained is running in parallel. Usually, only $functions with relatively long pathlength should specify MP=YES, because the cost of switching from the maintask to a subtask can be in the thousands of instructions. Because the exact cost of switching tasks depends on how busy the subtasks and the maintask are, measurements should be made in marginal circumstances.
  • $functions that are eligible for subtask execution actually execute on one of the subtasks under either of the following conditions:
    • SCHDOPT=X'02' is specified.
    • The section of code in which the $function is coded is executed at a time when other users are on the scheduler's READY queue.
  • $functions that specify MP=OK or MP=YES:
    • Are not guaranteed to always execute in the same subtask when NMPSUBS is greater than 1.
    • Must be re-entrant.
    • Must not use any internal Model 204 interfaces that require maintask execution, for example, APUT, DKIW, and CENQxxx.
  • MP=OK and MP=YES have no effect when the MP feature is not in use (NMPSUBS=0).

Additional requirements for zIIP processing

If Model 204 runs with zIIP processors, an MP=YES, MP=OK, MP=ZYES, or MP=ZOK setting in the FN macro might cause a $function to be executed on the zIIP subtask, which does not allow an SVC instruction. Customers planning to use zIIP processing must do either of these:

  • Inspect any user-written $functions for non-tolerant code. This is code that uses an explicit SVC instruction or requests system services that might use an SVC, like BSAM, VTAM, or task-mode z/OS macros, or macros that are not allowed to be invoked on an SRB (enclave Service Request Block, the environment when a $function is executed on a zIIP processor). Bracket this code with SRBMODE OFF and SRBMODE ON.
  • Specify MP=NO (the default) or no MP setting at all in the FN macro to cause $functions to run on the maintask and not on a zIIP SRB. Any other value for MP enables $functions to run on zIIP subtasks.

Note: It is not always obvious if code may or may not run on a zIIP subtask. Even if all explicit SVCs and non-task-mode system macros issued by Model 204 have been identified and bracketed, some may be issued implicitly by z/OS or other services, so user testing is important.