IFN TM10A,TM10B==0 IFE TM10A,TM10B==1 IFN TM10A,INFORM IO BUSS MAG TAPE,1 IFN TM10B,INFORM DATA CHANNEL MAG TAPE,1 MSCBL==8 ; COMMAND BUFFER LENGTH MGQDLL==6 ; INTERUPT LEVEL PDL MSCHN==240300 ; FOR MEMBLT MSEOFP==230100 MSWC==101300 MTXP==410300,, ;XPORT NUMBER MUNITF==170300 ; UNIT FIELD IN MTC CONI MNOPIN==10000 MWRITE==4000 MW3IN==14000 MSPRR==7000 MREAD==2000 MSPFR==6000 MSPFF==16000 MSPRF==17000 MREWND==1000 MRWNDD==11000 MWEOF==5000 MGNRTY==10. ;NUMBER OF READ RETRIES MTRCI==CPOPJ MTRKI==CPOPJ MTRCO==CPOPJ MTRKO==CPOPJ ;;MAG TAPE OPEN CODE ; C/ MODE,,DEV ; D/ MODE (ROT 1) 4.9=1=>OUTPUT ; I/ DEVICE NUMBER ; R/ IOCHNM WORD POINTER MAGTO: SKIPL W,I ; GET DEVICE CAIL W,NMTCS ; TO BIG? JRST OPNL1 ; NO SUCH DEVICE MOVSI T,40 TDNE T,MSRAC(W) ; REWINDING PUSHJ P,UFLS ; YES, THEN WAIT CONO PI,CLKOFF ; DON'T WANT STATUS CHANGED FROM UNDER ME SKIPGE MTUSE(W) ; CHECK FOR FIRST USER JRST MAGTU1 ; FIRST CAME U,MTUSR(W) ;SAME USER JRST OPNL21 ; DIFFERENT USER IS ERROR MOVE B,D EQV B,MSCRW(W) SKIPL B ; CHECK FOR SECOND OPEN IN SAME DIRECTION JRST OPNL2 ; WRONG DIRECTION MAGTU: MOVEM U,MTUSR(W) ; STORE USER SETZM MSCRW(W) ; INDICATE READ UNTIL FOUND TO BE OTHERWISE TLNE C,1 ; READ OR WRITE SETOM MSCRW(W) ;INDICATE WRITE AOS MTUSE(W) ;INDICATE 1 MORE USER PUSHJ P,SOSSET MTUSE(W) ; SOS IF PCLSRED CONO PI,CLKON ; LET UM GET ME PUSHJ P,MTSTAT ; GET CONIS OF 340 AND 344 IN I AND J MOVE A,MSRAC(W) TLNE A,40000 ; PI ERROR MEANS DEVICE NOT THERE JRST MTOL1 TRNN J,200040 JRST OPNL1 ; DEVICE NOT AVAILABLE SKIPN MSCRW(W) ;WRITING? JRST MTOW1 TRNE J,10 ; AND WRITE LOCKED JRST OPNL26 ; DEVICE WRITELOCKED SKIPE MSRAC(W) ; WRITING TRNN J,4000 ;EOT? JRST MTOW1 ; NO MOVSI A,140000 ; IF WRITE AND EOT,MAKE .IOT GIVE IOC ERROR BUT LET OPEN WIN IORM A,MSRAC(W) MTOW1: TRNN J,400000 ; XPORT HUNG JRST MTOW2 ; OK TRNN J,20000 ; OK IF REWINDING JRST OPNL1 ;DEVICE NOT AVAILABLE MTOW2: TLNN C,400 ; GET CORE DUMP MODE JRST MTOW3 TLNN C,300 JRST MTOW3 TLC C,300 TLCE C,300; IBM AND DENSITY 800 BPI OK JRST OPNL12 MTOW3: TLNE C,4 ; UNIT OR BLOCK JRST MTOW4 ; BLOCK MODE WILL WIN TLNE C,10 ; CHUNK OR READ COMPARE JRST OPNL12 ;BY THIS POINT OPEN WILL g ԟW4: PJA &Sf w̋ASE MTUSE SWITCH MOVEI A,MTCCHN_3 ;SET UP MAG TAPE CONO IFN TM10A, TRO A,1 ; DATA PI CHANNEL LDB B,[300200,,C] ; GET DENSITY FROM OPEN SKIPN B MOVEI B,3 SUBI B,1 ; CONVERT TO PROPER PARITY DPB B,[060200,,A] TLNN C,400 ; CORE DUMP TRO A,20000 ; YES TLNN C,40 ; PARITY CHECK TRO A,40000 ; SET ODD PARITY DPB W,[170300,,A] ; SET UNIT NUMBER MOVEM A,MTCONO(W) ; STORE IT LDB B,[330300,,C] ; GET WORDS PER BLOCK TRC B,7 MOVEI A,10 LSH A,(B) ;NUMBER OF WORDS PER RECORD MOVEM A,MTBLKS(W) ;BLOCKSIZE LDB A,[230300,,C] ; GET MODE TRZ D,-1 IORM A,D ADDI D,MTOPTB ; SET TO LOCATION IN OPEN DPT HLR C,(D) ; GET INPUT DISPATCH TLNE D,400000 ; OPEN FOR OUTPUT? HRR C,(D) ;CHANGE TO OUTPUT IF SO MOVEM C,(R) ;STORE IN IOCHNM DPB W,[MTXP(R)] ; STORE XPORT NUMBER JRST POPJ1 ; SKIP RETURN MTOPTB: MTUAIX,,MTUAOX MTBIX,,MTBOX MTUIIX,,MTUIOX MTBIX,,MTBOX REPEAT 4,MTCKIX,,MTCKOX MAGTU1: SETZM MSNBUF(W) ; TOTAL NUMBER OF BUFFERS MOVE A,[SETZ 377] MOVEM A,MSBUFP(W) ;INDICATE NO BUFFERS ON CHAIN SETZM MSNBOL(W) ; ANOTHER WAY OF SAYING ABOVE SETZM MSMPRC(W) ; BUFFER WORDS REMAINING SETZM MSMPRP(W) ; POINTER TO BUFFERS SETOM MTMDN(W) ;NO BUFFER AT MP SETOM MGCABN(W) ;NONE AT PI SETZM MSRAC(W) SETOM MSGNRB(W) ; GET NEW BUFFER FLAG MOVEI A,2 MOVEM A,MTCEFW(W) ; NUMBER OF EOF'S WRITTEN MOVSI A,1000 IORM A,MSRAC(W) ; INDICATE NOTHING WRITTEN ON TAPE JRST MAGTU MTOL1: SETZM MSRAC(W) JRST OPNL1 ;MAG TAPE INPUT .IOT ROUTINES MTUAI: JSP E,MTREAD ;UNIT ASCII INPUT JSP B,CHRKT ;CALL FOR SINGLE CHAR TRANSFER HRROI A,EOFCH ;EOF RETURN FROM MTREAD JRST MTUAIE ;EOF ROUTINE MTUII: JSP E,MTREAD ;UNIT IMAGE JSP B,WRDKT MTBI2: MOVE A,[EOFWRD] ;ENTRY FROM BLOCK MODE (WORD OF EOFS) MTUAIE: XCTR XW,[MOVEM A,(C)] JRST ACLOSE ; POPJ P, MTBI: JSP E,MTREAD ;BLOCK INPUT JSP B,BLKT ;MTBI1: MOVSI A,4 ; SETUP AC FOR IMAGE/ASCII TEST ; TDNE A,(R) ; JUMPGE C,CPOPJ ; RETURN IF HE DOESN'T WANT TO TRANSFER ; HRRZ D,(C) ;ASCII MODE. PREPARE TO RETURN EOF WORD ; PUSHJ P,DREL ; JRST IOADC ; JFCL ; MOVE A,[EOFWRD] ; MOVEM A,(D) ; MOVE A,[1,,1] ; UPDATE HIS POINTER ; ADDM A,(C) ; POPJ P, MTCKI: LDB W,[MTXP(R)] ; GET XPORT NUMBER PUSHJ P,MTIECK PUSHJ P,MTRBD ; DISCARD BUFFER IF IT EXISTS SKIPGE MSRAC(W) ; CHECK FOR EOF JRST ACLOSE MOVEM P,MTPSAV(W) MOVSI T,2400 ANDCAM T,MSRAC(W) JSP B,BLKT MSMPRP(W) ; WORD POINTER MSMPRC(W) ; COUNT SETZ MTRBG ; GET NEW BUFFER MTRBD @MTRBFS(W) ; SIZE PUSHJ P,MTCRBW ; WAIT FOR NEW BUFFER MTREAD: LDB W,[MTXP(R)] ; W <= XPT # PUSHJ P,MTIECK SKIPGE MSRAC(W) ;CHECK FOR EOF JRST ACLOSE MOVSI B,2400 ANDCAM B,MSRAC(W) ; INDICATE NOT CHUNK MODE MOVEM P,MTPSAV(W) ; SAVE P FOR EOF RETURN XCT (E) ;BLKT,CHRKT,WRDKT MSMPRP(W) ;LOC OF NEXT WORD MSMPRC(W) ;COUNT REMAINING SETZ MTRBG ; GET NEW BUFFER (SETZ FOR CHRKT RETURN ON EOF) MTRBD ; DISCARD BUFFER @ MTRBFS(W) ;READ BUFFER SIZE PUSHJ P,MTRBFW ; FLUSH INSTRUCTION WAIT FOR BUFFERS TO COME FROM PI CAIN A,EOFCH ; CHECK FOR EOF (CHRKT) MOVSI A,400000 ; EOF RETURN FROM CHRKT IORM A,MSRAC(W) ;SET EOF BIT POPJ P, MTRBD: SKIPGE A,MTMDN(W) ; ANY BUFFERS JRST MOVTWJ ;SET UP T FOR BUFFER WAIT,RETURN CONO PI,UTCOFF ; SHUT UP WORLD SETOM MTMDN(W) ; NO BUFFER CTIVE AT M.P. SETZM MSMPRC(W) SOS MSNBUF(W) ;ONE LESS BUFFER LDB T,[MUR,,MEMBLT(A)] CAIE T,MUMGB ; DO I OWN THIS BLOCK JRST 4,. ;NO I DON'T LDB TT,[MSEOFP,,MEMBLT(A)] ;EOF READ FROM PI PUSHJ P,IMEMR ; RETURN BLOCK CONO PI,UTCON ; YOU MAY SPEAK JUMPN TT,MTRBD2 ;EOF? MOVTWJ: MOVE T,W ; T NEEDS CHANNEL NUMBER ROF BUFFER WAIT UFLUSH POPJ P, MTRBD2: MOVSI A,400000 ; SET EOF IORM A,MSRAC(W) ; STORE MOVE P,MTPSAV(W) ; RESTORE P ; HRRZ B,(R) ; GET INDEX TO IOTTB ; JRST @IOTTB(B) ; WILL EXECUTE EOF SINCE MSRAC EOF IS SET SKIPN MSMPRC(W) POPJ P, ; RETURN IF A PERFECT MATCH MOVSI A,2 TDNE A,(R) JRST ACLOSE JRST MTBI2 ;MAG TAPE READ BUFFER GET ROUTINE ; BUFFER ASSUMED TO HAVE COME IN FROM PI LEVEL. MTRBG: PUSHJ P,MTIECK MOVE TT,MSRAC(W) ; CHECK FOR CHUNK MODE INPUT TLZE TT,400 JRST MTCRG1 HLRZ A,MSBUFP(W) ; GET IN POINTER HRRZ TT,MSBUFP(W) ; GET OUT POINTER MOVEM TT,MTMDN(W) ; STORE BUFFER ACTIVE AT MP CAMN A,TT ;IN = OUT? JRST MTRBG1 ; YES LDB T,[MLO,,MEMBLT(TT)] ; BACK POINTER TO NEXT BLOCK HRRM T,MSBUFP(W) ;STORE NEW OUT POINTER JRST MTRBG2 MTRBG1: MOVE A,[SETZ 377] ; IN = OUT, OUT GOES AWAY MOVEM A,MSBUFP(W) ;STORE IT MTRBG2: MOVEI A,-3 DPB A,[MLO,,MEMBLT(TT)] ; -3=> ACTIVE AT PI LDB T,[MSWC,,MEMBLT(TT)] MOVEM T,MTRBFS(W) ; GET READ BUFFER SIZE LSH TT,10. ; MAKE BLOCK NUMBER AN ADDRESS MOVEM TT,MSMPRP(W) ; SET LOCATION OF BLKT TO AVOID POSSIBLE QUICK SHUFFEL MOVSI A,400 ; CHECK FOR CHUNK MODE MOVSI T,2000 TDNE T,MSRAC(W) IORM A,MSRAC(W) ; SO THAT IT WILL STOP NEXT TIME SOh&ӝS() ; OPLtBѢALST AOS (P) ; MAKE IT SKIP JRST MOVTWJ ; RESTORE T MTRBFW: SKIPLE MSNBOL(T) ; ANY FREE BUFFERS ON LIST? JRST MTRBW1 ; YES MOVSI TT,40000 ; CHECK FOR ERRORS TDNE TT,MSRAC(T) AOS (P) AOSE MSGNRB(T) ; IF NOT ALREADY DONE SO, SEND OUT A CALL FOR TAPE READ POPJ P, ;ALREADY DONE MTRBW3: PUSH P,W ;THIS BEING DONE UNDER A UFLS. ONLY T GOOD PUSH P,B MOVE W,T MOVEI B,MGREAD ;WHERE TO GO AT PI LEVEL MOVEI T,MSCBL ;MAKE SURE THAT THERE IS ROOM IN THE RING BUFFER CAMG T,MSCMDC(W) JRST MTRBW2 ; NO ROOM, GO AWAY PUSHJ P,MTCMD1 SKIPA MTRBW2: SOS MSGNRB(W) ; NO ROOM, SET SO THAT IT WILL BE TRIED AGAIN MOVE T,W POP P,B POP P,W POPJ P, MTRBW4: MOVEM TT,MSRAC(T) MTRBW1: SETOM MSGNRB(T) ; BUFFER CAME, SET MSGNRB SO IT WILL WIN NEXT TIME AOS (P) POPJ P, MTCRBW: MOVE TT,MSRAC(T) ; CHECK FOR BUFFER IN TLZE TT,2000 ; FIRST OR SECOND TIME JRST MTRBW4 MOVSI TT,400 ANDCAM TT,MSRAC(T) ; MAKE SURE IT WILL PASS THE FIRST TIME SKIPLE MSNBOL(T) ; BUFFER HERE JRST MTCRW2 ; YESS MOVSI TT,40000 TDNE TT,MSRAC(T) ; ANY ERRORS AOS (P) ; LET PASS THROUGH SO THEY WILL BE DETECTED AOSE MSGNRB(T) POPJ P, ; ALREADY SENT OUT FOR NEW BUFFER JRST MTRBW3 ; GET ONE MTCRW2: MOVSI TT,2000 IORM TT,MSRAC(T) ;SET FLAG TO SAY THAT IT HAS COME ONCE JRST MTRBW1 MTCRG1: MOVEM TT,MSRAC(W) MOVE P,MTPSAV(W) POPJ P, ; KILL ONE LEVEL OF PUSHJ ;MAG TAPE OUTPUT MTUAO: JSP B,MTWRIT ;UNIT ASCII OUTPUT JRST CHRKT MTUIO: JSP B,MTWRIT ;UNIT IMAGE OUTPUT JRST WRDKT MTBO: JSP B,MTWRIT ; BLOCK OUT JRST BLKT MTWRIT: LDB W,[MTXP(R)] ; GET XPORT NUMBER PUSHJ P,MTIECK HRLZI A,100000 ; END OF TAPE CHECK TDNE A,MSRAC(W) JRST IOCER9 JSP B,(B) SETZ MSMPRP(W) ;LOC OF WORD MSMPRC(W) ; COUNT SETZ MTWBFG ; GET NEW BUFFER MTWBFD ; WRITE OUT BUFFERS @MTBLKS(W) ;SIZE SETZ MTCKO: LDB W,[MTXP(W)] ; GET XPORT PUSHJ P,MTIECK ; ERROR CHECK HRLZI A,100000 ; EOT TDNE A,MSRAC(W) JRST IOCER9 PUSHJ P,MTWBFD ; DISCARD BUFFER IF ONE EXISTS XCTR XR,[HLRE TT,(C)] MOVMM TT,MTCBKS(W) JSP B,BLKT SETZ MSMPRP(W) ; POINTER MSMPRC(W) ; COUNT SETZ MTWBFG ; GET BUFFER MTWBFD ; DISCARD BUFFER @MTCBKS(W) ; SIZE SETZ MTWBFG: PUSHJ P,MTIECK PUSHJ P,TCALL ; TURN OF UTC JRST MMBRQ POPJ P, ;GO BACK NO SKIP IF NO CORE MOVEM A,MTMDN(W) ; STORE ACTIVE BUFFER NUMBER MOVEI T,MUMGB DPB T,[MUR,,MEMBLT(A)] ; TELL WORLD THAT IT IS A MAG TAPE BUFFER HRREI T,-3 DPB T,[MLO,,MEMBLT(A)] ;ACTIVE AT MP DPB W,[MSCHN,,MEMBLT(A)] ; CHANNEL NUMBER SETZM TT DPB A,[121000,,TT] ;CONVERT BLOCK NUMBER TO ADDRESS IN TT JRST UTCOJ1 MTWBFD: PUSHJ P,MTIECK SKIPGE A,MTMDN(W) POPJ P, MOVEI T,MSCBL CAMG T,MSCMDC(W) PUSHJ P,UFLS ; MAKE SURE ROOM IN COMMAND BUFFER EXISTS IN CASE OF PCLSRING LDB TT,[250100,,(R)] ; CHUNK MODE MOVE T,MTBLKS(W) ; DISCARD BUFFER. FIRST SEE HOW BIG IT IS SKIPE TT MOVE T,MTCBKS(W) SUB T,MSMPRC(W) CONO PI,UTCOFF ;CAN'T TOLERATE ANY HANKY PANKY SETOM MTMDN(W) ;CLEAR IT SETZM MSMPRC(W) ; CLEAR COUNT JUMPE T, MEMR ; DON'T DO ANYTHING BUT RETURN BLOCK IF NO WORDS DPB T,[MSWC,,MEMBLT(A)] ; STORE WORD COUNT SKIPG MSNBOL(W) ; LIST STARTED YET? JRST MTWBD1 ;NO HLRZ TT,MSBUFP(W) ; GET OLD IN POINTER DPB A,[MLO,,MEMBLT(TT)] ;CHAIN BACK SKIPA MTWBD1: HRRM A,MSBUFP(W) ; START NEW LIST HRLM A,MSBUFP(W) ; IN = OUT = (A) MTWBD2: SETOM TT DPB TT,[MLO,,MEMBLT(A)] ; INDICATE END OF LIST AOS MSNBOL(W) ; ONE MORE BUFFER ON LIST CONO PI,UTCON PUSH P,B MOVEI B,MGWRIT PUSHJ P,MTCMD MOVSI B,1000 ANDCAM B,MSRAC(W) SETZM MTCEFW(W) ; INDICATE SOMETHING WRITTEN JRST POPBJ ; RETURN ;PUSHJ P,MTCMD ;RH(W) HAS XPORT NUMBER ;RH(B) HAS ADDR OF INTERUPT ROUTINE MTCMD: MOVEI T,MSCBL ; COMAND BUFFER LENGTH CAMG T,MSCMDC(W) ;COMAND COUNT PUSHJ P,UFLS ; WAIT FOR ROOM MTCMD1: MOVE T,MTCMBP(W) ; GET POINTER TO RING BUFFER AOBJN T,.+2 SUB T,[MSCBL,,MSCBL] ; REACHED END OF BUFFER, RING IT MOVEM B,(T) ; STORE COMMAND MOVEM T,MTCMBP(W) ; STORE NEW POINTER CONO PI,UTCOFF AOS MSCMDC(W) ; INDICATE ONE MORE COMMAND JRST MSTRTR ; START UP PI ROUTINE MTIECK: PUSH P,A ; CHECK FOR IOTERR MOVE A,MSRAC(W) TLNN A,40000 ; ERROR AT PI? JRST POPAJ SKIPLE MSCMDC(W) PUSHJ P,UFLS ; LET PI CLEAR BEFORE MUNGING BUFFERS SKIPL A,MTMDN(W) PUSHJ P,MEMR SETOM MTMDN(W) SETZM MSMPRP(W) SETZM MSMPRP(W) SKIPE MSNBOL(W) PUSHJ P,MTCBFF ; FREE CHAIN POP P,A MOVE T,MGCMTS(W) ; GET CONI MTS, TRNE T,440000 ; XPT HUNG,ILLOP JRST IOCER1 TRNE T,23600 ; PAR ERROR,R/C, RLI,DL,BT JRST IOCER3 ; IRRECORVERABLE DATA ERROR TRNE T,4000 ; EOT JRST IOCER9 ; EOT, DEV FULL MOVE A,MGEOFR(W) ; LOGICAL EOT CAIL A,2 JRST IOCER9 JRST IOCER3 ; UNKNOWN, GIVE IRR DATA ;.STATUS CODE STAMTC: LDB W,[MTXP(R)] ; LOAD W DPB A,[60300,,D] ; OPEN MODE PUSHJ P,MTSTAT LDB A,[410100,,MSRAC(W)] ; EOT OR WRITE LDB B,[420100,,MSRAC(W)] ; EOT ON READ IOR A,B DPB B,[140100,,D] ;EOT LDB A,[20100,,J] TRC A,1 DPB A,[150100,,D] ; 7 OR 9 LDB A,[160100,,MTCONO(W)] TRC A,1 DPB A,[200100,,D] ;PARITY LDB A,[60200,,MTCONO(W)] ; DENSITY ADDI A,1 CAIN A,3 SETZM A ; 800 IS 00 DPB A,[160200,,D] LDB A,[250100,,(R)] ; CHUNK DPB A,[210100,,D] LDB A,[370100,,MSRAC(W)] ; READ COMPARE ERROR DPB A,[130100,,D] MOVE A,MTCONO(W) TRNN J,4 ; 7 TRACK TRNE A,20000 ; OR CORE DUMP POPJ P, ; THEN DONE TRO D,140000 ; IBM, 9 TRACK AND 800 BPI POPJ P, EBLK ;MAG TAPE STORAGE AREA MGVTC: 0 ; 1 SCRATCH WORD FOR VIRGIN TAPE CHECK MGRWCD: BLOCK NMTCS ; REWIND COMMAND MGEOTT: BLOCK NMTCS ; TIMEOUT FOR VIRGIN TAPE MGJDTI: 0 ; WAIT FOR JOB DONE TIME OUT MGEOFR: BLOCK NMTCS ; NUMBER OF EOFS SINCE LAST READ MGNWRD: 0 ; NUMBER OF WORDS READ IN A PI LEVEL READ MTPSAV: BLOCK NMTCS ; STORAGE TO RESTORE P ON EOF MSRAC: BLOCK NMTCS ; MAG TAPE GENERAL GARBAGE ; 4.9=EOF ON READ ; 4.8 EOT ON INTERNAL READ ; 4.7 EOT ON WRITE ; 4.6 PI ERROR ; 4.5 READ COMPARE ERROR ; 4.4 CORE ALLOCATOR SAYS STOP ; 4.3 " ; 4.2 CHUNK BLOCK IN FLAG ; 4.1 FLAG TO SAY IF ANYTHING WRITTEN ; 3.9 ALSO FOR CHUNK MODE TESTING ; 3.8 EOF READ SINCE OPEN ; 3.7 TAPE MOVED SINCE FIRST OPEN ; 3.6 REWINDING FLAG MGTBZY: -1 ; FLAG TO GET INTURPT STARTED MTCONO: REPEAT NMTCS,\.RPCNT_17+20 ; MAIN CONO STORAGE MSGNRB: REPEAT NMTCS,-1 ; GET NEW READ BLOCK FROM PI MGUNIT: -1 ; UNIT EXPECTING INTERUPT MGCMTS: BLOCK NMTCS ; PI CONI MTS STORAGE MGCMTC: BLOCK NMTCS ; PI MTC STORAGE MGWCW: 0 ; WAIT FOR CONTROL WORD WRITTEN FLAG LMICWA: 0 ; LAST MICWA MGERRC: BLOCK NMTCS ; ERROR COUNT MTMFNC: BLOCK NMTCS ; .MTAPE FUNCTION STORAGE MTMTAP: BLOCK NMTCS ; MTAPE CALL WORD MTCEFW: BLOCK NMTCS ; NUMBER OF EOF'S WRITTEN AT CLOSE MSCMDC: REPEAT NMTCS,0 ; NUMBER OF COMMANDS MSBUFP: REPEAT NMTCS,SETZ 377 ; MAG TAPE BUFFER POINTER IN,,OUT MSCRW: BLOCK NMTCS ; -1=>OUTPUT 0=>INPUT MSMPRC: BLOCK NMTCS ; WORDS LEFT IN BUFFER MSMPRP: BLOCK NMTCS ;NEXT WORD IN BUFFER MSNBUF: BLOCK NMTCS ; NUMBER OF BLOCKS IN USE MTMDN: REPEAT NMTCS,-1 ; BLOCK ACTIVE AT MP MTRBFS: BLOCK NMTCS ; READ BUFFER SIZE MTUSE: REPEAT NMTCS,-1 ; NUMBER OF CHANNELS OPEN ON THIS MTAPE MTUSR: BLOCK NMTCS ; USER INDEX OF XPORT MSNBOL: BLOCK NMTCS ; NUMBER OF BUFFERS ON LIST MGCABN: REPEAT NMTCS,-1 ; BUFFER ACTIVE AT PI LEVEL MTBLKS: BLOCK NMTCS ; WRITE BUFFER SIZE MTCBKS: BLOCK NMTCS ; BLOCK SIZE ON CHUNK WRITE MGQDLP: REPEAT NMTCS,-MGQDLL,,CONC MGQD,\.RPCNT,-1 ;QDL POINTER REPEAT NMTCS,[ CONC MSCB,\.RPCNT,: BLOCK MSCBL ; COMMAND BUFFER MGRCV ; TO RING BUFFER MGNCMD ; GET NEW COMMAND CONC MGQD,\.RPCNT,: BLOCK MGQDLL IFE .RPCNT,MSLCTB==.-MSCB0 ; LENGTH OF EACH TABLE ] MTCMBP: REPEAT NMTCS,-MSCBL-1,,CONC MSCB,\.RPCNT,-1 ; INPUT TO COMMAND TABLE MGCMBP: REPEAT NMTCS,4400,,CONC MSCB,\.RPCNT,-1 ; OUTPUT FROM COMAND TABLE MICWA: BLOCK 2 ; CHANNEL PROGRAM IFN TM10A,[ MGDBRK: 0 CONO MTS,1 JRST 12,@MGDBRK ] BBLK ;ROUTINES TO GET INTERUPT ROUTINES STARTED MGXGO: MOVE Q,MGQDLP(W) ;GET QDLPOINTER PUSHJ P,QPOPJ ;CALL ROUTINE . SHOULD FINISH WITH POPJ P,OR PUSHJ Q,CPOPJ ;PUSHJ Q,CPOPJ IF ROUTINE WANTS TO RETURN ;POPJ P, IF AT END OF COMAND. AND NEW IS TO BE GOTTEN MOVEM Q,MGQDLP(W) ; STORE NEW QDL POPJ P, MGRCV: MOVNI A,MSCBL+1 ;AT END OF COMAND LIST,RING IT ADDM A,MGCMBP(W) ;RING THE BUFFER MGNCM1: ILDB B,MGCMBP(W) ; GET NEW COMMAND JRST (B) MGNCMD: AOBJN Q,MGNCM1 ; AT BOTTOM OF QDL, SIMULATE PUSHJ AND GET NEW COMMAND JRST 4,. ;QDL POINTER CLOBBERED QPOPJ1: AOS (Q) QPOPJ: POPJ Q, MSTRTR: CONO PI,UTCOFF ; GET MAGTAPE INTURPT STARTED SETZM MGTBZY CONO PI,4000+1_<7-MTCCHN> CONO PI,UTCON POPJ P, ;HERE FOR MAG TAPE FLAG CHANNEL INTERUPT MGHBRK: SKIPGE W,MGUNIT ; LOAD UNIT JRST MGUBRK ;NO ONE WANTS IT LDB B,[MUNITF,,A] CAME W,B ; UNITS AGREE JRST 4,. ; WE MUST NOT MIX UNITS MOVE J,C IFN TM10B,[ TLNE C,160 JRST MGERR ] TRNE C,40000 JRST MGERR PUSHJ P,MGXGO JRST DSKEX ; RETURN TO MICROTAPE MGSBRK: SETOM MGTBZY ;HERE FOR ANY RANDOM MP PI STARTUP MOVEI B,NMTCS-1 SKIPG MSCMDC(B) ;ANY COMMANDS IN BUFFER MGSBK1: SOJGE B,.-1 SKIPGE B ;LAST UNIT? JRST DSKEX ; THEN GOTO DSKEX MOVE W,B PUSH P,B MOVSI B,14000 TDNN B,MSRAC(W) ; CORE ALLOCATOR SAYING GO AWAY PUSHJ P,MGXGO ; START UP THAT ROUTINE POP P,B JRST MGSBK1 ; ANY MORE? MGUBRK: LDB W,[MUNITF,,A] ; WHO CAUSED INTERUPT? MOVE B,MTCONO(W) CONO MTC,(B) CONO MTS,31 ; CLEAR INTERUPT JRST DSKEX ; ROUTINE TO WAIT FOR JOB DONE TO SET MGWTJD: CONI MTS,J IFN TM10B, TDNE J,[20440400] ; ERRORS? IFN TM10A, TRNE J,440400 JRST MGERR MGWJD1: CONI MTS,J SKIPN MGJDTI ; TIME OUT? JRST MGWJD2 MOVE T,TIME CAML T,MGJDTI JRST MGERR MGWJD2: TRNN J,100 ; JOB DONE? JRST MGOVER ; NOT SET CONI MTS,J CONI MTC,I ; GET CONI MTC MOVEM J,MGCMTS(W) MOVEM I,MGCMTC(W) SKIPE MGWCW ; SHOULD I WAIT FOR CONTROL WORD WRITTEN PUSHJ Q,MGWCWC ; CHECK TO SEE IF IT IS WRITTEN SETZM MGWCW ;CLEAR FLAG CONO MTS,30 ; CLEAR CHANNEL CONDITIONS MOVE B,MTCONO(W) CONO MTC,(B) ; RELESE MTC, CLEAR JOB DONE IFN TM10B,[ TLNE J,160 POPJ Q, ;CHANNEL ERROR ] TRNE J,463600 POPJ Q, ; RANDOM OTHER NON PERFECTIONS, NOT NECESSARILY ERRORS JRST QPOPJ1 ; SUCCESS ; GET XPORT MGGXPT: CONSO MTS,2 ; LOAD NEXT UNIT SET? JRST MGOVER ; NO, WAIT FOR IT MOVEM W,MGUNIT MOVE T,TIME ADDI T,10.*30. ; TIME OUT IN 10. SECONDS MOVEM T,MGJDTI MOVE B,MTCONO(W) CONO MTC,MNOPIN(B) ; SELECT DRIVE PUSHJ Q,MGWJD1 JFCL ; WAIT FOR JOB DONE, BUT ALLOW ANY ERRORS SETZM MGJDTI POPJ Q, MGOVER: CONSZ MTS,440020 ; ANY PROBLEMS? JRST MGERR SOS (Q) POPJ P, ;ERROR MGERR: SETZM MSCMDC(W) ; ONE LESS COMMAND SETOM MGUNIT ; CLEAR UNIT WAIT FLAG IFN TM10B,[ TLNE J,160 ; CHANNEL ERROR? JRST 4,. ; CHANNEL ERROR ] HRLZI B,40000 ; PI ERROR SKIPL A,MGCABN(W) ; ANY PI BUFFERS? PUSHJ P,IMEMR SETOM MGCABN(W) IORM B,MSRAC(W) ; STORE IN STATUS WORD MOVE Q,[-MGQDLL,,MGQD0-1] MOVE T,MSLCTB IMUL T,W ADD Q,T ; RESTORE Q PUSH P,Q MOVE Q,[-MSCBL-1,,MSCB0-1] ADD Q,T MOVEM Q,MTCMBP(W) ; INITIALIZE MP AND PI COMMND POINTERS MOVE Q,[4400,,MSCB0-1] ADD Q,T MOVEM Q,MGCMBP(W) MOVSI B,40 ANDCAM B,MSRAC(W) ; CLEAR REWINDING SKIPN MSCRW(W) ; DONE IF READING JRST POPQJ SKIPN MSNBOL(W) ; ANY BUFFERS ON LIST? JRST POPQJ MGERR1: HRRZ A,MSBUFP(W) SOSE MSNBOL(W) ; ONE LESS BUFFER PUSHJ P,MTICL1 PUSHJ P,IMEMR SKIPN MSNBOL(W) ; ANY MORE JRST POPQJ JRST MGERR1 MGWCWC:IFN TM10B,[ SKIPE ICWA1+1 ; CONTROL WORD WRITTEN? POPJ Q, CONO MTS,4 ; TELL IT TO WRITE IT MGWCW1: SKIPE ICWA1+1 JRST MGWCW2 ; DONE PUSHJ Q,CPOPJ ; WAIT JRST MGWCW1 MGWCW2: MOVE I,MGCMTC(W) MOVE J,MGCMTS(W) ;RESTORE STATUS TLO J,10 ;SET CONTROL WORD WRITTEN ] POPJ Q, IFN TM10A,[ MGDCSI: MOVE A,[BLKI MTC,MICWA] SKIPA MGDCSO: MOVE A,[BLKO MTC,MICWA] MOVEM A,MAGLOC MOVE A,[JSR MGDBRK] MOVEM A,MAGLOC+1 POPJ Q, ] ; PI LEVEL WRITE MGWRIT: PUSHJ Q,MGGXPT ; GET XPORT TRNE J,600010 ; WRITE LOCKED,HUNG OR REWINDING JRST MGERR MOVEM W,MGUNIT ; SET UNIT MOVSI A,14000 ; CORE ALLOC WANT QUIT TEMPORARLY TDNE A,MSRAC(W) JRST MGWRT4 HRRZ A,MSBUFP(W) ; GET BUFFER POINTER HLRZ B,MSBUFP(W) ; IN POINTER SOS MSNBOL(W) ; ONE LESS BUFFER MOVEM A,MGCABN(W) ; BUFFER ACTIVE AT PI SKIPN MSCRW(W) ; WRITING JRST 4,. CAME A,B ; IN = OUT JRST MGWRT1 MOVE B,[SETZ 377] MOVEM B,MSBUFP(W) ; NEW BUFFER POINTER JRST MGWRT2 MGWRT1: LDB B,[MLO,,MEMBLT(A)] ; BACK POINTER HRRM B,MSBUFP(W) ; NEW OUT POINTER MGWRT2: HRREI B,-4 DPB B,[MLO,,MEMBLT(A)] ; INDICATE ACTIVE AT PI LDB B,[MSWC,,MEMBLT(A)] ; WORD COUNT MOVNS B ; NEGATE HRLS B ; FORM COUNT LSH A,10. ; FORM WORD POINTER SUBI A,1 HRRM A,B ; CHANNEL POINTER IN B IFN TM10B, DATAO MTS,[ICWA1] ; SET TO GO TO MAG TAPE IFN TM10A, PUSHJ Q,MGDCSO MOVEM B,MICWA MOVEM B,LMICWA ; LAST MICWA SETZM MICWA+1 ; TELL CHANNEL TO STOP MOVE B,MTCONO(W) CONO MTC,MWRITE(B) ; DO IT PUSHJ Q,MGWTJD ; WAIT FOR JOB DONE JRST MGWBT ; WRITE BLANK TAPE AND TRY AGAIN MGWRT3: MOVE A,MGCABN(W) ; GET BUFFER NUMBER HRLZI B,140000 ; END OF TAPE CHECK TRNE J,4000 ; END POINT IORM B,MSRAC(W) ; TELL MP LDB T,[MUR,,MEMBLT(A)] CAIE T,MUMGB ; DO I OWN BLOCK JRST 4,. SETOM MGCABN(W) ; NO BUFFER ACTIVE AT PI PUSHJ P,IMEMR ; GIVE BACK BUFFER MOVSI A,100 IORM A,MSRAC(W) ; TAPE MOVEMENT JRST MGCMDR MGWBT: SETZM MICWA ; WRITE BLANK TAPE OVER POSSIBLE BAD SPOT IFN TM10A,[ MOVE A,[-1,,MGVTC-1] MOVEM A,MICWA ; ONE RECORD ] TRNE J,644010 ; BAD TYPES OF ERRORS JRST MGERR MOVE B,MTCONO(W) CONO MTC,MSPRR(B) ; REVERSE 1 RECORD PUSHJ Q,MGWTJD ; WAIT FOR JOB DONE JRST MGERR ; ERROR MOVE B,LMICWA MOVEM B,MICWA ; RESTORE MICWA MOVE B,MTCONO(W) CONO MTC,14000(B) ; WRITE WITH EXTENDED EOR PUSHJ Q,MGWTJD ; WAIT JRST MGWBT ; INFINITE RETRIES ; JRST MGERR ; ERRORS JRST MGWRT3 MGWRT4: PUSHJ Q,CPOPJ ; WAIT A WHILE JRST MGWRIT ;MAG TAPE PI LEVEL READ MGREAD: PUSHJ Q,MGGXPT ; GET XPORT TRNE J,600000 ; UNIT HUNG OR REWINDING OR EOT JRST MGERR MOVE B,MGEOFR(W) ; EOF'S READ CAIL B,2 JRST MGERR MOVEM W,MGUNIT ; STORE UNIT NUMBER SKIPE MSCRW(W) ; MAKE SURE READING JRST 4,. MOVSI B,14000 ; CORE ALLOCATOR WANT OUT TDNE B,MSRAC(W) JRST MGROVR ; YES PUSHJ P,MMBRQ JRST MGROVR ; WAIT FOR IT SETZM MEMBLT(A) AOS MSNBUF(W) MOVEM A,MGCABN(W) ; STORE ACTIVE BUFFER AT PI LEVEL HRREI B,-4 DPB B,[MLO,,MEMBLT(A)] ; SAY ACTIVE AT PI MOVEI B,MUMGB DPB B,[MUR,,MEMBLT(A)] ; CLAIM BLOCK HRREI B,-MGNRTY ; NUMBER OF RETRIES MOVEM B,MGERRC(W) ; STORE ERROR COUNT LSH A,10. ; FORM ADDRESS SUBI A,1 HRLI B,-2000 HRR B,A MOVEM B,LMICWA ; STORE LAST ICWA FOR RETRY IFN TM10B, DATAO MTS,[ICWA1] ; SET CHANNEL STARTING ADDRESS IFN TM10A, PUSHJ Q,MGDCSI IFN TM10B, SETZM ICWA1+1 SETZM MICWA+1 MGRD1: MOVEM B,MICWA ; CHANNEL COMMAND MOVEI B,2000 MOVEM B,MGNWRD ; ASSUME AT FIRST THAT THE RECORD TO BE READ HAS 2000 WORDS MOVE B,MTCONO(W) CONO MTC,MREAD(B) ; DO IT IFN TM10B, SETOM MGWCW ; TELL IT TO WAIT FOR CONTROL WORD WRITTEN PUSHJ Q,MGWTJD ; WAIT FOR JOB DONE JRST MGRERR MGRD2: MOVE A,MGCABN(W) SETOM MGCABN(W) ; NO BUFFER ACTIVE AT PI HLRZ T,MSBUFP(W) SETOM B DPB B,[MLO,,MEMBLT(A)] ; BACK POINTER IS -1 SKIPG MSNBOL(W) HRRM A,MSBUFP(W) ; ONE BUFFER MEANS IN = OUT HRLM A,MSBUFP(W) ; NEW IN POINTER SKIPLE MSNBOL(W) DPB A,[MLO,,MEMBLT(T)] ; CHAIN BACK BUFFERS AOS MSNBOL(W) ; ONE MORE BUFFER ON LIST MOVE B,MGNWRD DPB B,[MSWC,,MEMBLT(A)] ; NUMBER OF WORDS IN BUFFER SETOM B TRNE J,10000 DPB B,[310100,,MSRAC(W)] TRNE J,10000 DPB B,[MSEOFP,,MEMBLT(A)] TRNN J,10000 SETZM MGEOFR(W) ; NO EOF TRNE J,10000 AOSA A,MGEOFR(W) MOVE A,MGEOFR(W) CAIL A,2 JRST MGRD4 ; EOT SPACE BACK OVER IT MOVSI A,100 IORM A,MSRAC(W) ; TAPE MOVEMENT TRNN J,4000 ; EOT? JRST MGCMDR MGRD3: DPB B,[MSEOFP,,MEMBLT(A)] DPB B,[420100,,MSRAC(W)] ; INDICATE EOT ON READ JRST MGCMDR ; RETURN MGRD4: MOVSI A,200 ANDCAM A,MSRAC(W) JRST MGSPRF MGRERR: IFN TM10B,[ TLNE J,160 JRST MGERR ; CHANNEL ERROR ] TRNE J,642000 JRST MGERR TRNE J,20200 JRST MGMRT ; DATA TYPE OF ERROR , MAYBE TRY AGAIN IFN TM10B, HRRZ A,ICWA1+1 IFN TM10A, HRRZ A,MICWA HRRZ B,LMICWA SUB A,B IFN TM10B, SOS A ; CHANNEL FUNNYNESS CAIN A,1 ; POS EOF IS ALL JRST MGRER2 MGRER1: MOVEM A,MGNWRD JRST MGRD2 MGRER2: TRNE J,14000 ; 1 WORD, EOF? SETZM A JRST MGRER1 MGMRT: AOSL MGERRC(W) JRST MGERR ; TOO MANY ERRORS SETZM MICWA IFN TM10A,[ MOVE A,[-1,,MGVTC-1] MOVEM A,MICWA ; ONE RECORD ] IFN TM10A,PUSHJ Q,MGDCSO MOVE B,MTCONO(W) CONO MTC,MSPRR(B) ; REVERSE RECORD PUSHJ Q,MGWTJD JRST MGERR ; NO ERRORS ALLOWED IFN TM10A, PUSHJ Q,MGDCSI ; PUT BACK PI 1 BLKI MOVE B,LMICWA JRST MGRD1 ; TRY AGAIN MGROVR: PUSHJ Q,CPOPJ JRST MGREAD ; SPACE PI ROUTINES MGSPCF: PUSHJ Q,MGGXPT ; GET XPORT SPACE FORWARD TRNE J,600000 JRST MGERR MGSPC: MOVEM W,MGUNIT MOVE B,MGRWCD(W) ; GET COMMAND ADD B,MTCONO(W) IFN TM10B, DATAO MTS,[ICWA1] ; CHANNEL STARTING ADDRESS IFN TM10A, PUSHJ Q,MGDCSO IFN TM10B, SETZM MICWA ; SPACE ONLY ONE RECORD IFN TM10A,[ MOVE A,[-1,,MGVTC-1] MOVEM A,MICWA ; ONE RECORD ] CONO MTC,(B) ; DO IT PUSHJ Q,MGWTJD JRST MGERR ; NO RETRIES TRNN J,10000 ; EOF SETZB B,MGEOFR(W) TRNE J,10000 AOS B,MGEOFR(W) CAIL B,2 ;TOO MANY EOF'S JRST MGSPRF MGCMDR: SOS MSCMDC(W) ; GENERAL EXIT ROUTINE SETOM MGUNIT SKIPG MSCMDC(W) POPJ P, ; NO MORE MOVE B,MTCONO(W) CONO MTC,MNOPIN(B) ; INTERUPT WHEN UNIT READY MOVEM W,MGUNIT ; RESTORE UNIT NUMBER PUSHJ Q,MGWTJD JRST MGERR SETOM MGUNIT POPJ Q, ; MORE MGSPFR: MOVEI B,MSPFR ; SPACE FOR RECORD MOVEM B,MGRWCD(W) MOVSI B,100 IORM B,MSRAC(W) ; TAPE MOVEMENT JRST MGSPCF MGSPFF: MOVSI B,200 TDZE B,MSRAC(W) JRST MGCMDR ; EOF ALREADY READ DURING THE READ AOS MSCMDC(W) ;SO IT WILL RETURN MOVEI B,MSPFR MOVEM B,MGRWCD(W) PUSHJ Q,MGSPCF SKIPE MGEOFR(W) JRST MGCMDR ; EOF READ ON SPACE RECORD. DONE MOVEI B,MSPFF MOVEM B,MGRWCD(W) JRST MGSPCF MGSPCR: PUSHJ Q,MGGXPT ; SPACE REVERSE TRNE J,600000 ; ERR JRST MGERR TRNE J,100000 ; BOT JRST MGCMDR ; THEN DO NOTHING MOVEM W,MGUNIT MOVE B,MGRWCD(W) ADD B,MTCONO(W) IFN TM10B, DATAO MTS,[ICWA1] IFN TM10A, PUSHJ Q,MGDCSO SETZM MICWA IFN TM10A,[ MOVE A,[-1,,MGVTC-1] MOVEM A,MICWA ; ONE RECORD ] CONO MTC,(B) PUSHJ Q,MGWTJD JRST MGERR TRNE J,10000 SOSGE MGEOFR(W) ; ONE LESS EOF SETZM MGEOFR(W) JRST MGCMDR MGSPRR: MOVEI B,MSPRR MOVEM B,MGRWCD(W) MOVSI B,100 IORM B,MSRAC(W) JRST MGSPCR MGSPRF: MOVEI B,MSPRF ; REVERSE FILE MOVEM B,MGRWCD(W) MOVSI A,200 ; EOF READ IN FORWARD DIRECTION TDNN A,MSRAC(W) JRST MGSPCR AOS MSCMDC(W) ; YES DO IT TWICE PUSHJ Q,MGSPCR MOVSI B,200 ANDCAM B,MSRAC(W) ; TURN OFF FLAG JRST MGSPCR ; SECOND TIME MGRWD1: PUSHJ Q,MGGXPT ; REWIND MOVEM W,MGUNIT MOVE B,MGRWCD(W) ; GET COMMAND ADD B,MTCONO(W) CONO MTC,(B) PUSHJ Q,MGWTJD ; WAIT JRST MGERR SETZM MGEOFR(W) MOVSI A,100 ANDCAM A,MSRAC(W) ;CLEAR TAPE MOTION MGRWD2: TRNN J,200000 ; STILL REWINDING? POPJ Q, ;NO PUSHJ Q,CPOPJ ; WAIT CONI MTS,J MOVEM J,MGCMTS(W) JRST MGRWD2 MGRWND: MOVEI B,MREWND MOVEM B,MGRWCD(W) ; NORMAL REWIND PUSHJ Q,MGRWD1 JRST MGRWRT MGRWDM: MOVEI B,MRWNDD MOVEM B,MGRWCD(W) ; REWIND AND DISMOUNT PUSHJ Q,MGRWD1 MGRWRT: MOVSI A,140 ANDCAM A,MSRAC(W) JRST MGCMDR MGSEOT: PUSHJ Q,MGGXPT ; SKIP TO LOGICAL EOT TRNE J,600000 JRST MGERR MOVEM W,MGUNIT TRNE J,100000 ; BOT? JRST MGVTCK ; VIRGIN TAPE CHECK MGNVT: MOVE B,MTCONO(W) IFN TM10A, PUSHJ Q,MGDCSO IFN TM10A,[ MOVE A,[-1,,MGVTC-1] MOVEM A,MICWA ; ONE RECORD ] CONO MTC,MSPRR(B) ; SPACE REVERSE FIRST PUSHJ Q,MGWTJD ; WAIT JRST MGERR SETZM MGEOFR(W) AOS MGEOFR(W) MGEOT2: MOVE B,MTCONO(W) CONO MTC,MSPFF(B) ; SKIP FORWARD FILE PUSHJ Q,MGWTJD JRST MGERR MOVSI B,200000 ; EOT CHECK TRNE J,4000 IORM B,MSRAC(W) ; TELL MP MOVE B,MTCONO(W) IFN TM10A,[ MOVE A,[-1,,MGVTC-1] MOVEM A,MICWA ; ONE RECORD ] CONO MTC,MSPFR(B) ; SPACE FORWARD RECORD PUSHJ Q,MGWTJD JRST MGERR MOVSI B,2000 ; EOT AGAIN TRNE J,4000 IORM B,MSRAC(W) ; TELL MP TRNN J,10000 ; EOF ALSO? JRST MGEOT2 ; NO, TRY AGAIN MOVE B,MTCONO(W) ; YES, NO GO BACK OVER LAST CONO MTC,MSPRF(B) PUSHJ Q,MGWTJD JRST MGERR MOVSI B,600000 ; TELL MP,EOF IORM B,MSRAC(W) JRST MGCMDR MGVTCK: MOVE T,TIME ADDI T,60. ; TWO SECOND TIME OUT MOVEM T,MGEOTT(W) ; EOT TIME IFN TM10B, DATAO MTS,[ICWA1] IFN TM10A, PUSHJ Q,MGDCSI MOVE A,[-1,,MGVTC-1] ; BLKI PNTR MOVEM A,MICWA SETZM MICWA+1 MOVE B,MTCONO(W) CONO MTC,MREAD(B) ; DO READ, WAIT EITHER FOR JOB DONE OR TIME OUT MGVTC1: CONI MTS,J MOVEM J,MGCMTS(W) TRNE J,100 ; J D? JRST MGNVT ; NOT VIRGIN TAPE TRNE J,440000 JRST MGERR ; ERRORS? MOVE T,MGEOTT(W) CAMG T,TIME ; TIME UP? JRST MGVT ; YES PUSHJ Q,CPOPJ ; WAIT JRST MGVTC1 MGVT: MOVE B,MTCONO(W) CONO MTS,31 CONO MTC,MNOPIN(B) ; NO-OP WAIT FOR JOB DONE PUSHJ Q,MGWTJD JFCL ; SEE IF I CARE IF THERE ARE ERRORS MOVEI B,MREWND MOVEM B,MGRWCD(W) PUSHJ Q,MGRWD1 ; REWIND SETZM MGEOFR(W) AOS MGEOFR(W) JRST MGCMDR ; RETURN MGMEOT: PUSHJ Q,MGGXPT TRNE J,600000 JRST MGERR MOVEM W,MGUNIT SKIPE MTCEFW(W) ;HOW MANY EOF WRITTEN? JRST MGMET1 AOS MSCMDC(W) ; SO WILL RETURN AOS MTCEFW(W) PUSHJ Q,MGWEOF MGMET1: MOVE A,MTCEFW(W) SOSLE A JRST MGMET2 AOS MSCMDC(W) AOS MTCEFW(W) PUSHJ Q,MGWEOF MGMET2: MOVE A,MSRAC(W) TLNE A,1000 ; BACK OVER LAST? JRST MGMET3 ; NO AOS MSCMDC(W) ; SO IT WILL RETURN PUSHJ Q,MGSPRF MGMET3: MOVSI A,1000 IORM A,MSRAC(W) JRST MGCMDR ; DONE ; WRITE EOF MGWEOF: PUSHJ Q,MGGXPT TRNE J,600010 JRST MGERR MOVEM W,MGUNIT MOVE B,MTCONO(W) CONO MTC,MWEOF(B) PUSHJ Q,MGWTJD JRST MGERR MOVSI A,100 IORM A,MSRAC(W) ; TAPE MOVEMENT JRST MGCMDR ; RETURN MGSTAT: PUSHJ Q,MGGXPT ; GETS STATUS JRST MGCMDR MGW3IN: PUSHJ Q,MGGXPT TRNE J,600010 JRST MGERR MOVEM W,MGUNIT IFN TM10B, DATAO MTS,[ICWA1] IFN TM10A, PUSHJ Q,MGDCSO MOVE A,[-1,,MGVTC-1] ; WRITE ANY RANDOM WORD MOVEM A,MICWA SETZM MICWA+1 MOVE B,MTCONO(W) CONO MTC,MW3IN(B) ; WRITE THE RANDOM WORD PRECEEDED BY 3 INCHES OF BLANK TAPE PUSHJ Q,MGWTJD JFCL ; ALLOW BAD TAPE ERROR JRST MGSPRR ; NO SPACE RECORD REVERSE OVER THE ONE WORD ;.MTAPE AC, ; AC/ CHNM,COMMAND ; COMMAND/ COUNT,,FUNCTION AMTAPE: XCTR XR,[HLRZ R,(J)] CAIL R,20 JRST ILUUO MOVEM R,UUAC(U) ;SO ERRORS ARE REPORTED ON THE CORRECT CHANNEL ADDI R,IOCHNM(U) ; FORM IOCHNM POINTER LDB W,[MTXP(R)] ; GET XPORT NUMBER CAME U,MTUSR(W) ; SAME USER POPJ P, ; NO XCTR XR,[MOVE J,(J)] MOVEM J,MTMTAP(W) ; SAVE J HRRZ A,MTMTAP(W) PUSHJ P,MTIECK XCTR XR,[MOVE A,(A)] MOVEM A,MTMFNC(W) ; STORE FUNCTION HRRZS A CAIL A,NMTAPC ; LEGAL COMMAND POPJ P, ; NO AOS (P) ; SKIP RETURN JRST @MTAPDT(A) MTAPDT: MTHANG ; HANG TILL TAPE MOTION DONE MTRWND ; REWIND MTRWDM ; REWIND AND DISMOUNT MTWEOR ; WRITE EOR IF APPROPRIATE MTW3IN ; WRITE 3 INCHES OF BLANK TAPE MTWEOF ; WRITE EOF MTSPR ; SPACE RECORDS MTSPF ; SPACE FILES MTSPEOT ; SPACE TO EOT MTSTOP ; STOP ALL COMMAND ASSOCIATED WITH THIS COMMAND NMTAPC==.-MTAPDT MTHANG: SKIPLE MSCMDC(W) ; HANG UNTILL ALL MOTION FINISHED PUSHJ P,UFLS JRST MTIECK MTRWND: MOVEI B,MGRWND ; REWIND MTRWD1: SKIPE MSCRW(W) JRST MTSOSP MOVSI A,40 IORM A,MSRAC(W) JRST MTCMD MTRWDM: MOVEI B,MGRWDM ; REWIND ND DISMOUNT JRST MTRWD1 MTWEOR: SKIPG MTMDN(W) ; ANY BUFFERS STARTED POPJ P, ; NO SKIPE MSCRW(W) ; WRITING JRST MTWBFD ; DISCARD BUFFER MTSOSP: SOS (P) ; NOT WRITING POPJ P, MTWEOF: SKIPN MSCRW(W) ; WRITING JRST MTSOSP ; NO PUSHJ P,MTWEOR MOVEI B,MGWEOF ; WRITE EOF AOS MTCEFW(W) MOVSI TT,1000 ANDCAM TT,MSRAC(W) ; SOMETHING WRITTEN JRST MTCMD MTW3IN: SKIPN MSCRW(W) ; WRITING? JRST MTSOSP MOVEI B,MGW3IN SETZM MTCEFW(W) MOVSI TT,1000 ANDCAM TT,MSRAC(W) JRST MTCMD MTSPR: SKIPL MTMFNC(W) JRST MTSPFR ; SPACE FORWARD MTSPRR: MOVEI B,MGSPRR ; SPACE REVERSE SKIPE MSCRW(W) ; NOT ALLOWED IT WRITING JRST MTSOSP PUSHJ P,MTCMD HLRE B,MTMFNC(W) ; GET COUNT ADDI B,1 HRLM B,MTMFNC(W) PUSHJ P,MTCNTR ; RETURN COUNT INCASE OF PCLSR SKIPE B JRST MTSPRR ; ANOTHER RECORD TO SPACE POPJ P, MTSPFR: MOVEI B,MGSPFR SKIPE MSCRW(W) ; NOT ALLOWED IT WRITING JRST MTSOSP PUSHJ P,MTCMD HLRE B,MTMFNC(W) ; GET COUNT SKIPN B POPJ P, ; ALL DONE IF ZERO SUBI B,1 HRLM B,MTMFNC(W) PUSHJ P,MTCNTR ; RETURN COUNT SKIPE B JRST MTSPFR ; AGAIN POPJ P, MTSPF: SKIPL MTMFNC(W) JRST MTSPFF ; SPACE FORWARD FILES MTSPRF: MOVEI B,MGSPRF SKIPE MSCRW(W) ; NOT ALLOWED IT WRITING JRST MTSOSP PUSHJ P,MTCMD HLRE B,MTMFNC(W) ; GET COUNT ADDI B,1 HRLM B,MTMFNC(W) PUSHJ P,MTCNTR ; RETURN COUNT SKIPE B JRST MTSPRF ; ANOTHER POPJ P, MTSPFF: MOVEI B,MGSPFF SKIPE MSCRW(W) ; NOT ALLOWED IT WRITING JRST MTSOSP PUSHJ P,MTCMD HLRE B,MTMFNC(W) ; GET COUNT SKIPN B POPJ P, ; ALL DONE IF ZERO SUBI B,1 HRLM B,MTMFNC(W) PUSHJ P,MTCNTR ; RETURN COUNT SKIPE B JRST MTSPFF ; AGAIN POPJ P, MTCNTR: HRRZ A,MTMTAP(W) MOVE B,MTMFNC(W) XCTR XW,[MOVEM B,(A)] HLRES B POPJ P, MTSTAT: SKIPLE MSCMDC(W) ; WAIT TILL ALL COMMANDS DONE PUSHJ P,UFLS MOVEI B,MGSTAT ; GET CONI'S PUSHJ P,MTCMD ; GIVE TO PI SKIPLE MSCMDC(W) ; WAIT TILL DONE PUSHJ P,UFLS MOVE I,MGCMTC(W) MOVE J,MGCMTS(W) POPJ P, MTSPEOT: MOVEI B,MGSEOT ; SPACE TO LOGICAL EOT JRST MTCMD MTSTOP: CONO PI,UTCOFF SETZM MSCMDC(W) ;NO MORE COMANDS MOVE Q,[-MGQDLL,,MGQD0-1] MOVE T,MSLCTB IMUL T,W ADD Q,T MOVEM Q,MGQDLP(W) ; RESTORE Q MOVE Q,[-MSCBL-1,,MSCB0-1] ADD Q,T MOVEM Q,MTCMBP(W) ; INITIALIZE MP AND PI COMAND POINTERS MOVE Q,[4400,,MSCB0-1] ADD Q,T MOVEM Q,MGCMBP(W) SKIPL A,MTMDN(W) PUSHJ P,IMEMR ; RELEASE MP BUFFER SETOM MTMDN(W) SETZM MSMPRP(W) SETZM MSMPRC(W) ; SO BLKT WON'T GET UNHAPPY SKIPE MSNBOL(W) PUSHJ P,MTCBFF ; FLUSH BUFFER LIST CAME W,MGUNIT ; SAME UNIT? JRST UTCONJ SETOM MGUNIT ; SO INTERUPT WILL GO AWAY CONI MTC,I ; SEE WHAT DRIVE IS BEING TALKED TO LDB B,[MUNITF,,I] CAME W,B JRST UTCONJ ; IF NOT SAME UNIT, DON'T DO ANYTHING MOVE B,MTCONO(W) CONO MTS,31 ; STOP THE TAPE CONO MTC,(B) ; CLEAR INTERUPTS SKIPGE A,MGCABN(W) ; ANY BUFFERS ACTIVE AT PI JRST UTCONJ ; NO PUSHJ P,IMEMR ; RETURN IT SETOM MGCABN(W) JRST UTCONJ ; MTOCL: LDB W,[MTXP(R)] SOSL MTUSE(W) POPJ P, ; NOT ONLY CHANNEL OPEN AOS MTUSE(W) ; INCASE PCLSRED MOVSI A,40000 ;ERROR? TDNE A,MSRAC(W) PUSHJ P,MTOCL3 ; MOVEI T,MSCBL-4 ; CAMG T,MSCMDC(W) ; PUSHJ P,UFLS ; WAIT FOR ROOM FOR THREE COMMANDS SKIPL MTMDN(W) ; MAG TAPE OUTPUT CLOSE PUSHJ P,MTWBFD ; WRITE OUT BUFFERS ; MOVEI B,MGWEOF ; WRITE OUT TWO EOF(S) ; SKIPE MTCEFW(W) ; JRST MTOCL2 ; MAY HAVE BEEN PCLSRED ;MTOCL1: PUSHJ P,MTCMD ; AOS MTCEFW(W) ; ONE MORE CLOSE EOF WRITTEN ;MTOCL2: MOVE A,MTCEFW(W) ; SOSG A ; DON'T WRITE EOF IF PCLSRED ; PUSHJ P,MTCMD ; DO IT TWICE ; SKIPG A ; AOS MTCEFW(W) ; MOVEI B,MGSPRF ; MOVE A,MSRAC(W) ; TLNN A,1000 ; PUSHJ P,MTCMD ; NOW BACK UP OVER ONE ; MOVSI A,1000 ; IORM A,MSRAC(W) MOVEI B,MGMEOT ; MAKE EOT PUSHJ P,MTCMD SKIPLE MSCMDC(W) ; NOW WAIT TILL DONE PUSHJ P,UFLS MOVEI A,1 MOVEM A,MGEOFR(W) SKIPL MTMDN(W) ;ANY ACTIVE BUFFERS JRST 4,. SKIPL MGCABN(W) JRST 4,. SKIPE MSNBOL(W) JRST 4,. SETOM MTUSR(W) SETOM MTUSE(W) SETZM MSRAC(W) POPJ P, MTOCL3: SKIPL A,MTMDN(W) PUSHJ P,MEMR ; IF BUFFER AROUND,FLUSH IT SETOM MTMDN(W) SETZM MSMPRC(W) POPJ P, MTICL: LDB W,[MTXP(R)] SOSL MTUSE(W) ; LAST USER POPJ P, AOS MTUSE(W) MOVEI T,1 CAMGE T,MSCMDC(W) ; ALLOW ONE COMMAND IF REWINDING PUSHJ P,UFLS ; ALL COMMANDS DONE MOVE T,MSRAC(W) TLNE T,40 ; REWINDING? JRST MTICL3 ; YES SKIPLE MSCMDC(W) ; NO, WAIT TILL COMMAND DONE PUSHJ P,UFLS MTICL3: SKIPL MGCABN(W) ; ANY PI BUFFERS LEFT JRST 4,. SKIPL MTMDN(W) PUSHJ P,MTRBD SETOM MTUSR(W) SKIPE MSNBOL(W) ; ANY BUFFERS LEFT ON LIST PUSHJ P,MTCBFF ; FREE BUFFERS SOS MTUSE(W) MOVE T,MSRAC(W) TLNE T,40 ; DON'T HAVE TO SKIP TO EOF IF REWINDING JRST MTICL2 MOVSI A,20 TDNE A,(R) ;CHECK TO SKIP TO EOF JRST MTICL2 MOVSI A,100 TDNN A,MSRAC(W) ;TAPE MOVEMENT JRST MTICL2 ; NO SKIPE MGEOFR(W) ;NO TIMING CONFLECT HERE SINCE WE WAITED FOR PI TO CLEAR JRST MTICL2 PUSHJ P,MTSTAT MOVE B,MGCMTS(W) TRNE B,100000 JRST MTICL2 MOVEI B,MGSPFF PUSHJ P,MTCMD SKIPLE MSCMDC(W) PUSHJ P,UFLS MTICL2: MOVSI T,40 ANDM T,MSRAC(W) ;CLEAR ALL BUT REWINDING POPJ P, ; NO, DONE MTCBFF: HRRZ A,MSBUFP(W) SOSE MSNBOL(W) ; ONE LESS BUFFER PUSHJ P,MTICL1 ; FIX CHAIN PUSHJ P,MEMR ; RETURN BUFFER SKIPN MSNBOL(W) ; ANY LEFT POPJ P, ; NO JRST MTCBFF MTICL1: LDB B,[MLO,,MEMBLT(A)] ; GET BACK POINTER HRRM B,MSBUFP(W) POPJ P,