!*********************************************************************** ! ! 2900 TAPE HANDLER ! !*********************************************************************** ! %IF SSERIES=NO %START !..........PSERIES..........PSERIES..........PSERIES..........PSERIES ! %CONSTINTEGER TOP LBE=36 ! { CH FN %CONSTINTEGERARRAY LBES(0:TOP LBE)= %C X'00000200', { 1 RF X'40001200', { 2 RR X'00000200', { 3 RF X'44C01200',X'86800D10',X'00006200', { 4 RR,AS,RFEC X'40001200', { 5 RR X'04C00200',X'86800D10',X'40007200', { 6 RF,AS,RREC X'04C00200',X'04805200',X'86800D10',X'00006200', { 7 RF,SR,AS,RFEC X'44C01200',X'04804200',X'86800D10',X'40007200', { 8 RR,SF,AS,RREC X'00000200', { 9 RF X'40001200', { 10 RR X'80000300', { 11 W X'80802300', { 12 WT X'04A05200',X'80004300', { 13 SR IGN TM,ER....FOR WRITE(TM) RETRY X'00804200', { 14 SF X'00805200', { 15 SR X'00802200', { 16 STF X'00803200', { 17 STR X'00803800', { 18 RW X'80004300', { 19 ER X'00A04200', { 20 SF IGN TM....FOR FINAL POSITIONING X'00A05200', { 21 SR IGN TM....DITTO X'04A04200',X'00805200', { 22 SF IGN TM,SR....FOR TM LOOK-AHEAD X'00000E00', { 23 SPC....AT LOAD TIME X'00805800', { 24 UNL....UNLOAD FLASH X'00803800' { 25 RW.....RLSE/RWND ! ! ALL LBES WHICH DO NOT INVOLVE A XFER REQUIRE IGNORE SHORT. ! %FINISHELSESTART !..........SSERIES..........SSERIES..........SSERIES..........SSERIES ! %CONSTINTEGER TOP CW=36 ! { CH FN %CONSTINTEGERARRAY CW(0:TOP CW)= %C X'2000C002', { 1 RF X'2000C012', { 2 RR X'2000C002', { 3 RF X'2C40C012',X'2840408D',X'20004062', { 4 RR,AS,RFEC X'2000C012', { 5 RR X'2C40C002',X'2840408D',X'20004072', { 6 RF,AS,RREC X'2C40C002',X'28404052',X'2840408D',X'20004062', { 7 RF,SR,AS,RFEC X'2C40C012',X'28404042',X'2840408D',X'20004072', { 8 RR,SF,AS,RREC X'2000C002', { 9 RF X'2000C012', { 10 RR X'2000C083', { 11 W X'2800C0A3', { 12 WT X'2A40C052',X'200040C3', { 13 SR IGN TM,ER X'2800C042', { 14 SF X'2800C052', { 15 SR X'2800C022', { 16 STF X'2800C032', { 17 STR X'2800C038', { 18 RW X'2000C0C3', { 19 ER X'2A00C042', { 20 SF IGN TM X'2A00C052', { 21 SR IGN TM X'2A40C042',X'28004052', { 22 SF IG TM,SR X'2000C00E', { 23 SPC X'2800C058', { 24 UNL X'2800C038' { 25 RW ! ! DO WE NEED IGNORE SHORT FOR NON-XFER, IF WERE NOT GOING TO GIVE A ! A DUMMY DATA AREA. DCU TELLS FROM LACK OF FIXED BIT IN STE THAT NO ! AREA REQUIRED. LEAVE IGN SHORT IN ABOVE FOR NOW. IT CANT DO ANY HARM. ! %FINISH;!.............................................................. ! %CONSTINTEGER MAX CHAINS=25,PRIVATE=MAX CHAINS+1 ! %CONSTBYTEINTEGERARRAY STATMASK(1:MAX CHAINS)=%C X'FE'(3),X'EC',X'FE',X'EC'(3),X'FE'(2),X'FC'(15) ! TERTIARY STATUS MASKS TO GO WITH EACH CHAIN ABOVE. ! FE=T0-T6. INCLUDES ADVISORY. ! EC=T0-T2,T4-T5. EXCLUDES MEDIA AND ADVISORY. ! %CONSTINTEGERARRAY CHAIN START(1:MAX CHAINS+1)= %C 0,1,2,3,6,7,10,14,18,19,20,21,22,24,25,26,27,28,29,30,31,32,34,35,36,0 ! THESE ARE THE LBE(CW) INDEX FOR CHAIN STARTS. ! CHAIN MAX+1 IS NOT REAL CHAIN.IT ACCOMMODATES PRIVATE CHAINS. ! SEE ROUTINE TERMINATE. ! %CONSTINTEGERARRAY CHAIN LENGTH(1:MAX CHAINS)= %C 1,1,1,3,1,3,4,4,1,1,1,1,2,1,1,1,1,1,1,1,1,2,1,1,1 ! THE NUMBER OF LBES(CWS) IN EACH CHAIN %CONSTINTEGER LAST READ CHAIN=10; ! JUST THAT %CONSTINTEGER LAST RETRY CHAIN=12 ! %CONSTINTEGER POSMASK=X'5A5A5'; ! READ CHAINS ONLY. BIT 2** INDEX SET ! IF THAT LBE(CW) LEAVES US AFTER THE BLOCK, UNSET IF BEFORE. %CONSTINTEGER REVMASK=X'A424A'; ! READ CHAINS ONLY. BIT 2** INDEX SET ! IF THAT LBE(CW) IS REVERSE READ. ! %IF SSERIES=NO %START !..........PSERIES..........PSERIES..........PSERIES..........PSERIES ! %CONSTINTEGER NODATA=X'20000000' %CONSTINTEGERARRAY IGNSHORTLONG(0:3)= %C 0,X'00800000',X'00400000',X'00C00000' %FINISHELSESTART !..........SSERIES..........SSERIES..........SSERIES..........SSERIES ! %CONSTINTEGER NODATA=X'00000200' %CONSTINTEGERARRAY IGNSHORTLONG(0:3)= %C 0,X'08000000',X'04000000',X'0C000000' %FINISH;!.............................................................. ! %CONSTLONGINTEGER LONG1=1 ! %CONSTINTEGER OK=0, NOTOK=-1 ! %CONSTINTEGER NOT AVAILABLE=0, MANUAL=1, LOADING=2, LOADED=3, CLAIMED=4 %CONSTINTEGER UNLOADING=5 %CONSTSTRING(11)%ARRAY STATES(0:5)= %C " NA ", " MANUAL ", " LOADING ", " LOADED ", " CLAIMED ", " UNLOADING " ! DRIVE STATES. ! %CONSTBYTEINTEGER TERM EXP=1, ATTN EXP=2 ! %CONSTINTEGER NRZI=2, PE=3 !* %CONSTINTEGER ME=X'310000' ! %CONSTINTEGER CONTROLLER=X'300000'; ! GPC OR DCU AS APPROPRIATE %CONSTINTEGER ALLOC=11, DEALLOC=5, EXEC=12 ! %CONSTINTEGER ON=1, OFF=0 ! %CONSTINTEGER REJECT=2, BAD PARAMS=1, NOT CLAIMED=2, SNO NOT FOUND=4 ! !------------------------------ FORMATS ------------------------------ ! %RECORDFORMAT PF(%INTEGER DEST,SRCE,P1,P2,P3,P4,P5,P6) ! %RECORDFORMAT SHORTPF(%INTEGER DEST,SRCE,P1,P2,P3,P4) ! %RECORDFORMAT CLF(%INTEGER DEST,SRCE,IDENT, (%HALFINTEGER H1,PERM, %STRING(7) DSN %OR %INTEGER REPLY,SNO,%BYTEINTEGER D1,D2,D3,DEVID), %STRING(3) MNEM,%BYTEINTEGER D4,D5,D6,MODE) ! %RECORDFORMAT REQF(%INTEGER ADDR,LENGTH,LSL,LSTBA, %BYTEINTEGER STATE,CHAIN,FINAL CHAIN, (%BYTEINTEGER TARGET POS %OR %BYTEINTEGER TM), (%INTEGER READORS %OR %INTEGER SKIP TOT), (%INTEGER COUNT %OR %INTEGER PRIVATE ATTN), %INTEGER RETRIES,RETRY LIMIT,%INTEGER COUNT1) ! %IF SSERIES=NO %START !..........PSERIES..........PSERIES..........PSERIES..........PSERIES ! %RECORDFORMAT RCBF(%INTEGER LIMFLAGS,LSTBA,LB BYTES,LBA,AL BYTES, ALA,INITWORD) ! %RECORDFORMAT TF(%INTEGER LINK,LAB1,LAB2,%STRING(7)DSN,%INTEGER LBE1, LBE2,LBE3,LBE4,ALE1,ALE2,STREAMR0,STREAMR1,OPS,PQ,%STRING(3)MNEM, %RECORD(REQF)REQ,%RECORD(RCBF)RCB,%INTEGER SNO,%RECORD(SHORTPF)REP, (%BYTEINTEGER T0,T1,T2,T3,T4,T5,T6,T7 %OR %LONGINTEGER T07), %BYTEINTEGER T8,T9,T10,T11,SSTAT,PROP1,PROP2,PROP3, %INTEGER FAULTS,%BYTEINTEGER STATE,MODE,LOAD STATE,UNLOAD PENDING) ! NOTE THAT TO OBTAIN ALIGNMENT OF RECORD 'REP' AND LONGINTEGER 'T07', ! 'SSTAT' IS FORCED OUT OF ITS NATURAL POSITION PRECEDING 'T0'. ! THE ABOVE RECORD IS MAPPED ONTO THE USER AREA IN THE DEVICE SLOT, ! AND MAY EXTEND UP TO 200 BYTES. ! CURRENT LENGTH OF ABOVE IS - 184 %CONSTINTEGER TFSIZE=184 %FINISHELSESTART !..........SSERIES..........SSERIES..........SSERIES..........SSERIES ! %RECORDFORMAT TCBF(%INTEGER CW,STE,LENGTH,ADDR,NEXT TCB, %BYTEINTEGER PSTAT,RESPONSE,%HALFINTEGER REMBC, %INTEGERARRAY PREAMBLE,POSTAMBLE(1:4)) ! %RECORDFORMAT TF(%INTEGER LINK,%STRING(3) MNEM,%INTEGER LAB1,LAB2, %STRING(7)DSN, %RECORD(REQF)REQ,%RECORD(SHORTPF)REP, (%BYTEINTEGER T0,T1,T2,T3,T4,T5,T6,T7 %OR %LONGINTEGER T07), %BYTEINTEGER T8,T9,T10,T11,SSTAT,PROP1,PROP2,PROP3, STATE,MODE,LOAD STATE,UNLOAD PENDING, %INTEGER SNO,STREAMR0,STREAMR1, %RECORD(TCBF)%ARRAY TCBS(1:6), %INTEGER PQ,FAULTS,OPS) ! SEE NOTE RE ALIGNMENT IN PSERIES FORMAT ABOVE. ! THIS MAY EXTEND TO 480 BYTES. CURRENT LENGTH IS 468 ! ONLY 4 OF THE 6 TCBS ARE USED HERE. UP TO 6 FOR PRIVATE CHAINS. %CONSTINTEGER TFSIZE=468 %FINISH;!.............................................................. ! %RECORDFORMAT DF(%INTEGER SER, PTSM, PROPADDR, TICKS SINCE, CAA, GRCB AD, LBA, ALA, STATE, RESP0, RESP1, SENSE1, SENSE2, SENSE3, SENSE4, REPSNO, BASE, ID, DLVN, MNEMONIC, ENTSIZE, PAW, USAW0, URCB AD, SENSDAT AD, LOGMASK, TRTAB AD, UA SIZE, UA AD, TIMEOUT, PROPS0, PROPS1) ! %RECORDFORMAT PBF(%RECORD(PF)P,%INTEGER LINK) ! !------------------------- EXTERNAL SPECS --------------------------- ! %IF MULTIOCP=YES %START %EXTERNALROUTINESPEC RESERVELOG %EXTERNALROUTINESPEC RELEASELOG %FINISH %EXTERNALROUTINESPEC OPMESS(%STRING(23) S) %EXTERNALLONGINTEGERSPEC KMON %EXTERNALROUTINESPEC PKMONREC(%STRING(20)TXT,%RECORD(PF)%NAME P) %EXTERNALROUTINESPEC PON(%RECORD(PF)%NAME P) %EXTERNALLONGINTEGERSPEC PARMDES %EXTERNALINTEGERFNSPEC NEWPPCELL %EXTERNALROUTINESPEC RETURNPPCELL(%INTEGER CELL) %EXTERNALSTRINGFNSPEC HTOS(%INTEGER VAL,PLACES) %EXTERNALROUTINESPEC DUMPTABLE(%INTEGER TABNO,ADDR,L) %SYSTEMROUTINESPEC MOVE(%INTEGER L,F,T) %SYSTEMROUTINESPEC ETOI(%INTEGER A,L) %EXTERNALROUTINESPEC PRHEX(%INTEGER N) ! !===================================================================== ! %EXTERNALROUTINE TAPE(%RECORD(PF)%NAME P) ! %OWNINTEGER FIRSTTP=0, VOLUMS=0, INITIALISED=0 %OWNINTEGER READ RETRIES=15,WRITE RETRIES=6 ! WRITE RETRIES ARE LIMITED BY THE MAX INTERBLOCK GAP=300 INCHES. ! 6 ASSUMES A MAX BLOCK SIZE OF @64K AT 1600 BPI(IE 40 INCHES). ! P SERIES BLOCKS CAN BE UP TO 256K, BUT WE CANT CATER FOR THAT WHICH ! WOULD GIVE US ONLY ONE RETRY! IT WOULD BE SMARTER TO MAKE THE RETRIES ! A FUNCTION OF THE WRITTEN LENGTH. %OWNINTEGER RLEVEL=0 ! REPORTING LEVEL: ! 2**0 - REPORT PARM RECORDS IN ! 2**1 - REPORT PARM RECORDS OUT ! 2**2 - DUMP TABLE AFTER CHAIN FIRED %OWNINTEGERNAME LASTLINK %OWNRECORD(PBF)%ARRAYFORMAT PBAF(0:4095) %OWNRECORD(PBF)%ARRAYNAME PB %RECORD(DF)%NAME D %RECORD(TF)%NAME T %RECORD(REQF)%NAME REQ %RECORD(SHORTPF)%NAME REP %RECORD(PF)PP %INTEGERNAME PREVLINK %INTEGER I,NDECKS,MODE,ACT,SNO,UNQ,TMON %STRING(4) M %SWITCH ACTSW(1:13) ! %ROUTINESPEC FIRE CHAIN %ROUTINESPEC TERMINATE(%INTEGER N,B) %ROUTINESPEC TELL VOLUMS(%INTEGER LOAD TYPE) ! %ROUTINE MON(%INTEGER MODE,%RECORD(PF)%NAME P) %CONSTSTRING(4)%ARRAY MODES(1:5)= %C "IN","OUT","PEND","UNPD","IN??" PKMONREC(" TAPE(".MODES(MODE)."): ",P) %END; ! ROUTINE MON ! ! %ROUTINE MYPON(%RECORD(PF)%NAME P) %IF TMON#0 %OR RLEVEL&2#0 %THEN MON(2,P) PON(P) %END; ! ROUTINE MYPON ! ! %ROUTINE REPORT(%STRING(255) MESS) !*********************************************************************** ! REPORTS ABNORMAL CONDITIONS TO LOG !*********************************************************************** %CONSTBYTEINTEGERARRAY HX(0:15)= %C '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' ! %ROUTINE PBYTE(%BYTEINTEGER N) PRINTSYMBOL(HX(N>>4)) PRINTSYMBOL(HX(N&X'F')) %END; ! ROUTINE PBYTE ! %INTEGER I,J,SIZE T_FAULTS=T_FAULTS+1 RESERVELOG %IF MULTIOCP=YES PRINTSTRING(" TAPE ERROR// ABNORMAL TERMINATION - ".MESS." DECK ") PBYTE(T_PROP2) PRINTSTRING(" FAULTS (DECK/REQ) ") PRHEX((T_FAULTS<<16)!REQ_RETRIES) PRINTSTRING(" REQ ID ") PRHEX(REP_P1) SPACE PRINTSTRING(T_DSN) %UNLESS 3<=T_LOAD STATE<=4 ! IT MIGHT BE JUNK IN THAT CASE. %IF REQ_CHAIN<=10 %START MESS=" READ" %FINISHELSEIF REQ_CHAIN<=12 %START MESS=" WRITE" %FINISHELSE MESS=" OTHER" PRINTSTRING(MESS) PRINTSTRING(" SST T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 ") SPACE PBYTE(T_SSTAT) J = ADDR(T_T0) %FOR I=0,1,11 %CYCLE SPACES(2) PBYTE(BYTEINTEGER(J+I)) %REPEAT %IF REQ_RETRIES=0 %THEN SIZE=TFSIZE %ELSE SIZE=64 ! TRUNCATE TABLE TO JUST WHAT JOURNAL NEEDS IF RETRYING DUMP TABLE(61,ADDR(T),SIZE) RELEASELOG %IF MULTIOCP=YES %END; ! ROUTINE REPORT ! ! %INTEGERFN SEARCH TPS(%INTEGER SWIND,IMATCH,%STRING(6) SMATCH) !********************************************************************** ! CALLED TO SCAN T CHAIN MATCHING IMATCH OR SMATCH RETURNING OK ! OR NOTOK,LEAVING T MAPPED TO MATCHING RECORD. ! OR TO SCAN ENTIRE CHAIN WITHOUT MATCHING, WHEN RESULT IS IRRELEVANT ! AND T IS LEFT MAPPED TO LAST RECORD. ! SWIND=1 - SMATCH MNEMONIC ! =2 - SMATCH DSN ! =3 - IMATCH SNO ! =4 - SCAN AND TELL VOLUMS ! =5 - SCAN AND DISPLAY !********************************************************************** %STRING(6) DSN %SWITCH SW(1:5) %RESULT=NOTOK %IF FIRSTTP=0; ! CHAIN EMPTY T==RECORD(FIRSTTP) PREVLINK==FIRSTTP ! %CYCLE ->SW(SWIND) ! SW(1):; ! MATCH MNEM %IF T_MNEM=SMATCH %THENRESULT=OK ->NEXT ! SW(2):; ! MATCH DSN %IF T_DSN=SMATCH %THENRESULT=OK ->NEXT ! SW(3):; ! MATCH SNO %IF T_SNO=IMATCH %THENRESULT=OK ->NEXT ! SW(4):; ! TELL VOLUMS %IF LOADED<=T_STATE<=CLAIMED %THEN TELL VOLUMS(1) ! COULD IT BE CLAIMED IF VOLUMS ONLY JUST HERE? ->NEXT ! SW(5):; ! TELL OPER %IF LOADED<=T_STATE<=CLAIMED %THEN DSN=T_DSN %ELSE DSN="" OPMESS(HTOS(T_SNO,4)." ".T_MNEM.STATES(T_STATE).DSN) ->NEXT ! NEXT: %RESULT=NOTOK %IF T_LINK=0 PREVLINK==T_LINK T==RECORD(T_LINK) %REPEAT %END; ! FN SEARCH TPS !* !* %ROUTINE TELL VOLUMS(%INTEGER LOAD TYPE) !*********************************************************************** ! TELLS VOLUMS ABOUT LOAD OR UNLOAD OF DRIVE. ! LOAD TYPE=0(NOT LOADED), 1(LOADED) ! VOLUMS ALSO NEEDS TO KNOW LOADED WITH LABEL(1) OR NO LABEL(2) !*********************************************************************** %RECORDFORMAT VF(%INTEGER DEST,SRCE,TYPE,LOAD,%STRING(4)MNEM, %C %STRING(7) DSN,%BYTEINTEGER D1,MODE,PERM) %RECORD(VF) V %IF VOLUMS=0 %THENRETURN; ! VOLUMS NOT THERE %IF LOAD TYPE=1 %AND T_DSN="NOLABEL" %THEN LOAD TYPE=2 V=0 V_DEST=VOLUMS V_SRCE=ME V_TYPE=4 V_LOAD=LOAD TYPE V_DSN=T_DSN %UNLESS LOAD TYPE=0 V_MNEM=T_MNEM V_PERM=2-((T_PROP3>>6)&1) V_MODE=T_MODE MYPON(V) %END; ! ROUTINE TELL VOLUMS ! ! %ROUTINE LOAD !*********************************************************************** ! ENTERED TO GET PROPS AND, IF APPROPRIATE, LOAD EACH DECK SUCCESSFULLY ! ALLOCATED AT START-UP, AND THEREAFTER FOR ANY DECK GIVING AN AUTO ! ATTENTION, AND ! TO UNLOAD OR RELEASE/REWIND A DECK WHEN USER RELEASES IT OR AT ! DISASTER. !*********************************************************************** %OWNINTEGER VOL1=X'E5D6D3F1' %INTEGER I,CH %STRING(7) DSN %STRING(40) S %SWITCH LDSW(0:9) ! ->LDSW(T_LOAD STATE) ! LDSW(0):; ! GET PROP CODE. REP=0 REQ=0 REQ_ADDR=ADDR(T_PROP1) REQ_LENGTH=3 REQ_CHAIN=23 T_MODE=PE FIRE CHAIN T_LOAD STATE=1 T_STATE=LOADING %RETURN ! LDSW(1):; ! REPLY FROM SEND PROPS %IF REP_P2#0 %START ! WE EXPECT IT TO FAIL FOR UNLOADED DECKS AT START-UP %IF T_T0&X'C0'#0 %START; ! UNAVAIL OR MANUAL %IF T_T0&X'40'#0 %THEN T_STATE=NOT AVAILABLE %ELSE T_STATE=MANUAL ->EXIT %FINISHELSE ->LOAD FAIL %FINISH ! SO ITS AVAILABLE AND LOADED ! THE SENSE BYTES ARE ONLY UPDATED BY CONTROLLER SENSE AFTER ABTERM. ! WE THEREFORE DONT HAVE THEM HERE TO TELL (T11) WHETHER ITS AT BT. ! WE MUST JUST DO A REWIND. ! REP_P2=0 REQ=0 REQ_CHAIN=18 %IF SSERIES=NO %START !........PSERIES..........PSERIES..........PSERIES..........PSERIES ! ! WE DONT NEED DUMMY DATA AREA FOR SSERIES. REQ_ADDR=X'81000000' REQ_LENGTH=50; ! STANDARD DUMMY ASL %FINISH;!............................................................ FIRE CHAIN T_LOAD STATE=2 %RETURN ! LDSW(2):; ! REPLY FROM INITIAL REWIND %IF REP_P2#0 %START ! INITIAL REWIND FAILED ->LOAD FAIL %FINISH ! SO LETS TRY TO READ SOMETHING LIKE A LABEL. ! FIRST IN PE MODE, AND IF THIS FAILS AND NRZI FITTED THEN TRY THAT SET UP READ: ! CAUTION*** COME HERE FROM LDSW(1) AND LDSW(4) ALSO ! REP_P2=0 REQ=0 REQ_ADDR=ADDR(T_LAB1) REQ_LENGTH=16 REQ_CHAIN=1; ! READ FORWARD REQ_FINAL CHAIN=9; ! STANDARD REQ_TARGET POS=1 REQ_READORS=IGNSHORTLONG(2); ! IGNORE LONG SINCE IT SURELY WILL BE REQ_RETRY LIMIT=4 ! THIS ACUALLY ONLY GIVES US 2 GOES AT IT, SINCE REVERSE READS LONG ! ARE INEVITABLY FAILURES (SEE OK(1) IN 'TERMINATE') FIRE CHAIN T_LOAD STATE=3 %RETURN ! LDSW(3):; ! REPLY FROM LABEL READ(PE OR NRZI) CH=0 %IF REP_P2#0 %START; ! FAILED %IF T_T4&128#0 %START; ! WRONG MODE %IF T_MODE=PE %AND T_PROP3&16#0 %START ! THAT WAS PE, AND NRZI IS FITTED, SO TRY THAT ! FIRST A REWIND REP=0 REQ_CHAIN=18 ! PREV ADDR/LENGTH WILL DO IF REQD T_LOAD STATE=4 FIRE CHAIN %RETURN %FINISH ! SO EITHER TRIED BOTH, OR NRZI NOT FITTED. SET MODE UNDEFINED. ! THE ONLY THING THAT CAN BE DONE TO THIS TAPE IS A WRITE AT BT, ! AFTER A MODE OVERRIDE IN 'CLAIM VOLUME'. T_MODE=0 OPMESS(T_MNEM." UNDEFINED MODE") %FINISH ! SO SOME ERROR OTHER THAN IDENTIFIER, MAYBE NOISE. RETAIN IT AS ! 'NOLABEL'. %FINISHELSESTART; ! PE OR NRZI READ SUCCEEDED. ! IBM LABELS ARE 80 BYTES STARTING 'VOL1' IN EBCDIC. ! ICL MAY BE 86,96 OR GREATER IF IPL BLOCKS. EACH BEGINS WITH INTEGER ! BLOCK COUNT AND HALFINTEGER BYTE LENGTH. %IF T_LAB1=0 %THEN MOVE(10,ADDR(T_LAB1)+6,ADDR(T_LAB1)) ! IE IT WAS A BLOCK COUNT, SO MOVE DATA FIELD DOWN. %IF T_LAB1=VOL1 %START; ! FORMAT OK MOVE(6,ADDR(T_LAB1)+4,ADDR(DSN)+1) LENGTH(DSN)=6 ETOI(ADDR(DSN)+1,6) ! NOW CHECK FOR VALID CHARS IN DSN %FOR I=1,1,6 %CYCLE CH=CHARNO(DSN,I) %UNLESS '0'<=CH<='9' %OR 'A'<=CH<='Z' %OR CH=' ' %START OPMESS(T_MNEM." FAULTY DSN - ".DSN) CH=0 %EXIT %FINISH %REPEAT %FINISH %FINISH ! SO UNDEFINED MODE, OR READ FAILED OTHER THAN IDENTIFIER, ! OR AN INVALID FORMAT READ, OR AN INVALID DSN READ, ! ALL GET HERE WITH CH=0 AND ARE ALL TREATED AS NOLABEL. ! GET HERE WITH CH#0 ONLY IF GOOD DSN READ. %IF CH#0 %THEN T_DSN=DSN %ELSE T_DSN="NOLABEL" REP=0 REQ_CHAIN=18 ! PREV ADDR AND LENGTH WILL DO FOR DUMMY IF NEEDED FIRE CHAIN T_LOAD STATE=5 %RETURN ! LDSW(4):; ! REWIND AFTER FAILED PE READ, FOR A TRY AT NRZI. %IF REP_P2#0 %THEN ->LOAD FAIL T_MODE=NRZI ->SET UP READ; ! WITH REP_P2=0 ! LDSW(5):; ! FINAL REWIND %IF REP_P2#0 %THEN ->LOAD FAIL ! LOAD OK: T_STATE=LOADED TELL VOLUMS(1) OPMESS(T_MNEM." LOADED ".T_DSN) ! EXIT: T_LOAD STATE=0 %RETURN ! LOAD FAIL: OPMESS(T_MNEM." LOAD FAILED") T_LOAD STATE=6 ! AND DROP THRU' TO ....... ! UNLOAD: LDSW(6):LDSW(8):; ! ENTRY POINT FOR UNLOAD, RELEASE/REWIND %IF LOADED<=T_STATE<=CLAIMED %THEN TELL VOLUMS(0) T_DSN=""; ! JUST TO KEEP 'CLAIM VOLUME' TIDY REP=0 REQ=0 %IF T_LOAD STATE=6 %THEN REQ_CHAIN=24 %ELSE REQ_CHAIN=18 ! DISCONNECT REWIND %IF SSERIES=NO %START !..........PSERIES..........PSERIES..........PSERIES..........PSERIES ! REQ_ADDR=X'81000000' REQ_LENGTH=50 %FINISH;!.............................................................. FIRE CHAIN T_LOAD STATE=T_LOAD STATE+1 T_STATE=UNLOADING %RETURN ! LDSW(7):; ! REPLY FROM UNLOAD %IF REP_P2#0 %AND T_T0&X'C0'=0 %THENC S=" UNLOAD FAILS. PRESS STOP/UNLOAD" %ELSE S=" UNLOADED" ! IT MIGHT ALREADY BE UNLOADED IF PRIVATE CHAIN USER HAS DONE IT. OPMESS(T_MNEM.S) T_STATE=MANUAL ->EXIT ! LDSW(9):; ! REPLY FROM RLSR/RWND %IF REP_P2#0 %START OPMESS(T_MNEM." RLSE/RWND FAILS") T_LOAD STATE=6 ->UNLOAD %FINISH ! NOW RE-READ LABEL. WE'RE AT BT AND REP_P2=0 SO GO STRAIGHT TO READ T_LOAD STATE=2 T_STATE=LOADING ->LDSW(2) ! ! %END; ! ROUTINE LOAD !* !* %ROUTINE CLAIM VOLUME(%RECORD(CLF)%NAME P) !********************************************************************** ! ALLOCATES VOLUME TO REQUESTING USER. ! P_DSN IS REQUIRED VOLUME, OR P_MNEM IF P_DSN="NOLABEL". ! P_PERM IS REQUIRED PERM, 1=READ, 2=RITE ! P_MODE IS REQUIRED MODE: ! MODE&3=3(PE),OR 2(NRZI) OVERRIDES MODE ESTABLISHED IN LABEL READ, ! (UNLESS NRZI SPECIFIED AND NOT FITTED, WHEN REJECT). ! IF NO OVERRIDE MODE SPECIFIED AND NO MODE ESTABLISHED AT LABEL ! READ (SOME OTHER MODE RECORDED OR BLANK TAPE), THEN REJECT. ! MODE&4 IS COMPRESS EXPAND AND IS ORED INTO TAPE MODE OR OVERRIDE ! AS APPROPRIATE. ! A MODE OF ZERO THUS USES CURRENT TAPE MODE AND NO CE. !********************************************************************** %STRING(6) DSN %INTEGER OVERMODE,I %IF P_DSN="NOLABEL" %THEN I=SEARCH TPS(1,0,P_MNEM) %C %ELSE I=SEARCH TPS(2,0,P_DSN) OVERMODE=P_MODE&3 %IF I=NOTOK %OR T_STATE#LOADED %START ! IF SEARCH FAILS, THEN DSN NOT FOUND, OR MNEMONIC NOT PRESENT ! IF SEARCH SUCCEEDS, T MAPPED. IF STATE#LOADED THEN TAPE ALREADY ! CLAIMED. THIS LATTER CHECK IS DONE BY VOLUMS BEFORE COMING HERE, ! BUT WE DO IT HERE FOR CHOPSUPE (NO VOLUMS AROUND YET). P_REPLY=1 %FINISHELSEIF T_PROP3&X'40'#0 %AND P_PERM=2 %START ! N0 RING FITTED AND WRITE REQUESTED P_REPLY=2 %FINISHELSEIF OVERMODE=1 %OR (OVERMODE=0 %AND T_MODE=0) %ORC (OVERMODE=NRZI %AND T_PROP3&X'10'=0) %START ! INVALID OVERRIDE MODE, OR ! NO OVERRIDE MODE AND NONE ESTABLISHED AT LABEL READ, OR ! NRZI OVERRIDE MODE AND NOT FITTED P_REPLY=3 %FINISHELSESTART; ! ALL OK T_STATE=CLAIMED %IF OVERMODE#0 %THEN T_MODE=OVERMODE T_MODE=T_MODE!(P_MODE&4); ! INCLUDE CE BIT IF ANY T_SNO=(T_SNO+X'100')&X'FFFF' ! BOTTOM BYTE IS SNO PROVIDED BY CONTROLLER. TOP BYTE IS CYCLIC 0-255. ! SO IF WE LOSE A DECK AND DO NOT GET THE EXPECTED RELEASE FROM USER ! WE CAN REALLOCATE THE DECK WITHOUT FEAR OF THE OUTSTANDING SNO COMING. ! BUT CAUTION*** THE SNO (STREAM ACTUALLY) PROVIDED BY CONTROLLER IS NOT ! GUARANTEED TO BE ONLY A BYTE. IF THERE ARE ENOUGH DEVICES IT COULD ! GO OVER. P_SNO=ME!T_SNO P_DEVID=T_PROP2; ! CONTROLLER/MECH ADDRESS. CAN BE USED BY USER ! IF WRITING, TO SHOW LAST DECK WRITTEN ON. P_MODE=T_MODE P_REPLY=OK %FINISH %END; ! ROUTINE CLAIM VOLUME ! ! %ROUTINE ATTENTION !*********************************************************************** ! ENTERED TO DEAL WITH ATTENTIONS. ! IT IS REPUTEDLY POSSIBLE FOR MULTIPLE INDEPENDENT BITS TO BE SET ! IF SEVERAL STATE CHANGES OCCURRED IN THE DEVICE WHILE THE SYSTEM ! WAS UNINTERRUPTIBLE (NORMALLY THE ONLY TWO WHICH WOULD BE EXPECTED ! TOGETHER ARE AUTO AND BT). THIS CODE ATTEMPTS TO DEAL WITH SUCH ! MULTIPLE OCCURENCES, BUT LACKING THE TIME SEQUENCE OF THE BITS ! THEY ARE NOT NECESSARILY UNAMBIGUOUS AND WE MAY END UP IN A STATE ! DIFFERENT FROM THE DEVICE. HOWEVER THIS SHOULD BE EXCEEDINGLY RARE ! AND IN MOST CASES REMEDIAL BY OPERATOR ACTION. !*********************************************************************** %CONSTINTEGER AUTO=X'80',BT=X'40',TM=X'10',ENGINR=8,AVAIL=4,NOT AVAIL=2, HOLD=1 %INTEGER ATTN,I %SWITCH SW(0:2) ! %ROUTINE RELEASE TELL VOLUMS(0) %IF LOADED<=T_STATE<=CLAIMED %IF REQ_STATE#0 %START ! TERM EXPECTED REQ_STATE=0 %IF REP_DEST#0 %START; ! BY USER REP_P2=3 MYPON(RECORD(ADDR(REP))); ! MUST DO IT THIS WAY SINCE REP'S LENGTH IS < THAN PARAM SPEC %FINISHELSE T_LOAD STATE=0 ! IE ABORT LOAD OR UNLOAD %FINISH T_UNLOAD PENDING=0; ! IN CASE IT ISNT %END; ! ROUTINE RELEASE ! %ROUTINE REPORT PRIVATE ATTN %IF REQ_PRIVATE ATTN=0 %THENRETURN P_DEST=REQ_PRIVATE ATTN ! THE REST IS AS RECEIVED FROM CONTROLLER. PASS IT ON MYPON(P) %END; ! REPORT PRIVATE ATTN ! ATTN=(T_STREAMR0>>8)&X'DF'; ! BIT 2**5 ALWAYS SET %IF ATTN&ENGINR#0 %THEN ATTN=(ATTN&(\ENGINR))!NOT AVAIL ! WE TREAT ENGINEER STATE AS SYNONYMOUS WITH NOT AVAILABLE? ! AGAIN: %IF ATTN=0 %THENRETURN %IF T_STATE>1 %THEN I=2 %ELSE I=T_STATE ! THUS LOADING,LOADED,CLAIMED AND UNLOADING=AUTO ->SW(I) ! SW(0):; ! NOT AVAILABLE %IF ATTN&AVAIL#0 %START T_STATE=MANUAL ATTN=ATTN&(\AVAIL) OPMESS(T_MNEM." AVAILABLE") ->AGAIN %FINISH ->SPURIOUS ! SW(1):; ! MANUAL %IF ATTN&NOT AVAIL#0 %START T_STATE=NOT AVAILABLE ATTN=ATTN&(\NOT AVAIL) OPMESS(T_MNEM." NOT AVAILABLE") ->AGAIN %FINISH %IF ATTN&AUTO#0 %START LOAD; ! INITIATE LOAD (SETTING STATE TO LOADING) ATTN=ATTN&(\AUTO) ATTN=ATTN&(\BT) ! BT MAY BE SET IF PREVIOUS TAPE WAS UNLOADED BY STOP/UNLOAD ! RATHER THAN BY SOFTWARE. TO BE IN MANUAL HERE WE MUST ALSO ! HAVE GONE NOT AVAILABLE, AVAILABLE AS WELL SO NO ACTION IS ! REQUIRED ON THE BT. ->AGAIN %FINISH ->SPURIOUS ! SW(2):; ! AUTO %IF ATTN&AUTO#0 %START ! IT HAS GONE TO MANUAL BEHIND OUR BACK, EITHER ! A) AT THE DEVICE BY STOP KEY, WHICH GIVES US NOTHING. IF IT HAS ! ALSO BEEN UNLOADED BEHIND OUR BACK BY UNLOAD KEY, THEN BT WILL ! BE SET NOW. ! B) BY A PRIVATE CHAIN WHICH HAS DONE AN UNLOAD. IN THIS CASE, BT ! WILL NOT BE SET NOW EVEN THOUGH IT HAS BEEN UNLOADED. ! SO IF LAST REQUEST WAS NOT PRIVATE AND BT IS NOT SET, THE TAPE HAS ! NOT BEEN UNLOADED AND WE CAN CONTINUE AS IF THIS HAD NOT HAPPENED. ATTN=ATTN&(\AUTO) %IF ATTN&BT#0 %OR REQ_CHAIN=PRIVATE %START ! TAPE MAY HAVE BEEN UNLOADED. WE MUST ASSUME CHANGED. ATTN=ATTN&(\BT) RELEASE T_DSN=""; ! TIDINESS LOAD; ! AND INITIATE A RELOAD %FINISH ->AGAIN %FINISHELSEIF ATTN&BT#0 %START ! BT WITHOUT AUTO %IF REQ_STATE=ATTN EXP %OR REQ_CHAIN=PRIVATE %START ATTN=ATTN&(\BT) %IF REQ_STATE=ATTN EXP %THEN TERMINATE(-1,1) %C %ELSE REPORT PRIVATE ATTN ->AGAIN %FINISH %FINISHELSEIF ATTN&NOT AVAIL#0 %START ATTN=ATTN&(\NOT AVAIL) OPMESS(T_MNEM." NOT AVAILABLE") RELEASE T_DSN="" T_STATE=NOT AVAILABLE ->AGAIN %FINISHELSEIF ATTN&HOLD#0 %START ATTN=ATTN&(\HOLD) OPMESS(T_MNEM." MANUAL WHEN IN USE") %IF T_STATE=CLAIMED %IF REQ_STATE=0 %START ! CLAIMED AND IDLE, OR LOADED. NOT LOADING OR UNLOADING. T_LOADSTATE=6 LOAD; ! UNLOAD ENTRY POINT %FINISHELSESTART ! CLAIMED AND IN USE, OR LOADING OR UNLOADING T_UNLOAD PENDING=1 %UNLESS T_STATE=UNLOADING %FINISH ->AGAIN %FINISHELSEIF ATTN&TM#0 %START %IF REQ_STATE=ATTN EXP %OR REQ_CHAIN=PRIVATE %START ATTN=ATTN&(\TM) %IF REQ_STATE=ATTN EXP %THEN TERMINATE(-1,0) %C %ELSE REPORT PRIVATE ATTN ->AGAIN %FINISH %FINISH ! SPURIOUS: REPORT("SPURIOUS ATTENTION(S)") %END; ! ROUTINE ATTENTION ! ! %ROUTINE TERMINATE(%INTEGER NORMAL,BT) !********************************************************************** ! ENTERED ON CHAIN TERMINATION. ! NORMAL=0 FOR NORMAL TERMINATION, ! >0 FOR ABNORMAL TERMINATION, ! =-1 IF WE ENTERED VIA ATTENTION FOR EXPECTED BT OR TM, ! WHEN BT=1 OR 0 RESPECTIVELY. ! THIS ENTRY FOR CHAINS 16,17(SKIP TM FORE AND AFT),18(REWIND) ! AND NOTIONAL CHAIN 0, SEE US(5) BELOW. !********************************************************************** %CONSTINTEGER ERROR CLASSES=6 ! %CONSTSTRING(13)%ARRAY USMESS(1:ERROR CLASSES)= %C "LOST DEVICE", "LOST POSITION", "IRRECOVERABLE", "RECOVERABLE", "REV BT", "STIE/RIPE" ! %INTEGER PSTAT,FINAL COMMAND,ERROR CLASS,SKIP,REMBC,FLAG %SWITCH OK(0:MAX CHAINS),US(1:ERROR CLASSES),LS,TM(1:MAX CHAINS) ! %INTEGERFN DIAGNOSE ! ENTERED ON ABTERM WITH UNSUCCESSFUL IN PSTAT TO DIAGNOSE ERROR BITS ! IN TERTIARY STATUS T0-T7 ! RETURNS ERROR CLASS. ! ! THE INTERPRETATION OF THE TERTIARY STATUS BITS FOLLOWS, TOGETHER WITH ! THEIR ASSIGNMENT TO ONE OF SIX CLASSES. THE CLASSES ARE: ! ! 1 - LOST DEVICE ! 2 - EITHER LOST POSITION OR SHOULD NEVER HAPPEN SO WE HAVE A BUG. ! 3 - COMMAND FAILED AND THEIR IS NO POINT IN RETRYING, BUT POSITION ! IS OK, AND THE USER MAY CONTINUE. ! 4 - COMMAND FAILED AND SHOULD BE RETRIED. ! 5 - REVERSED INTO BT ! 6 - ADVISORY (JUST LOG IT FOR ENGINEERS SAKE) ! ! SOME OF THE BITS INDICATE ERRORS IN THE STRUCTURE OF A BLOCK - ! EG 'NON VALID NRZI BLOCK', 'NO PREAMBLE', ETC. ! IT MIGHT BE THOUGHT THAT SINCE A BLOCK, ALBEIT DEFORMED, WAS DETECTED ! IT IS SAFE TO SKIP BACK OVER IT FOR A RETRY. HOWEVER, THE BLOCK MIGHT ! NOT BE DETECTED IN REVERSE AND POSITION WOULD THUS BE LOST. ALL SUCH ! BITS ARE THEREFORE ASSIGNED TO CLASS 2. THIS MAY BE TOO SEVERE IN THE ! LIGHT OF EXPERIENCE. ! 'NO POSTAMBLE' HAS BEEN RECLASSIFIED FROM 2 TO 4. IT WAS FOUND TO OCCUR ! SPURIOUSLY VERY OFTEN WITH UTIE, AND SO FAR HAS BEEN FOUND SAFE TO RETRY. ! ON THE OTHER HAND, EXPERIENCE HAS SHOWN THAT 'NO PREAMBLE' MUST VERY ! DEFINITELY NOT BE RETRIED. ! ! ! BIT POS CLASS MEANING ! 2**N ! ! 63 1 MANUAL ! 62 1 NOT AVAILABLE ! 55 2 IPE WE DONT KNOW WHETHER THE ERROR ! 54 2 2*RIPE WAS ON THE COMMAND GOING OR DATA ! 53 2 SRNH COMING, SO POSITION IS LOST. ! 47 2 ILLEGAL COMMAND A BUG ! 46 2 ILLEGAL MODE DITTO ! 45 3 ILLEGAL DATA CE MODE ONLY ! 44 3 DOUBLE FILLER ONLY WITH 2**45 ! 43 5 REVERSED INTO BT ! 42 2 NO RING FOR WRITE A BUG ! 41 2 DECK BUSY SHOULD NEVER HAPPEN, SO BUG ! 39 4 VRC ! 38 2 NON VALID NRZI BLOCK ! 37 4 UTIE ! 36 4 SKEW ! 35 2 NO PREAMBLE(PE) ! 4 CRC(NRZI) ! 34 4 DATA SHORT(PE) HAPPENS FOR PARTICULAR DATA PATTERN ! AND STIE CORRECTION ! 4 LRC(NRZI) ! 33 4 NO POSTAMBLE(PE) ! 4 TIE(NRZI) ! 32 4 THRESHOLD ! 31 2 IDENTIFIER A BUG(EXCEPT IN LOAD SEQUENCE ! 30 2 NO DATA WRITTEN WHAT DOES THIS MEAN??? ! 29 2 INVALID NRZI BLOCK OF A DIFFERENT KIND!! ! 27 2 25 FEET BLANK ! 25 2 POOR ERASURE. NOW YOU SEE IT, NOW YOU DONT ! 15 6 RIPE ! 12 6 STIE ERROR RECOVERED ON FLY ! 10 6 BUSY SET (BUT NOT MASKED IN) ON OK TERM ! SKIP REV TM, REWIND, AND ON ABTERM ! WITH 'REV BT' FOR READ REV AND ! SKIP REV. THUS IT WILL NEVER CAUSE ! ABTERM OR BE LOGGED ON ITS OWN. ! SINCE ALL POSSIBLE CLASS 4 AND 6 ERRORS ARE MASKED OFF AT THE START ! OF EVERY MULTI-COMMAND READ RETRY CHAIN, EACH SUCH CHAIN CAN ! TERMINATE BEFORE THE LAST COMMAND, ONLY FOR CLASSES 1,2 AND 3. ! FOR CLASSES 1 AND 2, POSITION IS ALREADY LOST BY VIRTUE OF THE ERROR, ! SO THE POSITION OF THE FAILING LBE(CW) IS IRRELEVANT. IT LOOKS UNLIKELY ! THAT THE CURRENTLY DEFINED CLASS 3 ERRORS (CONCERNING THE DATA COUNT ! IN CE MODE) COULD ARISE OTHER THAN ON THE PRIMARY READ OF A SEQUENCE, ! BUT IT IS POSSIBLE IF SUCH ERRORS ARE MASKED AT THE DEVICE LEVEL BY ! OTHER ERRORS. IN ANY CASE, TO CATER FOR THE RECLASSIFICATION OF SOME ! BITS, WE ARE PREPARED TO DO A FINAL REPOSITIONING FROM A CLASS 3 ! ERROR OCCURRING ANYWHERE THRU' A MULTI-COMMAND READ CHAIN. IN ALL ! CASES, HOWEVER, WE ASSUME THAT THE FAILING LBE(CW) WILL HAVE BEEN ! EFFECTIVE IN TRAVERSING ITS BLOCK. ! ! THE SAME PROBLEM DOES NOT ARISE FOR WRITE AND WRITE TM RETRIES ! WHICH ARE MUCH LESS COMPLEX. ! ! %CONSTLONGINTEGERARRAY PE ERROR MASKS(1:ERROR CLASSES)= %C X'FF00000000000000', X'00FFC708FF000000', X'0000300000000000', X'000000F700000000', X'0000080000000000', X'0000000000FFFFFF' %CONSTLONGINTEGERARRAY NRZI ERROR MASKS(1:ERROR CLASSES)= %C X'FF00000000000000', X'00FFC740FF000000', X'0000300000000000', X'000000BF00000000', X'0000080000000000', X'0000000000FFFFFF' ! %INTEGER I %LONGINTEGERARRAYNAME ERROR MASKS ! %IF T_MODE&3=3 %THEN ERROR MASKS==PE ERROR MASKS %C %ELSE ERROR MASKS==NRZI ERROR MASKS ! %FOR I=1,1,ERROR CLASSES %CYCLE %IF T_T07&ERROR MASKS(I)#0 %THENEXIT %REPEAT ! SO I HAS ERROR CLASS. %RESULT=I %END; ! FN DIAGNOSE ! !********* TERMINATE STARTS HERE ********** ! %IF REQ_STATE=0 %START REPORT("SPURIOUS TERMINATION") %RETURN %FINISH %IF T_STREAMR1=-1 %START; ! TIMEOUT REPORT("TIME-OUT") REP_P2=3 ->REPLY %FINISHELSESTART; ! NOT TIMOUT %IF NORMAL=-1 %THEN ->OK(REQ_CHAIN) ! IE ENTERED VIA ATTENTION FOR EXPECTED, NON-PRIVATE, TM OR BT ! CHAINS 16,17,18 AND 0 ONLY. PSTAT=(T_STREAMR0>>8)&X'FF' REMBC=T_STREAMR1&X'3FFFF'; ! REMAINING BYTE COUNT. FINAL COMMAND=CHAIN START(REQ_CHAIN)+T_STREAMR0&X'FF' ! THE LATTER WILL BE NONSENSE FOR PRIVATE CHAIN, BUT NOT REFERRED TO. %IF NORMAL=0 %START ! REP_P2=0 ->OK(REQ_CHAIN) %UNLESS REQ_CHAIN=PRIVATE ! OTHERWISE DROP THRU' TO 'REPLY'. %FINISHELSESTART; ! ABTERM ! GET GPC SENSE DATA. ! IN DCU CASE, THE H/W SENSE INTO POSTAMBLE IS NOT DONE FOR UNMASKED ! L,S,X,Y, BUT WE DONT NEED IT IN THAT CASE. %IF P_P4&X'FF'=X'80' %START; ! SENSE OK MOVE(12,D_SENSDATAD+1,ADDR(T_T0)) T_SSTAT=BYTEINTEGER(D_SENSDATAD) %FINISHELSESTART ! EITHER GPC SOFTWARE SENSE FAILED, OR DCU H/W SENSE FAILED REPORT("NONSENSE") ! NO IDEA WHAT DEVICE STATE IS. MAYBE LOST DEVICE OR POSITION. REP_P2=3 ->REPLY %FINISH ! NOW CHECK FOR CONTROLLER ERRORS FLAG=(T_STREAMR0>>16)&X'FF' %IF FLAG=X'41' %START REPORT("CDE"); ! THIS IS ACTUALLY ACTIVATE FAILS FOR DCU ! PROBABLY HAVEN'T MOVED TAPE IF IT SHOULD HAVE BEEN. BETTER BAIL OUT REP_P2=3 ->REPLY %FINISHELSEIF FLAG=X'42' %START ! THIS CASE ONLY ARISES FOR DCU REPORT("INITIALISE FAILURE") REP_P2=3 ->REPLY %FINISH ! SO IT MUST BE EITHER U/S OR UNMASKED L,S,X,Y %UNLESS REQ_CHAIN=PRIVATE %START; ! NO DIAGNOSES OR RETRYIES FOR PRIVATE %IF PSTAT&128#0 %START; ! UNSUCCESSFUL ERROR CLASS=DIAGNOSE REPORT(USMESS(ERROR CLASS)) %UNLESS ERROR CLASS=1=T_LOAD STATE ! DONT REPORT NOTAVAIL OR MANUAL FOR SEND PROPS. WE EXPECT IT ! FOR DECKS UNLOADED AT START-UP. ->US(ERROR CLASS) %FINISHELSEIF PSTAT&3#0 %START; ! TM OR ET ->TM(REQ_CHAIN) %FINISHELSEIF PSTAT&12#0 %START; ! LONG OR SHORT REP_P2=1 ->LS(REQ_CHAIN) %FINISHELSESTART; ! WHAT CAUSED IT THEN ???? REPORT("SPURIOUS ABTERM") REP_P2=3 ->REPLY %FINISH %FINISH; ! NOT PRIVATE. PRIVATE DROPS OUT TO 'REPLY' %FINISH; ! ABTERM %FINISH; ! NOT TIMEOUT ! ! CAUTION. DROP THRU' HERE FOR PRIVATE CHAINS ! REPLY: %IF REQ_CHAIN=PRIVATE %START REP_P3=T_STREAMR0 REP_P4=T_STREAMR1 %FINISH ! NOTOINAL P5 AND P6 ALWAYS GO BACK WITH T0-T7 REQ_STATE=0 MYPON(RECORD(ADDR(REP))) %IF REP_DEST#0; ! REPLY TO USER IF NOT 'LOAD' %IF T_UNLOAD PENDING#0 %START ! ONLY IF STATE IS LOADING OR CLAIMED T_UNLOAD PENDING=0 T_LOAD STATE=6; ! UNLOAD ENTRY. IF WE WERE ABOUT TO REPLY TO LOAD ! THIS TAKES THE PLACE OF THE REPLY. REP_DEST=0; ! IF IT WAS A USER WE WANT TO GO TO 'LOAD AS WELL %FINISH LOAD %IF REP_DEST=0 %RETURN ! ! !*********** OK *********** OK *********** OK *********** OK *********** ! OK(0): ! WE COME HERE VIA 'ATTENTION' AFTER GETTING A REVERSE BT FAILURE AT ! US(5) BELOW, AND THE RESULTING ATTENTION HAS COME. ! THE REPLY IS ALL SET UP. ->REPLY ! !------------------------------------------------------------------ ! OK(1):OK(2):OK(3):OK(4):OK(5):OK(6):OK(7):OK(8):OK(9):OK(10):; ! ALL READS LS(1):LS(2):LS(3):LS(4):LS(5):LS(6):LS(7):LS(8):LS(9):LS(10): ! LONG/SHORT ONLY ABTERM. GOES BACK TO USER WITH P2=1 AND P4 LONG/SHORT. ! THE LATTER DISTINGUISHING IT FROM MEDIA ERROR. ! ! ARE WE ON THE RIGHT SIDE OF THE BLOCK SKIP=REQ_TARGET POS-((POSMASK>>FINAL COMMAND)&1) ! TARGET POS SET IN ACCEPT REQUEST. 2**FINAL LBE(CW) IN POSMASK SET IF THAT ! LBE(CW) LEFT US AFTER BLOCK, ELSE BEFORE. ! SO SKIP=1 MEANS A FORWARD SKIP REQUIRED ! =0 MEANS POSITION CORRECT ! =-1 MEANS A REVERSE SKIP REQUIRED REP_P3=REQ_LENGTH %IF PSTAT&4#0 %START; ! LONG BLOCK %IF SKIP#0 %START ! IT WAS READ IN A DIRECTION OTHER THAN THE ORIGINAL REQUEST. THIS ! CANT BE COUNTED A SUCCESS SINCE WEVE FETCHED THE WRONG END. ! SIMULATE A MEDIA ERROR AND CONTINUE WITH RETRIES. ->US(4) %FINISH ! SO WE READ IN THE RIGHT DIRECTION. TELL USER IT WAS LONG REP_P4=2 ! LENGTH IS CORRECT %FINISHELSEIF PSTAT&8#0 %START; ! SHORT BLOCK REP_P3=REQ_LENGTH-REMBC; ! LATTER IS UNEXPIRED COUNT %IF (REVMASK>>FINAL COMMAND)&1#0 %START ! READ IN REVERSE. DATA IS AT TOP OF BUFFER REP_P3=-REP_P3; ! INDICATE THIS TO USER %FINISH REP_P4=1; ! SHORT FOR USER %FINISH %IF REQ_READORS&NODATA#0 %AND REP_P2=0 %THEN REP_P4=REQ_RETRIES ! 'NO DATA' SET, SO IT WAS A READCHECK. TELL RETRIES. %UNLESS REQ_RETRIES=0 %START PRINTSTRING(T_MNEM." ".T_DSN." ".HTOS(REQ_RETRIES,3)." READ RETRY OK ") %FINISH ! ! THATS THE REPLY ALL SET UP TEST FINAL SKIP: ! CAUTION. WE COME HERE FROM US(3) ALSO %IF SKIP=0 %THEN ->REPLY ! ! SO FINAL SKIP REQUIRED ! THE ORIGINAL USER'S ASL IS STILL SET UP IN REQ_ADDR ETC, SO NO NEED ! FOR A DUMMY. DO FINAL SKIP: ! CAUTION*** WE COME HERE FROM TM(1) AND TM(2) ALSO. %IF SKIP>0 %THEN REQ_CHAIN=20 %ELSE REQ_CHAIN=21 ! THESE SKIPS IGNORE TMS FIRE CHAIN %RETURN ! !------------------------------------------------------------------ ! OK(11):OK(12):; ! WRITE ,WRITE TM %UNLESS REQ_RETRIES=0 %START PRINTSTRING(T_MNEM." ".T_DSN." ".HTOS(REQ_RETRIES,3)." WRITE RETRY OK ") %FINISH ->REPLY ! !------------------------------------------------------------------ ! OK(13):; ! REPOSITION AND ERASE FOR WRITE AND WRITE TM RETRY ! COME HERE FROM TM(13) ALSO REQ_CHAIN=REQ_FINAL CHAIN; ! SET UP IN 'ACCEPT REQUEST' ! EVERYTHING ELSE REMAINS OK FIRE CHAIN %RETURN ! !------------------------------------------------------------------ ! OK(14):OK(15):; ! SKIP BLOCKS, FORE AND AFT TEST SKIP END:; ! CAUTION. ALSO COME HERE FROM SKIP TM FORE AND AFT %IF T_UNLOAD PENDING#0 %START; ! HOLD HAS BEEN KEYED REP_P2=3 ->REPLY %FINISH REQ_COUNT=REQ_COUNT+1 %IF REQ_COUNTREPLY ! !------------------------------------------------------------------ ! OK(16):OK(17):; ! SKIP TMS, FORE AND AFT %IF REQ_STATE=TERM EXP %THEN REQ_STATE=ATTN EXP %ANDRETURN ! THAT WAS THE TAPE MOVEMENT BEGINNING. WE COME BACK HERE VIA ! ROUTINE ATTENTION WHEN WE HIT TM OR BT. %IF BT#0 %START; ! MUST HAVE NEEN REVERSE REP_P2=4 REP_P3=REQ_COUNT*REQ_TM+REQ_COUNT1 ->REPLY %FINISH ! SO IT WAS A TM REQ_COUNT1=REQ_COUNT1+1 %IF REQ_COUNT1=REQ_TM %START; ! ONE FILES WORTH REQ_COUNT1=0 ->TEST SKIP END %FINISH FIRE CHAIN %RETURN ! !------------------------------------------------------------------ ! OK(18):; ! REWIND %IF REQ_STATE=TERM EXP %THEN REQ_STATE=ATTN EXP %ANDRETURN ! THAT WAS START OF MOVEMENT. COME BACK VIA ATTN AT BT. ->REPLY ! !------------------------------------------------------------------ ! OK(19):; ! ERASE ->REPLY ! !------------------------------------------------------------------ ! OK(20):OK(21):; ! FINAL POSITION SKIP. REPLY ALL SET UP ->REPLY ! !------------------------------------------------------------------ ! OK(22):; ! TEST FOR TM. SUCCESS MEANS TM NOT SEEN ON REVERSE SKIP REQ_CHAIN=16; ! REPLACE ORIGINAL CHAIN WHICH WAS SKIP FORE TO TM FIRE CHAIN %RETURN ! !------------------------------------------------------------------ ! OK(23):OK(24):OK(25):; ! SPC, UNLOAD, RLSE/RWND ->REPLY ! ! !*********** US *********** US *********** US *********** US *********** ! ! ADMINISTRATIVE SKIPS COME HERE ALSO IF THEY FAIL. THEY SHOULD ONLY APPEAR ! AS CLASSES 1 OR 2. ! US(1):; ! OFFLINE ! WE GET HERE FOR MANUAL/NOTAVAIL DURING A CHAIN. WE COULD DO THE STATE ! CHANGE HERE, BUT FOR CONSISTENCY WE LEAVE IT TO BE DEALT WITH BY ! 'ATTENTION' WHEN THE STATE CHANGE COMES. ! IN THE MEANTIME THE USER WILL CONTINUE TO GET REPLIES OF 3 FROM HERE ! IF HE PERSISTS. ! DROP THRU' TO ..... ! !------------------------------------------------------------------ ! US(2):; ! LOST POSITION ! CAUTION***. COME HERE FROM US(1) ALSO REP_P2=3; ! DISASTER ->REPLY ! !------------------------------------------------------------------ ! US(3):; ! STRAIGHT BACK ! CAUTION***. COME HERE FROM US(4) ALSO REP_P2=1 %IF T_T2&X'30'#0 %THEN REP_P4=4; ! BAD CE DATA COUNT ! NOW A FINAL REPOSITION MAY BE REQUIRED IF IT WAS A READ %IF REQ_CHAIN<=LAST READ CHAIN %START SKIP=REQ_TARGET POS-((POSMASK>>FINAL COMMAND)&1) ->TEST FINAL SKIP %FINISH ->REPLY ! !------------------------------------------------------------------ ! US(4):; ! RETRIABLE ! WE DO NOT EXPECT TO GET CLASS 4 ERRORS OM COMMANDS OTHER THAN READS ! WRITE AND WRITE TM, FOR ALL OF WHICH RETRIES ARE DEFINED (AND FOR ! WHICH THE EMBEDDED SKIPS INVOLVED IN MULTIPLE RETRY CHAINS HAVE ! CLASS 4 ERRORS MASKED OFF). IF THIS INTERPRETATION OF THE ERROR ! BITS IS INCORRECT AND A CLASS 4 ERROR OCCURS ON A STRAIGHT SKIP, REWIND, ! ERASE, ETC. WE WILL LOG IT HERE AND GIVE THE USER A DISASTER(3) REPLY, ! SINCE WE MAY HAVE LOST POSITION. IN THE LIGHT OF EXPERIENCE WE MAY ! HAVE TO RECLASSIFY THE BITS TAKING INTO ACCOUNT THE ACTUAL DEVICE ! COMMAND IN EXECUTION AT FAILURE. ! %IF REQ_CHAIN<=LAST RETRY CHAIN %START; ! ALL THE ONES WE EXPECT REQ_RETRIES=REQ_RETRIES+1 %IF REQ_RETRIES>REQ_RETRY LIMIT %START PRINTSTRING(T_MNEM." UNRECOVERED ERROR ".T_DSN." ") ->US(3) %FINISH ! IE, TEST FOR FINAL SKIP IF READ, OTHERWISE STRAIGHT BACK %IF REQ_CHAIN<=LAST READ CHAIN %START %IF REQ_CHAIN=REQ_FINAL CHAIN %THEN REQ_CHAIN=REQ_CHAIN-7 %C %ELSE REQ_CHAIN=REQ_CHAIN+1 ! SET BACK TO START+1, ELSE NEXT IN BASIC SEQUENCE %FINISHELSESTART; ! WRITE OR WRITE TM REQ_CHAIN=13; ! SKIP REV AND ERASE WRITTEN LENGTH %FINISH FIRE CHAIN %RETURN %FINISH ! ! SO WE SHOULDN'T BE HERE. REP_P2=3 PRINTSTRING(T_MNEM."*** UNEXPECTED RECOVERABLE ERROR *** "); ! ITS 'REPORTED' ABOVE ->REPLY ! !------------------------------------------------------------------ ! US(5):; ! REVERSED INTO BT. READ REV OR SKIP REV ONLY ! THERE IS NOW A BT ATTN TO COME %IF REQ_CHAIN=2 %OR REQ_CHAIN=15 %START ! OK. SET UP REPLY COMPLETELY READY TO GO BACK WHEN ATTN COMES. REP_P2=4 %IF REQ_CHAIN=15 %THEN REP_P3=REQ_COUNT; ! NUMBER SKIPPED BEFORE HERE %FINISHELSESTART PRINTSTRING(T_MNEM."***UNEXPECTED REV BT *** ") REP_P2=3; ! WE HAVEN'T CATERED FOR THIS. ALL HELL MAY NOW BREAK LOOSE %FINISH REQ_CHAIN=0; ! JUST TO WAIT FOR 'NORMAL' TERM FROM 'ATTENTION' REQ_STATE=ATTN EXP %RETURN ! !------------------------------------------------------------------ ! US(6):; ! ADVISORY ONLY ! HAS BEEN 'REPORTED' ABOVE. TREAT AS SUCCESS OTHERWISE ->OK(REQ_CHAIN); ! SHOULD ONLY BE READS ! ! ! !*********** TM *********** TM *********** TM *********** TM *********** ! TM(1):TM(2):; ! READ FORE AND AFT %IF REQ_RETRIES=0 %START ! JUST TO MAKE SURE WE ARE ON THE PRIMARY READ OF A SEQUENCE %IF REQ_CHAIN=1 %THEN SKIP=-1 %ELSE SKIP=1 REP_P2=4 ->DO FINAL SKIP %FINISH ! ELSE DROP THRU' TO...... ! !------------------------------------------------------------------ ! TM(3):TM(4):TM(5):TM(6):TM(7):TM(8):TM(9):TM(10): TM(16):TM(17):TM(18):TM(20):TM(21):TM(23):TM(24):TM(25): ! READ RETRIES,SKIP TM FORE AND AFT,REWIND,POSITIONING SKIPS,SEND PROPS, ! UNLOAD, RLSE/RWND REPORT("UNEXPECTED TM") REP_P2=3 ->REPLY ! !------------------------------------------------------------------ ! TM(11):TM(12):TM(19):; ! MUST BE ET AFTER WRITE, WRITE TM OR ERASE ! THE WRITE WAS OTHERWISE OK. REP_P2=4 ->REPLY ! !------------------------------------------------------------------ ! TM(13):; ! ET ON ERASE DURING WRITE(TM) RETRY 'SKIPREV,ERASE' REP_P2=4; ! THIS REMAINS THE REPLY IF IT FINALLY SUCCEEDS ->OK(13) ! !------------------------------------------------------------------ ! TM(14):TM(15):; ! SKIP FORE AND AFT %IF REQ_TM#0 %THEN->TEST SKIP END ! IE EXACTLY AS SUCCESS IF TMS TO BE TREATED AS BLOCKS %IF REQ_CHAIN=14 %THEN SKIP=-1 %ELSE SKIP=1 REP_P2=4 REP_P3=REQ_COUNT ->DO FINAL SKIP ! !------------------------------------------------------------------ ! ! TM(16,17,18) DEFINED AT TM(3) ABOVE ! !------------------------------------------------------------------ ! ! TM(19) DEFINED AT TM(11) ABOVE ! !------------------------------------------------------------------ ! ! TM(20,21) DEFINED AT TM(3) ABOVE ! !------------------------------------------------------------------ ! TM(22):; ! LOOK-AHEAD FOR TM AFTER SKIP TM FORE. FOUND ONE REP_P2=4 REP_P3=REQ_COUNT*REQ_TM ->REPLY ! !------------------------------------------------------------------ ! ! TM(23,24,25) DEFINED AT TM(3) ABOVE ! !------------------------------------------------------------------ ! !*********** LS *********** LS *********** LS *********** LS *********** ! ! LS(1-10) DEFINED AT OK(1) ABOVE ! !------------------------------------------------------------------ ! LS(11):LS(12):LS(13):LS(14):LS(15):LS(16):LS(17):LS(18):LS(19):LS(20): LS(21):LS(22):LS(23):LS(24):LS(25): REPORT("SPURIOUS LONG/SHORT") REP_P3=3; ! FOR NOW TREAT THIS AS DISASTER SINCE IT SHOULD NEVER HAPPEN ->REPLY; ! AND IF IT DOES THERE MAY BE SOMETHING FUNDAMENTALLY WRONG. ! ! ! %END; ! ROUTINE TERMINATE ! ! %INTEGERFN ACCEPT REQUEST !********************************************************************** ! CHECKS USER REQUEST AND REFORMATS IT FOR USE BY 'FIRE CHAIN'. ! SINCE WE'VE GOT HERE WITH T AND REQ MAPPED VIA THE SNO FROM THE USER ! WE KNOW THE DECK IS LOADED AND CLAIMED. !********************************************************************** ! DEFINED REQUESTS (HISTORICALLY QUAINT) ARE: ! 0=ERASE ! 1=READ ! 2=WRITE ! 3=UNDEF ! 4=READ CHECK ! 5=PRIVATE ! 6=READ REV ! 7=UNDEF ! 8=SKIP BLOCKS ! 9=SKIP TMS ! 10=WRITE TM ! 11-16=UNDEF ! 17=REWIND %CONSTINTEGER TOP REQ=17 %CONSTBYTEINTEGERARRAY CHAIN(0:TOP REQ)= %C 19,1,11,0,1,PRIVATE,2,0,14,16,12,0(6),18 ! THESE ARE THE PRIMARY CHAINS TO EFFECT THE REQUEST.(SEE ARRAYS LBE(CW) ABOVE). %CONSTBYTEINTEGERARRAY FINAL CHAIN(0:TOP REQ)= %C 0,9,11,0,9,0,10,0,0,0,12,0(6),0 ! THESE ARE THE FINAL CHAINS FOR THOSE WHICH CAN BE RETRIED ! %CONSTINTEGER READMASK=X'52'; ! READ,READ REV,READ CHECK %CONSTINTEGER WRITEMASK=X'405';! WRITE,ERASE,WRITETM %CONSTINTEGER XFERMASK=X'57'; ! ALL READS,WRITE,ERASE %CONSTINTEGER SKIPMASK=X'300'; ! SKIP BLOCK,SKIP TM %CONSTINTEGER SPADDRMASK=X'11'; ! ERASE, READ CHECK ! %INTEGER TYPE,TYPE BIT,CTRL ! %IF SSERIES=NO %START !..........PSERIES..........PSERIES..........PSERIES..........PSERIES ! %INTEGERFN MOVE PRIVATE RCB ! ! THE USER GIVES THE VIRTUAL ADDR OF HIS RCB IN P_P3. THIS IS SUPPOSED ! TO BE IN A LOCKED AREA (DLOCK), AND P_P5,P6 ARE SUPPOSED TO CONTAIN ! THE STB DELIVERED BY THAT DLOCK, IE A VM CONSISTING SOLELY OF LOCKED SPACE. ! WE WISH TO COPY THE RCB INTO THE DEVICE RECORD, SO THAT IT IS IN PUBLIC ! FOR THE GPC (ITS ALSO CONVENIENT TO HAVE IT THERE TO SEE WHATS GOING ! ON). SINCE THE USERS LST IS NOT LOCKED WE NEED TO ACCESS THE RCB VIA ! THIS STB. ! IF WE VALIDATE THE RCB VIA THE STB AND IT SUCCEEDS, THEN THE RCB ! MUST BE IN LOCKED SPACE, AND WE CAN PROCEED TO COPY IT WITHOUT FEAR ! OF A VS ERROR. HOWEVER IT IS POSSIBLE THAT THE STB ITSELF IS RUBBISH ! SO TO CHECK THE EXISTENCE OF THE ST ENTRY ADDRESS WHICH THE RCB ! VALIDATE WILL GO FOR, WE FIRST VALIDATE IT AS A PUBLIC ADDRESS. IF ! THIS SUCCEEDS THEN THE STE ALL EXISTS AND IN THE SAME SMAC. WE CAN ! THEREFORE GO AHEAD WITH THE RCB VALIDATE WITHOUT FEAR OF A STORE TIMEOUT. ! THE RCB VALIDATE MAY FAIL EITHER IF ITS SEGMENT IS OUTSIDE TH SUPPLIED ! STB LIMIT(EITHER ONE OR BOTH RUBBISH), OR IF THE RCB IS NOT CONTAINED ! IN THE LOCKED SPACE DEFINED BY THE STB. ! NONE OF THIS GUARANTEES THAT WE ACTUALLY COPY THE USERS RCB. ALL THE ! ABOVE CHECKS COULD SUCCEED ON GARBAGE ADDRESSES. HOWEVER, WE WILL NOT ! FALL OVER SETTING IT UP, AND WHAT HAPPENS AFTER DEPENDS ON WHAT GPC ! MAKES OF THE SUPPOSED RCB. %RECORDFORMAT COMF(%INTEGER OCPTYPE,IPLDEV,SBLKS,SEPGS,NDISCS, %C DDTADDR,GPCTABSIZE,GPCA,SFCTABSIZE,SFCA,SFCK,DIRSITE, %C DCODEDA,SUPLVN,KLOKCORRECT,DATE0,DATE1,DATE2, %C TIME0,TIME1,TIME2,EPAGESIZE,USERS,PROCMON,DQADDR, %C SACPORT,OCPPORT,ITINT,CONTYPEA,GPCCONFA,FPCCONFA,SFCCONFA, %C BLKADDR,DPTADDR,SMACS,TRANS,%LONGINTEGER KMON, %C %INTEGER SPDRQ,SMACPOS,SUPVSN,PSTVA,SECSFRMN,SECSTOCD, %C SYNC1DEST,SYNC2DEST,ASYNCDEST,MAXPROCS,INSPERSEC,ELAPHEAD, %C COMMSRECA,%INTEGERARRAY SP(0:13), %INTEGER %C LSTL,LSTB,PSTL,PSTB,HKEYS,HOOT,SIM,CLKX,CLKY,CLKZ, %C HBIT,SLAVEOFF,INHSSR,SDR1,SDR2,SDR3, %C SDR4,SESR,HOFFBIT,S2,S3,S4,END) %CONSTRECORD(COMF)%NAME COM=X'80C00000' %INTEGER VSEG,STEA,LSTL,LSTB,STL,STB,RES,I %LONGINTEGER DR %IF P_P3<0 %THEN MOVE(28,P_P3,ADDR(T_RCB)) %ANDRESULT=0 ! IE IT WAS IN PUBLIC SO NO HASSLE ! VSEG=P_P3&X'7FFC' STL=P_P5 STB=P_P6 %IF STB&X'F0000000'#0 %THENRESULT=1 STEA=STB+(VSEG>>15); ! REAL ADDR OF ST ENTRY DR=X'1800000881000000'+STEA; ! STE, LENGTH 8 VIA PST *LD_DR *VAL_(%LNB+1) *JCC_14, %RESULT=1; ! VAL GAVE 3, IE INVALID VALID: ! SO STEA EXISTS. NOW VALIDATE RCB. FIRST SAVE LSTBR I=COM_LSTL *LB_I *LSS_(0+%B) *ST_LSTL *LSS_STL *ST_(0+%B) I=COM_LSTB *LB_I *LSS_(0+%B) *ST_LSTB *LSS_STB *ST_(0+%B) ! NOW DO VALIDATE RES=1 DR=X'1800001C00000000'!P_P3; ! 28 BYTES *LD_DR *VAL_(%LNB+1) *JCC_3, ! SO OK. RES=0 MOVE(28,P_P3,ADDR(T_RCB)) RESET LSTBR: I=COM_LSTL *LB_I *LSS_LSTL *ST_(0+%B) I=COM_LSTB *LB_I *LSS_LSTB *ST_(0+%B) %RESULT=RES %END; ! FN MOVE PRIVATE RCB %FINISH;!.............................................................. ! ! ! ********** ACCEPT REQUEST STARTS HERE ********** REQ=0 REP=0; ! REPLY RECORD REP_DEST=P_SRCE REP_SRCE=P_DEST REP_P1=P_P1; ! IDENT ! REQ_LSL=P_P5 REQ_LSTBA=P_P6 ! TYPE=P_P2&X'FF' %IF TYPE>TOP REQ %THENRESULT=NOTOK; ! NOT DEFINED REQ_CHAIN=CHAIN(TYPE) %IF REQ_CHAIN=0 %THENRESULT=NOTOK; ! DITTO %IF TYPE=5 %START; ! PRIVATE CHAIN %IF SSERIES=NO %START !........PSERIES..........PSERIES..........PSERIES..........PSERIES ! %IF MOVE PRIVATE RCB#0 %THENRESULT=NOTOK REQ_PRIVATE ATTN=P_P4; ! ATTN DEST %RESULT=OK %FINISHELSESTART !........SSERIES..........SSERIES..........SSERIES..........SSERIES ! %RESULT=NOTOK; ! FOR NOW. UNTIL WE SEE HOW. %FINISH;!............................................................ %FINISH REQ_FINAL CHAIN=FINAL CHAIN(TYPE) REQ_RETRY LIMIT=WRITE RETRIES ! THIS IS OVERWRITTEN IF IT IS A READ, AND IRRELEVANT FOR OTHERS TYPE BIT=1<>16 %IF REQ_LENGTH&X'8000'#0 %THEN REQ_LENGTH=REQ_LENGTH!X'FFFF0000' %IF REQ_LENGTH=0 %THEN REQ_LENGTH=P_P4 CTRL=(P_P2>>8)&X'FF' %IF TYPE BIT&WRITEMASK#0 %AND T_PROP3&X'40'#0 %THENRESULT=NOTOK; ! NO RING %IF TYPE BIT&XFERMASK#0 %START; ! READ,READREV,READCHECK,WRITE,ERASE %IF REQ_LENGTH<=0 %THENRESULT=NOTOK ! LENGTH MUST BE POSITIVE. READ CHECK INCLUDED FOR CONVENIENCE ONLY. %IF TYPE BIT&SPADDRMASK#0 %THEN REQ_ADDR=X'81000000' %ELSEC REQ_ADDR=P_P3 ! ERASE AND READ CHECK NEED A GENUINE FIXED ADDRESS, FOR CONTROLLER ! CHECKS EVEN WHEN NO DATA XFER.THIS IS START OF REAL CORE MAP IN PS 64. %IF TYPE BIT&READMASK#0 %START; ! READ,READREV,READCHECK REQ_RETRY LIMIT=READ RETRIES %IF TYPE=4 %START; ! READCHECK %IF SSERIES=NO %THEN REQ_LENGTH=X'3FFFF' %ELSE REQ_LENGTH=X'FFFF' ! MAX. 256K-1 FOR PSERIES, 64K-1 FOR SSERIES. REQ_READORS=NODATA ! IGNSHORTLONG(1); ! NO DATA, IGNORE SHORT REQ_TARGET POS=1 %FINISHELSESTART; ! READ OR READREV REQ_READORS=IGNSHORTLONG((CTRL>>2)&3); ! IGN NEITHER, SHORT, LONG OR BOTH %IF TYPE=1 %THEN REQ_TARGET POS=1 %ELSE REQ_TARGET POS=0 ! READ READREV %FINISH %FINISH; ! READMASK %IF CTRL&2#0 %THEN REQ_RETRY LIMIT=0 ! NO ERROR RECOVERY. NOTE THAT WRITE TM RECOVERY IS NOT AFFECTED. %FINISHELSESTART; ! NOT XFERMASK. IE SKIP BLOCK,SKIP TM,WRITETM,REWIND ! PSERIES: ! A DUMMY ASL REQUIRED FOR ALL THESE WITH LENGTH>0 AND GEN FIXED ADDR. ! HOWEVER, FOR WRITE TM RETRY (SKIPREV, ERASE), THE ERASED ! LENGTH SHOULD BE AT LEAST A TMS WORTH - IE 41 IN PE, 8 IN NRZI. ! SSERIES: ! DUMMY DESCRIPTOR NOT REQUIRED, SINCE ABSENCE OF FIXED BIT IN TCB_STE ! TELLS DCU THAT DESCRIPTOR IS NOT VALID. HOWEVER, AS FOR PSERIES, ! THE WRITE TM RETRY 'ERASE' REQUIRES A SUITABLE LENGTH, AND ITS ! SIMPLER JUST TO DO IT FOR THEM ALL. SKIPS AND REWIND WONT USE IT ! IN 'FIRE CHAIN'. ! FIRST SAVE USER SUPPLIED LENGTH AS THIS IS BLOCKS OR LOGICAL FILES ! FOR SKIP AND SKIP TM RESPECTIVELY. REQ_SKIPTOT=REQ_LENGTH REQ_LENGTH=50 REQ_ADDR=X'81000000' %IF TYPE BIT&SKIPMASK#0 %START; ! SKIP BLOCKS, SKIP TMS %IF REQ_SKIPTOT=0 %THENRESULT=NOTOK %IF REQ_SKIPTOT<0 %THEN REQ_CHAIN=REQ_CHAIN+1 %ANDC REQ_SKIPTOT=-REQ_SKIPTOT %IF TYPE=8 %START; ! SKIP BLOCK REQ_TM=CTRL&1; ! TREAT TM AS BLOCK %FINISHELSESTART; ! SKIP TMS ! CTRL IS NUMBER OF TMS/LOGICAL FILE %RESULT=NOTOK %IF CTRL=0 REQ_TM=CTRL %FINISH %FINISH %FINISH %RESULT=OK %END; ! FN ACCEPT REQ ! ! %ROUTINE FIRE CHAIN !********************************************************************** ! ENTERED WITH REQUEST SET UP IN T_REQ. SPECIFICALLY REQ_CHAIN IS TO ! BE FIRED. ! %IF PSERIES, SETS UP LBES, ALE AND RCB AND TELLS GPC. ! %ELSE, SETS UP TCBS AND TELLS DCU. !********************************************************************** %CONSTINTEGER READMASK=X'E66EF'; ! 2**N SET IF LBE(CW) IS READ %OWNINTEGER DEST=CONTROLLER+EXEC,SRCE=ME+5,P1,P2,P3=X'11', P4,P5,P6 ! %IF SSERIES=NO %START !..........PSERIES..........PSERIES..........PSERIES..........PSERIES ! %INTEGER LBEN,CH START,I,MODE %INTEGERNAME LBEWORD %RECORD(RCBF)%NAME RCB RCB==T_RCB %IF REQ_CHAIN=PRIVATE %THEN ->FIRE; ! PRIVATE RCB ALL SET UP RCB=0; ! ******* CAUTION. PARTLY SET UP ONCE AT ALLOCATE CH START=CHAIN START(REQ_CHAIN) LBEN=CHAIN LENGTH(REQ_CHAIN) RCB_LB BYTES=LBEN<<2; ! CAN WE SET THIS TO 4 LBES AT ALLOC REGARDLESS ??? MOVE(RCB_LB BYTES,ADDR(LBES(CH START)),ADDR(T_LBE1)) RCB_LBA=ADDR(T_LBE1); !**** DO THIS ONCE AT ALLOCATE %IF REQ_CHAIN<=LAST READ CHAIN %START %FOR I=0,1,LBEN-1 %CYCLE %IF (1<<(CH START+I)&READMASK)#0 %START; ! LBE IS READ ! OR IN BITS FOR 'NO DATA','IGNORE SHORT/LONG' ! THE FIRST READ IN MULTIPLE CHAINS ALREADY HAS LONG/SHORT ! MASKED OFF. HOWEVER SINCE WERE DOING THE 'NO DATA' HERE AS ! WELL, WE MUST DO THEM ALL. LBEWORD==INTEGER(ADDR(T_LBE1)+I<<2) LBEWORD=LBEWORD ! REQ_READORS %FINISH %REPEAT %FINISH %IF REQ_CHAIN<=LAST RETRY CHAIN %THEN T_OPS=T_OPS+1 ! COUNT OF NON-POSITIONING OPERATIONS FOR JOURNAL MODE=T_MODE %IF MODE=0 %THEN MODE=PE ! IF UNDEFINED THEN SET TO PE. THIS WILL BE THE CASE FOR A BLANK TAPE ! BEING REWOUND OR UNLOADED FROM 'LOAD' WITHOUT BEING CLAIMED ! T_ALE1=REQ_LENGTH T_ALE2=REQ_ADDR RCB_AL BYTES=8 RCB_ALA=ADDR(T_ALE1); !*** DO THIS ONCE AT ALLOCATE %IF T_ALE2>0 %START; ! LOCAL ADDR FOR DATA. PUT IN LSTB RCB_LIMFLAGS=REQ_LSL RCB_LSTBA=REQ_LSTBA %FINISH; ! ELSE ALL IN PUBLIC. DO WE NEED ANYTHING HERE? RCB_LIMFLAGS=RCB_LIMFLAGS ! X'8000'; ! INITIALISE BIT IN FLAGS ! TELLS GPC TO USE THE FOLLOWING TO INIT THE DEVICE RCB_INITWORD=(STATMASK(REQ_CHAIN)<<8) ! MODE ! TERTIARY STAT MASK MODE ! FIRE: RCB_INITWORD=RCB_INITWORD ! ((T_PROP2&7)<<24); ! MECHANISM P1=ADDR(RCB) %FINISHELSESTART !..........SSERIES..........SSERIES..........SSERIES..........SSERIES ! %CONSTLONGINTEGER NOADDRMASK=X'1BDF608800' %CONSTINTEGER PAGE BIT=X'40000000' %OWNBYTEINTEGER ASBYTE=X'10'; ! ADD STATUS LITERAL BYTE %RECORD(TCBF)%NAME TCB %INTEGER CWS,CWN,CWB,CH START,I,STAD,STEAD,LEN,ADR %IF REQ_CHAIN<=LAST RETRY CHAIN %THEN T_OPS=T_OPS+1 CH START=CHAIN START(REQ_CHAIN) CWS=CHAIN LENGTH(REQ_CHAIN) %FOR I=1,1,CWS %CYCLE TCB==T_TCBS(I) TCB=0 CWN=CH START+I-1 TCB_CW=CW(CWN); ! COMMAND WORD %IF (LONG1<0 %THEN STAD=X'81000000'!REQ_LSTBA %ELSE STAD=PST VA ! PSTVA IS PUBLIC SEG VA. DEFINED IN CTOPT FILE STEAD=STAD+((ADR>>15)&X'FFF8'); ! ACTUALLY (>>18&X'1FFF')<<3 ! TO YIELD BYTE DISPLACEMNT OF ENTRY TCB_STE=(INTEGER(STEAD+4)&X'0FFFFFF8')!1; ! REAL ADDR+FIXED BIT %IF INTEGER(STEAD)&PAGE BIT#0 %THEN TCB_STE=TCB_STE!2 TCB_LENGTH=TCB_LENGTH!LEN; ! REMENBER BACKWARDS BIT MAY BE THERE TCB_ADDR=ADR&X'3FFFF' %FINISH; ! THOSE REQUIRING DATA AREA %UNLESS I=CWS %THEN TCB_NEXT TCB=ADDR(T_TCBS(I+1))!X'80000000' ! CHAIN ON THE NEXT ONE %REPEAT T_TCBS(1)_PREAMBLE(1)=(T_PROP2&7)<<24!STATMASK(REQ_CHAIN)<<8!T_MODE ! INITIALISE MECHANISM SECONDARY STATUS MODE P1=ADDR(T_TCBS(1)) %FINISH;!.............................................................. P2=T_SNO&X'FF' REQ_STATE=TERM EXP MYPON(RECORD(ADDR(DEST))) %IF RLEVEL&4#0 %THEN DUMPTABLE(61,ADDR(T),TFSIZE) %END; ! ROUTINE FIRE CHAIN ! ! %ROUTINE QUEUE !*********************************************************************** ! USER REQUESTS OR RELEASE(S) RECEIVED WHILE DEVICE IS BUSY ARE QUEUED !*********************************************************************** %INTEGER I %RECORD(PBF)%NAME NEWCELL,QCELL %IF TMON#0 %OR RLEVEL&1#0 %THEN MON(3,P) I=NEWPPCELL NEWCELL==PB(I) NEWCELL_P=P %IF T_PQ=-1 %START; ! CURRENTLY EMPTY NEWCELL_LINK=I; ! POINT IT AT ITSELF. ITS BOTH FIRST AND LAST %FINISHELSESTART; ! NOT EMPTY QCELL==PB(T_PQ); ! THE CURRENT LAST, WHOSE LINK POINTS AT THE FIRST NEWCELL_LINK=QCELL_LINK; ! THIS IS ABOUT TO BE THE LAST QCELL_LINK=I; ! TO THE NEW LAST %FINISH T_PQ=I %END; ! ROUTINE QUEUE ! ! %ROUTINE UNQUEUE !************************************************************************ ! UNQUEUES FIRST IN. NEVER ENTERED EMPTY. !************************************************************************ %INTEGER I %RECORD(PBF)%NAME OLDCELL,QCELL QCELL==PB(T_PQ); ! THE LAST, POINTING AT FIRST I=QCELL_LINK; ! THE ONE WE WANT OLDCELL==PB(I) P=OLDCELL_P %IF T_PQ=I %START ! POINT AT ITSELF, SO ONLY ONE THERE T_PQ=-1 %FINISHELSE QCELL_LINK=OLDCELL_LINK RETURNPPCELL(I) %IF TMON#0 %OR RLEVEL&2#0 %THEN MON(4,P) %END; ! ROUTINE UNQUEUE ! ! !******************* TAPE STARTS HERE ********************************** ! %IF KMON&(LONG1<<49)#0 %THEN TMON=1 %ELSE TMON=0 %IF TMON#0 %OR RLEVEL&1#0 %THEN MON(1,P) ! REENTER: ! UNQ=0 ACT=P_DEST&X'FFFF' %IF ACT>64 %THEN SNO=ACT %AND ACT=1 %UNLESS (INITIALISED>0 %OR ACT=4) %AND 1<=ACT<=13 %THEN ->FAULTY P ! ->ACTSW(ACT) ! REPLY: P_DEST=P_SRCE P_SRCE=ME!ACT MYPON(P) CHECK QUEUE: %IF UNQ#0 %AND (T_STATE#CLAIMED %OR REQ_STATE=0) %AND T_PQ#-1 %START ! USER REQUESTS ONLY GET ONTO Q WHEN STATE IS CLAIMED. SO IF Q IS ! NON EMPTY AND STATE NOT CLAIMED, IT HAS ONLY JUST CHANGED FROM CLAIMED, ! AND WE NEED TO UNQUEUE AND REJECT THEM ALL AT ACTSW(1) BELOW. IF ! STATE IS CLAIMED AND REQSTATE=0 , THEN THE NEXT QD CAN GO. UNQUEUE ->REENTER %FINISH %RETURN ! ! ACTSW(7):; ! USER RELEASE SNO=P_P2&X'FFFF' ACTSW(1):; ! USER REQUEST, SNO SET FROM P_DEST ABOVE. %IF SEARCH TPS(3,SNO,"")=OK %START; ! FOUND SNO AND MAPPED T REQ==T_REQ REP==T_REP %IF T_STATE=CLAIMED %START; ! THE DECK REMAINS ACCESSIBLE %IF REQ_STATE#0 %THEN QUEUE %ANDRETURN ! SO WE QUEUE RELEASES AS WELL AS REQUESTS %IF ACT=1 %START; ! USER REQUEST %IF ACCEPT REQUEST=OK %START; ! CHECKS OK FIRE CHAIN; ! REPLY WHEN TERM COMES %RETURN %FINISHELSE P_P4=BAD PARAMS %FINISHELSESTART; ! USER RELEASE, ACT 7 T_LOAD STATE=6+P_P5<<1; ! IE 6 FOR UNLOAD, 8 FOR RLSE/RWND LOAD P_P4=OK %FINISH %FINISHELSE P_P4=NOT CLAIMED ! FOR USER REQUEST: ! WE GET HERE EITHER, ! BAD PARAMS - IE T_STATE=CLAIMED AND REQ_STATE=0, SO IF THIS ! CAME OFF Q, WE WANT TO UNQ THE NEXT. ! OR NOT CLAIMED- IF THIS ONE CAME OFF Q, WE WANT TO KEEP UNQING ! THEM, SO THAT ALL GET REJECT REPLIES BEFORE THE ! DECK SNO CHANGES BY BEING RECLAIMED OR DEALLOCATED. ! REQ_STATE MAY OR MAY NOT BE ZERO DEPENDING ON ! WHETHER THE STATE CHANGE ALSO INDUCED A LOAD/UNLOAD. ! FOR USER RELEASE: ! WE GET HERE FOR SUCCESS OR FAILURE. THE STATE WAS EITHER NOT CLAIMED ! OR WE HAVE SUCCESSFULLY INITIATED AN UNLOAD, SO THE Q MUST BE CLEARED ! BEFORE WE LOSE SIGHT OF THE SNO. UNQ=1 %FINISHELSE P_P4=SNO NOT FOUND %IF P_P4=OK %THEN P_P2=OK %ELSE P_P2=REJECT ! ONLY SUCCESSFUL RLSE ALL OTHERS ->REPLY ! ! ACTSW(2):; ! TERMINATION/ATTENTION FROM CONTROLLER ! P_P1=STREAMR0, _P2=STREAMR1 ! P_P3=DEVICE ENTRY ADDRESS ! P_P4=RESPONSE ANAL FLAGS FROM CONTROLLER SENSE IF ORIGINAL REQUEST FAILED D==RECORD(P_P3) T==RECORD(D_UA AD) REQ==T_REQ REP==T_REP T_STREAMR0=P_P1 T_STREAMR1=P_P2 I=(P_P1>>20)&15 %IF I=1 %THEN ATTENTION %ELSE TERMINATE(I&7,0) ! IE 0 FOR NORMAL, >0 FOR ABTERM ! T_STATE MAY HAVE CHANGED FROM CLAIMED, OR REQ_STATE MAY HAVE CHANGED ! TO ZERO, SO CHECK Q UNQ=1 ->CHECK QUEUE ! ! ACTSW(3):; ! CONTROLLER ALLOCATE/DEALLOCATE REPLIES ! P_P1=0 SUCCESS ! P_P2=SNO (ALLOC ONLY) ! P_P3=DEVICE ENTRY ADDRESS ! P_P6=MNEMONIC(ALLOC ONLY) D==RECORD(P_P3) %IF P_SRCE&X'FF'=ALLOC %START %IF P_P1#OK %THENRETURN; ! ALLOC FAILED. SEE COMMENT AT ACTSW(4) ! SO ALLOCATED OK. SET UP DEVICE RECORD I=P_P6!X'3000000'; ! STRING MNEM M=STRING(ADDR(I)) %IF SEARCH TPS(1,0,M)=OK %START ! IT SHOULDNT ALREADY BE THERE OPMESS(M." ALLOCATE TWICE?") %RETURN %FINISH LASTLINK=D_UA AD T==RECORD(D_UA AD) T=0 REQ==T_REQ REP==T_REP LASTLINK==T_LINK; ! THIS IS NOW LAST T_MNEM=M T_PROP2=P_P6&X'FF'-X'30'; ! MECHANISM FROM MNEM TO DO SEND PROPS T_PQ=-1; ! Q EMPTY T_SNO=P_P2 ! T_STATE=0, NOT AVAILABLE ! T_LOAD STATE=0, READY FOR LOAD LOAD; ! GET PROPS AND SEE IF ANYTHING LOADED %FINISHELSESTART; ! DEALLOCATE %IF P_P1#OK %START OPMESS(T_MNEM." DEALLOCATE FAILS ".HTOS(P_P1,1)) %RETURN %FINISH T==RECORD(D_UA AD) ! DEALLOCS COME VIA VOLUMS WHICH DOESNT ALLOW THEM IF IN USE, SO THERE ! SHOULDNT BE ANY REQUEST OUTSTANDING. WE MIGHT BE IN A LOAD OR UNLOAD ! SEQUENCE BUT THATS IRRELEVANT. NOTHING TO DO BUT UNLINK IT. M=T_MNEM I=SEARCH TPS(1,0,M); ! REALLY JUST TO SET UP 'PREVLINK' %IF I#OK %START; ! DEAR DEAR. WHATS HAPPENED? OPMESS(M." DEALLOC SRCH FAILS?") %RETURN %FINISH PREVLINK=T_LINK; ! UNLINK IT ! AND RESET LAST IF THIS WAS IT %IF T_LINK=0 %THEN LASTLINK==PREVLINK %FINISH %RETURN ! ! ACTSW(4):; ! ONCE/STREAM FROM CONTROLLER AT STARTUP ! P_P1=BASE MNEMONIC. CONTROLLER CREATES STREAMS FOR THE MAX DECKS FOR THE ! STREAM TYPE IE EITHER 8 OR 4. WE DONT KNOW WHICH TYPE, SO WE DO ! ALLOCATE REQUESTS FOR MAX OF THESE. THE EXCESS WILL FAIL FROM CONTROLLER. ! IN FACT, THE DECKS FOR THOSE SUCCESSFULLY ALLOCATED MAY NOT EXIST, ! BUT WE DONT FIND THAT OUT UNTIL WE GET NOT AVAILABLE AT START OF LOAD. ! ! THIS ENTRY ALSO USED BY VOLUMS TO MODE ON/OFF DECK OR CLUSTER. !P_P1=BASE MNEMONIC, P2=ON/OFF(1/0), P3=NUMBER OF DECKS ! %IF P_SRCE&X'FF0000'=CONTROLLER %START ! INITIALISING CALL %IF INITIALISED=0 %START PB==ARRAY(INTEGER(ADDR(PARMDES)+4),PBAF) LASTLINK==FIRSTTP INITIALISED=1 %FINISH NDECKS=8 MODE=ON %FINISHELSESTART ! VOLUMS NDECKS=P_P3 MODE=P_P2 %FINISH %IF MODE=ON %THEN PP_DEST=CONTROLLER!ALLOC %C %ELSE PP_DEST=CONTROLLER!DEALLOC PP_SRCE=ME!3; ! WHERE CONTROLLER REPLIES COME PP_P2=ME!2; ! WHERE EVENTS ARE NOTIFIED PP_P1=P_P1; ! BASE MNEM P_P1=0; ! FOR REPLY TO VOLUMS, SEE BELOW %WHILE NDECKS>0 %CYCLE I=PP_P1!X'3000000' I=SEARCH TPS(1,0,STRING(ADDR(I))); ! IS IT THERE %IF (MODE=ON %AND I=OK) %OR (MODE=OFF %AND I=NOTOK) %THENC P_P1=P_P1+1 %ELSE MYPON(PP) ! IE IF ON AND ALREADY THERE, OR OFF AND NOT THERE, THEN INCREMENT ! COUNT OF 'NOT DONE' FOR VOLUMS. OTHERWISE DO IT PP_P1=PP_P1+1; ! NEXT MNEM UP NDECKS=NDECKS-1 %REPEAT %IF P_SRCE&X'FF0000'=CONTROLLER %THENRETURN ! SO IT WAS VOLUMS. REPLY. P1 ALREADY SET ->REPLY ! ! ACTSW(5):; ! EXECUTE REQUEST FAILS ! FAILURES ARE P1=1 - SNO OUT OF RANGE, IE UNKNOWN TO CONTROLLER ! =2 - DEVICE NOT READY ! P2=SNO ! P3=DEVICE ENTRY ADDRESS UNLESS P1=1 ! THE SNO IN P2 IS ONLY THE BOTTOM BYTE OF OUR FULL ONE(SEE FIRE CHAIN) ! SO WE CANNOT USE IT TO SEARCH FOR TP. FURTHER IF P1=1, CONTROLLER CLEARLY ! DOES NOT GIVE A DEVICE ADDR IN P3, SO WE HAVE NO WAY OF TELLING WHICH ! OF OUR ENTRIES WAS USED TO INITIATE THIS REQUEST OPMESS("CONTROLLER REJECTS REQUEST") PRINTSTRING("EXECUTE REQUEST FAILS - P1=".HTOS(P_P1,1). %C " P2=".HTOS(P_P2,2)) %IF P_P1#1 %START; ! WE CAN LOCATE IT DUMPTABLE(61,P_P3,TFSIZE) D==RECORD(P_P3) T==RECORD(D_UA AD) REQ==T_REQ REP==T_REP %IF REQ_STATE#0 %START; ! TELL THE USER OR 'LOAD' REQ_STATE=0 REP_P2=REJECT REP_P4=NOT CLAIMED %IF REP_DEST#0 %THEN MYPON(RECORD(ADDR(REP))) %ELSE LOAD %FINISH ! THIS MAY HAVE COME OFF Q, SO CHECK FOR MORE UNQ=1 ->CHECK QUEUE %FINISH %RETURN ! ! ACTSW(6):; ! VOLUMS REPORTING IN VOLUMS=P_SRCE I=SEARCH TPS(4,0,""); ! REPORT ALL LOADED TO VOLUMS %RETURN ! ! ! ACTSW(7) DEFINED AT ACTSW(1) ABOVE ! ! ACTSW(8):; ! SET REPORTING LEVEL %IF P_P1<=7 %START RLEVEL=P_P1 %FINISHELSEIF 0<=P_P2<=255 %START %IF P_P1=16 %START READ RETRIES=P_P2 %FINISHELSEIF P_P1=17 %START WRITE RETRIES=P_P2 %FINISH %FINISH %RETURN ! ! ACTSW(9):; ! SEND FAILURE DETAILS %IF SEARCH TPS(3,P_P1&X'FFFF',"")=OK %START P_P1=0 P_P2=T_STREAMR0 P_P3=T_STREAMR1 MOVE(12,ADDR(T_T0),ADDR(P_P4)) %FINISHELSESTART P_P1=REJECT P_P4=SNO NOT FOUND %FINISH ->REPLY ! ! ACTSW(10):; ! DUMP TABLE, SNO IN P1 %IF SEARCH TPS(3,P_P1&X'FFFF',"")=OK %START DUMPTABLE(61,ADDR(T),TFSIZE) %FINISH %RETURN ! NO REPLY ! ! ACTSW(11):; ! DUMMY %RETURN ! ! ACTSW(12):; ! CLAIM VOLUME CLAIM VOLUME(P) ! REPLY SET UP ->REPLY ! ! ACTSW(13):; ! DISPLAY TPS STATUS I=SEARCH TPS(5,0,"") %RETURN ! ! FAULTY P: MON(5,P) %END; ! ROUTINE TAPE ! ! %ENDOFFILE