TREAD/TWRITE SUBROUTINES TREAD/TWRITE SUBROUTINES REFERENCE GUIDE VERSION 3.02 AUTHOR: FRANK J. MANION CHI COMPUTER HORIZONS INC. 1050 KINGS HIGHWAY NORTH CHERRY HILL, N.J. 08034 (609)-779-0911 THIS SOFTWARE IS IN THE PUBLIC DOMAIN TREAD/TWRITE SUBROUTINES PAGE 2 INTRODUCTION INTRODUCTION The TREAD/TWRITE subroutine system for magnetic tape allows users to easily read and write IBM compatible magnetic tapes at 800 or 1600 BPI. The tapes to be read or written may contain data in any size of fixed length records. The logical records may be blocked, (i.e. several logical records make up one physical record) or unblocked (i.e. a logical and a physical record are one and the same). Input tapes can be properly read if they contain IBM standard labels, non-standard labels, ANSI standard labels, leading tapemarks, or no labels. Output tapes can be written with IBM standard OS/VS labels or no labels. Translation from EBCDIC to ASCII on input, or from ASCII to EBCDIC on output is available to the user as an option (Data must be character data for this option to work properly). Multiple reel input and output is supported. Input and output tapes may contain more than one data file. The subroutines are user friendly in that they relieve the user of most of the burden of error handling. The routines also include ex- tensive runtime diagnostic messages. All the routines in the package use QIO requests to perform I/O op- erations, thus bypassing the MTAACP. When using the subroutines, tapes should be logically unmounted if your operating system is RSX-11M, or logically mounted with foreign characteristics if you are running under RSX-11D or IAS. Bypassing the MTAACP allows for greater speed and more flexibility in I/O operations. An industry standard ten inch reel of tape at 800 BPI, containing fixed length logical records 100 bytes long, in physi- cal blocks 6000 bytes long can be read or written in approximately 12 minutes at 45 ips with these routines. TREAD/TWRITE SUBROUTINES PAGE 3 INTRODUCTION NOTES ON USE The TREAD/TWRITE routines are easy to use. To use them the user places an initialization call in his program. This call contains, am- oung other things, a logical unit number, a byte array big enough to hold one logical record, and an integer end-of-file variable. The user then places a call to the appropriate input or output subroutine where he would normally place a read or write statement. After each call to the input subroutine TREAD, the user usually tests the end-of-file variable. If this variable is equal to one (1) then the end of the file has been reached. If the variable is not equal to one, the user will find new data from the input file in the logical record array. If a write is to be done, the user first places data into the logical record array and then calls the output subroutine TWRITE. If the user wishes to close a file before the end of the pro- gram, he issues a call to the appropriate close subroutine. The data read or written on tape may be either binary or character data. Fields of binary data are easily accessed by equivalencing a variable to the logical record array. Character data may be accessed with an ENCODE or DECODE statment. All I/O errors are handled within the subroutines themselves, thus relieving the user of that burden. In general, input errors such as bad block length, parity errors, etc. are reported to the user at his terminal and the block in question is skipped. Serious output errors usually result in the halting of the program since most output errors are under the users control. In summary, the TREAD/TWRITE subroutines operate much like the file handling capabilities of FORTRAN. The major difference is that appro- priate subroutine calls replace the OPEN, READ, WRITE, and CLOSE statements. TREAD/TWRITE SUBROUTINES PAGE 4 INITIALIZATION ROUTINES I. INITIALIZATION ROUTINES TRINIT AND TWINIT Before using a file on magnetic tape, the file must be opened. This is accomplished by calling TRINIT if the file is to be used for input, or TWINIT if the file is to be opened for output. When either routine is called, the user is prompted at his or her terminal to enter the standard mnemonic for the tape device to be used. The form of the call is given below. Please note that all argu- ments after the sixth argument, "EOF", are optional and may be either missing or null. Arguments one through six must always be specified. All arguments should be of type INTEGER*2 (one word integers) unless otherwise noted. CALL TRINIT(LUN,BUF,BLEN,RECORD,RLEN,EOF, TRANSLATE,DENSITY,FILENO,LABELS, REREAD,EVENTFLG,FILENAME,FNLEN) OR CALL TWINIT(LUN,BUF,BLEN,RECORD,RLEN,EOF, TRANSLATE,DENSITY,FILENO,LABELS, REREAD,EVENTFLG,FILENAME,FNLEN) WHERE: LUN = Logical Unit Number. The logical unit number specified in the call may be any valid FORTRAN logical unit number. The only restrication is that the logical unit number is not already in use. BUF = The input or output buffer. This area is supplied by the user. BUF must be a byte array which is at least the size (in bytes) of the physical blocks to be read or written. EACH OPEN UNIT REQUIRES A UNIQUE BUFFER. BLEN = The length in bytes of the input or output block on magnetic tape (The buffer "BUF" must be at least BLEN bytes long). If BLEN is specified as a negative value then "BUF" is assumed to be a simple integer containing the address of the actual buffer to be used. In this case the length of the buffer is considered to be the absolute value of BLEN. This option allows the user to supply the address of a buffer created dynamically at run time. Note that the user must create the required storage area himself, the rou- tines do not do this automatically. RECORD = The logical record. This area should be a byte array at least the size (in bytes) of the logical record to be read or written. The area is supplied by the user. TREAD/TWRITE SUBROUTINES PAGE 5 INITIALIZATION ROUTINES RLEN = The length in bytes of the logical record. "RECORD" must be at least RLEN bytes in length. If RLEN is specified as a negative value, then "RECORD" is assumed to be a simple integer contain- ing the address of the actual logical record to be used. The lenth of this record is considered to be the absolute value of RLEN. This option allows the user to supply a dynamically created record buffer. Note that the user must create the required storage area himself, the routines do not do this automati- cally. EOF = An integer variable which will receive a value indicating the result of an I/O operation. The primary use of this variable is to test for end of file on input. EOF is explained in more detail in the following sections. TRANSLATE = An integer variable indicating whether of not translation is to occur on input or output. If se- lected on input, data is translated from EBCDIC to ASCII. If selected on output, data is translated from ASCII to EBCDIC. If TRANSLATE is non-zero, translation will occur. The defult value is zero, for no translation. DENSITY = An integer variable indicating the density of the input or output data. Set to 1600 to indicate 1600 BPI. The default value is 800 BPI. FILENO = An integer variable indicating which file number on the tape should be opened. The use of this ar- gument allows more than one data file to be kept on a magnetic tape. The default value for this argu- ment is file number one. The subroutines consider any occurrence of data followed by a tapemark as one file. Thus for a la- beled data set each occurrence of the header and trailer labels counts as one file. LABELS = An integer variable which, when set non-zero by the user indicates that tape dataset is to contain labels. On input this argument specifies that all tapes in the data set contain either leading tapemarks or dataset labels. The effect of this argument is to space into each tape volume of input past one end of file mark. This spacing function is executed BEFORE the search for a file other than file one is started. Any leading tapemarks or labels skipped with the use of this argument DO NOT count as a file. If this argument is specified on input and there are no labels or tapemarks on the magnetic tape, the routines will simply space forward until a ta- TREAD/TWRITE SUBROUTINES PAGE 6 INITIALIZATION ROUTINES pemark is found or the tape is exhausted. This may result in the opening of a file other than the one intended by the user. If this argument is set non-zero for use with an output dataset, IBM standard labels will be written on the output tape. This argument may only be set non-zero on output if the output file is to be file number one. The default value for this argument is zero, that is, no labels on input or output. REREAD = An integer variable that, if set non-zero by the user, will cause the input file to be automatically rewound and reopened at its' beginning when an end of file mark is encountered. Note that the use of this argument limits input to one reel of tape. Used on input only. EVENTFLG = An event flag value. This option allows the user to override the default event flag value. Event flags are used to syn- chronize I/O operations. Each open unit requires a unique event flag value. The TREAD/TWRITE subrou- tines automatically assign each unit a default event flag based on values assigned them by your system manager. A user supplied event flag value must be an integer value and must be a legal RSX event flag. FILENAME = A byte array or character string containing the filename to be placed in the tape labels of IBM standard label tapes. Note that the IBM label standard calls for a filename of not more than 17 characters. If you specify a string containing more than 17 characters, the filename is truncated after the 17th character. The filename specified should adhere to the IBM filename standards, not DIGITAL filename standards. No validity check is done on the filename, hence an invalid filename will result in a tape which cannot be read as a standard label dataset on an IBM system. If no value for filename is specified the filename "TWRITE.OUTPUT" is used by default. FNLEN = The number of characters in the "FILENAME" string. If "FILENAME" is specified, then this ar- gument must be present. NOTE Due to hardware restrictions int the TM11 and TJU16 controll- ers, the argument "BUF" must contain an even number of bytes and begin on a word boundary. For a write operation "BUF" must be at least 14 bytes in length. Since the last block in TREAD/TWRITE SUBROUTINES PAGE 7 INITIALIZATION ROUTINES an output file may contain any number of records between 1 and N, where N=BLEN/RLEN, it is strongly advised that the user never attempt to write records less than 14 bytes in length or that contain an odd number of bytes. To do so may result in the loss of data when the output file is closed. TREAD/TWRITE SUBROUTINES PAGE 8 INPUT/OUTPUT ROUTINES II. INPUT/OUTPUT ROUTINES SUBROUTINE TREAD(LUN) This subroutine reads the next logical record from the magnetic tape file currently associated with the "LUN" into the associated "RE- CORD" for that file. The value of the associated "EOF" variable is returned as follows after each read: EOF = 0 Normal return. EOF = 1 End of file encountered. The end of the input dataset has been reached. The file has been logically closed. The associated "LUN" has been released for other use. The magnetic tape has been rewound and placed offline. EOF = 2 The last call to TREAD resulted in the physical mounting of the next tape in the data- set. The associated "RECORD" for the file now contains the first record from the new tape. EOF = 3 The last call to TREAD resulted in the reading of an end of file mark while the reread option was in effect. The input file has been logically rewound and the rereading of the file has begun. "RECORD" now contains the first record in the file. SUBROUTINE TWRITE(LUN) This subroutine writes the next logical record to tape from the "RECORD" associated with the "LUN". A call to TWRITE does not modify "RECORD" in any way. The value of the associated "EOF" variable is returned as 2 if the last call to TWRITE necessitated the mounting of a new output tape. In all other cases "EOF" is returned as zero. NOTE Due to logic necessary to maintain compatibility with older versions of TWRITE, when "EOF" is returned as 2, the new out- put tape already contains one full block of data, plus one re- cord (see appendix c). TREAD/TWRITE SUBROUTINES PAGE 9 INPUT/OUTPUT ROUTINES III. FILE CLOSE ROUTINES RCLOSE AND WCLOSE SUBROUTINE RCLOSE(LUN) This subroutine logically closes a file being used for TREAD input. The tape associated with the specified "LUN" is rewound and set off- line. "LUN" is released for other use. The associated "EOF" variable is returned as one. SUBROUTINE WCLOSE(LUN) This routine properly closes a file which is open for TWRITE out- put. This routine MUST be called when TWRITE output is finished or the dataset will be lost (your system may support automatic calls to WCLOSE, see section V. for details). The tape unit associated with the "LUN" is rewound and set offline. "EOF" is returned as one. TREAD/TWRITE SUBROUTINES PAGE 10 MISCELLANEOUS ROUTINES IV. MISCELLANEOUS ROUTINES SUBROUTINE REWIND(LUN) This subroutine logically rewinds the input dataset associated with "LUN". If the current tape being used is not the first tape in the dataset, the subroutine will request that the first reel be remounted. The tape is positioned so that the next call to TREAD will transmit the first record in the file. "EOF" is returned to the user as a three. SUBROUTINE TPTT(LUN [,EFNO] ) This routine is used to change the logical unit number and event flag used by the TREAD/TWRITE subroutines to log messages on the users terminal. The default logical unit used is logical unit number 5. The default event flag used was determined by your system manager when the TREAD/TWRITE subroutines were assembled. The event flag argument is optional and need not be specified. If the logical unit number is changed, it is the users responsibility to assign the new logical unit number to a terminal device. TRANSLATION SUBROUTINES The following two routines are used by the TREAD/TWRITE subroutine system to perform data translation between EBCDIC and ASCII. Both of these routines may be called from a FORTRAN program. The calls are: CALL ASTOEB(BUFFER,LENGTH) CALL EBTOAS(BUFFER,LENGTH) In the above calls, data in the byte array "BUFFER", which is "LENGTH" bytes long, is replaced with the translated data values. Subroutine ASTOEB translates data from ASCII to EBCDIC. Subroutine EBTOAS translates data from EBCDIC to ASCII. TREAD/TWRITE SUBROUTINES PAGE 11 AUTOMATIC CALLS TO CLEANUP ROUTINES V. AUTOMATIC CALLS TO RCLOSE/WCLOSE ON PROGRAM EXIT An automatic clean-up routine may be incorporated into the TREAD/TWRITE subroutine system if the subroutines are to be used with a FORTRAN run time system. If this is the case, any execution of a STOP statement within a program will cause the TREAD/TWRITE routines to issue all necessary calls to WCLOSE or RCLOSE. The TREAD/TWRITE system accomplishes this procedure by calling the FORTRAN system subroutine USEREX each time a TRINIT or TWINIT call is issued. The subroutine USEREX allows only one user defined subroutine to be executed on program exit. Each call to the initialization rou- tines causes any previously defined exit routine to be replaced with a new routine. Hence, if you wish to make use of the subroutine USEREX, you must issue your call to USEREX after the last TRINIT/TWINIT call in your program. Additionally, you must issue all the proper calls to WCLOSE and RCLOSE yourself. If your system does not use FORTRAN, or your system already makes heavy use of the USEREX subroutine, or the TREAD/TWRITE subroutines are to be used with a language other than FORTRAN, then your system manager will not include the automatic cleanup procedure in the su- broutine system. TREAD/TWRITE SUBROUTINES PAGE 12 EXAMPLE PROGRAM VI. EXAMPLE PROGRAM The following program demonstrates some of the major features of the TREAD/TWRITE system. C C EXAMPLE PROGRAM OF TREAD/TWRITE SUBROUTINES C C DEFINE BUFFER AND RECORD AREAS NEEDED BY THE DATA SETS C BYTE BUF1(6000),BUF2(2400) BYTE REC1(60),REC2(24),REC3(100) C BYTE NAME(20) EQUIVALENCE (NAME,REC2),(REC2(21),DATE) C C SET UP TO LOG ALL TREAD/TWRITE MESSAGES C ON LOGICAL UNIT 4 C CALL ASNLUN(4,'TI',0) CALL TPTT(4) C C OPEN AN INPUT FILE. C THE PHYSICAL BLOCKSIZE IS 6000 BYTES LONG. C THE LOGICAL RECORD LENGTH IS 60 BYTES. C DATA IS IN THE FIRST FILE, THE TAPE HAS LABELS C AND INPUT DATA IS TO BE TRANSLATED FROM EBCDIC C CALL TRINIT(1,BUF1,6000,REC1,60,IER1,1,,,1) C C READ SOME RECORDS AND LIST THEM AT THE PRINTER C DO 100 I=1,100 CALL TREAD(1) IF(IER1.EQ.1)GO TO 200 PRINT 90,REC1 90 FORMAT(1X,60A1) 100 CONTINUE C C CLOSE INPUT FILE 1 C IF THE END OF FILE HAS BEEN ENCOUNTERED C THE FILE IS ALREADY CLOSED AND THIS C NEXT STATEMENT WILL BE SKIPPED C CALL RCLOSE(1) C C OPEN A NEW FILE FOR OUTPUT C THE FILE WILL CONTAIN BOTH CHARACTER AND BINARY DATA. C (NOTE THE EQUIVALENCE OF THE VARIABLES "NAME" AND "DATE" C TO "REC2" ABOVE.) C THE OUTPUT BLOCKS WILL BE 2400 BYTES LONG. C EACH RECORD IS 24 BYTES LONG TREAD/TWRITE SUBROUTINES PAGE 13 EXAMPLE PROGRAM C 200 CALL ASSIGN(1,'SY:DUMMY.DAT') CALL TWINIT(2,BUF2,2400,REC2,24,IER2) C C READ SOME RECORDS FROM A FORTRAN FILE, C PROCESS, AND WRITE THEM TO TAPE C 300 READ(1,END=400)NAME,MONTH,IDAY,IYEAR DATE=IYEAR*10000.+MONTH*100.+IDAY CALL TWRITE(2) GO TO 300 C C CLOSE THE OUTPUT FILE, INPUT FILE C 400 CALL WCLOSE(2) CALL CLOSE(1) C C IN THE NEXT EXAMPLE, THE USER CALLS A MAKE-BELIEVE C SUBROUTINE "DYNAMC" WHICH DYNAMICALLY ALLOCATES C A BUFFER OF THE SIZE SPECIFIED. C C ASK THE USER WHAT THE BLOCKSIZE IS TO BE. C TYPE *,'ENTER THE BLOCKSIZE, MUST BE A' TYPE *,'MULTIPLE OF 100.' ACCEPT *,ISIZE C C DYNAMICALLY ALLOCATE STORAGE, IBUF3 WILL CONTAIN C THE ADDRESS OF THE NEW STORAGE UPON RETURN C FROM "DYNAMC". C CALL DYNAMC(IBUF3,ISIZE) C C OPEN A TAPE FILE FOR INPUT C THE FILE IS THE 3RD FILE ON THE TAPE C THE BLOCKSIZE HAS BEEN DETERMINED BY THE USER C IBUF3 CONTAINS THE ADDRESS OF THE ACTUAL BUFFER C THE RECORD SIZE IS 100 BYTES C INPUT IS AT 1600 BPI. C CALL TRINIT(1,IBUF3,-1*ISIZE,REC3,100,IER3,,1600,3) C C READ SOME RECORDS AND WRITE OUT TO FORTRAN UNIT 2 C 500 DO 600 I=1,100 CALL TREAD(1) IF(IER3.EQ.1)GO TO 800 600 WRITE(2)REC3 C C REWIND THE INPUT DATASET AND THIS TIME WRITE THE C RECORDS TO THE PRINTER C CALL REWIND(1) DO 700 I=1,100 CALL TREAD(1) TREAD/TWRITE SUBROUTINES PAGE 14 EXAMPLE PROGRAM IF(IER3.EQ.1)GO TO 800 PRINT 690,REC3 690 FORMAT(1X,100A1) 700 CONTINUE C 800 STOP 'EXAMPLE' END TREAD/TWRITE SUBROUTINES PAGE 15 TASK BUILDING VII. TASK BUILDING TO USE THE TREAD/TWRITE SUBROUTINES Task building to use the TREAD system is simple. All that one does to include the TREAD system in a task is to link to the modules "TREAD", "ASTOEB", and "EBTOAS" in the command line to the task build- er. All three of the above modules are usually in the library file "TREAD.OLB". If this is the case, all that you have to do to use the routines is to task build to the library. On some systems, the system manager may elect to place the TREAD routines in the system library. If that is the case, TREAD will be incorporated in your task automati- cally whenever you call one of the routines. See your system manager to find out which of the above is true on your system. When using the routines in an overlaid task, place them in the root. This is needed because the routines maintain several tables within their own code. APPENDIX A TREAD/TWRITE MESSAGES The TREAD/TWRITE subroutines produce four classes of messages: informative messages, action messages, warning messages, and fatal error messages. Informative messages are produced strictly for docu- mentation. Action messages require some action on the part of the user. Warning messages usually result from errors that the user has little or no control over, such as input read errors. Fatal error messages arise from error situations outside the correctional abili- ties of the TREAD/TWRITE subroutines. Fatal errors always result in program exit. INFORMATIONAL MESSAGES 1.) [TRINIT: V03.02] This message appears on every call to TRINIT. 2.) [TWINIT: V03.02] This message appears on every call to TWINIT. 3.) INPUT TRANSLATION: EBCDIC TO ASCII This message appears in conjunction with message 1 above to indi- cate that input translation is in effect for the dataset. 4.) OUTPUT TRANSLATION: ASCII TO EBCDIC This message appears in conjunction with message 2 above to indi- cate that output translation is in effect for the dataset. 5.) ddnn INPUT TERMINATED This message indicates that the input dataset on the indicated device (ddnn) has been closed. 6.) ddnn END OF OUTPUT This message indicates that the output dataset on the device ddnn TREAD/TWRITE MESSAGES PAGE A-2 has been closed. ACTION MESSAGES 1.) LOGICAL UNIT n PLEASE ENTER THE TAPE DEV-UNIT: Each time a call is made to either TRINIT or TWINIT the user must supply the routines with the device name of the tape unit on which the dataset will reside. The reply to this message is in the DIGITAL standard form DDNN. 2.) TRINIT-TWINIT: DEVICE MUST BE TAPE, REENTER The user has responded to action message one with a device reply which is not a tape device, or which is currently mounted as a Files-11 volume. 3.) ddnn EOF-EOT ON INPUT IS THERE ANOTHER INPUT REEL?: An end of file mark has been reached on input. The user is ex- pected to tell the routines if there is another reel of tape to be read. The reply to this question is either YES of NO. 4.) REENTER RESPONSE - 'YES' OR 'NO': The response to action message number three was not YES or NO. This is a safety feature of the routines to insure that input in- tended for another program is not received by the routines. 5.) MOUNT NEXT INPUT REEL ON ddnn TYPE RES "[TASKNAME]" TO RESUME The response to action message three was "YES", consequently a new reel of input tape is needed. The program has been suspended while it waits for the user to mount the next reel in the data- set. When the new tape is mounted, issue the mcr command RES to resume the program. 6.) [REWIND]:REMOUNT FIRST TAPE VOLUME ON ddnn TYPE RES "[TASKNAME]" TO RESUME A call to rewind has occured while reading the second or later volume of a dataset, consequently, the first reel must be re- mounted to properly rewind the dataset. The program is suspend- ed. When the first reel is remounted, issue the mcr RES command to resume the program. 7.) ddnn OUTPUT TAPE IS WRITE LOCKED, REMOUNT TYPE RES "[TASKNAME]" TO RESUME An output tape is physically write protected. Insure that the proper reel of tape is mounted, write enable the tape and remount TREAD/TWRITE MESSAGES PAGE A-3 it. When this is done, issue the mcr RES command to resume the program. 8.) ddnn PLEASE ENTER THE VOL-SER NO.: This message occurs only when the IBM standard label option is in effect for output tapes. The message will occur each time a new output reel is mounted. The user is expected to enter the six character name by which the tape reel is to be requested when the file is read on an IBM computer. 9.) MOUNT NEXT OUTPUT REEL ON ddnn TYPE RES "[TASKNAME]" TO RESUME The current output volume is full and another volume is required. The program is suspended. When the new output tape is mounted, issue the mcr RES command to resume program execution. WARNING MESSAGES 1.) [TPINIT]:UNIT ddnn OPEN AT EOV This message appears if the user has specified a file number other than file one and the specified file does not exist. The tape is now positioned so that an output operation to the tape will create a new file. An input operation will result in an end of file mark being read (i.e. a file without any records). In either case program execution continues. 2.) [TREAD]:ddnn STRANGE BLOCK LENGTH, SOME DATA SKIPPED The probable cause for this message is that the user specified record length is incorrect. This situation will occur if the re- cord length does not divide evenly into the length of the input blocks. As many records as possible were transferred from the block. 3.) [TREAD]:ddnn BAD BLOCK, SKIPPED An unreadable block has been discovered on an input tape, after the standard number of retries (usually 9), the block is skipped. 4.) [TREAD]:ddnn LONG BLOCK, SKIPPED This error usually results from an error on the part of the user. A block longer than the user specified block length has been dis- covered on magtape. The block is skipped. TREAD/TWRITE MESSAGES PAGE A-4 FATAL ERROR MESSAGES 1.) [TPINIT]:MAXIMUM # LOGICAL UNITS IN USE The user has attempted to call TRINIT or TWINIT when the maximum number of tape drives on his system are already in use by his program. 2.) [TPINIT]:INIT ALREADY DONE FOR LOGICAL UNIT # The user has attempted to open two files on the same logical unit number. 3.) TRINIT-TWINIT: BLOCKSIZE < RECORDSIZE The user has specified a block length in a TRINIT or TWINIT call that is less than the size of the logical record. This repre- sents an impossible situation. 4.) TRINIT-TWINIT: BLOCKSIZE MUST CONTAIN AN EVEN # OF BYTES A call to TRINIT or TWINIT specified a block length that was odd. Due to hardware restrictions, all blocks which are read or writ- ten must contain an even number of bytes. 5.) [TWINIT]:LABELS ONLY SUPPORTED FOR FILE 1 The user has specified that an output tape is to contain standard labels and the file is not the first on the tape. Standard la- bels are only supported for file one on output. 6.) [TPINIT]:SPECIFIED LUN CONFLICTS WITH TERMINAL LUN The user has specified a call to TRINIT or TWINIT which contains the same logical unit number as the routines are using to send messages to the terminal. Correct this problem by using a dif- ferent logical unit number. An alternate solution is to correct the problem with the use of subroutine TPTT. 7.) [TPINIT]:UNIT ddnn FILE SEARCH FAILURE The user has specified that a tape file other than file one was to be opened. The file called for was not found before the phy- sical end of tape mark was read. 8.) TREAD-RCLOSE: INVALID LOGICAL UNIT # OF n The logical unit number specified in a call to TREAD or RCLOSE is not in use by the TREAD/TWRITE system. 9.) TREAD-RCLOSE: UNIT NOT OPEN FOR READ, UNIT: n The logical unit number specified in a call to TREAD or RCLOSE is in use by the TREAD/TWRITE system for output, not input. TREAD/TWRITE MESSAGES PAGE A-5 10.) [TREAD]:ddnn MAGTAPE ERROR # n Some sort of magtape hardware error has occured on the indicated device. The number "n" is the standard operating system error code. 11.) TWRITE-WCLOSE: INVALID LOGICAL UNIT # OF n The logical unit number specified in a call to TWRITE or WCLOSE is not in use by the TREAD/TWRITE system. 12.) TWRITE-WCLOSE: UNIT NOT OPEN FOR WRITE, UNIT: n The logical unit specified in a call to TWRITE or WCLOSE is in use by the TREAD/TWRITE system for input, not output. 13.) [TWRITE-WCLOSE]:ddnn MAGTAPE ERROR # n Some sort of magtape hardware error has occured on the indicated device. The number "n" is the standard operating system error code. 14.) [LABEL]: ddnn MAGTAPE ERROR # n This message is identical in meaning to fatal message 13 except that the error occured while the subroutines were attempting to write IBM tape labels. 15.) TASK TERMINATING DUE TO RDTAPE-WRTAPE DIRECTIVE STATUS ERROR CODE OF n An I/O request from somewhere within the TREAD/TWRITE subroutine system has been rejected by the operating system. The "n" speci- fied above is the standard operating system directive status error code. A possible cause for this message is that a user specified lun has a FORTRAN file open on it. This message will always appear if the reply to action message number one repre- sented a non-existent device. This message should not appear when the routines are in normal use. APPENDIX B TREAD/TWRITE I/O DESIGN The TREAD/TWRITE system achieves a level of multi-buffering by al- lowing I/O operations to occur concurrently with program execution. For example, on input, when the last logical record has been trans- ferred from the buffer "BUF" to the record "RECORD", TREAD immediately initiates, but does not wait for the completion of, the next physical transfer from magnetic tape. TWRITE works the same way, except that it starts the transfer as soon as the buffer "BUF" has been filled. The success of a physical I/O request is checked by TREAD or TWRITE on the next call to the routines which specifies the same tape unit. Note that TRINIT initiates the first physical read operation on a unit. APPENDIX C END OF TAPE HANDLING ON OUTPUT When TWRITE encounters the end-of-tape strip on a magnetic tape, it immediately backs up over the last block written, writes any labels that are needed, followed by two end-of-file marks (the last block on the tape has thus been erased, but is still in the "BUF" for this unit, see appendix b). TWRITE then starts a new output tape by writ- ing the last block from the previous reel of tape onto the start of the new reel of tape. TWRITE then finishes its normal processing, sets the "EOF" flag for the unit to 2, and returns to the user. This algorithm was used only to maintain compatibility with a previous DOS-11 version of TWRITE. Note that the algorithm causes "EOF" to be set to 2 only on the call to TWRITE which writes the first record of the second block to the newly mounted magnetic tape. The writing of two end-of-file marks at the end of each tape vio- lates IBM standards. IBM standards call for two end-of-file marks only at the end of a dataset. In over five years of use, however, we have never had any problems with tapes written in such a manner when reading them on an IBM system. Additionally, the use of two end-of-file marks allows one to use DEC and user supplied utility pro- grams that look for two end of file marks to denote the logical end of tape. APPENDIX D STANDARD IBM OUTPUT LABELS TWRITE outputs OS/VS tape labels that adhere to the conventions specified in the IBM publication "OS/VS Tape Labels" (fourth edition, November 1978), IBM order number GC26-3795-3. For simplicity, TWRITE places fixed information in some fields that on an IBM system would be created dynamically. In the HDR1 labels the creation date is set to Jan 1, 1980, the expiration date is set to Dec 31, 1999, and the data set security byte is set to "no password protection". In the HDR2 la- bels the record format is always set to fixed length records, and the block attribute always indicates blocked records. Please note that the block count needed for the block count field of the EOV1/EOF1 labels is kept by TWRITE in a single precision in- teger. The block count must be properly recorded in the EOV1/EOF1 la- bels or an IBM system will report an I/O error when it processes the labels. With an 800 or 1600 BPI tape drive, using a single precision integer to keep track of the block count presents no problem, given any resonable blocksize. Anyone using these routines to write labeled output tapes on a 6250 BPI tape drive can avoid problems by always using a blocksize greater than 2500 bytes. Note that the density field of the HDR2 label will not be properly recorded for 6250 BPI, since the routines were not written to support that density. APPENDIX E THE EBCDIC AND ASCII TRANSLATION ROUTINES The translation routines supplied with the TREAD package translate only the printable character set and the major control codes properly, other characters are converted to blanks by the translation. This convention is sufficient for normal data processing. Should better routines be needed, several are available through DECUS. There have also been several excellent routines for ASCII and EBCDIC translation on past DECUS symposium tapes. As the existing routines are each sep- erate object modules, they may be replaced at any time, as long as the calling sequence remains unchanged. My thanks to Steve B. Keith, formerly of the American College of Radiology, for the translation routines as distributed.