Customizing functions and translation tables
Overview
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:
- Label the function table in the FUNU source code FUNUTAB.
- 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.
- 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]...)
Where:
- 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)
- function-name specifies a unique 1- to 7-character name of the function without the leading
- 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:
POOL
- 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:
ARG n L R2,4(X1) CCALL RTSTRL EX R2,FOO STC R2,BUF1 . . FOO MVC BUF1(0),0(R1) .
- The
ARG
macro returns the VTBL pointer to the nth argument in X1. - The
RTSTRL
routine setsR2
to the length of the string, and it setsR1
to address-1 of the string. - The length of the string is given by register
R2
. - The string is moved to
BUF1
, starting at locationBUF1 + 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:
ARG n LA R3,x CCALL INTEG . . .
Where:
- 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)
Where:
- 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:
ARG n,NOARG=ALLDONE L R2,4(X1) CCALL RTST . . . CCALL DKRL ALLDONE DS OH . . . LEAVESTR
You can also specify the following, which returns control to the next sequential instruction after the ARG statement:
NOARG = *
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:
Code entry point | Format used for storing... |
---|---|
DATE |
`YY.DDD MON DD HH.MM.SS' |
DATE3 |
`CYY.DDD MON DD HH.MM.SS' |
DATE4 |
`YYYY.DDD MON DD HH.MM.SS' |
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).
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:
- Load R1 with a pointer to the location of the result string minus one.
- Load R2 with the length of the result string.
- Issue the LEAVESTR macro at the end of the code, just before 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:
- Load the binary integer into R1.
- Zero R2.
- Issue the LEAVENUM macro just before LTORG.
- For a floating-point result, end the code with the following:
- Load F0 with the long floating-point number.
- Issue the LEAVEF0 macro just before LTORG.
- 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.
- For an integer result, end the code end with the following:
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:
- Add EDEF statements to MSGU as needed in place of the dummy EDEF in the distributed module.
- Add ERROR macros to your functions, referring to messages in MSGU by message number as follows:
ERROR errnum,OPT=USER
- Reassemble MSGU and FUNU.
- 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
Where:
- 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
Where:
- 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, 'string'
Where:
- 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
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):
- List CDTB with its sequence numbers.
- Replace the sample tables by using an appropriate operating system utility program.
- Assemble the program.
- 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):
- Modify the source code.
- Assemble the source code.
- 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 the longest code + 1 (for string length) + the number of bytes in the 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.
- Additional requirements for systems using 31-bit architecture applies to all sites that use 31-bit architecture.
- Additional requirements for MP/204 (multiprocessing) applies to users of MP/204 (multiprocessing).
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
- 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 prior to adding KUPVT or KUPST.
- 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 theAMODE=31
parameter. You cannot reference KOMM or the pushdown list betweenAMODE=24
andAMODE=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:
CURROSW REG=x LLGF y,OSWPUK-OSW(,x)
- 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).
- 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:
Additional requirements for MP/204 (multiprocessing)
- The FN macro has an MP argument, which defaults to
NO
. Other legal values areOK
andYES
. When the FN macro specifiesMP=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 specifyMP=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
orMP=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
andMP=YES
have no effect when the MP feature is not in use (NMPSUBS=0
).