PROGRAMMING TIPS AND TECHNIQUES

The information presented in this section should assist the user in achieving maximum utilization of the Monitor system.

USING THE DISK I/O SUBROUTINES

All core loads, whether they use disk I/O or not, require one of the three disk I/O subroutines. As a minimum, this disk subroutine is used to read the core load into core and execute CALL EXIT, CALL LINK, CALL DUMP, and/or CALL PDUMP. Generally, DISKZ is used by FORTRAN core loads and DISK1 or DISKN by Assembler-Language core loads. DISKN provides faster operation than DISK1 for operations involving more than 320 words, as well as the simultaneous operation of disk drives. DISKZ is intended for use only in an error-free environment, because it does no preoperative parameter checking, whereas DISK1 and DISKN do. DISKZ also has a special calling sequence; DISK1 and DISKN have the LIBF calling sequence. Bear in mind that all three disk subroutines are assembled as mainlines and are thus not the same as programs stored in the System Library, even though DISK1 and DISKN (but not DISKZ) may be referenced with the LIBF statement. They are described with library subroutines because they are similar in some respects to library subroutines. Actually, they are neither incorporated into the core load like library subroutines nor are they stored in the System Library.

A switch is set in COMMA to indicate which version of disk I/O is requested on the XEQ record. The setting of this switch is not altered until 1) a Monitor control record is read or 2) a link that is stored in DCI is called. In the first case the switch is set to indicate DISKZ, unless the record was XEQ, in which case the switch is set to indicate whatever version is requested. In the second case the switch is set to indicate the version of disk I/O required by the link. In short, each DSF link except the first in an execution must utilize the same version of disk I/O as the preceding link. The first link must, of course, utilize the disk I/O specified on the XEQ record.

In order to save core in Monitor programs, all of which utilize DISKZ, DISKZ has been pared to a minimum. The following is a list of functions that are not available in DISKZ but are available in DISK1 and/or DISKN.

THE USE OF SOCALs

Restrictions on Subroutines in SOCALs

A rule of prime importance regarding subroutines in the SOCAL scheme is that none must cut across SOCALs. That is, a given subroutine that is in one SOCAL may not call a subroutine that is in another SOCAL or cause another SOCAL to be brought into core before the execution of the given subroutine is completed. This is due to the fact that the IBM-supplied 1130 subroutines that go into the SOCAL scheme are not re-enterable. It should also be noted that disk I/O is used every time a SOCAL is brought into core. This means that disk I/O will sometimes be entered without the user's direct knowledge.

Decreasing Program Execution Time

When writing or modifying a program that is known to require SOCALs, planning is required to minimize the flipping of the various SOCALs in and out of core during execution. Ideally the program should be written in sections, each of which employs a single SOCAL, e.g., input, computation, and output. Even input and output should be carefully planned so as to separate disk and non-disk operations whenever possible.

TIPS ON MONITOR CONTROL

Temporary JOB Mode

In many cases DUP delete functions must be performed to clear the User Area of old programs before newly assembled or compiled programs may be stored. The necessity for such deletions is avoided by using the temporary mode when running jobs that contain programs that are likely to be replaced at a later time. In the Temporary mode all programs stored to the User Area are automatically deleted when the next JOB record is processed. This assures the user that his new program is the one stored in the User Area and is particularly useful while debugging.

EJECT Monitor Control Record

The EJECT record is used to control the beginning of a new page on the principal print device during a job. For example, messages to the operator of the Monitor Comments control record type may be placed in a more readable position if followed by an EJECT record.

Example:

EJECT monitor control record example

SYSUP

Changing cartridges in the middle of a job is permissible; however, great care must be exercised. A system update operation must always be performed. This function is provided by the System Library subroutine SYSUP. The subroutine should be called immediately following the loading of the new cartridge or cartridges as follows:

Use of SYSUP system library routine

The IDs of cartridges to be used must be specified, even those that were previously specified except the master (logical 0), which if unspecified will be the previous master. Continuation of the job must be delayed until all the newly loaded cartridges are ready. Rules governing the specification of cartridges are the same as those for the JOB Monitor control record.

It is also permissible to provide no system cartridge on the system at this time if no further system operations are required, e.g., CALL EXIT, CALL DUMP, or CALL LINK. This is particularly useful to the one drive user.

