To be even more flexible, FLAM provides user exits which can be used for pre- and post-processing of uncompressed records as well as FLAMFILE records.
User exits are needed for inserting, deleting and editing records or fields before or after a compression or decompression procedure.
FLAMFILEs can also be modified to make it personal and incompatible by swapping bytes via FLAM user exits. The effect is basically the same like enciphering (by symmetrical exit modules).
Code conversion is controlled via standard code tables or user defined code tables. For special cases where a 1:1 code conversion is not possible for all characters, user exits can be used, too.
User exits can be written for any addressing mode
(AMODE=ANY
, AMODE=31
, AMODE=24
, no mode specified).
The addressing mode only has to be taken into account if FLAM is loaded
with AMODE=31
and, for some reason, the user exit is only able to run
with AMODE=24
. Only in this case, the addressing mode must be switched
in the user exit itself. It must be noted that the save area, the return
address, the parameter list and the parameters can be addressed only in
AMODE=31
. The addressing mode used by FLAM is stored in the most
significant bit of register R14 and can be looked up there.
In all other cases, the addressing mode is already set correctly and it is switched over again by FLAM after the return, if this is necessary. It is irrelevant whether the return is executed with a BR14 or a BSM 0,14 (Branch and Set Mode is a return branching instruction that set the addressing mode).
This user exit serves as an interface between the data record that is transferred to FLAM for compression.
Special processing can be defined for:
Records can be passed on, modified, deleted or inserted. This exit can be used to modify records in a structure dependent way.
EXK10 is only available in FLAM and FLAMUP and corresponds to EXD10 during decompression.
In this user exit, the original records (which shall be compressed) are passed to a user module immediately after they are read from the input file. This user exit can be used with the FLAM utility or with the subprogram FLAMUP. Records can be accepted, modified, inserted and deleted by this exit.
The exit is activated via the parameter EXK10=<user module name>
.
The user exit module must be contained in the library
that has been assigned with the STEPLIB command.
user module name | free choice (max. 8 characters) |
Register usage | |
R1 |
Address of parameter list |
R13 |
Points to save area (18 words) |
R14 |
Contains return address |
R15 |
Contains call address (entry point) |
Parameter list | ||
---|---|---|
1. FUCO | F | Function code |
0 |
First call for file (after OPEN) |
|
4 |
Record read and passed |
|
8 |
Last call for file (before CLOSE) |
|
2. RETCO | F | Return code |
0 |
Accept record / no error |
|
4 |
Do not accept record |
|
8 |
Insert record |
|
12 |
Enforce end of compression |
|
16 |
Error in user exit; abnormal termination |
|
3. RECPTR | A | Record pointer |
4. RECLEN | F | Record length (maximum 32760) |
5. EXWORK | 256F | During the first call, the working storage area contains the symbolic file name of the original file within the first 8 characters. The rest of the area is padded with x00. This area can be used by the user exit module for any purpose. With each call this working storage area is made available again with the old content. If a record shall be extended or inserted, the necessary working storage area must be provided by the user exit module. Return code 12 is only necessary if the compression shall be finished before the end of the input file is reached. For function code 0 and 8, no record is passed to the module. For function code 8, it is allowed to insert a record with return code 8. For return code 8, the record provided by the user exit module is processed. Then the user exit module is called again for the old record from the input file. The following table shows the valid function and return codes: |
Function code |
0 |
4 |
8 |
|
Return code |
0 |
x |
x |
x |
4 |
x |
|||
8 |
x |
x |
||
12 |
x |
|||
16 |
x |
x |
x |
This user exit treats compressed data before it is written to a FLAMFILE.
Special processing can be defined for:
This exit can be used to modify records in a structure independent way.
With this exit it is possible to modify the data with an own encryption routine or a special code translation can be applied if a non-transparent file transmission method shall be used.
It is possible to insert own records in front of the compressed records, for example archiving control records or origin information.
Another possibility is the extension of records to append specific revision information.
EXK20 is available in FLAM, FLAMUP and FLAMREC and corresponds to EXD20 during decompression.
In this user exit, the compressed records are passed to a user module immediately before they are written to the compressed file. This user exit can be used with the FLAM utility or with the subprogram FLAMUP. This user exit can accept, modify, insert and delete records.
The exit is activated via the parameter EXK20=<user module name>
.
The user exit module must be contained in the library
that has been assigned with the STEPLIB command.
user module name | free choice (max. 8 characters) |
Register usage | |
R1 |
Address of parameter list |
R13 |
Points to save area (18 words) |
R14 |
Contains return address |
R15 |
Contains call address (entry point) |
Parameter list | ||
---|---|---|
1. FUCO | F | Function code |
0 |
First call for file (after OPEN) |
|
4 |
Record passed |
|
8 |
Last call for file (before CLOSE) |
|
2. RETCO | F | Return code |
0 |
Accept record / no error |
|
4 |
Do not accept record |
|
8 |
Insert record |
|
12 |
Enforce end of compression |
|
16 |
Error in exit; abnormal termination |
|
3. RECPTR | A | Record pointer |
4. RECLEN | F | Record length (maximum 32760) |
5. EXWORK | 256F | During the first call the working storage area contains the symbolic file name of the original file within the first 8 characters. The rest of the area is padded with x00. This area can be used by the user exit module for any purpose. With each call, this working storage area is made available again with the old content. If a record shall be extended or inserted, the necessary working storage area must be provided by the user exit module. Return code 12 is only necessary if the compression shall be finished before the end of the input file is reached. For function code 0 and 8, no record is passed to the module. For function code 8, it is allowed to insert a record with return code 8. For return code 8, the record provided by the user exit module is written. Then the user exit module is called again for the old compressed record. |
Table of valid function codes and return codes:
Function code |
0 |
4 |
8 |
|
Return code |
0 |
x |
x |
x |
4 |
x |
|||
8 |
x |
x |
||
12 |
x |
|||
16 |
x |
x |
x |
This exit treats the decompressed records immediately before they are written to the target file.
Special processing can be defined for:
Records can be passed on, modified, deleted or inserted. This exit can be used to modify records in a structure dependent way.
EXD10 is only available in FLAM and FLAMUP and corresponds to EXK10 during compression.
In this user exit, the decompressed records are passed to a user module immediately before they are written to the output file. This user exit can be used with the FLAM utility or with the subprogram FLAMUP. This user exit can accept, modify, insert and delete records.
The exit is activated via the parameter EXD10=<user module name>
.
The user exit module must be contained in the library
that has been assigned with the STEPLIB command.
user module name | free choice (max. 8 characters) |
Register usage | |
R1 |
Address of parameter list |
R13 |
Points to save area (18 words) |
R14 |
Contains return address |
R15 |
Contains call address (entry point) |
Parameter list | ||
---|---|---|
1. FUCO | F | Function code |
0 |
First call for file (after OPEN) |
|
4 |
Record passed |
|
8 |
Last call for file (before CLOSE) |
|
2. RETCO | F | Return code |
0 |
Accept record / no error |
|
4 |
Do not accept record |
|
8 |
Insert record |
|
12 |
Enforce end of compression |
|
16 |
Error in exit; abnormal termination |
|
3. RECPTR | A | Record pointer |
4. RECLEN | F | Record length (maximum 32760) |
5. EXWORK | 256F | During the first call the working storage area contains the symbolic file name of the original file within the first 8 characters. The rest of the area is padded with x00. This area can be used by the user exit module for any purpose. With each call this working storage area is made available again with the old content. If a record shall be extended or inserted, the necessary working storage area must be provided by the user exit module. Return code 12 is only necessary if decompression shall be finished before the end of the compressed file is reached. For function code 0 and 8, no record is passed to the module. For function code 8, it is allowed to insert a record with return code 8. For return code 8, the record provided by the user exit module is written. Then the user exit module is called again for the old record. A change of the record length is accepted if the output
file is defined with |
Table of valid function codes and return codes:
Function code |
0 |
4 |
8 |
|
Return code |
0 |
x |
x |
x |
4 |
x |
|||
8 |
x |
x |
||
12 |
x |
|||
16 |
x |
x |
x |
This user exit treats the compressed data immediately after it is read from the FLAMFILE.
Special processing can be defined for:
This exit can be used to modify records in a structure independent way.
With this exit it is possible, to decrypt the data with an own decryption routine or to apply the reverse code translation as used during compression.
For a proper operation of FLAM it is indispensable that all changes applied to the compressed data are reversible. User exit EXD20 must deliver exactly the same data as user exit EXK20 received. All modifications applied to compressed data with EXK20 must be undone with EXD20.
EXD20 is available in FLAM, FLAMUP and FLAMREC and corresponds with EXK20 during decompression.
In this user exit, the compressed records are passed to a user module immediately after they are read from the compressed file. This user exit can be used with the FLAM utility or with the subprogram FLAMUP and in the record level interface FLAMREC. This user exit can accept, modify and delete records.
The exit is activated via the parameter EXD20=<user module name>
.
The user exit module must be contained in the library
that has been assigned with the STEPLIB command.
user module name | free choice (max. 8 characters) |
Register usage | |
R1 |
Address of parameter list |
R13 |
Points to save area (18 words) |
R14 |
Contains return address |
R15 |
Contains call address (entry point) |
Parameter list | ||
---|---|---|
1. FUCO | F | Function code |
0 |
First call for file (after OPEN) |
|
4 |
Record passed |
|
8 |
Last call for file (before CLOSE) |
|
2. RETCO | F | Return code |
0 |
Accept record / no error |
|
4 |
Do not accept record |
|
8 |
Insert record |
|
12 |
Enforce end of decompression |
|
16 |
Error in exit; abnormal termination |
|
3. RECPTR | A | Record pointer |
4. RECLEN | F | Record length (maximum 32760) |
5. EXWORK | 256F | During the first call the working storage area contains the symbolic file name of the original file within the first 8 characters. The rest of the area is padded with x00. This area can be used by the user exit module for any purpose. With each call this working storage area is made available again with the old content. If a record shall be extended or inserted, the necessary working storage area must be provided by the user exit module. Return code 12 is only necessary if decompression shall be finished before the end of the compressed file is reached. Because of the necessary synchronisation with the construction of the matrix, this return code is not always possible. For function code 0 and 8, no record is passed to the module. |
Table of valid function codes and return codes:
Function code |
0 |
4 |
8 |
|
Return code |
0 |
x |
x |
x |
4 |
x |
|||
8 |
x |
x |
||
12 |
(x) |
|||
16 |
x |
x |
x |
This user exit returns a key to the FLAM utility for en-/decryption of a FLAMFILE.
So, it is possible to enter any PASWORD/CRYPTOKEY in a secure way without notice to the JCL or the protocol.
This exit is implemented as an interface to special key management systems, without influence to the FLAM utility programs.
This user exit is an interface to a special (e.g. user written) key management system.
On encryption, parameters (KMPARM=...
) are passed to
the module. It returns a key for encryption of the
FLAMFILE and a string of up to 512 bytes. This data is
stored in the FLAMFILE as a user header (see
parameter COMMENT or function FLMPUH).
On decryption, parameters (KMPARM=...
) and the data
stored in the user header are passed to the exit. The
module returns the same key as on encryption.
It is up to the module, how to create a key and what
kind of information is to be stored into the user
header of the FLAMFILE. This data will help the
module to find the correct key on decryption.
The exit is activated via the parameter
KMEXIT=<user module name>
.
The user exit module must be contained in the library
that has been assigned with the STEPLIB command.
user module name | free choice (max. 8 characters) |
Register usage | |
R1 |
Address of parameter list |
R13 |
Points to save area (18 words) |
R14 |
Contains return address |
R15 |
Contains call address (entry point) |
Parameter list | ||
---|---|---|
1. FUCO | F | Function code |
0 |
Decryption |
|
1 |
Encryption |
|
2. RETCO | F | Return code |
0 |
No error |
|
else |
Error(s) detected |
|
3. PARMLEN | F | Length of parameter (up to 256 byte) |
4. PARAM | XLn | Parameter |
5. DATALEN | F | Decryption: |
6. DATA | XLn | PData (in length of DATALEN) |
7. CKYLEN | F | Length of key for en-/decryption |
8. CRYPTOKEY | XLn | Returned key (in length of CKYLEN) |
9. MSGLEN | F | Message length |
10. MESSAGE | CLn | Returned message (in length of MSGLEN) If a message is returned (MSGLEN > 0), it is sent to the protocol (FLM0445 ...). The returned key is not sent to the protocol. The data DATA is stored 'as is' in the user header of the FLAMFILE. If special security is required, it has to be done by the exit. Usage of this exit overwrites the parameter COMMENT and CRYPTOKEY, if any. The exit is called only once if encryption of many files
into a Group-FLAMFILE The exit is called many times for decryption of many
FLAMFILEs In the DD-statement, concatenated FLAMFILEs are treated as one FLAMFILE! Look for an example in FLAM.SRCLIB (KMX-SAMPL). |
During compression, it is possible to call additional routines for pre-processing of original records and for post-processing of compressed records.
E.g., pre-processing may perform a selection of specific records or fields.
Post-processing may introduce additional encryption of the compressed record.
Instead of using the more complicated record level interface record-orientated processing can be done often with user exit EXK10.
During decompression, it is possible to call additional routines for pre-processing of compressed records and for post-processing of original records.
E.g., pre-processing may decrypt encrypted records.
Post-processing may perform a selection of specific records or fields.
Instead of using the more complicated record level interface record-orientated processing can be done often with user exit EXD10.
The user exit for compressed records can also be used under the record level interface.
The actual interception of original records by the interface is not affected.
The user exit for compressed records can also be used under the record level interface.
The actual interception of original records by the interface is not affected.
The following exit routine can be used for compression as well as for decompression and has the purpose of modifying fields within records.
The sample code is found in the library FLAM.SRCLIB.
TITLE 'SEPARATE: EXIT FOR FLAM COMPRESSION' SEPARATE CSECT SEPARATE AMODE ANY SEPARATE RMODE ANY ********************************************************************** * THIS PROGRAM SEPARATES FIELDS WITHIN RECORDS WHICH CAN * BE SEPARATED BY DELIMITER CHARACTERS INTO DIFFERENT FLAM RECORDS. * THIS ENABLES A BETTER COMPRESSION. * THE DESIGN OF THE PROGRAM ALLOWS TO MODIFY THE DELIMITER AND * EVEN THE LENGTH OF THE DELIMITER BY CHANGING ONLY ONE STATEMENT. * * THE DELIMITERS ARE REMOVED FROM THE RECORD AND ARE REPLACED * BY FLAM SYNTAX. * IF THE RECORD DOES NOT CONTAIN DELIMITERS IT IS PASSED TO * FLAM WITHOUT MODIFICATIONS. * * THE ROUTINE SEPARATE IS ACTIVATED VIA PARAMETER 'EXK10=SEPARATE' * DURING THE CALL OF FLAM OR FLAMUP. * * THE FIELDS CONSIST OF PRINTABLE CHARACTERS SEPARATED BY * A TWO BYTE LONG DELIMITER (X'0D25'). * * THE DATA COMPRESSED IN THIS WAY IS TRANSMITTED VIA * FILE TRANSFER TO A PC, DECOMPRESSED FIELD BY FIELD * USING FLAM AND WRITTEN TO THE STORAGE MEDIUM (WITH * DELIMITER OF THE OPERATING SYSTEM, X'0D0A' WITH MSDOS * OR X'0A' WITH UNIX). * * NOTE: * * FOR DECOMPRESSION ON A MAINFRAME A FILE WITH * VARIABLE RECORD LENGTH MUST BE SPECIFIED. * EACH FIELD SEPARATED DURING COMPRESSION IS WRITTEN * AS A SEPARATE RECORD. THE DELIMITERS ARE NOT CONTAINED * IN THE DECOMPRESSED RECORDS. * THIS MEANS THAT THE ORIGINAL FILE CANNOT BE RECONSTRUCTED * ON A MAINFRAME. * * THIS MODULE IS REENTRANT AND REUSABLE * * *--------------------------------------------------------------------- * * AUTHOR: LIMES DATENTECHNIK GMBH * D-61381 FRIEDRICHSDORF/TS. * TEL. 06172-5919-0 * FAX 06172-5919-39 ********************************************************************** * * INTERFACE: R1 POINTS TO PARAMETER LIST * * 0(R1) - A(FUNCTION CODE) * 4(R1) - A(RETURN CODE) * 8(R1) - A(A(RECORD)) RECORD POINTER * 12(R1) - A(RECORD LENGTH) * 16(R1) - A(WORK AREA) NEW WITH FLAM V2.5 * ********************************************************************** EJECT STM R14,R12,12(R13) SAVE REGISTERS LR R12,R15 ENTRY ADDRESS USED AS PROGRAM BASE USING SEPARATE,R12 ASSIGN BASE REGISTER USING WORKAREA,R2 BASE REGISTER WORK AREA LA 15,0 INITIALISE RETURN CODE WITH 0 * L R3,0(,R1) LOAD A(FC) CLC 0(4,R3),FCSATZ PASS RECORD ? BE SATZUEB == YES CLC 0(4,R3),FCOPEN OPEN ? BNE RET == NO * * AT OPEN TIME RESET WORK AREA FIELDS * L R2,16(,R1) A(WORKAREA) MVI FLAG,X'00' RESET FLAGS B RET SATZUEB DS 0H * * RECORD WAS PASSED * L R10,8(,R1) A(A(RECORD)) TO R10 L R4,0(,R10) LOAD A(RECORD) L R11,12(,R1) A(RECORD LENGTH) L R5,0(,R11) LOAD RECORD LENGTH LA R9,0(R5,R4) A(RECORD END) L R2,16(,R1) A(WORK AREA) * TM FLAG,SATZDA RECORD ALREADY PRESENT ? BNO BEGINN == NO TM FLAG,LOESCH DELETE RECORD ? BO LOESATZ == YES * BEGINNA DS 0H RECORD WAS ALREADY PROCESSED L R4,SATZPTR A(FIELD) FROM LAST TIME * BEGINN DS 0H OI FLAG,SATZDA INDICATE RECORD PRESENT LR R7,R4 SAVE A(FIELD BEGIN) LR R6,R9 A(FIELD END) SR R6,R7 - A(FIELD BEGIN) = L'REMAINDER BZ LEERSATZ L'= 0, PASS EMPTY RECORD C R6,LTRENNKZ BNL SUCH L' L'DELIMITER - HAS NO DELIMITER OI FLAG,LOESCH INDICATE DELETE OPERATION FOR NEXT RUN LR R4,R9 A(RECORD END) B SUCHEND SUCH DS 0H LA R8,1 INCREMENT FOR BX INSTRUCTION S R9,LTRENNKZ FOR BX INSTR. SET RECORD END -L' SUCHLOOP DS 0H * * SEARCH STRING IS (DELIMITER) * CLC 0(L'TRENNKZ,R4),TRENNKZ DELIMITER ? BE ISTDA == YES BXLE R4,R8,SUCHLOOP NEXT CHARACTER * OI FLAG,LOESCH INDICATE DELETE OPERATION FOR NEXT RUN LA R4,L'TRENNKZ-1(R4) FIELD IS BIGGER BY L'-1 B SUCHEND * ISTDA DS 0H LA R6,L'TRENNKZ(R4) INCREMENT RECORD POINTER ST R6,SATZPTR SAVE RECORD POINTER SUCHEND DS 0H * * FILL FLAM PARAMETER LIST * SR R4,R7 FIELD LENGTH ST R4,0(R11) IS RECORD LENGTH FLAM ST R7,0(R10) RECORD ADDR FOR FLAM LA R15,8 RETURN CODE: INSERT RECORD * RET DS 0H * * RETURN TO FLAM * L R3,4(,R1) LOAD A(RC) ST R15,0(,R3) PASS RC L R14,12(R13) RESTORE REGISTERS LM R0,R12,20(R13) BR R14 RETURN * LOESATZ DS 0H LA R15,4 RETURN CODE: DELETE RECORD MVI FLAG,X'00' RESET FLAG B RET AND RETURN * LEERSATZ DS 0H AFTER DELIMITER AT RECORD END OI FLAG,LOESCH INDICATE DELETE OPERATION FOR NEXT RUN LA R4,0 RECORD IS EMPTY ST R4,0(R11) RECORD LENGTH FOR FLAM LA R15,8 RETURN CODE: INSERT RECORD B RET AND RETURN * * CONSTANTS AND WORK AREAS * * FCSATZ DC F'4' FUNCTION CODE RECORD PASSED FCOPEN DC F'0' OPEN LTRENNKZ DC A(L'TRENNKZ) LENGTH OF DELIMITER *-------------------------------------------------------------------- * * IN CASE OF DIFFERENT DELIMITER MAKE MODIFICATIONS HERE * TRENNKZ DC XL2'0D25' DELIMITER TO BE FOUND *-------------------------------------------------------------------- * * REGISTER * R0 EQU 0 R1 EQU 1 PARAMETER ADDRESS R2 EQU 2 BASE REGISTER FOR WORK AREA R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 R10 EQU 10 R11 EQU 11 R12 EQU 12 BASE REGISTER R13 EQU 13 A(SAVE AREA) R14 EQU 14 RETURN ADDRESS R15 EQU 15 ENTRY ADDRESS * LTORG * DC C'*** MODULE SEPARATE V1.02 FOR FLAM ' DC C' COPYRIGHT (C) 1990-91 BY LIMES DATENTECHNIK GMBH. ' DC C'DATE, TIME ASSEMBLED: ' DC C'&SYSDATE , &SYSTIME ' DC C'***' * * WORKAREA IS PROVIDED BY FLAM (1024 BYTES) * WORKAREA DSECT * DDNAME DS CL8 DD-NAME OF CURRENT FILE SATZPTR DS A RECORD POINTER FLAG DS X INDICATORS FOR PROCESSING SATZDA EQU 1 RECORD ALREADY PRESENT LOESCH EQU 2 DELETE RECORD END
Since FLAM protects compressed files against manipulations by applying a checksum, it is possible to provide encryptions within the user exits with a very low overhead.
Because the compressed data is already encrypted, simple deterministic character swapping within the compressed data cannot be detected easily by an unauthorized user.
During decompression this character swapping - if not redone by an authorized user - will lead to a check sum error and the compressed file cannot be read.
The symmetric construction of the user exits allows to use the same routine for encryption as well as for decryption provided that algorithms are used that will restore the original data when executed twice. This is the case with mutual character swapping.
Similar results can be obtained with translate tables for cyclic (cycle length 2) character code exchange.
TITLE 'EX20 (B) | VERSION 1.00:06/25/91 | ' *********************************** * COLUMBUS-ASSEMBLER * *********************************** * SYMBOLIC CONDITIONS FOR #IF,#WHEN,#WHIL(E),#TOR,#AND,#OR #LT EQU 4 LESS THAN #GT EQU 2 GREATER THAN #EQ EQU 8 EQUAL #NE EQU 7 NOT EQUAL #LE EQU 13 LESS OR EQUAL #GE EQU 11 GREATER OR EQUAL #LZ EQU 4 LESS THAN ZERO #GZ EQU 2 GREATER THAN ZERO #ZE EQU 8 ZERO #NZ EQU 7 NOT ZERO #ON EQU 1 ONES #MI EQU 4 MIXED #ZO EQU 11 ZEROS OR ONES #ZM EQU 14 ZEROS OR MIXED #OM EQU 7 ONES OR MIXED #F EQU 15 TRUE IN ANY CASE * FLOATING POINT REGISTERS, GENERAL REGISTERS, COLUMBUS REGISTERS FA EQU 0 FB EQU 2 FC EQU 4 FD EQU 6 R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 R10 EQU 10 R11 EQU 11 R12 EQU 12 R13 EQU 13 R14 EQU 14 R15 EQU 15 R#PAR EQU R1 R#BASE EQU R10 R#STACK EQU R13 R#EXIT EQU R14 R#PASS EQU R15 EJECT EX20 CSECT USING EX20,R#PASS *********************************************************************** * NAME: EX20 VERSION: 13.03.91 * * FUNCTION: * * FLAMFILE IS ENCRYPTED AND DECRYPTED IN A SIMPLE WAY. * * * * THE 16TH AND 17TH CHARACTER ARE SWAPPED WHICH * * CHANGES THE CHECKSUM. THE COMPRESSED DATA * * CAN ONLY DECOMPRESSED IF THE SWAP OPERATION * * DONE AGAIN. * * PARAMETER * * 1 -> ID F IDENTIFICATION * * 2 <- RETCO F RETURN CODE * * 3 -> RECPTR A RECORD POINTER * * 4 -> RECLEN F RECORD LENGTH * *********************************************************************** * * SAVE REGISTERS AND LOAD BASE REGISTERS * STM R14,R12,12(R13) * * LOAD PARAMETERS * LM R1,R4,0(R1) * PASS COMPRESSED RECORD CLC 0(4,R1),F4 BC #F-#EQ,#F1001 * LOAD RECORD LENGTH L R4,0(R4) * RECORD LENGTH GREATER 16 LA R14,16 CR R4,R14 BC #F-#GT,#F1002 * * SWAP 16TH AND 17TH CHARACTER * L R3,0(R3) LA R14,0(R3,R14) IC R5,0(R14) MVC 0(1,R14),1(R14) STC R5,1(R14) #F1002 DS 0H #F1001 DS 0H * * RETURN CODE = ACCEPT RECORD / NO ERROR * LA R0,0 ST R0,0(R2) * * RETURN * LM R14,R12,12(R13) BR R#EXIT * * LOCAL CONSTANTS * F4 DC F'4' F16 DC F'16' LTORG DS 0D DROP R#PASS END