!TITLE Magnetic Tape Facilities !<DMAGCLAIM externalintegerfn DMAG CLAIM(string (6)TSN, integername SNO, integer REQ, MODE) ! ! The magnetic tape volume labelled TSN is either claimed (REQ=0) or ! released (REQ=1). MODE should be set to 1 to allow read access to the ! tape, 2 if write access is required, or 3 for either read or write ! access. If a CLAIM call is successful, SNO is set with a number to be ! used in subsequent calls of DMAG IO. ! ! If TSN is null in a RELEASE call, then all claimed tapes are released. ! ! Possible error results from Volumes: ! 101 Bad parameters ! 102 Duplicate request ! 103 Request lists full ! 104 Volume not available (Operators have said "NO <val id>") ! 105 Volume request list full ! 106 No tapes in tape list (A, B, S or E) ! 107 Device not claimed when a "release" is done. !> INTEGER J, K, L K = IN2(256 + 37) -> OUT UNLESS K = 0 ! K = 45 -> OUT IF VAL(ADDR(SNO), 4, 1, DCALLERS PSR) = 0 ! K = 8 -> OUT UNLESS 0<=REQ<=1 L = LENGTH(TSN) -> OUT UNLESS (L=0 OR L=6) UCTRANSLATE(ADDR(TSN)+1, 6) IF L = 6 ! IF REQ=0 START ! CLAIM -> OUT UNLESS L = 6 ! K = 90; ! MAX TAPES ALREADY CLAIMED -> OUT IF TAPES CLAIMED > TOP ENT -> OUT IF UINF_REASON = BATCH AND TAPES CLAIMED >= UINF_DECKS ! K = 92; ! INTERACTIVE USE OF TAPES NOT ALLOWED -> OUT IF UINF_REASON = INTER AND DTRYING << 16 >= 0 ! K=VOL REQ(TSN,SNO,REQ,MODE) IF K=0 START CYCLE J=0,1,TOP ENT IF CLAIMED(J)_TSN="" START CLAIMED(J)_TSN=TSN CLAIMED(J)_SNO=SNO TAPES CLAIMED=TAPES CLAIMED + 1 -> OUT FINISH REPEAT K=73; ! SHOULD NOT ARRIVE HERE ! FINISH FINISH ELSE START ! RELEASE K=0 CYCLE J=0,1,TOP ENT IF TSN = "" # CLAIMED(J)_TSN C OR (""#CLAIMED(J)_TSN=TSN) C START K=VOL REQ(CLAIMED(J)_TSN,CLAIMED(J)_SNO,1,0) IF K=0 START CLAIMED(J)=0 TAPES CLAIMED=TAPES CLAIMED - 1 FINISH FINISH REPEAT FINISH ! OUT: RESULT = OUT(K, "SJII") END ; ! DMAG CLAIM ! !----------------------------------------------------------------------- ! !<DMAGIO externalintegerfn DMAG IO(integername REPLY FLAG, CONTROL, LEN, integer TYPE, SNO, ADR) ! ! The parameter TYPE determines the action of the procedure: ! TYPE = 0 erase ! 1 read ! 2 write ! 3 check-write (not implemented) ! 4 check-read (no data transfer) ! 5 private chain (not implemented) ! 6 rewind to BT ! 7 spare ! 8 file position ! 9 tape position ! 10 write tape-mark ! ! SNO should be set with the value returned by a previous CLAIM ! (procedure DMAG CLAIM). ADR and LEN specify the area from or to which ! data is to be transferred (if relevant). In the case of TYPE = 1 ! (read) LEN is set on return to be the number of bytes transferred. ! ! Bits in parameter CONTROL are used to specify detailed actions by the ! tape handler routine, as follows: ! ! 2**0 - ! 2**1 suppress error re-try ! 2**2 ignore short-block indication ! 2**3 ignore long-block indication ! ! Bits in CONTROL on return are used to indicate the occurrence of ! conditions during execution of a request, as follows: ! ! 2**0 short-block indication ! 2**1 long-block indication ! ! These bits will not be set on return if the respective bits for ! "ignore short/long-block indication" were specified in the request. ! REPLY FLAG (valid when the result of the function is zero) is set ! to zero for a successful operation, or ! ! 1 failure (parity etc.) ! 2 request rejected ! 4 beginning of tape, end of tape or unexpected tape ! mark found, but operation otherwise successful ! ! ! TYPE=8 ! ! For request TYPE=8 (file position), LEN specifies the number of blocks ! to be skipped: negative means backwards, positive forwards, zero is ! invalid. If a tape-mark is found (REPLY FLAG=4) then a skip back of one ! block is performed before the reply is given. It is thus impossible ! to pass a tape-mark except by the use of a "tape position" request. ! ! TYPE=9 ! For request TYPE=9 (tape position), LEN is the number of (notional) ! files to be skipped, and CONTROL is the number of tape-marks in a ! notional file, CONTROL must be positive. If LEN is negative the skip ! is backwards, if positive then it is forwards, zero is invalid. ! CONTROL*LEN tape-marks are skipped. A backwards skip will stop at BT. ! A forward skip will stop if the first block within a (notional) file is ! a tape-mark, the tape will then be positioned before the tape-mark and ! REPLY FLAG=4 will be returned. Thus if CONTROL=1 and LEN="very large", ! the tape will be positioned between the first double tape-mark ! encountered. !> ! 09876543210 CONSTINTEGER VALMASK=B'11111010111' ! DATA TRAN MASK has bits set for operations for which: ! data transfer is to be done ! hence validate to be done on the area ! the area is to be locked down, and ! OUT 18 is to be done. ! 09876543210 CONSTINTEGER DATA TRAN MASK=B'00000001110' CONSTINTEGER OUT11MASK =B'10000010001' ! Other operations get OUT 7 (an ordinary OUT) unless OUT11MASK has a bit set, ! when they get an OUT 11. INTEGER ENTRY,LLEN, LCONTROL INTEGER READWRITE,OUT18,K,DUM,EPAGE BYTES,TIMES,SAVID INTEGER FLAG RECORD (PARMF)Q RECORD (PARMF)NAME P ! LLEN = 0 LCONTROL = 0 ! FLAG = IN2(256 + 38) -> OUT UNLESS FLAG = 0 ! FLAG = 45 -> OUT IF VAL(ADDR(REPLY FLAG),4,1,DCALLERS PSR)=0 -> OUT IF VAL(ADDR(CONTROL),4,1,DCALLERS PSR)=0 -> OUT IF VAL(ADDR(LEN),4,1,DCALLERS PSR)=0 ! FLAG=8 UNLESS (1<<TYPE)&VALMASK#0 THEN -> OUT ! CYCLE ENTRY=0,1,TOPENT IF CLAIMED(ENTRY)_SNO=SNO AND CLAIMED(ENTRY)_TSN#"" C THEN -> GOTT REPEAT FLAG=67; ! TAPE NOT CLAIMED -> OUT GOTT: LLEN = LEN LCONTROL = CONTROL Q = 0 ! IF TYPE = 7 START ! PASS REQUEST ON TO TAPE FOR SENSE ETC ! INPUT: SNO AND ADR ! OUTPUT: 5 WORDS IN ADR, ADR+4, ETC P == RECORD(OUTPAD) P = 0 P_P1 = SNO P_DEST = X'310009' *OUT_11 FLAG = 45 -> OUT IF VAL(ADR, 20, 1, DCALLERS PSR) = 0 MOVE(20, ADDR(P_P2), ADR) FLAG = 0 -> OUT FINISH ! IF TYPE=6 THEN TYPE=17 OUT18=0; ! SAYS WHETHER OR NOT TO USE THE SPECIAL OUT 18 IF (1<<TYPE)&DATA TRAN MASK#0 START ! DATA AREA MUST BE READ-MODE FOR WRITING TO TAPE, AND WRITE MODE FOR ! READING FROM TAPE READWRITE=0; ! FOR READ-ACCESS CHECK IF TYPE=1 THEN READWRITE=1; ! FOR WRITE ACCESS CHECK FLAG=45; ! AREA NOT AVAILABLE -> OUT IF VAL(ADR,LLEN,READWRITE,DCALLERS PSR)=0 ! ALSO THE DATA AREA MUST NOT CROSS A SEG BOUNDARY, AS THE GPC ! CANNOT COPE WITH THIS. FLAG=56; ! CROSSES SEG BOUNDARY IF ADR>>18 # (ADR+LLEN-1)>>18 THEN -> OUT; ! crosses seg bdy OUT18=1 FINISH ! FOR A DATA TRANSFER WE REFERENCE ALL THE PAGES IN THE DATA AREA, TO GET THEM INTO ! MAIN STORE. IF THEY ARE NOT STILL THERE AT THE TIMEOF THE OUT 18, THEN ! P_DEST WILL BE SET TO -1, AND WE TRY AGAIN, UP TO FOUR TIMES (SAY). TIMES=0 P==RECORD(OUTPAD) UNTIL OUT18=0 C OR (OUT18#0 AND (TIMES>4 OR P_DEST#-1)) C CYCLE ! PASS REQUEST TO THE TAPE ROUTINE Q_DEST=CLAIMED(ENTRY)_SNO !Q_P1=ID - NOT REQUIRED Q_P2=LCONTROL<<8 ! TYPE Q_P3=ADR Q_P4=LLEN Q_P5=LLEN ! (DCALLERS ACR<<24) ! SET TOP BIT FOR A READ SO THAT SUPVR CAN MAKE SURE THAT ! THE WRITTEN BITS ARE SET - THE GPC DOESN'T DO IT! IF TYPE=1 THEN Q_P5=Q_P5 ! (1<<31) Q_P6=ADR IF OUT18=0 START SRCE ID=(SRCE ID + 1)&X'FFFF' SAVID=SRCE ID Q_SRCE=SAVID LOUTP=Q P=Q MOUT AGAIN: IF (1<<TYPE)&OUT11MASK#0 START LOUTP STATE="DMAG IO DOUT 11" *OUT_11 FINISH ELSE START LOUTP STATE="DMAG IO OUT 7" *OUT_7; ! PON AND SUSPEND FINISH IF P_DEST#-1 AND P_DEST&X'FFFF'#SAVID START Q=P PRINTSTRING("NREQ: ") DDUMP(ADDR(Q),ADDR(Q)+32,-1,-1) P_DEST=0; ! POFF -> MOUT AGAIN FINISH FINISH ELSE START ! NOW REFERENCE ALL THE PAGES EPAGE BYTES=EPAGE SIZE<<10 K=ADR & (¬(EPAGE BYTES - 1)) WHILE K<ADR+LLEN CYCLE DUM=BYTEINTEGER(K) K=K+EPAGE BYTES REPEAT P=Q *OUT_18; ! SPECIAL PON AND SUSPEND FINISH TIMES=TIMES+1 REPEAT IF P_DEST = -1 START PREC("DMAGIO, FLAG=68", P, 0) WRSN("TIMES ", TIMES) WRSN("OUT18 ", OUT18) FLAG = 68; ! Lock down fails -> OUT FINISH ! FLAG=P_P2 ! LEN is also used to return no. of tape marks passed, in the case of ! 'tape position', 'file position', etc. ! ! K = P_P3; ! length of data read, or almost anything else! IF TYPE = 1 START ; ! READ IF K < 0 START ; ! backward read K = -K MOVE(K, ADR+LLEN-K, ADR) IF K < LLEN; ! need to move data down FINISH LLEN = K FINISH LLEN = K ! LCONTROL=P_P4 OUT: LOUTP STATE="DMAG IO exit" ! IF 45 # FLAG # 47 START ! USER FIELDS ARE ACCESSIBLE REPLY FLAG = FLAG CONTROL = LCONTROL LEN = LLEN FINISH ! RESULT = OUT(FLAG, "") END ; ! DMAG IO ! !-------------------end-of-included-file--------------------------------- !