The FORTRAN calling sequence for SYSUP is described in the section of this manual entitled System Library Utility Subroutines.

MAXIMUM PERFORMANCE OF HIGH SPEED DEVICES

Double Buffering

The 2501 Card Reader model A2, rated at 1000 cards per minute presents a special problem to the programmer who desires maximum performance from his card I/O operations. If any conversion of the card data is required, the reading speed is likely to drop to 500 cards per minute, unless double-buffering is used.

The principle involved, is to read into one buffer while converting and processing the data from another buffer. This scheme does cost core for the extra buffer and additional programming involved, but in most cases it should allow the card throughput for the 2501 to remain at 1000 cards per minute. The coding illustrated below shows the double-buffering technique used for reading cards from the 2501, and converting them to EBCDIC.

Double-buffering example

1403 Conversion Subroutines

Two subroutines are provided with the Monitor system that may be used by Assembler object programs to convert EBCDIC to 1403 Printer Code. These subroutines are EBPRT and ZIPCO.

Using the execution times listed in the Subroutine Library manual, the average time EBPRT requires to convert a 120 character line is 156 ms. This compares with an estimate of 72 ms per line for ZIPCO.

Considering that the available times on the 1403 Printer are

it would be difficult or impossible to run the printer at rated speed, depending on the model, using EBPRT. If overlapped I/O were attempted, it would be impossible to run either model at rated speed.

The assembly language programmer is therefore advised to use ZIPCO for all EBCDIC to 1403 Printer code conversions.

TIPS FOR ASSEMBLER LANGUAGE USERS

Grouping of Mnemonics

Assembler language programs can often be organized in such a manner as to improve the assembly time. The Assembler Program is divided into overlay phases, each phase processing a certain group of mnemonics. By grouping mnemonics of a common type in the source program, fewer disk reads of overlay phases will be required by the Assembler. The following is a list of the mnemonics as they are grouped within the Assembler program:

  1. ABS. FILE, ENT, ISS, ILS, SPR, EPR
  2. DCs arid imperative instructions (A, LD, EOR, BSC, etc.)
  3. DEC and XFLC
  4. DMES
  5. HDNG, ORG, EQU, BSS, BES, LIST, SPACE, EJCT, DUMP, PDMP
  6. LIBF, CALL, DSA, LINK, EXIT, EBC, DN

Each time a mnemonic is encountered during the assembly process, the overlay phase required to process it will be read into core, unless it is already residing in core.

Intermediate I/O

As the source records are read and processed by the Assembler in Pass 1, each statement is packed and saved on the disk in Working Storage. The part of the record that is saved is from column 21 to the last nonblank column. If no listing is specified, comments records are not saved on the disk. Each record saved on the disk is preceded by a prefix word that contains the length of the associated record plus one. Up to sixteen 38-column records are saved on one sector.

WRITING ISS AND ILS

Interrupt Service Subroutines

The following rules must be adhered to when writing an ISS:

Table 4. ISS/ILS Correspondence
ISS
Number
Device Device Interrupt
Level Assignments
n
1 1442 Card Reader Punch 0, 4 +4, +7
2 Input Keyboard/Console Printer 4 +4
3 1134/1055 Paper Tape Reader/Punch 4 +4
4 Disk Storage 2 +4
6 1132 Printer 1 +4
7 1627 Plotter 3 +4
8 Synchronous Communications Adopter 1 +4
9 1403 Printer 4 +4
10 1231 Optical Mark Page Reader 4 +4

Interrupt Level Subroutines

An ILS is included in a core load only if requested by an ISS that is a part of the same core load. ILS02 and ILS04 are a part of the Resident Monitor unless they are deleted from the System Library and replaced with userwritten subroutines. The following rules must be adhered to when writing an ILS.

Word Corresponding To  
ILSW Bit 15
ILSW Bit 14
.
.
.
ILSW Bit 0
Image of a long curly brace grouping the left-most column ISS Branch Table

