.PS 59,79 .LM 5 .RM 75 .Enable BOlding .fl bold ~ .fl substitute .ts 10,15,20,25,30,35,40,45,50,55,60,65,70,75 .C ;INTRODUCTION TO .C ;^&^~TAPESUBS\&\~ .s 1 .c ;Foreign Magnetic Tape Input/Output routines .s 1 .indent 5 TAPESUBS is a package of foreign tape handling subroutines which are designed to aid the VAX user with handling foreign (i.e. not VAX labeled) magnetic tape functions from a program. The functions of reading and writing tape blocks, rewind, and unload are included. These subroutines also perform error correcting and reading or writing in reverse if desired. All of the subroutines are callable from FORTRAN or any other high level language which uses the "standard" VAX calling procedure. .S 1 .INDENT 5 The programs in the package are listed below along with a brief explanation of their function. .S 1 .C ;^~SETUPFT (LUN,CDEV,ISTAT)\~ .indent 2 Does necessary initialization and "housekeeping" functions prior to starting tape processing. It must be called before using any of the other TAPESUBS routines. .s 1 .c ;^~CLOSEFT (LUN,ISTAT)\~ .indent 2 Does the appropriate CLOSE and DEASSIGN of the VMS I/O channel. This undoes any links done by SETUPFT. .s 1 .c ;^~RITAPE (LUN,BUFF,NBYTE,IBYTE,ISTAT[,MODIF])\~ .c ;^~RCTAPE (LUN,BUFF,NBYTE,IBYTE,ISTAT[,MODIF])\~ .indent 5 Read a magnetic tape block (physical record) to an integer (byte) array (RITAPE) or to a character variable (RCTAPE). .s 1 .c ;^~WITAPE (LUN,BUFF,NBYTE,IBYTE,ISTAT[,MODIF])\~ .c ;^~WCTAPE (LUN,BUFF,NBYTE,IBYTE,ISTAT[,MODIF])\~ .indent 5 Write an integer (byte) array (WITAPE) or a character variable (WCTAPE), to a magnetic tape block (physical record). .s 1 .c ;^~REWTAPE (LUN,ISTAT[,NOWAIT])\~ .c ;^~UNLOAD# (LUN,ISTAT[,NOWAIT])\~ .indent 5 Rewind a tape (REWTAPE) or rewind and unload a tape (UNLOAD). .s 1 .c ;^~SKIPREC (LUN,NUMB,NSKIP,ISTAT)\~ .indent 5 Skips magnetic tape records in both the forward and reverse directions. .s 1 .c ;^~SKIPFILE (LUN,NUMB,NSKIP,ISTAT)\~ .c ;^~SKIPFILE__VAX (LUN,NUMB,NSKIP,ISTAT)\~ .indent 5 Skip magnetic tape files in both the forward and reverse direction. SKIPFILE emulates the skip function on the SIGMA-7, SKIPFILE__VAX does a normal VAX skip. .s 1 .c ;^~DBLEOF (LUN,NSKIP,ISTAT)\^ .indent 5 Find the first End-of-Volume mark. .s 1 .c ;^~TAPE__EOF (LUN,ISTAT)\~ .indent 5 Writes an end-of-file (EOF) mark written twice to provide a logical end to the tape and then the tape is backspaced to position between the two EOF marks. .s 2 .indent 5 TAPESUBS is Linked by using the following DCL command: .s 1 .c ;_$^&LINK object,[object,...,object]TAPE_$SUBS/LIB\& .pg .c ;^~SETUPFT\~ .s 1 .indent 5 This routine will do necessary initialization and "housekeeping" functions prior to starting foreign tape processing with the foreign tape subroutines. It will establish the link between the user's logical unit number and the desired tape device. SETUPFT builds a logical name if none is supplied by the user and then translates the logical name until the physical device name is found. Once it has the device name, SETUPFT checks to be sure the logical unit number is within limits and has not been used previously. The I/O channel is assigned next and then the device type is checked to be sure that it is a magnetic tape unit and that it is mounted foreign. SETUPFT maintains an internal table of logical unit assignments. It is important to remember that the logical unit numbers used in TAPESUBS are not the same as logical unit numbers in FORTRAN. .s 1 .c ;^~CALL SETUPFT (LUN,CDEV,ISTAT)\^ .s 1 .indent 5 The arguments for these calls are: .s 1 .lm 15 .indent -10 LUN An integer variable which contains the logical unit number for the tape device. This number must be greater than zero (0) and less than or equal to 99 (0 0 for a forward (positive) skip. .s 1 .indent -10 NSKIP An integer variable into which the subroutine will put the actual number of files skipped. This is an unsigned value and does not indicate the direction actually skipped. .s 1 .indent -10 ISTAT An integer variable into which the subroutine will put the status of the skip function. On return this variable will contain the translated value of the status returned from the _$QIOW system service. .s 1 .lm 5 .indent 5 SKIPFILE is most useful for positioning a tape prior to adding more data to a file or more files to a tape. In the forward direction, the tape will be positioned after the last tape mark skipped (at the beginning of the next file). In the reverse direction, the tape will be positioned at the beginning of the last file skipped. For examples of the tape positioning, see the illustrations below. This entry will skip the number of files specified by NUMB and will skip over double end-of-file marks. SKIPFILE will be terminated in the forward direction only by skipping the desired number of files and will not be stopped by the end-of tape mark. In the reverse direction, the skip will be terminated by either the number of files skipped or by the beginning-of-tape mark. .s 1 .indent 5 A value of 0 (zero) for the argument NUMB will cause the tape to be positioned at the end of the current file. The SKIPREC routine is called to perform this skip and it will skip up to 32767 blocks in the positive direction to position the tape at the end of the file. Any file with greater than 32767 blocks will not be skipped properly. .s 1 .indent 5 Examples of SKIPFILE use - in all examples, the tape moves from location marked by "_*" to location marked by "_$". .s 1 .nj .nf file _# 1 2 3 4 +---------+---------+---------+---------+ | | _* _$| | | +---------+---------+---------+---------+ CALL SKIPFILE (LUN,0,NSKIP,ISTAT) returned: NSKIP = 0 ISTAT = 1 .s 1 file _# 1 2 3 4 +---------+---------+---------+---------+ | |_$ | | _* | +---------+---------+---------+---------+ CALL SKIPFILE (LUN,-2,NSKIP,ISTAT) returned: NSKIP = 2 ISTAT = 1 .s 1 file _# 1 2 3 4 +---------+---------+---------+---------+ | _* | |_$ | | +---------+---------+---------+---------+ CALL SKIPFILE (LUN,+2,NSKIP,ISTAT) returned: NSKIP = 2 ISTAT = 1 .s 1 file _# 1 2 3 4 5 6 7 8 9 +-------+----+---++-------+---++-------+------+ | | _* | || | ||_$ | | +-------+----+---++-------+---++-------+------+ CALL SKIPFILE (LUN,6,NSKIP,ISTAT) returned: NSKIP = 6 ISTAT = 1 .j .f .pg .c ;^~DBLEOF\~ .s 1 .indent 5 This entry allows the calling routine to locate the first end-of-volume mark (double end-of-file) and position between the two EOF marks. This is an easy way to position the tape for adding more files to the end of the tape. The calling sequence for FORTRAN is: .s 1 .c ;^~CALL DBLEOF (LUN,NSKIP,ISTAT)\~ .s 1 .lm 15 .indent -10 The arguments for these calls are: .s 1 .indent -10 LUN An integer variable which contains the logical unit number of the tape device. .s 1 .indent -10 NSKIP An integer variable into which the subroutine will put the actual number of files skipped. This is an unsigned value and does not indicate the direction actually skipped. .s 1 .indent -10 ISTAT An integer variable into which the subroutine will put the status of the skip function. On return this variable will contain the translated value of the status returned from the _$QIOW system service. .s 1 .lm 5 .indent 5 DBLEOF always skips in a forward direction until the first end-of- volume mark is found. If there are multiple end-of-volume marks on the tape, only the first is found. DBLEOF will skip a maximum of 32767 files to find the end-of-volume any tape with more than 32767 files will not be positioned correctly. See example below for tape positioning with DBLEOF. .s 1 .indent 5 Examples of DBLEOF use - in this example, the tape moves from location marked by "_*" to location marked by "_$". .nj .nf .s 1 file _# 1 2 3 4 5 6 7 8 9 +-------+----+---+-+-------+---++-------+-----+ | | _* | |_$| | || | | +-------+----+---+-+-------+---++-------+-----+ EOV EOV CALL DBLEOF (LUN,NSKIP,ISTAT) returned: NSKIP = 2 ending location ISTAT = 1 is at the EOV between files _#3 _& _#5. .j .f .pg .c ;^~SKIPFILE__VAX\~ .s 1 .indent 5 This entry point allows a calling routine to skip files in the standard VAX skip mode. The calling sequence for FORTRAN is: .s 1 .c ;^~CALL SKIPFILE__VAX (LUN,NUMB,NSKIP,ISTAT)\~ .s 1 .lm 15 .indent -10 The arguments for these calls are: .s 1 .indent -10 LUN An integer variable which contains the logical unit number of the tape device. .s 1 .indent -10 NUMB An integer variable which contains the number of files to be skipped. This number may be < 0 for a reverse (negative) skip, = 0 for no position change, or > 0 for a forward (positive) skip. .s 1 .indent -10 NSKIP An integer variable into which the subroutine will put the actual number of files skipped. This is an unsigned value and does not indicate the direction actually skipped. .s 1 .indent -10 ISTAT An integer variable into which the subroutine will put the status of the skip function. On return this variable will contain the translated value of the status returned from the _$QIOW system service. .lm 5 .s 1 .indent 5 SKIPFILE__VAX performs the standard VAX skip and positions the tape following the end-of-file mark in the forward skip and before the end-of-file mark in the reverse skip (compare with SKIPFILE). For examples, see the illustration below. This skip will be terminated in the forward direction by the number of files being skipped or the end-of-volume, which ever is first. In the reverse direction, the skip will be terminated by the number of files or the beginning-of-tape mark. .s 1 .indent 5 Examples of SKIPFILE__VAX use : In all examples, the tape moves from location marked by "_*" to location marked by "_$". .nj .nf .s 1 file _# 1 2 3 4 +---------+---------+---------+---------+ | | _* | | | +---------+---------+---------+---------+ CALL SKIPFILE (LUN,0,NSKIP,ISTAT) returned: NSKIP = 0 results in no ISTAT = 1 change in location. .s 1 file _# 1 2 3 4 5 +---------+--------+---------+----------+---------+ | | _* | | |_$ | +---------+--------+---------+----------+---------+ CALL SKIPFILE__VAX (LUN,3,NSKIP,ISTAT) returned: NSKIP = 3 ISTAT = 1 .pg file _# 1 2 3 4 5 +---------+---------+---------+---------+---------+ | _$| | | _* | | +---------+---------+---------+---------+---------+ CALL SKIPFILE__VAX (LUN,-3,NSKIP,ISTAT) returned: NSKIP = 3 ISTAT = 1 .s 1 file _# 1 2 3 4 5 6 7 8 9 +-------+----+---+-+------+---++--------+------+ | _* | | |_$| | || | | +-------+----+---+-+------+---++-------+------+ EOV EOV CALL SKIPFILE (LUN,6,NSKIP,ISTAT) returned: NSKIP = 3 ending location ISTAT = 4 is at EOV between files _#3 _& _#5 .s 1 .j .f .indent 5 The SETUPFT routine must be called at least once prior to calling any of the skip routines to establish the link between the logical unit number and the magnetic tape device. The skip entry points have different functions and will leave the tape positioned in different locations as described above. On the VAX, no skip file functions will be terminated by the end-of-tape foil so it is up to the calling program to be sure that the tape is not wound off the reel. .s 1 .indent 5 The normal status returned from the file skipping routines is one (1). Errors which occur during the skip are checked to see if they are potentially recoverable. Those which may be recoverable are translated to error codes which make ISTAT useful as the parameter of a FORTRAN computed GO TO statement. .lm 20 .rm 65 .s 1 .indent -5 The error values are: .s 1 .indent -5 1 = Normal successful completion. .indent -5 2 = End-of-file found - not applicable to skipping files. .indent -5 3 = End-of-tape found - not returned by device driver. .indent -5 4 = End-of-volume found - this error is handled internally by the skip routines and is not returned to the calling program. .indent -5 5 = Datacheck - not normally returned on skip. .indent -5 6 = Parity - not normally returned on skip. .indent -5 7 = Data overrun - not normally returned on skip. .indent -5 9 = Beginning-of-tape found - The beginning of tape marker was found. This will be returned if the drive is a low density (TU45, TU77, TS11) tape drive. If the tape is on one of the high density tape drives (TU78) the indicator is not returned due to a "bug" in the tape driver. When the driver is fixed, the BOT should be returned correctly. .indent -6 10 = Position unknown - This is returned if the skip was in reverse direction, no files were actually skipped, and the tape drive is a TU78. The implication is that the tape is at the beginning-of-tape; however, due to an error in the driver, this can not be verified. .lm 5 .rm 75 .s 1 .indent 5 Values which are not included here are considered to be fatal (drive failure, drive write-locked, device off-line,...) and are not handled by the foreign tape subroutines. .pg .c ;^~TAPE__EOF\~ .s 1 .indent 5 This subroutine writes an EOF to a magnetic tape with an extended inter-record gap. Two EOF's are written to provide a logical end to the tape. The EOF parameters are established and the subroutine loops through a call the _$QIOW system service to write the EOF's. After the second EOF, the subroutine backspaces one of the EOF's to position the tape head between the two EOF's. Following the skips, the subroutine checks for errors and, if found, calls a subroutine to convert the error codes to a form which is more suitable to FORTRAN processing. .s 1 .indent 5 The TAPE__EOF subroutine allows the calling routine to end a file on the tape. It also puts a second EOF mark to provide an end-of-volume mark and logically end the tape. The calling sequence for FORTRAN is: .s 1 .c ;^~CALL TAPE__EOF (LUN,ISTAT)\~ .s 1 .lm 15 .indent -10 The arguments for this call are: .s 1 .indent -10 LUN An integer containing the logical unit number for the tape unit. .s 1 .indent -10 ISTAT An integer variable into which TAPE__EOF will put the status of the EOF function. On return this variable will contain the translated value of the status returned from the _$QIOW system service. .lm 5 .s 1 .indent 5 The SETUPFT routine must be called at least once prior to calling the EOF routine to establish the link between the logical unit number and the magnetic tape device. .s 1 .indent 5 The normal status returned from the EOF routine is one (1). Errors which occur during the EOF function are checked to see if they are potentially recoverable. Those which may be recoverable are translated to error codes which make ISTAT useful as the parameter of a FORTRAN computed GO TO statement. .lm 20 .rm 65 .s 1 .indent -5 The error values are: .s 1 .indent -5 1 = Normal successful completion. .indent -5 2 = End-of-file found - not applicable to writing an end-of-file. .indent -5 3 = End-of-tape found - indicates that the tape has advanced beyond the end-of-tape foil and it should not be advanced any further. The tape should be rewound and another tape used if there is more data. .indent -5 4 = End-of-volume found - not applicable to writing an end-of-file. .indent -5 5 = Datacheck - indicates that a write error has occurred. The calling program may wish to try the end-of-file again or possibly try another tape. .indent -5 6 = Parity - not applicable to writing an end-of-file. .indent -5 7 = Data overrun - not applicable to writing an end-of-file. .indent -5 9 = Beginning-of-tape found - not applicable to writing an end-of-file. .indent -6 10 = Position unknown - not applicable to writing an end-of-file. .rm 75 .lm 5 .s 1 .indent 5 Values which are not included here are considered to be fatal (drive failure, drive write-locked, device off-line,...) and are not handled by the foreign tape subroutines.