!*MAGNETIC TAPE INTERFACE ROUTINES !THESE ROUTINES ARE USED FOR HIGH LEVEL PROGRAMMING LANGUAGE ACCESS !TO MAGNETIC TAPE. THEY ARE ACCESSED BY NEWFILEOP FOR FORTRAN !AND BY THE IMP SQ ROUTINES DIRECTLY. THEY IN TURN CALL ROUTINE MAGIO !WHICH CONTAINS THE MAIN MAG TAPE DRIVER ROUTINES. CONSTINTEGER CLOSED = 0 CONSTINTEGER AFTERREAD = 2 CONSTINTEGER AFTERWRITE = 3 CONSTINTEGER AFTERENDFILE = 6 CONSTINTEGER EBCDICBIT = X'20' CONSTINTEGER RINGNEEDED = X'40' RECORDFORMAT MTFDF(INTEGER LEVEL, DSNUM, C BYTEINTEGER STATUS, ACCESS ROUTE, VALID ACTION, CUR STATE, C MODE OF USE, MODE, FILE ORG, DEV CODE, REC TYPE, FLAGS, C CHANNEL, BCF, INTEGER REL FILE NUM, AREC, REC SIZE, MINREC, C MAXREC, REL BLOCK NO, RECPTR, SOB, EOB, SOD, EOD, TRANSFERS C , BLOCK XFERS, BLOCK LENGTH, RTLEN, RECLEN, C BYTEINTEGER BLOCKING, DATA FORMAT, BWF, C STRING (17) DSN, STRING (6) VOLUME, C INTEGER BLOCKPTR, INTEGER FIRST TIME, C INTEGER RTRACE, RTCHAN) EXTERNALINTEGERFNSPEC UINFI(INTEGER N) SYSTEMINTEGERFNSPEC OPEN(INTEGER AFD, MODE) SYSTEMROUTINESPEC PSYSMES(INTEGER ROOT, FLAG) SYSTEMINTEGERFNSPEC PSTOI(STRING (63) S) SYSTEMROUTINESPEC SETFNAME(STRING (40) NAME) SYSTEMROUTINESPEC SETPAR(STRING (255) S) SYSTEMINTEGERFNSPEC PARMAP SYSTEMSTRINGFNSPEC SPAR(INTEGER N) SYSTEMINTEGERFNSPEC FDMAP(INTEGER CHAN) SYSTEMROUTINESPEC DEFINE(INTEGER CHAN, C STRING (31) IDEN, INTEGERNAME AFD, FLAG) SYSTEMROUTINESPEC MAGIO(INTEGER FD ADDR, OPERATION, C INTEGERNAME FLAG) EXTERNALROUTINE DEFINEMT(STRING (255) S) CONSTINTEGER MINBLOCKSIZE = 18 CONSTINTEGER MAXBLOCKSIZE = 32767 CONSTINTEGER OPTBLOCKSIZE = 4096 SWITCH BLOCKCHECK(1 : 6) CONSTINTEGER MAXRECFMS = 14 CONSTSTRING (4)ARRAY RECFMS(1:MAXRECFMS)=C "F","FA","FB","FBA", "V","VA","VB","VBA","VS","VSA","VBS","VBSA", "U","" CONSTINTEGERARRAY ASA(1:MAXRECFMS)=C 0,16,0,16,0,16,0,16,0,16,0,16,0,0 CONSTBYTEINTEGERARRAY MINREC(1:MAXRECFMS)=18(4),1(8),18,0 CONSTBYTEINTEGERARRAY BLOCKAT(1:MAXRECFMS)=C 1(2),2(2),1(2),2(2),3(2),4(2),1,0 CONSTBYTEINTEGERARRAY RECTYPE(1:MAXRECFMS)=1(4),2(8),0,255 CONSTINTEGERARRAY MAXREC(1:MAXRECFMS)=C 32760(4),32752(4),32767(4),32760,0 CONSTBYTEINTEGERARRAY BCCODE(1:MAXRECFMS)=1(2),2(2),3(2),4(2),5(4),6(2) STRING (31) DSN, VOL, SRECSIZE STRING (8) SCHAN, SLABEL, RECFM, SREC, SBLOCKSIZE INTEGER CHAN, LABEL, LREC, BLOCKSIZE, AFD, FLAG, I, CHAR, C RING, RECFMCODE INTEGER RECSIZE RECORDNAME F(MTFDF) INTEGER ACR, LNB ! *STLN_LNB; !TO FIND ACR LEVEL ! ACR = (INTEGER(LNB+4)>>20)&X'F'; !PRIV IF 9 OR LESS ! %IF ACR > 9 %AND UINFI(2)&1 = 1 %START; !UN-PRIV ATTEMT TO USE TAPE !FROM INTERACTIVE TERMINAL ! PRINTSTRING( %C "DEFINEMT fails - No tape access allowed from interactive terminal") ! %STOP ! %FINISH RING = 0; !NO RING BY DEFAULT SETPAR(S) IF PARMAP&7 # 7 OR PARMAP > X'3F' C THEN FLAG = 263 AND -> ERR !WRONG NUMBER OF PARAMETERS CHAN = PSTOI(SPAR(1)); !CHANNEL NUMBER UNLESS 1 <= CHAN <= 80 THEN FLAG = 223 AND -> ERR !INVALID CHANNEL NUMBER DSN = SPAR(2) UNLESS 1 <= LENGTH(DSN) <= 17 C THEN SETFNAME(DSN) AND -> BADPARAM VOL = SPAR(3); !VOLUME LABEL IF CHARNO(VOL,LENGTH(VOL)) = '*' START LENGTH(VOL) = LENGTH(VOL)-1 RING = RINGNEEDED FINISH !WITH OR WITHOUT WRITE UNLESS 1 <= LENGTH(VOL) <= 6 C THEN SETFNAME(VOL) AND -> BADPARAM SLABEL = SPAR(4) LABEL = 1; !DEFAULT IF SLABEL # 0 THEN LABEL = PSTOI(SLABEL) UNLESS 1 <= LABEL THEN SETFNAME(SLABEL) AND -> BADPARAM !INVALID LABEL PARAMETER SREC = SPAR(5) IF SREC # "" START ; !USER PROVIDES FORMAT INFORMATION RECFM = "" CYCLE I = 1,1,LENGTH(SREC) CHAR = CHARNO(SREC,I) UNLESS 'A' <= CHAR <= 'Z' THEN EXIT RECFM = RECFM.TOSTRING(CHAR) REPEAT IF RECFM = SREC THEN SETFNAME(SREC) AND -> BADPARAM !NO RECORD SIZE SPECIFIED SRECSIZE = FROMSTRING(SREC,LENGTH(RECFM)+1,LENGTH(SREC)) RECSIZE = PSTOI(SRECSIZE) CYCLE RECFMCODE = 1,1,MAXRECFMS IF RECFM = RECFMS(RECFMCODE) START ; !RECFM FOUND UNLESS MINREC(RECFMCODE) <= RECSIZE <= MAXREC( C RECFMCODE) THEN SETFNAME(SREC) AND -> BADPARAM EXIT FINISH IF RECFMCODE = MAXRECFMS C THEN SETFNAME(SREC) AND -> BADPARAM REPEAT SBLOCKSIZE = SPAR(6) IF SBLOCKSIZE # "" THEN BLOCKSIZE = PSTOI(SBLOCKSIZE) C ELSE BLOCKSIZE = 0 -> BLOCKCHECK(BCCODE(RECFMCODE)) BLOCKCHECK(1): !FIXED IF BLOCKSIZE # 0 THEN START IF BLOCKSIZE # RECSIZE THEN -> BADBLOCKSIZE FINISH ELSE BLOCKSIZE = RECSIZE -> ENDBLOCK BLOCKCHECK(2): !FIXED BLOCKED IF BLOCKSIZE # 0 START UNLESS (BLOCKSIZE//RECSIZE)*RECSIZE = BLOCKSIZE C THEN -> BADBLOCKSIZE FINISH ELSE START BLOCKSIZE = RECSIZE WHILE BLOCKSIZE < OPTBLOCKSIZE C THEN BLOCKSIZE = BLOCKSIZE+RECSIZE FINISH !CHOOSE A SUITABLE SIZE -> ENDBLOCK BLOCKCHECK(3): !VARIABLE UN-BLOCKED IF BLOCKSIZE # 0 START IF BLOCKSIZE < RECSIZE+8 THEN -> BADBLOCKSIZE FINISH ELSE BLOCKSIZE = RECSIZE+8 -> ENDBLOCK BLOCKCHECK(4): !VARIABLE BLOCKED IF BLOCKSIZE # 0 START IF BLOCKSIZE < RECSIZE+8 THEN -> BADBLOCKSIZE FINISH ELSE START IF RECSIZE < OPTBLOCKSIZE-8 C THEN BLOCKSIZE = OPTBLOCKSIZE C ELSE BLOCKSIZE = RECSIZE+8 FINISH -> ENDBLOCK BLOCKCHECK(5): !SPANNED IF BLOCKSIZE = 0 THEN BLOCKSIZE = OPTBLOCKSIZE -> ENDBLOCK BLOCKCHECK(6): !UNSTRUCTURED IF BLOCKSIZE # 0 START IF BLOCKSIZE < RECSIZE THEN -> BADBLOCKSIZE FINISH ELSE START IF BLOCKSIZE = 0 THEN BLOCKSIZE = RECSIZE FINISH ENDBLOCK: UNLESS MINBLOCKSIZE <= BLOCKSIZE <= MAXBLOCKSIZE C THEN -> BADBLOCKSIZE FINISH ELSE RECSIZE = 0 AND BLOCKSIZE = 0 AND RECFMCODE = 14 !FORMAT INFO NOT SUPPLIED FILLREC: DEFINE(CHAN,".NULL",AFD,FLAG); !GET EMPTY DESCRIPTOR IF FLAG # 0 THEN -> ERR F == RECORD(AFD) F_ACCESSROUTE = 5; !MAGNETIC TAPE F_MODEOFUSE = 2; !SEQUENTIAL F_MODE = 11; !FOR FORTRAN I/O F_RECTYPE = RECTYPE(RECFMCODE) F_FLAGS = F_FLAGS!ASA(RECFMCODE)!RING!EBCDICBIT F_RELFILENUM = LABEL; !FILE ON TAPE IF F_RECTYPE = 1 THEN F_MINREC = RECSIZE C ELSE F_MINREC = MINREC(RECFMCODE) F_MAXREC = RECSIZE F_BLOCKLENGTH = BLOCKSIZE F_BLOCKING = BLOCKAT(RECFMCODE) F_DSN = DSN F_VOLUME = VOL FLAG = 0 -> ERR BADBLOCKSIZE: SETFNAME(SBLOCKSIZE) BADPARAM: FLAG = 202 -> ERR ERR: IF FLAG # 0 THEN PSYSMES(100,FLAG) END ; !OF DEFINEMT SYSTEMINTEGERFN NEWMTFILEOP(INTEGER AFD, ACT) RECORDNAME F(MTFDF) INTEGER FLAG BYTEINTEGERNAME CURSTATE F == RECORD(AFD) CURSTATE == F_CURSTATE IF ACT = 1 START ; !READ IF CURSTATE = AFTERREAD THEN -> OK; !AFTER READ IF CURSTATE = CLOSED START FLAG = OPEN(AFD,1); !OPEN FOR READING CURSTATE = AFTERREAD RESULT = FLAG FINISH IF CURSTATE = AFTERWRITE THEN RESULT = 156 !FAILURE READ AFTER WRITE IF CURSTATE = AFTERENDFILE THEN RESULT = 153 !END OF FILE FINISH !* !* WRITE !* IF ACT = 2 START IF CURSTATE = AFTERWRITE THEN -> OK IF CURSTATE = CLOSED START FLAG = OPEN(AFD,2); !OPEN FOR WRITING IF FLAG # 0 THEN RESULT = FLAG CURSTATE = AFTERWRITE -> OK FINISH IF CURSTATE = AFTERREAD START IF F_FLAGS&RINGNEEDED = 0 THEN RESULT = 319 !NO RING F_VALIDACTION = F_VALIDACTION!2; !OR IN WRITE BIT MAGIO(AFD,1,FLAG); !PREPARE FOR WRITE CURSTATE = AFTERWRITE IF FLAG # 0 THEN RESULT = FLAG -> OK FINISH FINISH !* !* REWIND !* IF ACT = 4 START IF CURSTATE = CLOSED THEN -> OK IF CURSTATE = AFTERWRITE START ; !AFTER WRITE - NEED TO DO AN ENDFILE MAGIO(AFD,6,FLAG); !ENDFILE IF FLAG # 0 THEN RESULT = FLAG CURSTATE = AFTERREAD FINISH IF CURSTATE = AFTERENDFILE THEN CURSTATE = AFTERREAD IF CURSTATE = AFTERREAD START MAGIO(AFD,4,FLAG); !THE REWIND ITSELF RESULT = FLAG FINISH FINISH !* !* BACKSPACE !* IF ACT = 8 START IF CURSTATE = AFTERREAD START MAGIO(AFD,5,FLAG) RESULT = FLAG FINISH IF CURSTATE = AFTERWRITE START MAGIO(AFD,6,FLAG); !DO AN ENDFILE FIRST IF FLAG # 0 THEN RESULT = FLAG MAGIO(AFD,5,FLAG); !THE BACKSPACE ITSELF CURSTATE = AFTERREAD RESULT = FLAG FINISH IF CURSTATE = AFTERENDFILE C THEN CURSTATE = AFTERREAD AND -> OK FINISH !* !* ENDFILE !* IF ACT = 16 START IF CURSTATE = AFTERWRITE START MAGIO(AFD,6,FLAG) RESULT = FLAG FINISH FINISH !* RESULT = 171; !INVALID OPERATION !* OK: RESULT = 0 END ; !OF NEWMTFILEOP ENDOFFILE