The ISS branch table identifies both the ISS subroutine and the point within the ISS which should be entered for each bit used in the ILSW. The actual linkage is generated by the Core Load Builder. Basic to this generation is the ISS number implied by bits 8-15 of the branch table word and specified in the ISS statement. This number identifies a core location in which the Core Load Builder has stored the address of the called entry point in the ISS. This entry point address is incremented by the value in bits 0-7 of the branch table word, producing the interrupt entry point address. The Core Load Builder replaces the ISS branch table word with the interrupt entry point address. During execution, each address in the branch table may be used with an indirect branch and store I (BSI) instruction to reach the ISS corresponding to that ILSW bit position. The ILSW bit that is ON can be determined by the execution of a SLCA instruction. At the completion of this instruction, the index register specified contains a relative value equivalent to the bit position in the ISS branch table. An indirect, indexed BSI may then be used to reach the appropriate ILS. Before processing by the Core Load Builder, each word in the ISS branch table has the following format:

Bits 0-7 -- Increment added to the entry point named in the ISS statement to obtain the interrupt entry point in the ISS for this ILSW bit. (In IBM-written ISS subroutines, this increment is +4 for the primary interrupt level and +7 for the second interrupt level.)

Bits 8-15 -- @ISTV+ the ISS number for the ISS subroutine for this ILSW bit.

READING A CORE MAP AND A FILE MAP

The core maps described below are taken from the sample programs supplied with the Monitor system. (The sample program listings and operating instructions are printed in Appendix J.)

The core map for the Assembler-language sample program indicates that there were /7904 words of core storage not occupied by the core load (R41 is an informational message, not an error message). There was only one CALL (FSQR), but there were several LIBFs, e.g., FARC. The ILS02 and ILS04 subroutines are required; however, their addresses indicate that they are a part of the Resident Monitor and not in the core load proper. The entry point to the mainline program is /01FE.

The principal difference in the core map printed for the FORTRAN-language sample program is that it includes a file map. The file defined as file number 103 has been equated to a data file named FILEA, which begins at sector /01AE, is one sector in length, and is stored on a cartridge labeled 000F.

If file 103 had required more than the two sectors available in FILEA, the record count would have been reduced to make the file fit in FILEA, and the file map entry would have been

    103 01AE 0002 000F FILEA TRUNCATED

The files defined as 101 and 102 are files in Working Storage because they do not appear in the *FILES record. This can be determined by looking at the rightmost entry in the file map. For files defined in the User/Fixed Area, for example, FILEA, this entry is the name of the file; otherwise, it is the address of Working Storage.

The second entry for a User/Fixed Area file is the absolute sector address of the first sector of the file. For files in Working Storage, this address is relative to the first sector of Working Storage. Thus, the absolute sector address of the first sector of file 101 is /0000 + /01B0; for file 102 it is /0001 + /01B0.

Note that the 4K example requires both LOCALs and SOCALs. The LOCALs were, of course, requested by the user, and the core map entries for the LOCAL subroutines (FLOAT, FARC, and IFIX) have been flagged. The presence of SOCALs, which were selected and constructed by the Core Load Builder, are also indicated by flags on the core map entries for the subroutines included in the various SOCALs. The number following the word "SOCAL" indicates in which of the SOCALs a particular subroutine is to be found. In this case SOCAL Option 2 was employed. This can be deduced from the fact that there are three SOCALs. Option 1 consists of only two.

Several other facts about the 4K core load can be extracted from the core map. For one thing, the core load exceeds the capacity of core storage (before SOCALizing) by /03AB words (message R40). Furthermore messages R43, R44, and R45 indicate that SOCALs 1, 2, and 3 require /0124, /06AC, and /02A2 words of core, respectively. This information indicates that, for example, since SOCAL 2 is much larger than SOCAL 1, more arithmetic and function subprograms may be called at little extra cost in core. (It would be necessary to reduce the dimension of the variable B to realize this.) Message R41 says that, after SOCALizing, there are only /0004 words of core that are not used by this core load.


Assembler Core Map

// XEQ       L
R 41  7904 (HEX) WDS UNUSED BY CORE LOAD
CALL TRANSFER VECTOR
 FSQR   0248
LIBF TRANSFER VECTOR
 FARC   069E
 XMDS   0682
 HOLL   0632
 PRTY   05E2
 EBPA   0592
 FADD   04E1
 FDIV   0540
 FLO    048C
 FADDX  04E7
 FMPYX  04A2
 FSTO   0470
 FGETP  0456
 NORM   042C
 TYPE0  0312
 EBPRT  02AC
 IFIX   0280
 FLOAT  0230
