TITLE TM2KON - RH10/RH20/RH11 TM02/TM03(TU16/TU45/TU77) DRIVER FOR TAPSER V121 SUBTTL T WACHS/TW 10 SEP 85 SEARCH F,S FTRH11==FTKS10 ;KEEP TRACK OF WHAT WE'RE DOING IFE FTRH11,< SEARCH ICHPRM ;RH20 PARAMS (SYMBOLS REQUIRED BUT NOT USED IF KI) > SALL .DIRECT FLBLST $RELOC $HIGH ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; .CPYRT<1975,1986> ;COPYRIGHT (C) 1975,1976,1977,1978,1979,1980,1982,1984,1986 ;BY DIGITAL EQUIPMENT CORP, MAYNARD MASS. ;ALL RIGHTS RESERVED. ; XP VTM2KN,121 IFE FTRH11,< ENTRY TM2KON TM2KON::INTERN TM2DSP TTXREG==TT2REG## ;RH REGISTERS FOR ERROR TTXUVA==TT2UVA## ;READ-BACKWARDS TEMP > IFN FTRH11,< ENTRY TRHKON TRHKON::TRHDSP=:TM2DSP TTXREG==TRHREG## ;RH REGISTERS FOR ERROR TTXUVA==TRHUVA## ;READ-BACKWARDS TEMP > ;SYSERR REGISTER BLOCK DEFINITIONS E..CNI==TTXREG+0 ;RH10/20 - CONI AT ERROR ;RH11 - DO.CS2,,DO.CS1 AT ERROR E..DTI==TTXREG+1 ;RH10/20 - DATAI CONTROL AT ERROR ;RH11 - UBA STATUS REGISTER AT ERROR E..DT2==TTXREG+2 ;RH10/20 - DATAI DATA BUFFER AT ERROR ;RH11 - UBA MAP ENTRY AT ERROR E..LCM==TTXREG+3 ;LAST COMMAND ISSUED E..MBR==TTXREG+4 ;BLOCK OF MASSBUS REGISTERS AT ERRROR ;DISPATCH TABLE FOR TAPSER CALLS TM2DSP::IFIW TM2INI ;00 - INITIALIZE IFIW TM2RES ;01 - RESET ACTIVE I/O IFIW TM2SIO ;02 - START I/O IFIW TM2INT ;03 - INTERRUPT SERVICE EXP 0 ;04 - SET DEVICE COMMAND IFIW CPOPJ## ;05 - KONTROLLER IS IDLE IFIW TM2ONL ;06 - TEST IF CTL ON-LINE IFIW TM2SCH ;07 - FORCE A SCHEDULE CYCLE IFIW TM2INR ;10 - RE-INITIALIZATION IFIW CPOPJ## ;11 - LOAD MICROCODE IFIW CPOPJ## ;12 - ENABLE/DISABLE MICROCODE LOADING IFN FTAUTC, ;13 - AUTOCONFIGURE IFE FTRH11,< ;MACRO MAKES SURE MASSBUS DATA IS STABLE WHEN READ DEFINE STALL,< IMULI P,1 IFN FTKL10,< IMULI P,1 > ;;THE KL IS FASTER, DO IT AGAIN >;STALL >;FTRH11 ;OFFSETS INTO TKBCCL TKBFLG==TKBCCL##+2 ;FLAGS FROM FNCTBL TKBCHR==TKBCCL##+3 ;CHARACTER (FRAME) COUNT TKBSCH==TKBCCL##+4 ;-1 IF A SCHEDULE CYCLE SUBTTL PARAMETERS ;MACRO TO ASSIGN MASSBUS REGISTERS DEPENDING ON KONTROLLER TYPE DEFINE MBR(NAME,RH1020,RH11),< IFE FTRH11,< IFNB /RH1020/, >;;RH10/20 DATAO CODE IFN FTRH11,< IFNB /RH11/, >;; RH11 WRIO OFFSET IFNB /RH1020/,;;TUB OFFSET OF REGISTER FOR SYSERR >;MBR ;DRIVE REGISTERS MBR CS1,0,0 ;DRIVE CONTROL REGISTER MBR WC,,2 ;WORD COUNT REGISTER MBR BA,,4 ;BUS ADDRESS REGISTER MBR CS2,,10 ;STATUS REGISTER MBR DS,1,12 ;DRIVE STATUS REGISTER MBR ER,2,14 ;ERROR REGISTER MBR DB,,22 ;DATA BUFFER REGISTER MBR MR,3,24 ;MAINTENANCE REG MBR AS,4,16 ;ATTN SUMMARY MBR FC,5,6 ;FRAME COUNTER MBR DT,6,26 ;DRIVE TYPE MBR CK,7,20 ;CHK CHARACTER REG MBR SN,10,30 ;SERIAL NUMBER MBR TC,11,32 ;TAPE CONTROL REGISTER IFN FTRH11,< ;CONTROL REGISTER BITS (DO.CS1) DC.SC==1B20 ;SPECIAL CONDITION DC.TRE==1B21 ;TRANSFER ERROR DC.CPE==1B22 ;CONTROL BUS PARITY ERROR DC.DVA==1B24 ;DRIVE AVAILABLE DC.PSL==1B25 ;PORT SELECT DC.RDY==1B28 ;READY DC.IE==1B29 ;INTERRUPT ENABLED ; DC.FNG==77 ;FUNCTION + GO ;STATUS REGISTER BITS (DO.CS2) D2.DLT==100000 ;(R) DATA LATE (OVERRUN) D2.WCE==40000 ;(R) WRITE CHECK ERROR D2.UPE==20000 ;(R/W) UNIBUS PARITY ERROR D2.NXD==10000 ;(R) NON-EXISTANT DRIVE D2.NXM==4000 ;(R) NON-EXISTANT MEMORY D2.PGE==2000 ;(R) PROGRAM ERROR D2.MXF==1000 ;(R/W) MISSED TRANSFER D2.DPE==400 ;(R) DATA BUS PARITY ERROR D2.OR==200 ;(R) OUTPUT READY D2.IR==100 ;(R) INPUT READY D2.CLR==40 ;(W) CONTROLLER CLEAR D2.PAT==20 ;(R/W) PARITY TEST D2.BAI==10 ;(R/W) UNIBUS ADDRESS INCREMENT INHIBIT ; D2.UNI==7 ;(R/W) MASSBUS UNIT # TO TALK TO D2%CHE==D2.DLT!D2.UPE!D2.NXD!D2.NXM!D2.PGE!D2.MXF!D2.DPE ;CHANNEL-TYPE ERRORS >;FTRH11 ;DRIVE FUNCTIONS LOADED INTO DRIVE CONTROL REG (DO1CRC/.DOSTC/DO.CS1) DF.NOP==1 ;NO-OP DF.UNL==3 ;UNLOAD (REWIND OFF-LINE) DF.INT==5 ;ILLEGAL FUNCTION TO CAUSE AN INTERRUPT DF.REW==7 ;REWIND DF.CLR==11 ;DRV CLR DF.RIPS==21 ;READ-IN, PRESET DF.ERA==25 ;ERASE DF.WTM==27 ;WRITE TAPE MARK DF.SPF==31 ;SPACE FWD DF.SPR==33 ;SPACE REVERSE DF.WCF==51 ;WRITE CHK FWD (READ FWD) DF.WCR==57 ;WRITE CHK REV (READ REV) DF.WTF==61 ;WRITE FORWARD DF.RDF==71 ;READ FORWARD DF.RDR==77 ;READ REVERSE ;TAPE CONTROL REGISTER (DO.TC) TC.PAR==1B32 ;ON IF WRITE EVEN PARITY ;DRIVE TYPE REGISTER (DO.DT) DT.SPR==1B25 ;SLAVE PRESENT ;DRIVE STATUS REGISTER (DO.DS) DS.ATA==1B20 ;ATTENTION DS.ERR==1B21 ;COMPOSITE ERROR DS.PIP==1B22 ;POSITIONING IN PROGRESS DS.MOL==1B23 ;MEDIUM ON LINE DS.WRL==1B24 ;WRITE LOCKED DS.EOT==1B25 ;END OF TAPE DS.DPR==1B27 ;DRIVE PRESENT DS.DRY==1B28 ;DRIVE READY (NOT GO) DS.SSC==1B29 ;SLAVE STATUS CHANGE DS.PES==1B30 ;PHASE ENCODED STATUS DS.SDN==1B31 ;SHUTDOWN BIT DS.IDB==1B32 ;IDENT BURST (FOR PE) DS.TM==1B33 ;TAPE MARK DS.BOT==1B34 ;BEGINNING OF TAPE DS.SLA==1B35 ;SLAVE ATTENTION DS.OK==DS.EOT!DS.PES!DS.TM!DS.BOT!DS.SSC!DS.SDN!DS.IDB ;BITS WHICH DON'T MATTER DS.GUD==DS.MOL!DS.DPR!DS.DRY ;THESE BITS MUST BE ON ;DRIVE ERROR REGISTER (DO.ER) ER.COR==1B20 ;CORRECTABLE DATA/ CRC ERROR ER.UNS==1B21 ;UNSAFE ER.OPI==1B22 ;OPERATION INCOMPLETE ER.DTE==1B23 ;DRIVE TIMING ERROR ER.NEF==1B24 ;NON-EXISTANT FUNCTION ER.CS==1B25 ;CORRECTABLE SKEW/ ILLEGAL TAPE MARK ER.FCE==1B26 ;FRAME COUNT ERROR ER.NSG==1B27 ;NON-STANDARD GAP (CRAP IN THE GAP) ER.LRC==1B28 ;LRC ERROR/ FORMAT (PREAMBLE POSTAMBLE) ERROR ER.INC==1B29 ;INCORRECTABLE DATA/ VERTICAL PARITY ERROR ER.DPA==1B30 ;DATA BUS PARITY ERROR ER.FMT==1B31 ;FORMAT ERROR ER.CPA==1B32 ;CBUS PARITY ERROR ER.RMR==1B33 ;REG MODIFICATION REFUSED ER.ILR==1B34 ;ILLEGAL REGISTER ADR ER.ILF==1B35 ;ILLEGAL FUNCTION IFE FTRH11,< ;RH10 BITS, FUNCTIONS DO1CRC==40B5 ;RH10 CONTROL REG DO1CDB==50B5 ;RH10 DATA BUFFER DO1CRA==54B5 ;RH10 RAE REGISTER ;CONI/CONO BITS ;LH BITS CI1SDR==200 ;SELECTED DRIVE REGISTER ACCESS ERROR CI1CDP==4 ;CHAN DATA PARITY ERROR CI1CWP==2 ;CHAN COMMAND WORD PARITY ERROR CI1NXM==1 ;CHAN-DETECTED NXM ;RH BITS CI1ATN==40 ;ATTENTION CI1DON==10 ;DONE CI1ERR==536220 CO1CLR==734210 ;CLEAR ALL ERRORS ;DATAI/DATAO BITS CBTO==2000 ;CONTROL BUS TIMEOUT ;RH20 ;CONI/CONO CI.ERR==CI.LWC!CI.DRE!CI.RAE CO.CLR==CO.RAE!CO.TEC!CO.CCD ;CHANNEL LOGOUT AREA CS.ERR==CS.MPE!CS.NAE!CS.NXM!CS.RHE!CS.OVR ;ALL CHAN LOGOUT ERRS >;IFE FTRH11 SUBTTL TAPSER CALL PROCESSING ;HERE TO START IO ;REGISTER USAGE: ;T1/ IORB ADDRESS ;T2/ TEMP, MASSBUS REGISTER READ/WRITTEN ;T3/ MASSBUS UNIT # OF TM02/3 ;T4/ MODTBL ENTRY FOR IORB ;P1/ FNCTBL ENTRY (FLAG BITS+IORB FCN,,DF.XXX) ;P2/ CONTROLLER TYPE / IO ADDRESS OF RH11 ;U/ TUB FOR IO ;W/ TKB FOR IO TM2SIO: PUSHJ P,CHKIRB## ;GET IORB FOR THIS OP JRST TAPDIS## ;NONE, GO AWAY PUSHJ P,SAVST2 ;SAVE ACS, P2=0 (RH10), =1 (RH20), CSR (RH11) LDB T4,PRBFCN## ;FUNCTION SKIPN P1,FNCTBL(T4) ;LEGAL? JRST ILLFNC ;NO SKIPGE T2,TRBRCT(T1) ;IF POSITIVE IN ERROR RECOVERY MOVEM T2,TTXUVA(W) ;REAL IOWD - SAVE IT LDB T2,[POINT 3,TUBAKA##(U),17] ;YES, GET DRIVE NUMBER LDB T4,PRBDEN## ;GET DENSITY CAILE T4,MAXDEN ;LEGAL? MOVEI T4,MAXDEN ;TOO HIGH - MAKE IT THE HIGHEST DPB T4,PRBDEN## ;SAVE SKIPGE T4,DENTBL(T4) ;LEGAL DENSITY? JRST ILLFNC ;NO TRO T2,(T4) ;YES, PUT DENSITY INTO COMMAND MOVSI T4,RB.PAR ;EVEN PARITY? TDNE T4,TRBLNK(T1) TRO T2,TC.PAR ;YES, TELL THE HARDWARE LDB T4,PRBMOD## ;GET MODE SKIPGE T4,MODTBL(T4) ;LEGAL? JRST ILLFNC ;NO TRO T2,(T4) ;YES, TELL THE HARDWARE IFE FTRH11,< MOVEI T3,CO.MBE ;DONT ALLOW INTERRUPTS (BIT IGNORED IF RH10) XCT TT2CO3##(W) ;(REWINDING DRIVE) >;FTRH11 IFN FTRH11,< MOVEI T3,1 ;MAKE SURE GO BIT ISN'T SET, AS IT WILL TIOE T3,<(DO.CS1)>(P2);CAUSE A PGE, AND MAYBE DO LAST OP TWICE... JRST TAPDIS## ;IN ANY CASE, WE'LL GET ANOTHER INTERRUPT MOVEI T3,DC.IE ;IT'S SAFE, CLEAR INTERRUPT ENABLE BCIOB T3,<(DO.CS1)>(P2);(REWINDING DRIVE) >;FTRH11 HRLI T2,(DO.TC) ;SET TO TALK TO TAPE CNTRL REG PUSHJ P,WTREG ;TELL MODE, DENSITY, SLAVE #, PARITY HRLI T3,-1 ;1ST TIME THROUGH (RH SET BY WTREG) TM2SI2: MOVSI T2,(DO.DS) ;READ THE STATUS REGISTER OF THE SLAVE PUSHJ P,RDREGX TRNE T2,DS.BOT ;BOT? JUMPL P1,[.CREF TB.REV ;YES, JUMP IF FUNCTION GOES BACKWARDS MOVSI P1,TUSBOT## ;SW BOT, UPDATE STATUS IORM P1,TUBSTS##(U) ;LET THE UDB KNOW MOVSI P1,TUSWTL## ;YES, UPDATE WRITE-LOCK STATUS ANDCAM P1,TUBSTS##(U) ; BY CLEARING IT TRNE T2,DS.WRL ; AND SET IT AGAIN IF WE REALLY ARE IORM P1,TUBSTS##(U) ; WRITE LOCKED MOVSI P1,RB.SNM!RB.SBT ;SINCE DRIVE IS AT BOT IORM P1,TRBSTS(T1) ;INDICATE NO MOTION, BOT MOVE P1,FNCNOP ;CHANGE FUNCTION TO NO-OP JRST .+1] ;AND CONTINUE TLNN P1,(TB.WRT) ;ARE WE READING? TRZ T2,DS.WRL ;YES, WRITE-LOCKED TAPE IS OK SKIPL T3 ;SKIP IF PASS 1 TRZ T2,DS.ATA ;IF DID A DRIVE CLEAR IGNORE ATTN TRZ T2,DS.OK ;CLEAR THE BITS WHICH DON'T MATTER CAIE T2,DS.GUD ;IS THE DRIVE OK? JRST NOSTRT ;NO, INVESTIGATE FURTHER ;YES, CONTINUE TLNN P1,(TB.DAT) ;DATA OPERATION? JRST TM2SI3 ;NO IFN FTRH11,< PUSH P,T3 ;SAVE TM02 NUMBER HRRZ T3,TKBCDB##(W) ;ADDRESS OF CHANNEL DATA BLOCK MOVE T2,CHNBTC##(T3) ;GET THE BYTE COUNT FOR THIS TRANSFER AOJ T2, ;ROUND UP TO WORDS LSH T2,-1 ;MAKE 11 STYLE WORD COUNT MOVNS T2 ;2'S COMPLEMENT WRIO T2,<(DO.WC)>(P2);LOAD THE WORD COUNT REGISTER HRRZ T2,P1 ;GET FUNCTION CODE CAIE T2,DF.RDR ;IS IT A READ REVERSE? JRST TRHS2A ;NO--PROCEED MOVE T2,CHNTCW##(T3) ;GET ENDING -11 STYLE ADDRESS SOSA T2 ;"REAL" START FOR READ REVERSE TRHS2A: MOVE T2,CHNIEA##(T3) ;GET STARTING -11 STYLE ADDRESS WRIO T2,<(DO.BA)>(P2);LOAD INTO BUS ADDRESS REGISTER LSH T2,-^D16 ;GET HIGH TWO BITS OF ADDRESS ANDI T2,3 ;AND ONLY THEM WRIOB T2,<(DO.CS1)>+1(P2) ;STORE IN RH11 POP P,T3 ;RESTORE TM02 NUMBER >;FTRH11 MOVS T2,TTXUVA(W) ;GET WORD COUNT HLRZS T4 ;NO OF FRAMES PER WORD TLOE T2,-1 ;DO WE ALREADY HAVE FRAME COUNT ? IMULI T2,(T4) ;NO, COMPUTE FRAME COUNT MOVNM T2,TKBCHR(W) ;SAVE IN KDB TLNE P1,(TB.NFC!TB.OFC) ;0 OR -1 TO F.C.? TM2SI3: SETZ T2, ;YES TLNE P1,(TB.NFC!TB.DAT) ;IF T2 IS ALREADY SET, JRST NOFC ;GO TLNE P1,(TB.OFC) ;IF -1 TO F.C. SOJA T2,NOFC ;GO MOVN T2,TRBXCW(T1) ;GET -NO OF RECS TO SPACE NOFC: ANDI T2,177777 ;ONLY 16 BIT'S WORTH HRLI T2,(DO.FC) ;TALK TO FRAME COUNT REG PUSHJ P,WTREGX ;TELL IT HOW MUCH TO DO TM2SI4: IFE FTRH11,< .CREF DO.CS1 ;NEXT INSTR SETS UP TO WRITE CS1 FOR SPACE OP HRRZ T2,TKBICP##(W) ;ICWA HRRZ T3,TRBXCW(T1) ;CHAN LIST SKIPE P2 ;IF AN RH20, TLO T3,RH2JMP## ; MAKE A JUMP-WORD MOVEM T3,(T2) ;POINT ICWA AT IO LIST SKIPE P2 ;IF AN RH20, TDZA T2,T2 ; ICWA ISNT IN COMMAND LSH T2,6 ;POSITION ICWA FOR DATAO TRO T2,(P1) ;INSERT FUNCTION TLNE P1,(TB.DAT) ;TALK TO CS1 IF SPACE OP, TDO T2,[DO1CRC!DO.DTE ;TALK TO RH10 CNTRL REG .DOSTC!DO.RCP!DO.SCS!DO.DTE!177700](P2) ;OR RH20 CNTRL REG MOVEM T2,E..LCM(U) ;SAVE LAST COMMAND IN UDB PUSHJ P,WTREG ;GO START UP THE WORLD MOVEM P1,TKBFLG(W) ;REMEMBER WHAT WE ARE DOING MOVEI T3,TAPCHN##+CO.MBE ;PIA TLNN P1,(TB.DAT) ;DATA OPERATION? TRO T3,CO.AIE ;NO, ENABLE FOR ATTENTIONS ;CONTINUE PUSHJ P,SETIV ;SET UP INTERRUPT VECTOR JUMPE P2,TM2SI6 ;NO SWEAT IF RH10 XCT TKBCIS##(W) ;DID WE WIN IN THE SETUP? TRNE T2,CI.RAE TRO T3,CO.STP ;NO, CAUSE AN IMMEDIATE INTERRUPT TM2SI6: XCT TT2CO3##(W) ;TURN ON RH10 PI >;FTRH11 IFN FTRH11,< HRRZ T2,P1 ;GET FUNCTION TRO T2,DC.IE ;INTERRUPT ENABLED MOVEM T2,E..LCM(U) ;SAVE LAST COMMAND IN UDB WRIOB T2,<(DO.CS1)>(P2) ;WRITE COMMAND, PRESERVE ADDRESS BITS MOVEM P1,TKBFLG(W) ;REMEMBER WHAT WE ARE DOING >;FTRH11 POPJ P, ;GO AWAY AND WAIT FOR INTERRUPT ;HERE IF THE DRIVE STATUS REGISTER ISN'T RIGHT NOSTRT: CAIE T2,DS.GUD!DS.WRL ;ONLY WRITE-LOCK? JRST BADSTS ;NO, IT REALLY IS BAD SKIPA T2,[RB.SLK!RB.SER,,] ;WRITE-LOCKED ILLFNC: MOVSI T2,RB.SER!RB.SIL ;ILLEGAL FUNCTION ILLORM: IORM T2,TRBSTS(T1) ;TELL TAPUUO WHAT THE PROBLEM IS ;WE WILL NOW ISSUE AN ILLEGAL FUNCTION IN ORDER TO CAUSE AN INTERRUPT ;BUT WE CANNOT ISSUE THE COMMAND TO A DRIVE THAT IS REWINDING, ;AS THAT MIGHT HANG SOME TM03'S. SO WE SEARCH FOR ANY DRIVE WHICH ;IS NOT REWINDING, PERHAPS EVEN A NON-EXISTANT ONE. MOVEI P1,7 ;START WITH DRIVE 7 ILLRM2: MOVE T2,P1 ;TALK TO IT HRLI T2,(DO.TC) ;SELECT THIS SLAVE PUSHJ P,WTREG MOVSI T2,(DO.DS) ;IS IT REWINDING? PUSHJ P,RDREGX TRNE T2,DS.PIP ;POSITIONING IN PROGRESS SOJGE P1,ILLRM2 ;YES, KEEP LOOKING MOVE P1,FNCNOP ;FUNCTION TO CAUSE AN INTERRUPT JRST TM2SI4 ;GO CAUSE AN INTERRUPT BADSTS: TRNE T2,DS.PIP ;IF PIP IS UP DON'T BOTHER TRYING TLZ T3,-1 ;AGAIN, CLRDRV WILL HANG SOME TMO3'S MOVSI T2,RB.SOL!RB.SER ;SAY THE DRIVE IS DOWN JUMPGE T3,ILLORM ;IF THIS IS SECOND TIME MOVSI T2,(DO.TC) ;FIRST TIME-CLEAR DRIVE PUSHJ P,RDREGX PUSH P,T2 ;SAVE TAPE CNTRL REG PUSHJ P,CLRDRV ;DRVPOL CHANGES TC REG POP P,T2 ;(AND CLEARS 1ST TIME FLAG IN LH(T3)) HRLI T2,(DO.TC) PUSHJ P,WTREGX ;RESTORE TC REG JRST TM2SI2 ;AND TRY AGAIN SUBTTL INTERRUPT LEVEL PROCESSING ;INTERRUPT CODE ;REGISTER USAGE: ;T1/ IORB ADDRESS ;T2/ TEMP, MASSBUS REGISTER READ/WRITTEN ;T3/ MASSBUS UNIT # OF TM02/3 ;T4/ DO.ER,,DO.DS - LH = 0 IF DS.ERR NOT SET ;P1/ FNCTBL ENTRY (FLAG BITS+IORB FCN,,DF.XXX) ;P2/ CONTROLLER TYPE / IO ADDRESS OF RH11 ;U/ TUB FOR IO ;W/ TKB FOR IO TM2INT: PUSHJ P,SAVE3## ;SAVE SOME ACS PUSHJ P,SETP2 ;SET P2=0 IF RH10, =1 IF RH20, CSR IF RH11 MOVE U,TKBCUN##(W) ;UNIT WE'RE TALKING TO (MAYBE) MOVE U,(U) IFE FTRH11,< XCT TKBCIS##(W) ;CONI TRNE T2,CI.RAE ;REGISTER ACCESS ERROR? JRST TM2IN3 ;YES, GO CLEAR IT AND RETRY >;FTRH11 IFN FTRH11,< LDB T3,[POINT 3,TUBAKA##(U),14];GET TM02 NUMBER WRIO T3,<(DO.CS2)>(P2);SELECT TM02 RDIO T2,<(DO.CS2)>(P2);GET STATUS TRNE T2,D2.NXD ;TMO3 THERE? JRST [SETZ T1, ;NO, TELL TAPSER NOTHING TO DO POPJ P,] ;RETURN >;FTRH11 MOVSI T2,(DO.TC) ;WE WILL LATER ZAP THE TC PUSHJ P,RDREG MOVEM T2,E..TC(U) ; SO READ AND SAVE IT NOW MOVSI T2,(DO.DS) ;READ STATUS REGISTER NOW, TALKING PUSHJ P,RDREG ; TO TC REG LATER MAY CHANGE IT PUSH P,T2 ;SAVE STATUS REG MOVSI T2,(DO.AS) ;READ THE ATTN SUMMARY REGISTER PUSHJ P,RDREG ANDI T2,377 ;JUST THE ATTENTION BITS IFE FTRH11,< TDNN T2,TKBUNI##(W) ;ATTEN FOR THIS KDB? JRST TM2IN2 ;NO HRRZ T2,TKBUNI##(W) ;YES. GET THE CORRECT BIT >;FTRH11 HRLI T2,(DO.AS) ;CLEAR THE BIT PUSHJ P,WTREGX IFN FTRH11,< HRRZ T1,T2 ;COPY ATTENTIONS WE HAVE SETZ T3, ;START WITH TM02 # 0 TRHIN1: LSHC T1,-1 ;GET NEXT UNPROCESSED ATTENTION JUMPGE T2,NXTU45 ;DON'T TOUCH IF ATTENTION NOT UP MOVE T4,T3 ;SAVE UNIT NUMBER LSH T4,3 ;PUT IN EXPECTED PLACE >;FTRH11 PUSHJ P,DRVPL1 ;POLL THE DRIVES FOR REW DONE IFN FTRH11,< NXTU45: JUMPE T1,TM2IN2 ;EXIT IF ALL ATTNS DONE AOJA T3,TRHIN1 ;THERE IS ANOTHER ATTN, TRY NEXT UNIT >;FTRH11 ;HERE AFTER THE ATTENTION (IF ANY) IS HANDLED TM2IN2: LDB T2,[POINT 3,TUBAKA##(U),17] ;SLAVE NUMBER HRLI T2,(DO.TC) ;SET TO RECONNECT TO DRIVE, DRVPOL MIGHT HAVE PUSHJ P,WTREG ; SET TO TALK TO ANOTHER SLAVE POP P,T4 ;STATUS REGISTER TM2IN3: SKIPL T1,TKBSCH(W) ;SCHEDULE CYCLE? SKIPN T1,TKBFLG(W) ;OR OPERATION IN PROGRESS? JRST [SETZM TKBSCH(W) PJRST CLRCTL] ;RETURN 0 OR -1 TO TAPSER SETZM TKBFLG(W) ;NOW NO OP IS GOING MOVE P1,T1 ;FLAGS IN P1 LDB P3,[POINT 4,P1,17] ;INDEX FOR FUNCTION IN P3 PUSHJ P,CHKIRB## ;GET THE IORB JRST TAPDIS## ;NOTHING THERE - GO AWAY IFE FTRH11,< XCT TKBDIS##(W) ;DATAI HLL T3,T2 ;SAVE (DBTO,CBTO) XCT TKBCIS##(W) ;CONI TLNN T3,CBTO ;IF NOT CNTRL BUS TIMEOUT TRZ T2,CI.DRE ; IGNORE DRIVE RESPONSE ERR JUMPE P2,TM2IN4 ;EASY WIN IF RH10 MOVE T3,TKBICP##(W) ;RH20, GET LOGOUT AREA HLL T2,1(T3) ;GET ERROR BITS FROM ICWA+1 TLNN P1,(TB.DAT) ;IF NOT A DATA OPERATION TLZA T2,-1 ; IGNORE ERROR BITS, THEY'RE USELESS TLC T2,(CS.NAE) ;MAKE BIT=1 IF AN ERROR TM2IN4: TDNE T2,[CI1ERR ;ERROR? CS.ERR!CI.ERR](P2) JRST CHNERR ;TOO BAD! >;FTRH11 IFN FTRH11,< MOVEI T2,DC.CPE ;CHANNEL-TYPE ERRORS MOVEI T3,D2%CHE ;... TION T2,<(DO.CS1)>(P2) TIOE T3,<(DO.CS2)>(P2) JRST CHNERR ;JUMP IF SO >;FTRH11 CAIN P3,RB.FYB ;YELLOW BALL/ILLEGAL FNCTN? JRST INTNOP ;YES, GO HANDLE IT TRNN T4,DS.ERR ;ERROR? JRST TSTERR ;NO MOVSI T2,(DO.ER) ;YES, READ ERROR REG PUSHJ P,RDREG ;(ONLY CALL RDREG ON "REAL" ERROR) HRL T4,T2 ;T4=ERROR,,STATUS JRST TSTBOT TSTERR: SKIPE TUBERR##(U) ;IN ERROR RETRY? PUSHJ P,RDREGS ;YES, GET FINAL (GOOD) REGISTERS TSTBOT: MOVSI T2,TUSBOT## ;CLEAR BOT ANDCAM T2,TUBSTS##(U) TRNE T4,DS.BOT ;AND SET IT IF WE REALLY ARE IORM T2,TUBSTS##(U) ; AT BOT MOVSI T2,TUSWTL## ;CLEAR WRITE-LOCK ANDCAM T2,TUBSTS##(U) TRNE T4,DS.WRL ;AND SET IT AGAN IF WE REALLY ARE IORM T2,TUBSTS##(U) ; WRITE LOCKED TRNN T4,DS.BOT ;AT BOT? JRST TSTMOV ;NO TLO T1,RB.SBT ;YES, TELL TAPUUO PUSHJ P,UNIBOT## ;CLEAR TUBREC,FIL; SET TUBSTS JUMPGE P1,TSTMOV ;IF WE MOVED BACKWARDS INTO BOT, TLNN P1,(TB.DAT) ;DATA OPERATION? TLZ T4,ER.COR!ER.FCE ;CAN'T BE ERROR AT BOT TLZE T4,ER.OPI!ER.NEF; THESE REALLY AREN'T ERRORS JRST NOMOVE ;IF ON WE DIDN'T MOVE TAPE TSTMOV: TLNN T4,ER.ILF!ER.RMR!ER.NEF!ER.UNS JRST MOVED ;TAPE REALLY MOVED TLOA T1,RB.SNM!RB.SED;TAPE DIDN'T MOVE NOMOVE: TLO T1,RB.SNM JRST TM2GO ;CONTINUE MOVED: TLNE P1,(TB.REV) ;REVERSE? SOSA TUBREC##(U) ;DECR OR INCR RECORD COUNT AOS TUBREC##(U) TRNN T4,DS.TM ;PASS OVER (OR JUST WROTE) EOF? JRST NOTM ;NO TLNE P1,(TB.REV) ;YES, INCR OR DECR FILE COUNT SOSA TUBFIL##(U) AOS TUBFIL##(U) SETZM TUBREC##(U) ;AT 0TH RECORD ********* -1 IF REV? TLNN P1,(TB.WRT) ;IF NOT WRITING AN EOF, TLO T1,RB.STM ; TELL TAPUUO WHAT WE SAW NOTM: TLNE P1,(TB.WRT) ;IF WRITING, TRNN T4,DS.EOT ;AND WE SAW EOT CAIA TLO T1,RB.SET ;TELL TAPUUO TM2GO: JRST @INTABL(P3) ;GO TO SPECIFIC INTERRUPT HANDLER INTABL: TAPIFI## INTRD ;(1)READ FORWARD INTWRT ;(2)WRITE INTRD ;(3)READ BACKWARDS INTSPC ;(4)SKIP RECORD INTSPC ;(5)BACKSPACE RECORD TAPIFI## ;(6)SKIP FILE TAPIFI## ;(7)BACKSPACE FILE INTERA ;(10)ERASE GAP TAPIFI## ;(11)DATA SECURITY ERASE INTREW ;(12)REWIND INTUNL ;(13)UNLOAD INTWTM ;(14)WRITE TAPE MARK INTNOP ;(15)YELLOW BALL/ILLEGAL FUNCTIONS INTRD ;(16)CORRECTION READ INTRD ;(17)LOW-THRESHOLD READ ;HERE ON READ INTERRUPT INTRD: MOVEI T2,RB.D16 ;ASSUME DRIVE IN PE MODE TRNN T4,DS.PES ;ARE WE? MOVEI T2,RB.D8 ;NO, ASSUME 800 NRZI LDB T3,PRBDEN ;GET WHAT DDB (IORB) SAYS CAIE T2,RB.D16 ;IF DRIVE SAYS PE, MAKE MONITOR AGREE CAIN T3,RB.D16 ;NOT PE; IF MONITOR THINKS PE, CHANGE TO 800 DPB T2,PRBDEN ;UPDATE IORB (AND EVENTUALLY DDB) MOVSI T2,(DO.FC) ;READ THE FRAME COUNTER PUSHJ P,RDREG MOVEM T2,TRBRCT(T1) ;SAVE CHAR-COUNT OF RECORD MOVEM T2,TUBCCR##(U) ADDM T2,TUBCRD##(U) ;UPDATE TOTAL STATS ADDM T2,.CPTFI## CAMLE T2,TKBCHR(W) ;TOO LARGE A RECORD? TLO T1,RB.STL!RB.SER ;YES, TELL TAPUUO LDB T3,PRBMOD## ;MODE IDIV T2,TMODTB##(T3);COMPUTE NUMBER OF WORDS XFERRED HRLM T2,TUBCHR##(U) ;SAVE WORDS DPB T3,PMTNCR## ;SAVE RESIDUE IFE FTRH11,< ;THE KS UBA DOES THIS CAIE P3,RB.FRB ;IF READ BACKWARDS JRST DONE ;NO SKIPE T3 ;IF NOT EVEN NO OF WORDS ADDI T2,1 ;BUMP WRDCNT JUMPE T2,DONE ;NULL RECORD HRRZ P1,TTXUVA(W) ;GET USER VIRTUAL ADDRESS MOVE F,TUBCUR##(U) ;MAKE JOB ADDRESSABLE PUSHJ P,SVEUF## PUSH P,T1 LDB T3,PRBMOD## ;SINCE THE TM02 READS BACKWARDS MOVE T2,TKBCHR(W) ; IN REVERSE ORDER, HALVES SWAPPED IDIV T2,TMODTB##(T3) ; WE HAVE TO REARRANGE THE DATA AOS P3,P1 ;FIRST WORD ADDI P3,-1(T2) ;LAST WORD LSH T2,-1 INTRD1: EXCTUX ;GET 2 WORDS EXCTUX EXCTXU ;SWAP HALVES AND INVERT ORDER EXCTXU ADDI P1,1 SUBI P3,1 SOJG T2,INTRD1 ;DO FOR WHOLE BLOCK POP P,T1 CAMN P1,P3 ;IF AN ODD NUMBER OF WORDS, EXCTUU ; SWAP HALVES OF MIDDLE WORD OF BLOCK >;FTRH11 ; JRST DONE ;OPERATION COMPLETE ;HERE AFTER AN OPERATION IS THROUGH DONE: TLNE T4,-1 ;ERROR BIT UP? PUSHJ P,TM2ERR ;YES, GO HANDLE IT TRBSTO: HLLZ T2,T1 ;BITS WE WANT TO TELL TAPUUO ABOUT IORM T2,TRBSTS(T1) ;STORE IN THE IORB TRBEXC: MOVSI T2,RB.EXC TLZE T1,-1 ;ANY FUNNY THINGS? IORM T2,TRBLNK(T1) ;YES, AN EXCEPTION HAS OCCURRED IFE FTRH11,< CLRCTL: MOVE T3,[CO1CLR CO.CLR+CO.MBE](P2) XCT TT2CO3##(W) CLRCTX: MOVEI T3,TAPCHN##+CO.AIE+CO.MBE ;ENABLE FOR INTERRUPTS XCT TT2CO3##(W) SETZM TKBFLG(W) ;NOTHING HAPPENING NOW POPJ P, ;AND RETURN >;FTRH11 IFN FTRH11,< CLRCTL: MOVEI T2,D2.CLR ;CLEAR ALL ERRORS WRIO T2,<(DO.CS2)>(P2); CLRCTX: MOVEI T3,DC.IE ;ENABLE FOR INTERRUPTS WRIO T3,<(DO.CS1)>(P2) SETZM TKBFLG(W) ;NOTHING HAPPENING NOW POPJ P, ;AND RETURN >;FTRH11 ;HERE ON WRITE INTERPT INTWRT: MOVE T2,TKBCHR(W) ;NO OF FRAMES WE WROTE ADDM T2,TUBCWR##(U) ;UPDATE STATS ADDM T2,.CPTFO## JRST DONE ;AND FINISH UP INTSPC: JRST DONE INTWTM: JRST DONE INTERA: SOS TUBREC##(U) ;IT ISN'T ANOTHER RECORD JRST DONE INTUNL: MOVSI T2,TKSOFL## ;LET REST OF WORLD KNOW IORM T2,TUBSTS##(U) ; THAT THE DRIVE IS OFF-LINE TLO T1,RB.SOL ;SAY DRIVE IS OFF-LINE INTREW: MOVSI T2,TUSREW## ;SAY WE'RE REWINDING IORM T2,TUBSTS##(U) TRNN T4,DS.PIP ;ARE WE? PUSHJ P,REWDON## ;NO, MUST HAVE FINISH SETZM TUBREC##(U) ;CLEAR STATS SETZM TUBFIL##(U) JRST DONE ;AND FINISH UP INTNOP: MOVSI T2,(DO.DS) ;DON'T CLEAR IF REWINDING PUSHJ P,RDREG ;THAT WILL HANG SOME TM03'S TRNN T2,DS.PIP PUSHJ P,CLRDRV ;CLEAR THE DRIVE HLL T1,TRBSTS(T1) ;GET ERROR BITS MOVSI T2,TKSOFL## ;DRVPOL MAY HAVE CLEARED TKSOFL TLNE T1,RB.SOL ;IS TKSOFL SUPPOSED TO BE ON? IORM T2,TUBSTS##(U) ;YES, MAKE SURE IT IS JRST TRBEXC ;SET EXCEPTION IF AN ERROR SUBTTL RH10/20/11 ERROR ANALYSIS ;HERE ON CONI ERROR BIT OR CHANNEL ERROR CHNERR: IFE FTRH11,< TDNN T2,[CI1SDR,, CI.RAE](P2) JRST NORAE ;NO JUMPE P2,CHNER1 TLO T1,RB.SNM!RB.SED ;YES, NO TAPE MOTION+ERROR JRST TRBSTO CHNER1: HRRZ T2,TKBUNI##(W) ;YES. GET BIT TO CLEAR HRLI T2,(DO1CRA) ;CLEAR REG ACCESS ERROR PUSHJ P,WTREG JRST CHNRTY ;AND RETRY THE OPERATION NORAE: TDNN T2,[CI1CDP!CI1CWP!CI1NXM,, CS.MPE!CS.NXM](P2) JRST CHNRTY ;NO, JUST RETRY PUSHJ P,SAVE1## ;YES PUSH P,T1 ;SAVE T1 PUSH P,T4 ;SAVE T4 MOVEI T3,CHNNXM## ;SET TO CALL RIGHT ROUTINE MOVSI T4,IOCHNX ;ASSUMING NXM TDNN T2,[CI1NXM,, CS.NXM](P2) PUSHJ P,[MOVEI T3,CHNMPE## ;NO--SET FOR MEMORY PARITY MOVSI T4,IOCHMP ; ... POPJ P,] HRRZ T1,TKBICP##(W) ;T1=ICWA HRRZ P1,TKBCDB##(W) ;P1=CDB HRRZ F,TUBCUR##(U) ;F=DDB IORM T4,CHNNUM##(P1) ;MARK MEMORY ERROR FOR LATER SWEEP SKIPN TUBERR##(U) ;CALL ERRCON ON FIRST ERROR ONLY PUSHJ P,(T3) ;GO CALL ERRCON POP P,T4 POP P,T1 CHNRTY:>;FTRH11 IFN FTRH11,< HRRZ T3,TKBCDB##(W) ;GET CHANNEL DATA BLOCK MOVEI T2,UNBTMO!UNBBME BSIO T2,@CHNUBA##(T3) ;CLEAR POSSIBLE UBA ERRORS >;FTRH11 TLO T1,RB.SED ;INDICATE AN ERROR PJRST TRBSTO ;FINISH UP SUBTTL TM02/TM03 ERROR ANALYSIS ;HERE ON ERROR BIT IN TM02 TM2ERR: TLNN T4,ER.UNS!ER.FMT!ER.ILR!ER.ILF!ER.OPI!ER.NEF JRST TM2ER1 ;NOT AN IMMEDIATE PROBLEM TLNE T4,ER.FMT ;FORMAT ERROR? TLNN T4,ER.COR!ER.CS!ER.FCE!ER.NSG!ER.LRC!ER.INC CAIA ;REAL NON-RECOVERABLE ERR JRST TM2ER1 ;FAKE FORMAT ERROR TLNE T4,ER.UNS ;REALLY BAD PROBLEM TLO T1,RB.SOL ;OFFLINE IF UNSAFE IS UP TLO T1,RB.SED!RB.SER;NON-RECOVERABLE ERROR PJRST CLRDRV ;DRIVE-CLEAR AND RETURN TM2ER1: TLNE P1,(TB.WRT) ;IF READING, JRST TM2ER2 TLZ T4,ER.NSG!ER.FCE ;THESE AREN'T ERRORS TRNE T4,DS.PES ;IF IN PE MODE TLZ T4,ER.COR!ER.CS!ER.LRC ;THESE AREN'T ERRORS TM2ER2: TLNN T4,ER.COR!ER.CS!ER.FCE!ER.NSG!ER.LRC!ER.DPA!ER.INC!ER.DTE!ER.CPA PJRST CLRDRV ;NOT A "REAL" ERROR, CLEAR DRIVE AND RETURN TLNN T4,ER.COR!ER.CS!ER.INC!ER.LRC ;REAL ERROR TLOA T1,RB.SED ;PLAIN ERROR TLO T1,RB.SDE!RB.SED ;DATA ERROR PUSHJ P,RDREGS ;READ DRIVE REGS INTO UDB ;FALL INTO CLRDRV AND RETURN SUBTTL DRIVE CLEAR LOGIC ;DUE TO THE PROBLEM OF DRIVE CLEAR MAKING DS.SSC GO AWAY ; IF SOME OTHER SLAVE BROUGHT IT UP, WE HAVE TO POLL THE DRIVES ; AFTER A DRIVE CLEAR TO FIND ANY THAT MAY HAVE FINISHED REWINDING CLRDRV: MOVEI T2,DF.CLR ;CLEAR THE DRIVE PUSHJ P,WTREG DRVPOL: PUSH P,T4 ;SAVE T4 PUSHJ P,DRVPLX PJRST T4POPJ## ;RESTORE T4 AND RETURN DRVPLX: IFN FTRH11,< HLRZ T4,TUBAKA##(U) ;TU45 # + SLAVE NUMBER ANDI T4,70 ;TU45 NUMBER >;FTRH11 DRVPL1: IFN FTRH11,< MOVE T2,T4 ADD T4,TKBIUN##(W) ;POSITION TO RIGHT PART OF KDB LSH T2,^D21 ;SHIFT TU45 # ADD T2,T4 ;FORM LH OF AOBJN WORD JUMPGE T2,CPOPJ## ;WE DON'T KNOW ABOUT THIS TU45 IF NOT NEG. HRLI T4,P1 ;SET INDEX FOR RIGHT SLAVE NUMBER >;FTRH11 PUSHJ P,SAVE4## ;SAVE SOME ACS SETZ P4, ;SET A FLAG PUSH P,U ;SAVE U IFE FTRH11,< HRRZ T4,TKBIUN##(W) ;POINT TO RIGHT PART OF KDB TLO T4,P1 ;SET INDEX FOR RIGHT SLAVE NUMBER >;FTRH11 DRVPL5: MOVSI T2,(DO.DS) ;READ STATUS REG PUSHJ P,RDREGX TRNN T2,DS.SSC ;SLAVE STATUS CHANGE? JRST DRVPL2 ;NO IFN 1,< ;YES, WE HAVE TO FIND A DRIVE WE CAN CLEAR. ;OUR CHOICE OF WHAT DRIVE TO CLEAR DEPENDS ON ;WHAT TYPE OF DRIVES WE'VE GOT. ;FOR MOST TYPES WE CAN GET AWAY WITH CLEARING ANY DRIVE ;(EVEN A NON-EXISTENT ONE). ;BUT FOR CERTAIN TYPES WE MUST ISOLATE THE EXACT DRIVE THAT RAISED SSC. ;IN ORDER TO FIGURE OUT WHAT TYPE OF DRIVE WE'VE GOT, WE MUST ;FIRST LOCATE A DRIVE THAT ACTUALLY EXISTS. THE DRIVE WHICH ;IS CURRENTLY SELECTED IN TC MAY NO LONGER EXIST (AS THE OPR ;MAY HAVE PLAYED WITH THE THUMB WHEEL). SETZ P1, ;START WITH DRIVE 0 DRVPL7: MOVE T2,P1 ;SELECT THE DRIVE HRLI T2,(DO.TC) PUSHJ P,WTREGX MOVSI T2,(DO.DT) ;GET THE DRIVE TYPE PUSHJ P,RDREGX TRNE T2,7 ;DOES THE DRIVE EXIST? JRST DRVPL8 ;YES CAIE P1,7 ;NO, KEEP LOOKING AOJA P1,DRVPL7 DRVPL8: ANDI T2,75 ;GET RID OF NOISE BITS CAIE T2,11 ;TM02/TE16? CAIN T2,51 ;TM03/TE16? TDZA P3,P3 ;YES, CLEAR ALL DRIVES MOVEI P3,-54(T2) ;IF A TU77 IT MUST BE THE DRIVE WHICH RAISED SSC JUMPE P3,DRVPL0 ;GO IF ONE OF THE SPECIAL TYPES ;HERE IF NOT ONE OF THE SPECIAL TYPES. ;WE MUST NOW FIND A NON-EXISTANT DRIVE AND CLEAR IT. MOVEI P1,7 ;START WITH DRIVE 7 DRVPL6: MOVE T2,P1 ;SELECT THE DRIVE HRLI T2,(DO.TC) PUSHJ P,WTREGX MOVSI T2,(DO.DT) ;GET THE DRIVE TYPE PUSHJ P,RDREGX TRNE T2,7 ;DOES THE DRIVE EXIST? SOJGE P1,DRVPL6 ;YES, KEEP LOOKING TLOE P1,-1 ;DID WE FIND ONE? > DRVPL0: MOVSI P1,-10 ;NO, CLEAR EVERYTHING NOT REWINDING FNDCLR: SKIPE T2,TKBFLG(W) ;IF WE'RE ACTIVELY TALKING TO A DRIVE HRRZ T2,TKBCUN##(W) ;DONT CLEAR THAT DRIVE CAIN T2,@T4 JUMPE P4,FNDCL1 ;SO TRY ANOTHER MOVE T2,P1 ;WE CAN DO A DRIVE CLEAR ON THIS ONE HRLI T2,(DO.TC) ;TALK TO THIS DRIVE PUSHJ P,WTREGX MOVSI T2,(DO.DS) PUSHJ P,RDREGX ;READ SLAVE'S STATUS REGISTER TRNE T2,DS.PIP ;IS DRIVE REWINDING? JUMPE P4,FNDCL1 ;YES (TU77). DON'T CLEAR AS THAT WILL HANG TM03 MOVEI T2,DF.CLR ;DO A DRIVE CLEAR PUSHJ P,WTREGX FNDCL1: AOBJN P1,FNDCLR ;CLEAR NEXT DRIVE CAIGE P4,3 ;TRIED ENOUGH TIMES? AOJA P4,DRVPL5 ;NO, KEEP TRYING IFE FTRH11,< PUSH P,T3 ;YES, SAVE TM03 NUMBER MOVEI T3,CO.MBI ;THE TM03 MUST BE HUNG XCT TT2CO3##(W) ;MASSBUS INIT IS THE ONLY WAY JUMPE P2,DRVPL9 ;EASY IF RH10 MOVEI T3,CO.MBE ;ENABLE MASSBUS TRANSMITTERS XCT TT2CO3##(W) ;BUT DON'T ENABLE INTERRUPTS TILL LATER PUSHJ P,SETIV ;RESTORE INTERRUPT VECTOR DRVPL9: POP P,T3 ;RESTORE TM03 NUMBER >;FTRH11 IFN FTRH11,< MOVEI T2,D2.CLR ;THE TM03 MUST BE HUNG WRIO T2,<(DO.CS2)>(P2);MASSBUS INIT IS THE ONLY WAY >;FTRH11 DRVPL2: MOVSI P1,-10 ;SET TO LOOK AT ALL DRIVES DRVPL3: SKIPN U,@T4 ;POINT U AT UDB JRST DRVPL4 ;NONE, LOOK AT NEXT MOVSI T2,(DO.TC) ;SET TO TALK TO THIS DRIVE HRR T2,P1 PUSHJ P,WTREGX ;CONNECT TO IT MOVSI T2,(DO.DS) PUSHJ P,RDREGX ;READ STAUS REGISTER MOVSI P3,TKSOFL## TDNE P3,TUBSTS##(U) ;IF DRIVE WAS OFF-LINE TRNN T2,DS.MOL ; AND IS NOW ON-LINE CAIA PUSHJ P,NOWON ;LET THE WORLD KNOW TRNE T2,DS.MOL ;OFF LINE? ANDCAB P3,TUBSTS##(U) ;NO TRNN T2,DS.MOL IORB P3,TUBSTS##(U) ;YES TLNE P3,TUSREW## ;WAS IT LAST REWINDING? TRNE T2,DS.PIP ;YES, IS IT NOW JRST DRVPL4 ;YES, CONTINUE WITH NEXT DRIVE PUSHJ P,REWDON## ;THROUGH REWINDING, TELL TAPUUO DRVPL4: AOBJN P1,DRVPL3 ;GO TEST NEXT DRIVE JRST UPOPJ## ;DONE, RETURN ;SUBROUTINE TO TELL TAPUUO WHEN A SLAVE COMES ON-LINE ;PRESERVES ALL ACS NOWON: PUSHJ P,SAVT## ;SAVE T1-T4 PJRST TPMONL## ;AND TELL TAPUUO SUBTTL SYSINI INITIALIZATION ;HERE TO INITIALIZE THE TM02 TM2INI: MOVEI T1,TUCIRD## ;TELL TAPUUO WE GET AN INTERRUPT MOVE T2,TKBCUN##(W) ; WHEN A REWIND FINISHES TM2INL: SKIPE T3,(T2) ;NEXT DRIVE IORM T1,TUBSTS##(T3);SET BIT IN IT AOBJN T2,TM2INL PUSHJ P,SAVST2 ;SAVE ACS, SET UP P2 IFN FTRH11,< MOVE T1,P2 ;GET IO ADDRESS OF RH11 PUSHJ P,UBGOOD## ;IS RH11 ALIVE ON THE UNIBUS? SKIPA ;NO--SKIP NEXT INSTRUCTION JRST TRHIN0 ;YES--CONTINUE MOVSI T1,TKSSIL##!TKSOFL## ;SILENCE MESSAGE AND OFF-LINE IORM T1,TKBSTS##(W) ;SET THEM POPJ P, ;RETURN TRHIN0: PUSH P,F ;SAVE F FOR SYSINI HRRZ T2,TRHVEC##(W) ;-11 STYLE INTERRUPT VECTOR ADDRESS LSH T2,-2 ;DIVIDE BY 4 HLRZ T3,P2 ;UBA NUMBER ADD T2,.EPVIT##-1(T3) ;ADD INT VECTOR TABLE BASE ADDRESS MOVE T3,TRHIVI##(W) ;GET INT VECTOR INSTRUCTION MOVEM T3,(T2) ;PUT INTO VECTOR TABLE MOVE T1,DEVNAM(F) ;GET NAME AS SET UP BY COMDEV >;FTRH11 MOVE T4,TKBIUN##(W) ;SET TO LOOP OVER ALL UNITS TM2INN: SKIPN U,(T4) ;GET A UNIT JRST TM2INX ;NOT THERE IFN FTRH11,< HRRZ T2,TUBADR##(U) ;GET UDB DPB T2,PUNIT## ;STORE RIGHT UNIT LSHC T2,-3 ;SET RIGHT NAME IN DDB LSH T2,^D15 LSHC T2,3 ;HAVE TO FIDDLE CAUSE MORE THAN 1 TU45 DOES ADD T2,T1 ; VERY FUNNY THINGS TO THE NAMES MOVEM T2,DEVNAM(F) ;EG MTA21 HLRZ F,DEVSER(F) ;ADVANCE TO THE NEXT DDB >;FTRH11 HRRZ T2,TUBADR##(U) ;GET UDB HRLI T2,(DO.TC) ;SELECT RIGHT SLAVE PUSHJ P,WTREG MOVSI T2,(DO.SN) ;READ SERIAL NUMBER PUSHJ P,RDREG ;AND STORE IN UDB MOVEM T2,E..SN(U) ;FOR DIAGNOSTICS MOVSI T2,(DO.DS) ;READ STATUS REG PUSHJ P,RDREG MOVSI T3,TKSOFL## TRNN T2,DS.MOL ;IF NOT MEDIUM-ON-LINE IORM T3,TUBSTS##(U) ; THE DRIVE IS OFF-LINE TM2INX: AOBJN T4,TM2INN IFE FTRH11,< TM2INC: MOVEI T3,CO.MBI ;CLEAR ANY PENDING INTERRUPTS XCT TT2CO3##(W) MOVEI T3,CO.MBE ;MASSBUS ENABLE XCT TT2CO3##(W) PUSHJ P,TM2ONL ;IF NOT THERE POPJ P, ; DON'T SET UP CONSO MASK PUSHJ P,SETIV ;SET UP INTERRUPT VECTOR >;FTRH11 IFN FTRH11,< POP P,F ;RESTORE F >;FTRH11 JRST CLRCTL ;CLEAR RH10 AND RETURN SUBTTL KONTROLLER ON-LINE & AUTO-CONFIG ;HERE ON KONTROLLER ONLINE. SKIP THE CODE TO RESET THE DDB NAMES. IFE FTRH11,< TM2INR: PUSHJ P,SAVST2 ;SAVE P1,P2, SETUP P2 JRST TM2INC ;JOIN COMMOD CODE >;FTRH11 IFN FTRH11, IFN FTAUTC,< ;HERE TO DETERMINE WHAT SLAVES ARE PRESENT ;ENTER P3= LAST SLAVE WE'VE SEEN, LH(P2) = RH UNIT NUMBER ;EXIT P3 = NEXT SLAVE, OR 0 IF NO MORE TM2CFG: AOS T2,P3 TRZE P3,10 ;OVER THE TOP? SOJA P3,CPOPJ## ;YES, RETURN WITH P3=-1 HLRZ T3,P2 HRLI T2,(DO.TC) ;SET TO TALK TO THIS DRIVE PUSHJ P,WTREGX MOVSI T2,(DO.DT) ;READ DRIVE TYPE PUSHJ P,RDREGX TRNE T2,DT.SPR ;SLAVE PRESENT? TDZA T3,T3 ;YES, RETURN WITH T3=0 (NO TUBCNF CHANGES) JRST TM2CFG ;NO, TRY NEXT SLAVE POPJ P, ;AND RETURN P3= NEXT DRIVE NUMBER > SUBTTL CHECK ON-LINE STATUS ;HERE TO CHECK IF ON-LINE TM2ONL: IFE FTRH11,< MOVE T2,TKBSTS##(W) HRRZ T1,TKBCDB##(W) ;POINTER TO CHANNEL SKIPGE (T1) ;DON'T DO CONO'S IF CHAN IS IN USE (USER MODE DIAG) TLNE T2,TKSSEL##!TKSSTD##!TKSSCH## JRST CPOPJ1## ;SKIP THE TEST IF THE CONTROLLER IS GOING XCT TKBCIS##(W) MOVE T1,T2 ;REMEMBER ATTEN ENABLE >;FTRH11 PUSHJ P,SAVST2 ;SETUP P2 (IF KL, DOES CONO) IFN FTRH11,< MOVE T1,P2 ;GET IO ADDRESS OF RH11 PUSHJ P,UBGOOD## ;BE SURE IT IS THERE POPJ P, ;OFF-LINE RDIO T2,<(DO.DS)>(T1);CAUSE A REGISTER ACCES RDIO T2,<(DO.CS2)>(T1);GET STATUS REGISTER TRNN T2,D2.NXD ;IS TM03 THERE? JRST TM2RL1 ;YES, CHECK DRIVE TYPE MOVEI T2,D2.CLR ;NO--DO CONTROLLER CLEAR WRIO T2,<(DO.CS2)>(T1); IN CASE IT COMES BACK TO CLEAR NXD POPJ P, ;OFF-LINE RETURN TM2RL1: ;(****KROQUE UNTIL RDREG FOR THE KS GETS ITS UNIT FROM TKBUNI...****) RDIO T2,<(DO.DT)>(P2);READ THE DRIVE TYPE OF THE SELECTED SLAVE ;(****) >;FTRH11 IFE FTRH11,<;****MORE...**** MOVSI T2,(DO.DT) PUSHJ P,RDREG ;READ DRIVE-TYPE >;FTRH11 (****END****) ANDI T2,730 CAIN T2,10 ;LEGAL? AOS (P) ;YES. SKIP-RETURN IFE FTRH11,< MOVEI T3,CO.AIE+TAPCHN## ;PIA AND ATTN ENABLE SKIPE P2 TRO T3,CO.MBE+CO.RAE TRNN T1,CO.AIE ;WERE ATTENS ENABLED? TRZ T3,CO.AIE ;NO, DON'T ENABLE THEM NOW XCT TT2CO3##(W) >;FTRH11 POPJ P, SUBTTL SCHEDULE, RESET, & INTERRUPT VECTOR ;HERE TO CAUSE A SCHEDULE CYCLE TM2SCH: PUSHJ P,SAVST2 ;SAVE ACS, SET UP P2 SETOM TKBSCH(W) ;SET FLAG IFE FTRH11,< JRST TM2RS1 ;CAUSE AN INTERRUPT >;FTRH11 IFN FTRH11,< SETZM TKBFLG(W) ;NOTHING HAPPENING NOW MOVEI T3,DC.RDY+DC.IE ;CAUSE AN INTERRUPT WRIOB T3,<(DO.CS1)>(P2) POPJ P, ;RETURN >;FTRH11 ;HERE TO RESET AN ACTIVE DRIVE TM2RES: PUSHJ P,SAVST2 ;SAVE ACS, SET UP P2 IFE FTRH11,< MOVSI T2,(DO.TC) ;READ TC REGISTER PUSHJ P,RDREG MOVEM T2,E..TC(U) PUSHJ P,RDREGS ;READ OTHER REGS >;FTRH11 PUSHJ P,CLRDRV IFE FTRH11,< TM2RS1: PUSHJ P,SETIV ;SET UP INTERRUPT VECTOR MOVEI T3,CO.STP ;CLEAR BUSY, SET DONE XCT TT2CO3##(W) ;DO IT >;FTRH11 JRST CLRCTX ;CLEAR RH10 AND RETURN IFE FTRH11,< ;ROUTINE TO SET UP INTERRUPT VECTOR ;PRESERVES ALL ACS EXCEPT T2 SETIV: MOVE T2,TKBIVI##(W) ;WHERE TO INTERRUPT TO XCT TKBDOS##(W) ;TELL THE HARDWARE PUSH P,T1 MOVEI T1,TKBVIN##(W) ;SET UP VECTORED INTERRUPT ADDRESS HRLI T1,(XPCW) MOVE T2,TKBICP##(W) MOVEM T1,3(T2) ;IN ICWA+3 JRST TPOPJ## >;FTRH11 SUBTTL MASSBUS REGISTER READ/WRITE ;READ A REGISTER - ENTER, EXIT WITH FNCN IN T2 ;RESPECTS T1,T4 IFE FTRH11,< RDREG: HLRZ T3,TKBUNI##(W) ;TM02 NUMBER RDREGX: TLO T2,(T3) SKIPE P2 ;IF AN RH20, TLO T2,(DO.DRE) ; DISABLE REGISTER ACCESS ERR INTERRUPT XCT TKBDOS##(W) ;SAY WHAT WE WANT TO READ STALL XCT TKBDIS##(W) ;READ IT ANDI T2,177777 ;ONLY 16 BITS POPJ P, ;AND RETURN >;FTRH11 IFN FTRH11,< RDREG: LDB T3,[POINT 3,TUBAKA##(U),14];TM02 NUMBER RDREGX: WRIO T3,<(DO.CS2)>(P2);SELECT THE TM02 "DRIVE" HLRZS T2 ;GET DESIRED REGISTER NUMBER ADD T2,P2 ;COMPUTE UNIBUS ADDRESS OF DESIRED REGISTER RDIO T2,0(T2) ;READ THAT REGISTER POPJ P, ;DONE >;FTRH11 ;ROUTINE TO WRITE A REGISTER ;ENTER T2=WHAT TO DO THE DATAO WITH ;RESPECTS T1, T4 IFE FTRH11,< WTREG: HLRZ T3,TKBUNI##(W) ;TM02 NUMBER WTREGX: TLO T2,<(DO.LDR)>(T3) ;LIGHT LR SKIPE P2 ;IF AN RH20, TLO T2,(DO.DRE) ;NO INTERRUPT ON RAE XCT TKBDOS##(W) ;DATAO POPJ P, ;AND RETURN >;FTRH11 IFN FTRH11,< WTREG: LDB T3,[POINT 3,TUBAKA##(U),14];GET TM02 NUMBER WTREGX: WRIO T3,<(DO.CS2)>(P2);SELECT DRIVE PUSH P,T3 ;SAVE T3 (SOME CALLERS USE LH) HLRZ T3,T2 ;GET REGISTER NUMBER TO WRITE ADD T3,P2 ;COMPUTE UNIBUS ADDRESS WRIO T2,0(T3) ;WRITE THE REGISTER POP P,T3 ;RETURN TM02 NUMBER POPJ P, >;FTRH11 ;PRESERVES T1 SAVST2: POP P,T4 ;SAVE RETURN ADDRESS PUSHJ P,SAVE2## ;SAVE P1,P2 PUSH P,T4 ;RESTORE RETURN ADDR ;SUBROUTINE TO SET UP P2 =0 FOR RH10, =1 FOR RH20, = CSR ADDRESS FOR RH11 ;PRESERVES T1,T4 SETP2: IFE FTRH11,< LDB P2,[POINT 3,TKBDOS##(W),5] ;GET CONTROLLER CODE CAIE P2,5 ;RH20? TDZA P2,P2 ;NO, P2=0 MOVEI P2,1 ;YES, P2=1 JUMPE P2,CPOPJ## ;GO IF AN RH10 MOVEI T3,CO.MBE ;RH20, ENSURE THAT MASSBUS IS ENABLED XCT TT2CO3##(W) >;FTRH11 IFN FTRH11,< MOVE P2,TRHBAS##(W) ;GET RH11 REGISTER ADDRESS >;FTRH11 POPJ P, ;AND RETURN IFE FTRH11,< ;ROUTINE TO READ REGISTERS ON ERROR RDREGS: XCT TKBCIS##(W) MOVEM T2,E..CNI(U) ;SAVE CONI MOVE T2,[DO1CRC .DOPTC](P2) PUSHJ P,RDREG MOVEM T2,E..DTI(U) ;DATAI RH10 CNTRL REG MOVE T2,[DO1CDB .DOPBA](P2) PUSHJ P,RDREGX MOVEM T2,E..DT2(U) ;DATAI RH10 DATA BUFFER PUSH P,T1 MOVEI T1,E..MBR(U) ;(REG+3 = LAST COMMAND) HRLI T1,E..CS1-E..TC ;READ REGISTERS 0- (TC READ AT TM2INT) MOVSI T2,(DO.CS1) ;STARTING HERE RDREG1: PUSHJ P,RDREGX MOVEM T2,(T1) ;STORE DATA IN UDB ADD T2,[1B5] ;STEP TO NEXT REGISTER TLZ T2,^-<(77B5)> ;KEEP ONLY REGISTER NUMBER AOBJN T1,RDREG1 JRST TPOPJ## >;FTRH11 IFN FTRH11,< ;ROUTINE TO READ REGISTERS ON ERROR ; RESPECTS T1-T4 RDREGS: PUSHJ P,SAVT## ;SAVE TEMP REGS RDIO T2,<(DO.CS1)>(P2) ;GET RH11 STATUS RDIO T1,<(DO.CS2)>(P2) HRLI T2,(T1) MOVEM T2,E..CNI(U) ;SAVE "CONI" STATUS MOVE T4,TKBCDB##(W) ;GET ADDRESS OF CHANNEL DATA BLOCK RDIO T3,@CHNUBA##(T4) ;READ UBA STATUS REGISTER MOVEM T3,E..DTI(U) ;SAVE HERE IN KDB LSH T2,-10 ;POSITION 2 BIT ADDRESS EXT (IN MTCS1) RDIO T1,<(DO.BA)>(P2) ;GET THE ENDING BUS ADDRESS DPB T2,[POINT 2,T1,19] ; AND PUT IN HIGH ORDER BITS IDIVI T1,UBAMUL ;COMPUTE MAP REGISTER OFFSET ADDI T1,UBAEXP ;ADD IN THE BASE ADDRESS HLL T1,CHNUBA##(T4) ;PUT IN PROPER UBA NUMBER RDIO T2,(T1) ;READ OUT MAP SLOT OF LAST WORD XFER'ED MOVEM T2,E..DT2(U) ;SAVE HERE IN KDB MOVEI T1,E..MBR(U) ;(REG+3 = LAST COMMAND) HRLI T1,E..CS1-E..TC ;READ REGISTERS 0- (TC READ AT TM2INT) MOVE T4,[POINT 6,RH11OF] ;CONVERSION TABLE RDREG1: ILDB T2,T4 ;GET NEXT REGISTER (BY MASSBUS #) ADD T2,P2 ;CONVERT TO IO ADDRESS RDIO T2,(T2) ;READ CONTENTS MOVEM T2,(T1) ;STORE DATA IN UDB AOBJN T1,RDREG1 ;LOOP FOR ALL BUT TC POPJ P, ;RETURN DEFINE X(A), IRP A,,> ZZZ==ZZZ!<('A')>B<5+> ZZ==ZZ+1> EXP ZZZ PURGE ZZ,ZZZ > ;TABLE DEFINING ORDER IN WHICH ERROR REGISTERS ARE STORED IN UDB ;DAEMON/SPEAR KNOW ABOUT THIS, AND ASSUME RH10/20 ORDER IS SAME RH11OF: X >;FTRH11 SUBTTL IO CONTROL TABLES ;TABLES TO CONTROL IO TB.REV==1B0 ;TAPE MOVES BACKWARDS TB.WRT==1B1 ;OPERATION WRITES ON TAPE TB.DAT==1B2 ;DATA TRANSFER OPERATION TB.SPC==1B3 ;SPACING OPERATION TB.RD==1B4 ;OPERATION READS TAPE TB.ERA==1B5 ;OPERATION IS ERASE TB.WTM==1B6 ;OPERATION IS WRITE TAPE MARK TB.NFC==1B7 ;PUT NULL/ZERO IN FRAME COUNTER TB.OFC==1B8 ;PUT -1 IN FRAME COUNTER TB.REW==1B9 ;OPERATION IS REWIND ; TB.FNC==17B17 ;TAPSER FUNCTION CODE FNCTBL: 0 ;0 - ILLEGAL TB.DAT!TB.RD!TB.NFC!DF.RDF!1B17 ;1 - READ FORWARD TB.WRT!TB.DAT!DF.WTF!2B17 ;2 - WRITE TB.DAT!TB.RD!TB.NFC!TB.REV!DF.RDR!3B17 ;3 - READ REVERSE TB.SPC!DF.SPF!4B17 ;4 - SKIP RECORD TB.SPC!TB.REV!DF.SPR!5B17 ;5 - BACKSPACE RECORD 0 ;6 - SKIP FILE (ILLEGAL) 0 ;7 - BACKSPACE FILE (ILLEGAL) TB.WRT!TB.ERA!TB.OFC!DF.ERA!10B17 ;10 - ERASE 0 ;11 - DATA SECURITY ERASE (ILLEGAL) TB.NFC!TB.REW!TB.REV!DF.REW!12B17 ;12 - REWIND TB.NFC!DF.UNL!13B17 ;13 - REW, UNLOAD TB.WRT!TB.WTM!TB.OFC!DF.WTM!14B17 ;14 - WRITE TAPE MARK FNCNOP: TB.SPC!DF.INT!15B17 ;15 - YELLOW BALL TB.DAT!TB.RD!TB.NFC!DF.RDF!16B17 ;16 - CORRECTION READ TB.DAT!TB.RD!TB.NFC!DF.RDF!17B17 ;17 - LOW THRESHOLD READ ;FRAMES/WORD,,MODE MODTBL: -1 ;0 - ILLEGAL 5,,0B31 ;1 - CORE DUMP 4,,3B31 ;2 - BYTE (4 B-BIT BYTES/WRD) -1 ;3 - SIXBIT...ILLEGAL 5,,2B31 ;4 - 7 BIT (ASCII) 6,,1B31 ;5 - 7 TRACK CORE DUMP ;TM02 DENSITY CODE BY TAPSER CODE DENTBL: -1 0B27 ;200 1B27 ;556 2B27 ;800 4B27 ;1600 MAXDEN==.-DENTBL-1 IFN FTRH11, TM2END: END