Fast/Unload customer-written assembler function packages: Difference between revisions

From m204wiki
Jump to navigation Jump to search
m (# in page title)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{DISPLAYTITLE:Fast/Unload customer-written assembler #function packages}}
<!-- Page name: Fast/Unload customer-written assembler function packages-->
<!-- Page name: Fast/Unload customer-written assembler function packages-->
{{DISPLAYTITLE:Fast/Unload customer-written assembler #function packages}}
You can extend the set of #functions available at your site by writing
You can extend the set of #functions available at your site by writing
one or more collections of them and making them available to FUEL.
one or more collections of them and making them available to FUEL.
The items enabling you to do this are:
The items enabling you to do this are:
<ul>
<ul>
<li>The FUNCTIONS statement has been added to FUEL to identify the
<li>The <var>FUNCTIONS</var> statement identifies the
location of #functions you have written.
location of #functions you have written.</li>
<li>An efficient, easy-to-use interface has been designed for matching
 
a #function name to the code implementing that #function.
<li>An efficient, easy-to-use interface matches
<li>An efficient, easy-to-use interface has been designed for performing
a #function name to the code implementing that #function.</li>
 
<li>An efficient, easy-to-use interface performs
common operations needed by #functions, such as obtaining the value of
common operations needed by #functions, such as obtaining the value of
arguments and setting the result value and output arguments.
arguments and setting the result value and output arguments.</li>
<li>The interfaces have been designed with compatibility in mind;
 
<li>The interfaces are designed with compatibility in mind:
with new releases of <var class="product">Fast/Unload</var> you will
with new releases of <var class="product">Fast/Unload</var> you will
not even need to reassemble your #functions.
not even need to reassemble your #functions.
Line 19: Line 21:


==Members of SIRIUS.OBJLIB used in coding #functions==
==Members of SIRIUS.OBJLIB used in coding #functions==
<p></p>
Some assembler language source files are included in your <var class="product">Fast/Unload</var>
Some assembler language source files are included in your <var class="product">Fast/Unload</var>
distribution tape to assist you in developing #functions.
distribution tape to assist you in developing #functions.
Line 30: Line 31:
the <var class="product">Fast/Unload</var> #function service routine, for the various
the <var class="product">Fast/Unload</var> #function service routine, for the various
services being requested.
services being requested.
The only value defined in this COPY member which will change is
The only value defined in this COPY member that will change is
the symbol FUNQX, which will increase when additional services are
the symbol <var>FUNQX</var>, which will increase when additional services are
added to the interface.
added to the interface.
<p></p>
 
Note: Prior to the release of version 4.0 of <var class="product">Fast/Unload</var>, one of the symbols,
<blockquote class="note">
FUNQAFS, was incorrectly defined.
<p>
Be sure you are using the corrected FUNCEQU COPY, which contains the
<b>Note:</b> Prior to the release of version 4.0 of <var class="product">Fast/Unload</var>, one of the symbols,
<var>FUNQAFS</var>, was incorrectly defined.
Be sure you are using the corrected <code>FUNCEQU COPY</code>, which contains the
following assembler statement:
following assembler statement:
<p class="code"><nowiki>FUNQAFS  EQU  11    Assign float to arg...
<p class="code"><nowiki>FUNQAFS  EQU  11    Assign float to arg...
</nowiki></p>
</nowiki></p>
</blockquote>
===Example #function package: UFUN ASSEMBLE===
===Example #function package: UFUN ASSEMBLE===
<p></p>
This ASSEMBLE program contains the package-searching code, along with
This ASSEMBLE program contains the package-searching code, along with
one sample #function available in the package.
one sample #function available in the package.
You can modify this program to write a #function package, using your
You can modify this program to write a #function package, using your
own #function names in the table.
own #function names in the table.
<p></p>
 
Since future versions of <var class="product">Fast/Unload</var> may contain new standard #functions,
Since future versions of <var class="product">Fast/Unload</var> may contain new standard #functions,
you should choose a naming convention for your #functions which is not
choose a naming convention for your #functions that is not
likely to overlap the standard #functions.
likely to overlap the standard #functions.
==Compiler call to package to locate #function==
==Compiler call to package to locate #function==
<p></p>
When a #function call
When a #function call
is compiled in a FUEL program, if the #function name is not one of
is compiled in a FUEL program, if the #function name is not one of
Line 58: Line 62:
are dynamically loaded and called, in the order specified, until the
are dynamically loaded and called, in the order specified, until the
<nowiki>#function</nowiki> name is in the package.
<nowiki>#function</nowiki> name is in the package.
<p></p>
 
The registers passed to the #function package are:
The registers passed to the #function package are:
<table>
<table class="thJustBold">
<tr><th>R1</th><td>The address of a byte, which contains the length of the <nowiki>#function</nowiki> name, followed by the #function name, blank padded to 255 bytes.</td></tr>
<tr><th>R1</th>
<tr><th>R6</th><td>The address of a 4096 byte work area which is passed to all <nowiki>#function</nowiki> packages and to all #functions. This area is initally all binary zeroes and is aligned on a doubleword boundary. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
<td>The address of a byte, which contains the length of the #function name, followed by the <nowiki>#function</nowiki> name, blank-padded to 255 bytes.</td></tr>
<tr><th>R13</th><td>The address of a 4096 byte work area which is passed only to this #function package and to all #functions within this package. This area is initially all binary zeroes and is aligned on a doubleword boundary. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
 
<tr><th>R14</th><td>The return address.</td></tr>
<tr><th>R6</th>
<tr><th>R15</th><td>The entry point of the #function package.</td></tr>
<td>The address of a 4096 byte work area which is passed to all <nowiki>#function</nowiki> packages and to all #functions. This area is initally all binary zeroes and is aligned on a doubleword boundary. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
 
<tr><th>R13</th>
<td>The address of a 4096 byte work area which is passed only to this #function package and to all #functions within this package. This area is initially all binary zeroes and is aligned on a doubleword boundary. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
 
<tr><th>R14</th>
<td>The return address.</td></tr>
 
<tr><th>R15</th>
<td>The entry point of the #function package.</td></tr>
</table>
</table>
<p></p>
 
The registers returned by the #function package are:
The registers returned by the #function package are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Must contain 0.</td></tr>
<tr><th>R0</th>
<tr><th>R1</th><td>One of the following two cases: <ul>
<td>Must contain 0.</td></tr>
<li>0 to indicate the #function is not part of the package.
 
<li>A positive number, which is the entry point of the #function. </ul></td></tr>
<tr><th>R1</th>
<tr><th>R2</th><td>A bit mask, to indicate which arguments are required. For example, X'A0000000' indicates the first and third arguments are required (a rather strange example).</td></tr>
<td>One of the following two cases:  
<tr><th>R3</th><td>A bit mask, to indicate which arguments, if specified, must be %variables (i.e., available as output). For example, X'30000000' indicates the third and fourth arguments are output arguments.</td></tr>
<ul>
<tr><th>R4</th><td>Maximum number of arguments the #function can accept.</td></tr>
<li>0 to indicate the #function is not part of the package.</li>
<tr><th>R5-R15</th><td>Need not be restored, can contain any value.</td></tr>
<li>A positive number, which is the entry point of the #function.</li>
</ul></td></tr>
 
<tr><th>R2</th>
<td>A bit mask, to indicate which arguments are required. For example, X'A0000000' indicates the first and third arguments are required (a rather strange example).</td></tr>
 
<tr><th>R3</th>
<td>A bit mask, to indicate which arguments, if specified, must be %variables (that is, available as output). For example, X'30000000' indicates the third and fourth arguments are output arguments.</td></tr>
 
<tr><th>R4</th>
<td>Maximum number of arguments the #function can accept.</td></tr>
 
<tr><th>R5-R15</th>
<td>Need not be restored, can contain any value.</td></tr>
</table>
</table>
==Run-time invocation of #function==
==Run-time invocation of #function==
<p></p>
This section describes the registers passed to a #function
This section describes the registers passed to a #function
(none need be returned by the #function),
(none need be returned by the #function),
and the services that <var class="product">Fast/Unload</var> makes available for use by a #function.
and the services that <var class="product">Fast/Unload</var> makes available for use by a #function.
<p></p>
 
The registers passed to a #function are:
The registers passed to a #function are:
<table>
<table class="thJustBold">
<tr><th>R5</th><td>The address of a service routine to retrieve from or assign to the #function arguments or perform other services. See the description of the interface to the service routine, presented next in this section.</td></tr>
<tr><th>R5</th>
<tr><th>R6</th><td>The address of a 4096 byte work area which is passed to all <nowiki>#function</nowiki> packages and all to #functions. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
<td>The address of a service routine to retrieve from or assign to the #function arguments or perform other services. See the description of the interface to the service routine, presented next in this section.</td></tr>
<tr><th>R13</th><td>The address of a 4096 byte work area which is passed only to a given #function package and to all <nowiki>#functions</nowiki> which were resolved by a call to that package. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
 
<tr><th>R14</th><td>The return address.</td></tr>
<tr><th>R6</th>
<tr><th>R15</th><td>The entry point of the #function.</td></tr>
<td>The address of a 4096-byte work area which is passed to all <nowiki>#function</nowiki> packages and all to #functions. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
 
<tr><th>R13</th>
<td>The address of a 4096 byte work area which is passed only to a given #function package and to all <nowiki>#functions</nowiki> that were resolved by a call to that package. <var class="product">Fast/Unload</var> does not modify this area.</td></tr>
 
<tr><th>R14</th>
<td>The return address.</td></tr>
 
<tr><th>R15</th>
<td>The entry point of the #function.</td></tr>
</table>
</table>
<p></p>
 
The argument values can be returned by the service routine;
The argument values can be returned by the service routine;
various values (<b>FUNQ2</b>xxx) are used for different types.
various values (<var>FUNQ2<i>xxx</i></var>) are used for different types.
<p></p>
 
There is no information returned from a #function in the registers.
There is no information returned from a #function in the registers.
No registers need be restored; they can contain any value.
No registers need be restored; they can contain any value.
The result value and output arguments
The result value and output arguments
of a #function are set by
of a #function are set by passing various values
passing various values
(<var>FUNQ2<i>xxx</i></var>) to the service routine.
(<b>FUNQ2</b>xxx) to the service routine.
 
<p></p>
The service routine that is passed to a #function in register R5 is
The service routine which is passed to a #function in register R5 is
used to retrieve the value of or perform assignment into the #function
used to retrieve the value of or perform assignment into the #function
arguments or result, issue error messages, terminate <var class="product">Fast/Unload</var>, and
arguments or result, issue error messages, terminate <var class="product">Fast/Unload</var>, and
manage memory.
manage memory.
<p></p>
 
The registers at entry to the service routine are described below;
The registers at entry to the service routine are described below.
individual services have some exceptions, which are explained in the
Individual services have some exceptions, which are explained in the
description of the services in this section.
description of the services in this section.
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Unless specified otherwise, the argument number for the service. Argument number 0 designates the #function result.</td></tr>
<tr><th>R0</th>
<tr><th>R1</th><td>A code indicating the service required (symbols for this code are defined in FUNCQEU COPY).</td></tr>
<td>Unless specified otherwise, the argument number for the service. Argument number 0 designates the #function result.</td></tr>
<tr><th>R2</th><td>As described for individual service descriptions in this section.</td></tr>
 
<tr><th>F0</th><td>(Floating point register 0); as described for individual service descriptions in this section.</td></tr>
<tr><th>R1</th>
<tr><th>R14</th><td>The return address.</td></tr>
<td>A code indicating the service required (symbols for this code are defined in <code>FUNCQEU COPY</code>).</td></tr>
 
<tr><th>R2</th>
<td>As described for individual service descriptions in this section.</td></tr>
 
<tr><th>F0</th>
<td>(Floating point register 0); as described for individual service descriptions in this section.</td></tr>
 
<tr><th>R14</th>
<td>The return address.</td></tr>
</table>
</table>
<p></p>
 
The registers on return from
The registers on return from the service routine are
the service routine are
explained in the description of the services in this section.
explained in the
description of the services in this section.
For all services, the registers on return from the service routine are:
For all services, the registers on return from the service routine are:
<table>
<table class="thJustBold">
<tr><th>R0-R2</th><td>Unless specified for an individual service, unpredictable.</td></tr>
<tr><th>R0-R2</th>
<tr><th>R3-R14</th><td>Unchanged from values at entry.</td></tr>
<td>Unless specified for an individual service, unpredictable.</td></tr>
<tr><th>R15</th><td>Usually a return code; if not specified by the service routine description, unpredictable.</td></tr>
 
<tr><th>R3-R14</th>
<td>Unchanged from values at entry.</td></tr>
 
<tr><th>R15</th>
<td>Usually a return code; if not specified by the service routine description, unpredictable.</td></tr>
</table>
</table>
===Get information about #function argument(s)===
===Get information about #function argument(s)===
<p></p>
This service obtains the number of arguments to the #function and optionally the type (omitted/present, <var>MISSING</var> value or not, and output or not)
This service obtains the number of arguments to the
<nowiki>#function</nowiki> and optionally the type (omitted/present,
MISSING value or not, and output or not)
of a specified argument.
of a specified argument.
<p></p>
 
<p></p>
This service is most often invoked for #functions that have a variable number of arguments (such as <var>#CONCAT</var>). For a different usage
<p></p>
This service is most often invoked for #functions which
have a variable number of arguments (such as #CONCAT).
For a different usage
example, it can be invoked as follows to see if a particular
example, it can be invoked as follows to see if a particular
argument is an output argument (although the function package
argument is an output argument (although the function package
Line 152: Line 192:
   BP    ...              No, handle condition
   BP    ...              No, handle condition
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for this service are:
Special input registers for this service are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Argument number (0 means don't get single arg info).</td></tr>
<tr><th>R0</th>
<td>Argument number (0 means don't get single arg info).</td></tr>
</table>
</table>
<p></p>
 
Output registers for this service are:
Output registers for this service are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Number of arguments (including omitted arguments after a comma) (i.e., 0 if no args, else 1 + number of commas). :lp.Following output registers only apply if this service is called with R0 > 0:</td></tr>
<tr><th>R0</th>
<tr><th>R1</th><td>0: Argument has a value. <br/> 4: Argument is not present. <br/> 8: Argument is present but value is MISSING.</td></tr>
<td>Number of arguments (including omitted arguments after a comma) (that is, 0 if no arguments, else 1 + number of commas). </td></tr>
<tr><th>R15</th><td>0: Argument is an output arg; assignment will be OK. <br/> 4: Argument is not present. <br/> 8: Argument present but not an output arg.</td></tr>
 
<tr><th>R0 > 0</th>
<td>The following output registers only apply if this service is called with R0 greater than 0:<table class="thJustBold">
<tr><th>R1</th>
<td><ul>
<li>0: Argument has a value. </li>
<li>4: Argument is not present. </li>
<li>8: Argument is present but value is <var>MISSING</var>.</li>
</ul></td></tr>
 
<tr><th>R15</th>
<td><ul>
<li>0: Argument is an output argument; assignment will be OK. </li>
<li>4: Argument is not present. </li>
<li>8: Argument present but not an output argument.</li>
</ul></td></tr>
</table>
</td></tr>
</table>
</table>
===Get string value of argument===
===Get string value of argument===
<p></p>
This pair of services obtains the string value of a specified argument.
This pair of services obtains the string
The strict service (<var>FUNQ2SS</var>) will terminate if the argument is omitted.
value of a specified argument.
The conditional service (<var>FUNQ2SC</var>) will allow all argument cases.
The strict service (FUNQ2SS) will terminate if the argument is
omitted.
The conditional service (FUNQ2SC) will allow all argument cases.
Either service will reflect exception argument cases
Either service will reflect exception argument cases
by a return code in register R15 and a zero length in register R0.
by a return code in register R15 and a zero length in register R0.
<p></p>
 
For example, they can be invoked as follows:
For example, they can be invoked as follows:
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
Line 186: Line 242:
   EX    R15,MVCA  MVC xx(0,R13),0(R1)  Copy to work area
   EX    R15,MVCA  MVC xx(0,R13),0(R1)  Copy to work area
</nowiki></p>
</nowiki></p>
or
 
Or:
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
   LA    R1,FUNQ2SC      Get service number - allow errors
   LA    R1,FUNQ2SC      Get service number - allow errors
Line 200: Line 257:
   BC    ...              Handle condition
   BC    ...              Handle condition
</nowiki></p>
</nowiki></p>
<p></p>
 
These services have no special input registers.
These services have no special input registers.
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Length of string value (0 if omitted or MISSING value).</td></tr>
<tr><th>R0</th>
<tr><th>R1</th><td>Address of string value.</td></tr>
<td>Length of string value (0 if omitted, or <var>MISSING</var> value).</td></tr>
<tr><th>R2</th><td>   0: Not a DBCS string or not DBCS run <br/> > 0: Mixed DBCS string <br/> < 0: Pure DBCS string</td></tr>
 
<tr><th>R15</th><td>0: Argument contains string value. <br/> 4: Argument is not present. <br/> 8: Argument present but value is MISSING.</td></tr>
<tr><th>R1</th>
<td>Address of string value.</td></tr>
 
<tr><th>R2</th>
<td><ul>
<li>0: Not a DBCS string or not DBCS run </li>
<li>> 0: Mixed DBCS string </li>
<li>< 0: Pure DBCS string</li>
</ul></td></tr>
 
<tr><th>R15</th>
<td><ul>
<li>0: Argument contains string value. </li>
<li>4: Argument is not present. </li>
<li>8: Argument present but value is <var>MISSING</var>.</li>
</ul></td></tr>
</table>
</table>
===Get float value of argument===
===Get float value of argument===
<p></p>
This pair of services obtains the 8-byte floating point
This pair of services obtains the 8 byte floating point
value of a specified argument.
value of a specified argument.
The strict service (FUNQ2FS) will terminate if the argument is
The strict service (<var>FUNQ2FS</var>) will terminate if the argument is
omitted, has a non-numeric value, or has a
omitted, has a non-numeric value, or has a
value too large in absolute value to store in
value too large in absolute value to store in
an eight byte floating point number (insignificant
an 8-byte floating point number (insignificant fractions will be truncated without
fractions will be truncated without
error).
error).
The conditional service (FUNQ2FC) will allow all argument cases.
The conditional service (<var>FUNQ2FC</var>) will allow all argument cases.
Either service will reflect exception argument cases
Either service will reflect exception argument cases
by a return code in register R15 and a zero in float register F0.
by a return code in register R15 and a zero in float register F0.
<p></p>
 
For example, they can be invoked as follows:
For example, they can be invoked as follows:
<p></p>
 
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
   LA    R1,FUNQ2FS      Service num: omit/non-num CANCEL
   LA    R1,FUNQ2FS      Service num: omit/non-num CANCEL
Line 234: Line 305:
   STD  F0,xxx(,R13)    Save value in work area
   STD  F0,xxx(,R13)    Save value in work area
</nowiki></p>
</nowiki></p>
<p></p>
 
or
Or:
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
   LA    R1,FUNQ2FC      Get service number - allow errors
   LA    R1,FUNQ2FC      Get service number - allow errors
Line 246: Line 317:
OK STD  F0,xxx(,R13)    Save value in work area
OK STD  F0,xxx(,R13)    Save value in work area
</nowiki></p>
</nowiki></p>
<p></p>
 
These services have no special input registers.
These services have no special input registers.
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>F0</th><td>Float value (0 if omitted/unconvertible).</td></tr>
<tr><th>F0</th>
<tr><th>R15</th><td> 0: Argument contains float value. <br/>  4: Argument is not present. <br/>  8: Argument present but value is MISSING. <br/> 12: Argument value can't be converted to float.</td></tr>
<td>Float value (0 if omitted/unconvertible).</td></tr>
 
<tr><th>R15</th>
<td><ul>
<li>0: Argument contains float value. </li>   
<li>4: Argument is not present. </li>   
<li>8: Argument present but value is MISSING. </li>
<li>12: Argument value can't be converted to float.</li>
</ul></td></tr>
</table>
</table>
===Get fixed value of argument===
===Get fixed value of argument===
<p></p>
This pair of services obtains the 4-byte binary integer
This pair of services obtains the 4 byte binary integer
value of a specified argument.
value of a specified argument.
The strict service (FUNQ2BS) will terminate if the argument is
The strict service (<var>FUNQ2BS</var>) will terminate if the argument is
omitted, has a non-numeric value, or has a
omitted, has a non-numeric value, or has a
value too large (positive) or too small (negative) to store in
value too large (positive) or too small (negative) to store in
a four byte signed binary number (fractions will be truncated without
a 4-byte signed binary number (fractions will be truncated without
error).
error).
The conditional service (FUNQ2FC) will allow all argument cases.
The conditional service (<var>FUNQ2FC</var>) will allow all argument cases.
Either service will reflect exception argument cases
Either service will reflect exception argument cases
by a return code in register R15 and a zero in register R1.
by a return code in register R15 and a zero in register R1.
<p></p>
 
For example, they can be invoked as follows:
For example, they can be invoked as follows:
<p></p>
 
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
   LA    R1,FUNQ2BS      Service num: omit/non-num CANCEL
   LA    R1,FUNQ2BS      Service num: omit/non-num CANCEL
Line 277: Line 356:
   ST    R1,xxx(,R13)    Save value in work area
   ST    R1,xxx(,R13)    Save value in work area
</nowiki></p>
</nowiki></p>
<p></p>
 
or
Or:
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Get value of arg xxx
   LA    R1,FUNQ2BC      Get service number - allow errors
   LA    R1,FUNQ2BC      Get service number - allow errors
Line 289: Line 368:
OK ST    R1,xxx(,R13)    Save value in work area
OK ST    R1,xxx(,R13)    Save value in work area
</nowiki></p>
</nowiki></p>
<p></p>
 
These services have no special input registers.
These services have no special input registers.
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R1</th><td>Binary value (0 if omitted/unconvertible).</td></tr>
<tr><th>R1</th>
<tr><th>R15</th><td>   0: Argument contains integer value (maybe truncated). <br/>  4: Argument is not present. <br/>  8: Argument present but value is MISSING. <br/> 12: Argument value can't be converted to fullword int.</td></tr>
<td>Binary value (0 if omitted/unconvertible).</td></tr>
 
<tr><th>R15</th>
<td><ul>
<li>0: Argument contains integer value (maybe truncated). </li>   
<li>4: Argument is not present. </li>   
<li>8: Argument present but value is <var>MISSING</var>. </li>
<li>12: Argument value can't be converted to fullword int.</li>
</ul></td></tr>
</table>
</table>
===Assign string value to argument===
===Assign string value to argument===
<p></p>
This pair of services sets the
This pair of services sets the
value of a specified argument to a specified byte string.
value of a specified argument to a specified byte string.
The strict service (FUNQASS) will terminate if the argument is
The strict service (<var>FUNQASS</var>) will terminate if the argument is
omitted or is not an output argument.
omitted or is not an output argument.
The conditional service (FUNQASC) will reflect these errors
The conditional service (<var>FUNQASC</var>) will reflect these errors
by a return code in register R15.
by a return code in register R15.
<p></p>
 
<p></p>
They are invoked as follows:
They are invoked as follows:
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
Line 316: Line 402:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
or
Or:
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
   LA    R1,FUNQASC      Get service number - allow errors
   LA    R1,FUNQASC      Get service number - allow errors
Line 328: Line 414:
   BC    ...              Handle condition
   BC    ...              Handle condition
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for these services are:
Special input registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R2</th><td>Address of value to assign.</td></tr>
<tr><th>R2</th>
<tr><th>R3</th><td>Length of value to assign (must be < 256).</td></tr>
<td>Address of value to assign.</td></tr>
<tr><th>R4</th><td>If a DBCS run: <br/>       0: Not a DBCS string <br/>   > 0: Mixed DBCS string <br/>    < 0: Pure DBCS string</td></tr>
 
<tr><th>R3</th>
<td>Length of value to assign (must be < 256).</td></tr>
 
<tr><th>R4</th>
<td>If a DBCS run:  
<ul>
<li>0: Not a DBCS string </li>
<li>> 0: Mixed DBCS string </li>     
<li>< 0: Pure DBCS string</li>
</ul></td></tr>
</table>
</table>
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R15</th><td>0: Assignment successful. <br/> 4: Assignment failed: arg omitted. <br/> 8: Assignment failed: arg is not output.</td></tr>
<tr><th>R15</th>
<td><ul>
<li>0: Assignment successful. </li>
<li>4: Assignment failed: argument omitted. </li>
<li>8: Assignment failed: argument is not output.</li>
</ul></td></tr>
</table>
</table>
<p></p>
 
For FUNQASS, since the non-0 cases for R15 cause the
For <var>FUNQASS</var>, since the non-0 cases for R15 cause the
<var class="product">Fast/Unload</var> program to be terminated, if the service returns then R15 will
<var class="product">Fast/Unload</var> program to be terminated, if the service returns then R15 will
be 0.
be 0.
===Assign float value to argument===
===Assign float value to argument===
<p></p>
This pair of services sets the
This pair of services sets the
value of a specified argument to a specified 8 byte floating point value.
value of a specified argument to a specified 8-byte floating point value.
The strict service (FUNQAFS) will terminate if the argument is
The strict service (<var>FUNQAFS</var>) will terminate if the argument is
omitted or is not an output argument.
omitted or is not an output argument.
The conditional service (FUNQAFC) will reflect these errors
The conditional service (<var>FUNQAFC</var>) will reflect these errors
by a return code in register R15.
by a return code in register R15.
<p></p>
 
<p></p>
They are invoked as follows:
They are invoked as follows:
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
Line 360: Line 460:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
or
Or:
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
   LA    R1,FUNQAFC      Get service number - allow errors
   LA    R1,FUNQAFC      Get service number - allow errors
Line 369: Line 469:
   BC    ...              Handle condition
   BC    ...              Handle condition
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for these services are:
Special input registers for these services are:
<table>
<table class="thJustBold">
<tr><th>F0</th><td> Value to assign.</td></tr>
<tr><th>F0</th>
<td> Value to assign.</td></tr>
</table>
</table>
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R15</th><td>0: Assignment successful. <br/> 4: Assignment failed: arg omitted. <br/> 8: Assignment failed: arg is not output.</td></tr>
<tr><th>R15</th>
<td><ul>
<li>0: Assignment successful. </li>
<li>4: Assignment failed: arg omitted. </li>
<li>8: Assignment failed: arg is not output.</li>
</ul></td></tr>
</table>
</table>
<p></p>
 
For FUNQAFS, since the non-0 cases for R15 cause the
For <var>FUNQAFS</var>, since the non-0 cases for R15 cause the
<var class="product">Fast/Unload</var> program to be terminated, if the service returns then R15 will
<var class="product">Fast/Unload</var> program to be terminated, if the service returns then R15 will
be 0.
be 0.
<p></p>
 
Note: Prior to the release of version 4.0 of <var class="product">Fast/Unload</var>,
<blockquote class="note">
FUNQAFS was incorrectly defined.
<p><b>Note:</b> Prior to the release of version 4.0 of <var class="product">Fast/Unload</var>, <var>FUNQAFS</var> was incorrectly defined.
Be sure you are using the corrected FUNCEQU COPY, which contains the
Be sure you are using the corrected <code>FUNCEQU COPY</code>, which contains the
following assembler statement:
following assembler statement: </p>
<p class="code"><nowiki>FUNQAFS  EQU  11    Assign float to arg...
<p class="code"><nowiki>FUNQAFS  EQU  11    Assign float to arg...
</nowiki></p>
</nowiki></p>
</blockquote>
===Assign fixed value to argument===
===Assign fixed value to argument===
<p></p>
This pair of services sets the
This pair of services sets the
value of a specified argument to a specified 4 byte binary integer value.
value of a specified argument to a specified 4 byte binary integer value.
The strict service (FUNQABS) will terminate if the argument is
The strict service (<var>FUNQABS</var>) will terminate if the argument is
omitted or is not an output argument.
omitted or is not an output argument.
The conditional service (FUNQABC) will reflect these errors
The conditional service (<var>FUNQABC</var>) will reflect these errors
by a return code in register R15.
by a return code in register R15.
<p></p>
 
<p></p>
They are invoked as follows:
They are invoked as follows:
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
Line 406: Line 512:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
or
Or:
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
<p class="code"><nowiki>  LA    R0,xxx          Set value of arg xxx
   LA    R1,FUNQABC      Get service number - allow errors
   LA    R1,FUNQABC      Get service number - allow errors
Line 415: Line 521:
   BC    ...              Handle condition
   BC    ...              Handle condition
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for these services are:
Special input registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R2</th><td> Value to assign.</td></tr>
<tr><th>R2</th>
<td> Value to assign.</td></tr>
</table>
</table>
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R15</th><td>0: Assignment successful. <br/> 4: Assignment failed: arg omitted. <br/> 8: Assignment failed: arg is not output.</td></tr>
<tr><th>R15</th>
<td><ul>
<li>0: Assignment successful. </li>
<li>4: Assignment failed: argument omitted. </li>
<li>8: Assignment failed: argument is not output.</li>
</ul></td></tr>
</table>
</table>
<p></p>
 
For FUNQABS, since the non-0 cases for R15 cause the
For <var>FUNQABS</var>, since the non-0 cases for R15 cause the
<var class="product">Fast/Unload</var> program to be terminated, if the service returns then R15 will
<var class="product">Fast/Unload</var> program to be terminated, if the service returns then R15 will
be 0.
be 0.
===Allocate storage===
===Allocate storage===
<p></p>
This pair of services allocates dynamic storage, above (<var>FUNQGMA</var>) or
This pair of services allocates dynamic storage, above (FUNQGMA) or
below (<var>FUNQGMB</var>) the 16 meg line, respectively.
below (FUNQGMB) the 16 meg line, respectively.
 
<p></p>
<p></p>
They are invoked as follows:
They are invoked as follows:
<p class="code"><nowiki>  LA    R0,...          Length of storage to allocate
<p class="code"><nowiki>  LA    R0,...          Length of storage to allocate
Line 441: Line 552:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
or
Or:
<p class="code"><nowiki>  LA    R0,...          Length of storage to allocate
<p class="code"><nowiki>  LA    R0,...          Length of storage to allocate
   LA    R2,=C'...        Label for storage
   LA    R2,=C'...        Label for storage
Line 448: Line 559:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for these services are:
Special input registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Length of storage in bytes.</td></tr>
<tr><th>R0</th>
<tr><th>R2</th><td>Address of 8 character eyecatcher for storage.</td></tr>
<td>Length of storage in bytes.</td></tr>
 
<tr><th>R2</th>
<td>Address of 8-character eyecatcher for storage.</td></tr>
</table>
</table>
<p></p>
 
Output registers for these services are:
Output registers for these services are:
<table>
<table class="thJustBold">
<tr><th>R1</th><td>Address of storage allocated.</td></tr>
<tr><th>R1</th>
<td>Address of storage allocated.</td></tr>
</table>
</table>
<p></p>
 
If the storage is
If the storage is
not available, the FUEL program is terminated (i.e.,
not available, the FUEL program is terminated (that is, the service does not return).
the service does not return).
 
===Release storage===
===Release storage===
<p></p>
This service releases a block of storage that was
This service releases a block of storage which was
previously allocated (partial blocks may not be released).
previously allocated (partial blocks may not be released).
<p></p>
 
<p></p>
It is invoked as follows:
It is invoked as follows:
<p class="code"><nowiki>  LR    R0,...          Address of storage to release
<p class="code"><nowiki>  LR    R0,...          Address of storage to release
Line 474: Line 587:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for this service are:
Special input registers for this service are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Address of storage to release.</td></tr>
<tr><th>R0</th>
<td>Address of storage to release.</td></tr>
</table>
</table>
<p></p>
 
This service has no output registers.
This service has no output registers.
===Issue an error message and/or set return code===
===Issue an error message and/or set return code===
<p></p>
This service issues the <code>FUNL0111</code> message, with the specified
This service issues the FUNL0111 message, with the specified
text, and/or changes the <var class="product">Fast/Unload</var> program return code.
text, and/or changes the <var class="product">Fast/Unload</var> program return code.
<p></p>
 
<p></p>
The <var>FUNQMSG</var> service is invoked in a variety of ways.
The FUNQMSG service is invoked in a variety of ways.
To issue a message without changing the current return code:
To issue a message without changing the current return code:
<p class="code"><nowiki>  LA    R0,MSG          Address of message text
<p class="code"><nowiki>  LA    R0,MSG          Address of message text
Line 495: Line 608:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
To issue a message and ensure that the return code is
To issue a message and ensure that the return code is
set at least as large as a supplied value:
set at least as large as a supplied value:
Line 505: Line 618:
   ST    R15,xxx(,RD)    Save prior value of return code
   ST    R15,xxx(,RD)    Save prior value of return code
</nowiki></p>
</nowiki></p>
<p></p>
 
To ensure that the return code is set at least as large as a
To ensure that the return code is set at least as large as a
supplied value, without printing a message:
supplied value, without printing a message:
Line 515: Line 628:
   ST    R15,xxx(,RD)    Save prior value of return code
   ST    R15,xxx(,RD)    Save prior value of return code
</nowiki></p>
</nowiki></p>
<p></p>
 
To force return code to specific value, without regard to
To force return code to specific value, without regard to
previous value, with or without printing a message:
previous value, with or without printing a message:
Line 531: Line 644:
   ST    R15,xxx(,RD)    Save prior value of return code
   ST    R15,xxx(,RD)    Save prior value of return code
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for this service are:
Special input registers for this service are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Address of message.</td></tr>
<tr><th>R0</th>
<tr><th>R2</th><td>Length of message; if less than 0, message not issued. Must be less than 256.  Trailing blanks preserved.</td></tr>
<td>Address of message.</td></tr>
<tr><th>R3</th><td>   0: do not change return code. <br/> > 0: change return code to this value if it is less than that value. <br/> < 0: change return code to value in R4, regardless.</td></tr>
 
<tr><th>R4</th><td>New return code, if R3 less than 0.</td></tr>
<tr><th>R2</th>
<td>Length of message; if less than 0, message not issued. Must be less than 256.  Trailing blanks preserved.</td></tr>
 
<tr><th>R3</th>
<td><ul>
<li>0: do not change return code. </li>
<li>> 0: change return code to this value if it is less than that value. </li>
<li>< 0: change return code to value in R4, regardless.</li>
</ul></td></tr>
 
<tr><th>R4</th>
<td>New return code, if R3 less than 0.</td></tr>
</table>
</table>
<p></p>
 
Output registers for this service are:
Output registers for this service are:
<table>
<table class="thJustBold">
<tr><th>R15</th><td>Prior value of return code.</td></tr>
<tr><th>R15</th>
<td>Prior value of return code.</td></tr>
</table>
</table>
===Terminate Fast/Unload., optionally set return code===
===Terminate Fast/Unload., optionally set return code===
<p></p>
This service terminates <var class="product">Fast/Unload</var>, and optionally
This service terminates <var class="product">Fast/Unload</var>, and optionally
changes the <var class="product">Fast/Unload</var> program return code.
changes the <var class="product">Fast/Unload</var> program return code.
<p></p>
 
<p></p>
The <var>FUNQTRM</var> service is invoked in a variety of ways.
The FUNQTRM service is invoked in a variety of ways.
To terminate the current run without changing the return code:
To terminate the current run without changing the return code:
<p class="code"><nowiki>  LA    R1,FUNQTRM      Get service number
<p class="code"><nowiki>  LA    R1,FUNQTRM      Get service number
Line 556: Line 680:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
To terminate the current run and ensure that the return code
To terminate the current run and ensure that the return code
is at least as high as a provided number:
is at least as high as a provided number:
Line 563: Line 687:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
To terminate the current run and set the return code to a given
To terminate the current run and set the return code to a given
value without regard to its previous value:
value without regard to its previous value:
Line 571: Line 695:
   BALR  R14,R5          Call service
   BALR  R14,R5          Call service
</nowiki></p>
</nowiki></p>
<p></p>
 
Special input registers for this service are:
Special input registers for this service are:
<table>
<table class="thJustBold">
<tr><th>R0</th><td>Unused.</td></tr>
<tr><th>R0</th>
<tr><th>R3</th><td>   0: do not change return code. <br/> > 0: change return code to value in R3 if it is less than that value. <br/> < 0: change return code to value in R4, regardless.</td></tr>
<td>Unused.</td></tr>
<tr><th>R4</th><td>New return code, if R3 less than 0.</td></tr>
 
<tr><th>R3</th>
<td><ul>
<li>0: do not change return code. </li>
<li>> 0: change return code to value in R3 if it is less than that value. </li>
<li>< 0: change return code to value in R4, regardless.</li>
</ul></td></tr>
 
<tr><th>R4</th>
<td>New return code, if R3 less than 0.</td></tr>
</table>
</table>
<p></p>
 
This service does not return.
This service does not return.
==Example - z/OS==
 
==z/OS example==
This example demonstrates use of the sample #function package contained
This example demonstrates use of the sample #function package contained
on the distribution tape, in the z/OS environment.
on the distribution tape, in the z/OS environment.
===Installing a #function package===
===Installing a #function package===
<p></p>
This step consists of assembling and link-editing a #function package.
This step consists of assembling and link-editing a #function package.
<p class="code"><nowiki>//ASMLINK EXEC ASMCL
<p class="code"><nowiki>//ASMLINK EXEC ASMCL
Line 594: Line 728:
/*
/*
</nowiki></p>
</nowiki></p>
===Using a #function package===
===Using a #function package===
<p></p>
Shown here are the changes to the <var class="product">Fast/Unload</var> JCL and FUEL needed
Shown here are the changes to the <var class="product">Fast/Unload</var> JCL and FUEL needed
to use a #function package.
to use a #function package.
Line 602: Line 736:
//FUNCPKG DD DISP=SHR,DSN=USER.FUNCPKG  Custom package
//FUNCPKG DD DISP=SHR,DSN=USER.FUNCPKG  Custom package
//FUNIN DD *
//FUNIN DD *
OPEN PEOPLE
FUNCTIONS IN FUNCPKG LOCFUNCS
FUNCTIONS IN FUNCPKG LOCFUNCS
OPEN PEOPLE
FOR EACH RECORD
FOR EACH RECORD
   %PALINDROME = #RVRSTR(NAME)
   %PALINDROME = #RVRSTR(NAME)
Line 611: Line 745:
END FOR
END FOR
</nowiki></p>
</nowiki></p>
==Example - CMS==
 
==CMS example==
This example demonstrates use of the sample #function package contained
This example demonstrates use of the sample #function package contained
on the distribution tape, in the CMS environment.
on the distribution tape, in the CMS environment.
===Installing a #function package===
===Installing a #function package===
<p></p>
This step consists of assembling a #function package.
This step consists of assembling a #function package.
<p class="code"><nowiki>* Create a macro library with FUNCEQU:
<p class="code"><nowiki>* Create a macro library with FUNCEQU:
Line 623: Line 758:
HASM UFUN
HASM UFUN
</nowiki></p>
</nowiki></p>
===Using a #function package===
===Using a #function package===
<p></p>
If the <code>TEXT</code> file created in the preceding step is on an accessed
If the TEXT file created in the preceding step is on an accessed
CMS minidisk, you can use the following <code>FUNIN</code> file:
CMS minidisk, you can use the following FUNIN file:
<p class="code"><nowiki>
<p class="code"><nowiki>FUNCTIONS UFUN
OPEN PEOPLE
OPEN PEOPLE
FUNCTIONS UFUN
FOR EACH RECORD
FOR EACH RECORD
   %PALINDROME = #RVRSTR(NAME)
   %PALINDROME = #RVRSTR(NAME)
Line 636: Line 772:
END FOR
END FOR
</nowiki></p>
</nowiki></p>
==See also==
==See also==
[[Fast/Unload overview#WIKFUN$$topics|Fast/Unload topics]]
{{Template:Fast/Unload topic list}}

Latest revision as of 14:20, 15 June 2015

You can extend the set of #functions available at your site by writing one or more collections of them and making them available to FUEL. The items enabling you to do this are:

  • The FUNCTIONS statement identifies the location of #functions you have written.
  • An efficient, easy-to-use interface matches a #function name to the code implementing that #function.
  • An efficient, easy-to-use interface performs common operations needed by #functions, such as obtaining the value of arguments and setting the result value and output arguments.
  • The interfaces are designed with compatibility in mind: with new releases of Fast/Unload you will not even need to reassemble your #functions.

Members of SIRIUS.OBJLIB used in coding #functions

Some assembler language source files are included in your Fast/Unload distribution tape to assist you in developing #functions. They are described in this section.

Run-time interface symbols: FUNCEQU COPY

This COPY member should be made available in a MACLIB to assemble any #functions you write. The symbols defined in it consist of the values you can pass to the Fast/Unload #function service routine, for the various services being requested. The only value defined in this COPY member that will change is the symbol FUNQX, which will increase when additional services are added to the interface.

Note: Prior to the release of version 4.0 of Fast/Unload, one of the symbols, FUNQAFS, was incorrectly defined. Be sure you are using the corrected FUNCEQU COPY, which contains the following assembler statement:

FUNQAFS EQU 11 Assign float to arg...

Example #function package: UFUN ASSEMBLE

This ASSEMBLE program contains the package-searching code, along with one sample #function available in the package. You can modify this program to write a #function package, using your own #function names in the table.

Since future versions of Fast/Unload may contain new standard #functions, choose a naming convention for your #functions that is not likely to overlap the standard #functions.

Compiler call to package to locate #function

When a #function call is compiled in a FUEL program, if the #function name is not one of the standard Fast/Unload #functions, all #function packages are dynamically loaded and called, in the order specified, until the #function name is in the package.

The registers passed to the #function package are:

R1 The address of a byte, which contains the length of the #function name, followed by the #function name, blank-padded to 255 bytes.
R6 The address of a 4096 byte work area which is passed to all #function packages and to all #functions. This area is initally all binary zeroes and is aligned on a doubleword boundary. Fast/Unload does not modify this area.
R13 The address of a 4096 byte work area which is passed only to this #function package and to all #functions within this package. This area is initially all binary zeroes and is aligned on a doubleword boundary. Fast/Unload does not modify this area.
R14 The return address.
R15 The entry point of the #function package.

The registers returned by the #function package are:

R0 Must contain 0.
R1 One of the following two cases:
  • 0 to indicate the #function is not part of the package.
  • A positive number, which is the entry point of the #function.
R2 A bit mask, to indicate which arguments are required. For example, X'A0000000' indicates the first and third arguments are required (a rather strange example).
R3 A bit mask, to indicate which arguments, if specified, must be %variables (that is, available as output). For example, X'30000000' indicates the third and fourth arguments are output arguments.
R4 Maximum number of arguments the #function can accept.
R5-R15 Need not be restored, can contain any value.

Run-time invocation of #function

This section describes the registers passed to a #function (none need be returned by the #function), and the services that Fast/Unload makes available for use by a #function.

The registers passed to a #function are:

R5 The address of a service routine to retrieve from or assign to the #function arguments or perform other services. See the description of the interface to the service routine, presented next in this section.
R6 The address of a 4096-byte work area which is passed to all #function packages and all to #functions. Fast/Unload does not modify this area.
R13 The address of a 4096 byte work area which is passed only to a given #function package and to all #functions that were resolved by a call to that package. Fast/Unload does not modify this area.
R14 The return address.
R15 The entry point of the #function.

The argument values can be returned by the service routine; various values (FUNQ2xxx) are used for different types.

There is no information returned from a #function in the registers. No registers need be restored; they can contain any value. The result value and output arguments of a #function are set by passing various values (FUNQ2xxx) to the service routine.

The service routine that is passed to a #function in register R5 is used to retrieve the value of or perform assignment into the #function arguments or result, issue error messages, terminate Fast/Unload, and manage memory.

The registers at entry to the service routine are described below. Individual services have some exceptions, which are explained in the description of the services in this section.

R0 Unless specified otherwise, the argument number for the service. Argument number 0 designates the #function result.
R1 A code indicating the service required (symbols for this code are defined in FUNCQEU COPY).
R2 As described for individual service descriptions in this section.
F0 (Floating point register 0); as described for individual service descriptions in this section.
R14 The return address.

The registers on return from the service routine are explained in the description of the services in this section. For all services, the registers on return from the service routine are:

R0-R2 Unless specified for an individual service, unpredictable.
R3-R14 Unchanged from values at entry.
R15 Usually a return code; if not specified by the service routine description, unpredictable.

Get information about #function argument(s)

This service obtains the number of arguments to the #function and optionally the type (omitted/present, MISSING value or not, and output or not) of a specified argument.

This service is most often invoked for #functions that have a variable number of arguments (such as #CONCAT). For a different usage example, it can be invoked as follows to see if a particular argument is an output argument (although the function package makes sure that if an argument is declared as output, any function call using that argument is a %variable):

LA R0,xxx Get info about arg xxx LA R1,FUNQAI Get service number BALR R14,R5 Call service LTR R15,R15 Is arg an output arg? BP ... No, handle condition

Special input registers for this service are:

R0 Argument number (0 means don't get single arg info).

Output registers for this service are:

R0 Number of arguments (including omitted arguments after a comma) (that is, 0 if no arguments, else 1 + number of commas).
R0 > 0 The following output registers only apply if this service is called with R0 greater than 0:
R1
  • 0: Argument has a value.
  • 4: Argument is not present.
  • 8: Argument is present but value is MISSING.
R15
  • 0: Argument is an output argument; assignment will be OK.
  • 4: Argument is not present.
  • 8: Argument present but not an output argument.

Get string value of argument

This pair of services obtains the string value of a specified argument. The strict service (FUNQ2SS) will terminate if the argument is omitted. The conditional service (FUNQ2SC) will allow all argument cases. Either service will reflect exception argument cases by a return code in register R15 and a zero length in register R0.

For example, they can be invoked as follows:

LA R0,xxx Get value of arg xxx LA R1,FUNQ2SS Service number: omitted CANCEL BALR R14,R5 Call service * Omit following two lines if null for MISSING is OK: CH R15,=H'8' Is value MISSING? BE ... Yes, handle condition LTR R15,R0 Is string zero-length? BZ ... Yes, handle condition BCTR R15,0 No, get length - 1 EX R15,MVCA MVC xx(0,R13),0(R1) Copy to work area

Or:

LA R0,xxx Get value of arg xxx LA R1,FUNQ2SC Get service number - allow errors BALR R14,R5 Call service CH R15,=H'4' Is arg present? BE ... No, handle condition LTR R15,R0 Is string zero-length? BZ ... Yes, handle condition BCTR R15,0 No, get length - 1 EX R15,MVCA MVC xx(0,R13),0(R1) Copy to work area * Omit following two lines if no DBCS data handled: LTR R2,R2 Is string DBCS? BC ... Handle condition

These services have no special input registers.

Output registers for these services are:

R0 Length of string value (0 if omitted, or MISSING value).
R1 Address of string value.
R2
  • 0: Not a DBCS string or not DBCS run
  • > 0: Mixed DBCS string
  • < 0: Pure DBCS string
R15
  • 0: Argument contains string value.
  • 4: Argument is not present.
  • 8: Argument present but value is MISSING.

Get float value of argument

This pair of services obtains the 8-byte floating point value of a specified argument. The strict service (FUNQ2FS) will terminate if the argument is omitted, has a non-numeric value, or has a value too large in absolute value to store in an 8-byte floating point number (insignificant fractions will be truncated without error). The conditional service (FUNQ2FC) will allow all argument cases. Either service will reflect exception argument cases by a return code in register R15 and a zero in float register F0.

For example, they can be invoked as follows:

LA R0,xxx Get value of arg xxx LA R1,FUNQ2FS Service num: omit/non-num CANCEL BALR R14,R5 Call service * Omit following two lines if zero for MISSING is OK: CH R15,=H'8' Is value MISSING? BE ... Yes, handle condition STD F0,xxx(,R13) Save value in work area

Or:

LA R0,xxx Get value of arg xxx LA R1,FUNQ2FC Get service number - allow errors BALR R14,R5 Call service B *+4(R15) Handle conditions B OK Handle success B ... Handle arg omitted B ... Handle MISSING value B ... Handle conversion error OK STD F0,xxx(,R13) Save value in work area

These services have no special input registers.

Output registers for these services are:

F0 Float value (0 if omitted/unconvertible).
R15
  • 0: Argument contains float value.
  • 4: Argument is not present.
  • 8: Argument present but value is MISSING.
  • 12: Argument value can't be converted to float.

Get fixed value of argument

This pair of services obtains the 4-byte binary integer value of a specified argument. The strict service (FUNQ2BS) will terminate if the argument is omitted, has a non-numeric value, or has a value too large (positive) or too small (negative) to store in a 4-byte signed binary number (fractions will be truncated without error). The conditional service (FUNQ2FC) will allow all argument cases. Either service will reflect exception argument cases by a return code in register R15 and a zero in register R1.

For example, they can be invoked as follows:

LA R0,xxx Get value of arg xxx LA R1,FUNQ2BS Service num: omit/non-num CANCEL BALR R14,R5 Call service * Omit following two lines if zero for MISSING is OK: CH R15,=H'8' Is value MISSING? BE ... Yes, handle condition ST R1,xxx(,R13) Save value in work area

Or:

LA R0,xxx Get value of arg xxx LA R1,FUNQ2BC Get service number - allow errors BALR R14,R5 Call service B *+4(R15) Handle conditions B OK Handle success B ... Handle arg omitted B ... Handle MISSING value B ... Handle conversion error OK ST R1,xxx(,R13) Save value in work area

These services have no special input registers.

Output registers for these services are:

R1 Binary value (0 if omitted/unconvertible).
R15
  • 0: Argument contains integer value (maybe truncated).
  • 4: Argument is not present.
  • 8: Argument present but value is MISSING.
  • 12: Argument value can't be converted to fullword int.

Assign string value to argument

This pair of services sets the value of a specified argument to a specified byte string. The strict service (FUNQASS) will terminate if the argument is omitted or is not an output argument. The conditional service (FUNQASC) will reflect these errors by a return code in register R15.

They are invoked as follows:

LA R0,xxx Set value of arg xxx LA R1,FUNQASS Get service number - errors CANCEL LA R2,... Address of string to assign set R3,... Length of string to assign * Omit following line if no DBCS data handled: set R4,... Indicate DBCS string type BALR R14,R5 Call service

Or:

LA R0,xxx Set value of arg xxx LA R1,FUNQASC Get service number - allow errors LA R2,... Address of string to assign LA R3,... Length of string to assign * Omit following line if no DBCS data handled: set R4,... Indicate DBCS string type BALR R14,R5 Call service CH R15,=H'4' Is arg present/output? BC ... Handle condition

Special input registers for these services are:

R2 Address of value to assign.
R3 Length of value to assign (must be < 256).
R4 If a DBCS run:
  • 0: Not a DBCS string
  • > 0: Mixed DBCS string
  • < 0: Pure DBCS string

Output registers for these services are:

R15
  • 0: Assignment successful.
  • 4: Assignment failed: argument omitted.
  • 8: Assignment failed: argument is not output.

For FUNQASS, since the non-0 cases for R15 cause the Fast/Unload program to be terminated, if the service returns then R15 will be 0.

Assign float value to argument

This pair of services sets the value of a specified argument to a specified 8-byte floating point value. The strict service (FUNQAFS) will terminate if the argument is omitted or is not an output argument. The conditional service (FUNQAFC) will reflect these errors by a return code in register R15.

They are invoked as follows:

LA R0,xxx Set value of arg xxx LA R1,FUNQAFS Get service number - errors CANCEL LD F0,... Value to assign BALR R14,R5 Call service

Or:

LA R0,xxx Set value of arg xxx LA R1,FUNQAFC Get service number - allow errors LD F0,... Value to assign BALR R14,R5 Call service CH R15,=H'4' Is arg present/output? BC ... Handle condition

Special input registers for these services are:

F0 Value to assign.

Output registers for these services are:

R15
  • 0: Assignment successful.
  • 4: Assignment failed: arg omitted.
  • 8: Assignment failed: arg is not output.

For FUNQAFS, since the non-0 cases for R15 cause the Fast/Unload program to be terminated, if the service returns then R15 will be 0.

Note: Prior to the release of version 4.0 of Fast/Unload, FUNQAFS was incorrectly defined. Be sure you are using the corrected FUNCEQU COPY, which contains the following assembler statement:

FUNQAFS EQU 11 Assign float to arg...

Assign fixed value to argument

This pair of services sets the value of a specified argument to a specified 4 byte binary integer value. The strict service (FUNQABS) will terminate if the argument is omitted or is not an output argument. The conditional service (FUNQABC) will reflect these errors by a return code in register R15.

They are invoked as follows:

LA R0,xxx Set value of arg xxx LA R1,FUNQABS Get service number - errors CANCEL L R2,... Value to assign BALR R14,R5 Call service

Or:

LA R0,xxx Set value of arg xxx LA R1,FUNQABC Get service number - allow errors L R2,... Value to assign BALR R14,R5 Call service CH R15,=H'4' Is arg present/output? BC ... Handle condition

Special input registers for these services are:

R2 Value to assign.

Output registers for these services are:

R15
  • 0: Assignment successful.
  • 4: Assignment failed: argument omitted.
  • 8: Assignment failed: argument is not output.

For FUNQABS, since the non-0 cases for R15 cause the Fast/Unload program to be terminated, if the service returns then R15 will be 0.

Allocate storage

This pair of services allocates dynamic storage, above (FUNQGMA) or below (FUNQGMB) the 16 meg line, respectively.

They are invoked as follows:

LA R0,... Length of storage to allocate LA R2,=C'... Label for storage LA R1,FUNQGMB Get service number - below 16 MB BALR R14,R5 Call service

Or:

LA R0,... Length of storage to allocate LA R2,=C'... Label for storage LA R1,FUNQGMA Get service number - above 16 MB BALR R14,R5 Call service

Special input registers for these services are:

R0 Length of storage in bytes.
R2 Address of 8-character eyecatcher for storage.

Output registers for these services are:

R1 Address of storage allocated.

If the storage is not available, the FUEL program is terminated (that is, the service does not return).

Release storage

This service releases a block of storage that was previously allocated (partial blocks may not be released).

It is invoked as follows:

LR R0,... Address of storage to release LA R1,FUNQFM Get service number BALR R14,R5 Call service

Special input registers for this service are:

R0 Address of storage to release.

This service has no output registers.

Issue an error message and/or set return code

This service issues the FUNL0111 message, with the specified text, and/or changes the Fast/Unload program return code.

The FUNQMSG service is invoked in a variety of ways. To issue a message without changing the current return code:

LA R0,MSG Address of message text LA R1,FUNQMSG Get service number LA R2,L'MSG Length of message text SLR R3,R3 Indicate no change to return code BALR R14,R5 Call service

To issue a message and ensure that the return code is set at least as large as a supplied value:

LA R0,MSG Address of message text LA R1,FUNQMSG Get service number LA R2,L'MSG Length of message text LA R3,value Set minimum return code BALR R14,R5 Call service ST R15,xxx(,RD) Save prior value of return code

To ensure that the return code is set at least as large as a supplied value, without printing a message:

LA R1,FUNQMSG Get service number SLR R2,R2 Indicate no message text BCTR R2,0 Optionally suppress FUNL0111 LA R3,value Set minimum return code BALR R14,R5 Call service ST R15,xxx(,RD) Save prior value of return code

To force return code to specific value, without regard to previous value, with or without printing a message:

LA R1,FUNQMSG Get service number IF ... Message desired LA R0,MSG Address of message text LA R2,L'MSG Length of message text ELSE , No message SLR R2,R2 No message text, but FUNL0111 BCTR R2,0 Eliminate FUNL0111 header as well ENDIF , LH R3,=H'-1' Change return code in any case LA R4,value Set new return code BALR R14,R5 Call service ST R15,xxx(,RD) Save prior value of return code

Special input registers for this service are:

R0 Address of message.
R2 Length of message; if less than 0, message not issued. Must be less than 256. Trailing blanks preserved.
R3
  • 0: do not change return code.
  • > 0: change return code to this value if it is less than that value.
  • < 0: change return code to value in R4, regardless.
R4 New return code, if R3 less than 0.

Output registers for this service are:

R15 Prior value of return code.

Terminate Fast/Unload., optionally set return code

This service terminates Fast/Unload, and optionally changes the Fast/Unload program return code.

The FUNQTRM service is invoked in a variety of ways. To terminate the current run without changing the return code:

LA R1,FUNQTRM Get service number SLR R3,R3 Indicate no change to return code BALR R14,R5 Call service

To terminate the current run and ensure that the return code is at least as high as a provided number:

LA R1,FUNQTRM Get service number LA R3,value Set minimum return code BALR R14,R5 Call service

To terminate the current run and set the return code to a given value without regard to its previous value:

LA R1,FUNQTRM Get service number LH R3,=H'-1' Change return code in any case LA R4,value Set return code BALR R14,R5 Call service

Special input registers for this service are:

R0 Unused.
R3
  • 0: do not change return code.
  • > 0: change return code to value in R3 if it is less than that value.
  • < 0: change return code to value in R4, regardless.
R4 New return code, if R3 less than 0.

This service does not return.

z/OS example

This example demonstrates use of the sample #function package contained on the distribution tape, in the z/OS environment.

Installing a #function package

This step consists of assembling and link-editing a #function package.

//ASMLINK EXEC ASMCL //ASM.SYSIN DD DISP=SHR,DSN=SIRIUS.LIB(UFUN) Sample package //ASM.SYSLIB DD DISP=SHR,DSN=SIRIUS.LIB FUNCEQU macro //LINK.SYSLMOD DD DISP=(NEW,CATLG),DSN=USER.FUNCPKG //LINK.SYSIN DD * NAME LOCFUNCS(R) /*

Using a #function package

Shown here are the changes to the Fast/Unload JCL and FUEL needed to use a #function package.

//FUNLOAD EXEC PGM=FUNLOAD //... Normal JCL //FUNCPKG DD DISP=SHR,DSN=USER.FUNCPKG Custom package //FUNIN DD * OPEN PEOPLE FUNCTIONS IN FUNCPKG LOCFUNCS FOR EACH RECORD %PALINDROME = #RVRSTR(NAME) %PALINDROME = #CONCAT(NAME, %PALINDROME) PUT %PALINDROME OUTPUT END FOR

CMS example

This example demonstrates use of the sample #function package contained on the distribution tape, in the CMS environment.

Installing a #function package

This step consists of assembling a #function package.

* Create a macro library with FUNCEQU: MACLIB GEN FUNLOAD FUNCEQU * Assemble the package: GLOBAL MACLIB FUNCEQU HASM UFUN

Using a #function package

If the TEXT file created in the preceding step is on an accessed CMS minidisk, you can use the following FUNIN file:

OPEN PEOPLE FUNCTIONS UFUN FOR EACH RECORD %PALINDROME = #RVRSTR(NAME) %PALINDROME = #CONCAT(NAME, %PALINDROME) PUT %PALINDROME OUTPUT END FOR

See also