SYSTEM SUBROUTINES
 ILS04  00C4
 ILS02  0083
      01FE (HEX) IS THE EXECUTION ADDR

FORTRAN Sample 4K Core and File Map

// XEO       L  2
*LOCAL,FLOAT,FARC,IFIX
*FILES(103,FILEA)
FILES ALLOCATION
  103 01AE  0001  000F FILEA
  101 0000  0001  000F  01B0
  102 0001  0001  000F  01B0
STORAGE ALLOCATION
R 40  03AB (HEX) ADDITIONAL CORE REOUIRD
R 43  0124 (HEX) ARITH/FUNC SOCAL WD CNT
R 44  06AC (HEX) FI/O, I/O SOCAL WD CNT
R 45  02A2 (HEX) DISK FI/O SOCAL WD CNT
R 41  0004 (HEX) WDS UNUSED BY CORE LOAD
LIBF TRANSFER VECTOR
 EBCTB  0F53 SOCAL 2
 HOLTB  0F17 SOCAL 2
 GETAD  0ED4 SOCAL 2
 XMDS   09B2 SOCAL 1
 HOLEZ  0E9E SOCAL 2
 NORM   07DC
 FADDX  095D SOCAL 1
 FSBRX  0934 SOCAL 1
 FMPYX  0900 SOCAL 1
 FDIV   08AE SOCAL 1
 FSTOX  0788
 FLDX   07A4
 SDCOM  0920 SOCAL 3
 SDFX   08E6 SOCAL 3
 SDWRT  0954 SOCAL 3
 SIOFX  099A SOCAL 2
 SUBSC  07BE
 SIOI   099E SOCAL 2
 SCOMP	0982 SOCAL 2
 SWRT   08AB SOCAL 2
 SRED   08B0 SOCAL 2
 FSTO   07BC
 FLD    07A8
 PRNTZ  0DE0 SOCAL 2
 CARDZ  0036 SOCAL 2
 SFIO   09AD SOCAL 2
 SDFIO  0959 SOCAL 3
 IFIX   087C LOCAL
 FARC   087C LOCAL
 FLOAT  087C LOCAL
SYSTEM SUBROUTINES
 ILS04  00C4
 ILS02  00B3
 ILS01  0F5A
 ILS00  0F75
 FLIPR  0816
      04DD (HEX) IS THE EXECUTION ADDR

FORTRAN Sample 8K Core and File Map

// XEQ       L  1
*FILES(103.FILEA)
FILES ALLOCATION
  103 01AE  0001  000F FILEA
  101 0000  0001  000F  01B0
  102 0001  0001  000F  01B0
STORAGE ALLOCATION
R 41  0C9C (HEX) WDS UNUSED BY CORE LOAD
LIBF TRANSFER VECTOR
 EBCTB  12CD
 HOLTB  1291
 GETAD  124E
 NORM   1224
 XMDS   1208
 FARC   11E6
 HOLEZ  11B0
 FLOAT  11A6
 IFIX   117A
 FADDX  1125
 FSBRX  10FC
 FMPYX  10C8
 FDIV   1076
 FSTOX  101E
 FLDX   103A
 SDCOM  07FE
 SDFX   07C4
 SDWRT  0832
 SIOFX  0B1A
 SUBSC  1054
 SIOI   0B1E
 SCOMP  0B02
 SWRT   0A2B
 SRED   0A30
 FSTO   1022
 FLD    103E
 PRNTZ  0F60
 CARDZ  0EB6
 SFIO   0B2D
 SDFIO  0837
SYSTEM SUBROUTINES
 ILS04  00C4
 ILS02  00B3
 ILS01  12D2
 ILS00  12ED
      04DD (HEX) IS THE EXECUTION ADDR

LOCATING FORTRAN ALLOCATION ADDRESSES

The variable allocations listed below are taken from the FORTRAN sample program in Appendix J.

VARIABLE ALLOCATIONS
     A(R )=00DC-0016     X(R )=00F0-00DE     B(R )=0208-00F2
    V3(I )=020E          M(I )=020F          L(I )=0210
    L2(I 1=0214         N1(I )=0215         N2(I )=0216
     K(I )=021A         IK(I )=0218         I1(1 )=021C



     D(R )=020A         V1(I )=020C         V2(I )=020D
    M1(I 1=0211         M2(I )=0212         L1(I )=0213
     N(I )=0217          I(I )=0218          J(I )=0219
 

The variable array A is to be found between core locations /00DC + /001E + $ZEND and /0016 + /001E + $ZEND, inclusive. That is, A1 is at /00DC + /001E + $ZEND, A2 at /00DB + /001E + $ZEND, etc. The /001E term is the length of the Core Image Header and $ZEND is the address of the first core location following DISKZ.

The other allocation addresses, e. g., statement allocation, may be calculated in a similar manner.

INITIALIZING $$$$$ DATA FILES FOR USE WITH FORTRAN UNFORMATTED I/O

The user must define a Data File with the name prior to executing a FORTRAN mainline program or subroutine that uses unformatted I/O. This Data File must be located in the Fixed Area. One file may be defined in the Fixed Area of each cartridge on the system; however, only one $$$$$ file may be referenced in any one job.

The following example shows a $$$$$ file being defined on a satellite cartridge.

After the file is defined, program ML1 which uses unformatted I/O can be executed. Note that no *FILES card is required at execution time to define the $$$$$ file.

*DEFINE FILE example

USE OF DEFINED FILES

When an *FILES Supervisor control record is used following a // XEQ Monitor control record, or a *STORECI control record, the Core Load Builder attempts to locate the file name by searching LET or FLET. If the name is found, the sector address of this Data File is inserted in the file table (created as a result of the FORTRAN DEFINE FILE statement or the Assembler FILE mnemonic) identified by the file number specified on the *FILES record. If the file name is not found in LET or FLET, the Core Load Builder causes this file to be a Working Storage file. A suggested way of initially allocating a disk area for a Data File is to perform a *STOREDATA DUP operation from Working Storage to the User or Fixed Area. The number of sectors stored should be determined on the basis of the number of records the file is to contain, and the size of each record. Note that records do not continue across sector boundaries. Once the number of sectors required has been determined, this number of sectors should be specified on the *STOREDATA control record, provided the User Area or Fixed Area is large enough to contain this file.

DUPLICATE PROGRAM AND DATA FILE NAMES

On a multi-drive system, it is possible to have more than one program or data file with the same name. This can cause problems when attempting to execute or delete the named program.

Example:
Example of an ambiguous case, with multiple files with the same name on different disks

This sequence of instructions will cause PROG1 on the cartridge labeled 1111 to be executed when PROG1 on 2222 may have been desired. A similar problem can occur on a DELETE operation.
Example of an ambiguous DUP *DELETE operation
would delete the program on 1111, not the one on 2222.

The answer to this problem is to avoid having two programs or data files with the same name. If a strange cartridge is on line and it is not needed for the job, disable it.

NAME CONFLICTS

In STORE and DELETE operations, care should be taken to avoid name conflict with IBM-supplied programs. If the program to be stored or deleted carries the same name as an IBM program, the system may execute the operation on the wrong program.

RESTORING DESTROYED CHARACTERS

Cartridges that contain data and/or programs in the User Area or Fixed Area, and which may be difficult to replace, can sometimes be restored to use after being rendered unusable. If only sector addresses are affected, DCIP may be used to initialize sector addresses only. (See p. 87 for operating procedure.)

If some part of the Monitor System has been destroyed (including LET, FLET, User Area and Fixed Area) a reload function may be performed with the System Loader. In this case, the entire Monitor System deck, except the System Library, should be processed by the System Loader.

MAINLINE PROGRAMS THAT USE ALL OF CORE

Before writing a program that occupies all or nearly all of core, the user should weigh the advantage gained against the possible later rewriting required if IBM-supplied subroutines used by the core load are expanded due to modification.

TIPS FOR FORTRAN LANGUAGE USERS

It is strongly recommended that the use of the 1130 device code be avoided in READ and WRITE statements, the use of integer variables in such cases allows for easier modification.

CONNECTING FROM VERSION 1 TO VERSION 2



But wait, there's MORE...

Valid HTML 4.01 Transitional