Trailing-Edge
-
PDP-10 Archives
-
BB-X140B-BB_1986
-
10,7/703mon/t78kon.mac
There are 10 other files named t78kon.mac in the archive. Click here to see a list.
TITLE T78KON - RH20/TM78/TU78 DRIVER FOR TAPSER V062
SUBTTL T WACHS/TW 10 SEP 85
SEARCH F,S,ICHPRM
$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<1980,1986>
;COPYRIGHT (C) 1980,1981,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP, MAYNARD MASS.
;ALL RIGHTS RESERVED.
;
XP VT78KN,062
SALL
ENTRY T78KON
;OFFSETS INTO TKBCCL
TKBSCW==TKBCCL##+1 ;SAVED CHANNEL WORD
TKBFLG==TKBCCL##+2 ;FLAGS FROM FNCTBL
TKBCHR==TKBCCL##+3 ;CHARACTER (FRAME) COUNT
TKBSCH==TKBCCL##+4 ;-1 IF A SCHEDULE CYCLE
T78KON::
T78DSP::IFIW T78INI ;00 - INITIALIZE
IFIW T78RES ;01 - RESET ACTIVE I/O
IFIW T78SIO ;02 - START IO
IFIW T78INT ;03 - INTERRUPT SERVICE
EXP 0 ;04 - SET DEVICE COMMAND
IFIW CPOPJ## ;05 - KONTROLLER IS IDLE
IFIW T78ONL ;06 - TEST IF CTL IS ON-LINE
IFIW T78SCH ;07 - FORCE A SCHEDULE CYCLE
IFIW T78INR ;10 - RE-INITIALIZATION
IFIW CPOPJ## ;11 - LOAD MICROCODE
IFIW CPOPJ## ;12 - ENABLE/DISABLE MICROCODE LOADING
IFN FTAUTC,<IFIW T78CFG> ;13 - AUTO CONFIGURE
SUBTTL PARAMETERS
;DRIVE REGISTERS USED IN DATAO'S
.DOCR==0B5 ;DRIVE CONTROL REGISTER
.DOICD==1B5 ;INTERRUPT CODE (DATA XFER)
DO.ICD==77 ;INTERRUPT CODE
DI.FCD==176000 ;FAILURE CODE
.DOFMT==2B5 ;RECORD COUNT/FORMAT
DO.SER==100000 ;SUPRESS ERROR RETRY
DO.RC1==4 ;RECORD COUNT RIGHTMOST BIT
.DOER==3B5 ;ERROR REGISTER
.DOAS==4B5 ;ATTENTION SUMMARY
.DOBC==5B5 ;BYTE COUNT
.DODT==6B5 ;DRIVE TYPE
.DOSR==7B5 ;STATUS REGISTER
DI.RDY==100000 ;READY
DI.PRS==40000 ;PRESENT
DI.PE==4000 ;PHASE ENCODED
DI.BOT==2000 ;BOT
DI.FPT==400 ;FILE PROTECTED
DI.AVL==200 ;AVAILABLE
DI.MNT==40 ;IN MAINTENANCE MODE
.DOSN==10B5 ;SERIAL NUMBER
.DODG==11B5 ;DIAGNOSTIC
.DODG2==12B5 ;DIAGNOSTIC
ICNREG==13
.DOICN==13B5 ;INTERRUPT CODE (NON DATA-XFER)
DI.DRV==1400 ;DRIVE NUMBER
.DOND0==14B5 ;NON DATA-XFER COMMAND, UNIT 0
DO.NDC==177400 ;COUNT FIELD
DO.NDF==77 ;FUNCTION CODE
NDCSHF==^D8 ;SHIFT VALUE FOR COUNT
.DOND1==15B5 ;COMMAND, UNIT 1
.DOND2==16B5 ;COMMAND, UNIT 2
.DOND3==17B5 ;COMMAND, UNIT 3
.DOIA==20B5 ;INTERNAL ADDRESS
.DOTMS==21B5 ;TM STATUS
DI.TMR==1B20 ;TM READY
DO.TMC==1B21 ;TM CLEAR
DO.HLA==1B26 ;HOLD ACKNOWLEDGED
DO.HLD==1B27 ;HOLD
;DRIVE FUNCTIONS
DF.NOP==3 ;NO-OP
DF.UNL==5 ;UNLOAD
DF.REW==7 ;REWIND
DF.SNS==11 ;SENSE
DF.DSE==13 ;DATA SECURITY ERASE
DF.WTM==15 ;WRITE TAPE MARK (PE)
DF.SPF==21 ;SPACE FORWARD RECORD
DF.SPR==23 ;SPACE REVERSE RECORD
DF.SFF==25 ;SPACE FORWARD FILE
DF.SRF==27 ;SPACE REVERSE FILE
DF.SFE==31 ;SPACE FORWARD RECORD OR FILE
DF.SRE==33 ;SPACE REVERSE RECORD OR FILE
DF.ERG==35 ;ERASE 3 INCHES OF TAPE (PE)
DF.CLF==41 ;CLOSE FILE (PE) - 2 EOFS, BACKSP 1
DF.LET==45 ;SKIP TO LOGICAL EOT
DF.WRT==61 ;WRITE (PE)
DF.RED==71 ;READ
DF.RRV==77 ;READ REVERSE
DF.XSN==73 ;EXTENDED SENSE
;BYTE POINTER TO FAILURE CODE IN EXTENDED SENSE DATA
TUYECD: POINT 8,T78REG##+30(U),35
SUBTTL START IO
;HERE TO START IO
T78SIO: PUSHJ P,CHKIRB## ;GET IORB FOR THIS OP
JRST TAPDIS## ;NONE, GO AWAY
PUSHJ P,SAVE1## ;SAVE P1
LDB T4,PRBFCN## ;FUNCTION
SKIPN T78RRO##(W) ;ARE WE IN RETRY OPPOSITE?
JRST T78SI1 ;NO
CAIN T4,RB.FRB ;YES, TRYING TO DO A REVERSE READ?
MOVEI T4,RB.FRD ;YES, RETRY FORWARD
CAIN T4,RB.FCR ;DOING A CORRECTIVE READ?
MOVEI T4,RB.FRB ;YES, READ BACKWARDS
T78SI1: SKIPN P1,FNCTBL(T4) ;LEGAL?
JRST ILLFNC ;NO
SKIPGE T2,TRBRCT(T1) ;IF POSITIVE IN ERROR RECOVERY
MOVEM T2,T78UVA##(W) ;REAL IOWD - SAVE IT
SKIPGE T78ACT##(W) ;DID WE SHUT OFF TM TO PREVENT EXCESSIVE INTERRUPTS?
PUSHJ P,CLRHLD ;YES, CLEAR HOLD SO WE CAN TALK TO IT AGAIN
SETZM T78ACT##(W) ;CLEAR ASYNC INTERRUPT COUNT
LDB T4,PRBDEN## ;GET DENSITY
CAIGE T4,RB.D16 ;TOO LOW?
MOVEI T4,RB.D16
; CAILE T4,RB.D62 ;TOO HIGH?
; MOVEI T4,RB.D62
DPB T4,PRBDEN## ;TELL THE REST OF THE WORLD
CAIN T4,RB.D62 ;6250?
TLNN P1,(TB.WRT) ;YES, WRITE?
JRST T78SI2 ;NO
TROA P1,WT.GCR ;YES, SET 6250 IN FUNCTION
ILLFNC: MOVE P1,FNCNOP ;ILLEGAL FNCN - JUST GET AN INTERRUPT
JRST T78SI2 ;GO START THE OPERATOIN
SENSE: MOVEM P1,T78SNS##(U) ;TELL INTERRUPT SERVICE WE ARE DOING A SENSE
T78SI2: MOVEI T3,CO.MBE ;ENABLE THE MASSBUS, DISABLE INTERRUPTS
XCT T78COS##(W)
LDB T3,[POINT 2,TUBADR##(U),35] ;GET UNIT NUMBER
SKIPE T78SNS##(U) ;SENSE?
JRST [MOVEI T2,DF.SNS ;YES, DO IT
JRST T78SI3]
JUMPL P1,T78SI4 ;NO, GO IF A DATA OP
MOVE T2,TRBXCW(T1) ;SENSE OR NON-DATA. GET COUNT
LSH T2,NDCSHF ;POSITION IT
ANDI T2,DO.NDC ;MASK OUT GARBAGE
TRO T2,(P1) ;SET FUNCTION FROM TABLE
T78SI3: ADDI T3,<(.DOND0)>_-14 ;GET RIGHT REGISTER (14=DRIVE 0, 15=DRIVE 1,...)
DPB T3,[POINT 4,T2,5] ;SAVE REGISTER IN FUNCTION
JRST T78SI6 ;GO START UP THE WORLD
;HERE TO START A DATA OPERATION
T78SI4: LDB T4,PRBMOD## ;GET MODE
SKIPGE T4,MODTBL(T4) ;LEGAL?
JRST ILLFNC ;NO
MOVEI T2,(T4) ;YES. SET MODE IN COMMAND
TRO T2,DO.RC1(T3) ;RECORD COUNT=1, SET UNIT
TLNE S,IOSRTY## ;IF NOT DOING RETRIES
TRO T2,DO.SER ;INFORM THE HARDWARE
HRLI T2,(.DOFMT) ;TELL MODE, COUNT, UNIT
PUSHJ P,WTREG
MOVS T2,T78UVA##(W) ;GET WORD COUNT
HLRZS T4 ;NO OF FRAMES PER WORD
TLOE T2,-1 ;DO WE ALREADY HAVE FRAME COUNT ?
IMULI T2,(T4) ;COMPUTE FRAME COUNT
MOVNM T2,TKBCHR(W) ;SAVE IN KDB
MOVNS T2 ;+FRAME COUNT
ANDI T2,DO.ERD ;ONLY 16 BITS WORTH
HRLI T2,(.DOBC)
PUSHJ P,WTREGX ;TELL BYTE COUNT REGISTER
HRRZ T2,TKBICP##(W) ;INITIAL CNTRL WORD ADDRESS
HRRZ T3,TRBXCW(T1) ;LOC OF FIRST IOWD
TLO T3,RH2JMP## ;MAKE A JUMP TO IT
MOVEM T3,(T2) ;STORE IN ICWA
HRRZ T2,P1 ;FUNCTION (READ/WRITE, PE/GCR)
T78SI5: TDO T2,[.DOSTC!DO.RCP!DO.SCS!DO.CNT]
T78SI6: SKIPN T78SNS##(U) ;IF NOT DOING A SENSE
MOVEM T2,T78REG##+5(U);SAVE FUNCTION IN UDB FOR SYSERR
MOVE T3,T2 ;COPY FUNCTION WORD
ANDI T3,77 ;MASK TO FUNCTION BYTE
CAIE T3,DF.SNS ;IF NOT DOING A SENSE,
MOVEM P1,TKBFLG(W) ;SAVE WHAT THE KONTROLLER IS DOING
PUSHJ P,WTREG ;START UP THE WORLD
PUSHJ P,SETIVI ;SET UP INTERRUPT VECTOR
MOVEI T3,TAPCHN##+CO.AIE+CO.MBE
XCT TKBCIS##(W) ;CONI
TRNE T2,CI.RAE ;REGISTER ACCESS ERROR?
MOVEI T3,TAPCHN##+CO.MBE+CO.STP ;YES, GET TO INTERRUPT LEVEL RIGHT AWAY
XCT T78COS##(W) ;NO, ENABLE FOR INTERRUPTS
SKIPE T78SNS##(U) ;SENSE?
RTZER: SETZ T1, ;YES, ANOTHER INTERRUPT COMING
POPJ P, ;RETURN TO TAPSER
SUBTTL INTERRUPT PROCESSING
T78INT: PUSHJ P,SAVE3## ;SAVE SOME ACS
MOVE P1,TKBFLG(W) ;GET COMMUNICATION/FLAGS WORD
XCT TKBCIS##(W) ;CONI
MOVE P2,T2 ;SAVE IT IN P2
TRNE T2,CI.RAE ;REGISTER ACCESS ERROR?
JRST NOATT1 ;YES, HANDLE IT
MOVSI T2,(.DOAS) ;NO, READ ATTEN SUMMARY
PUSHJ P,RDREG
ANDI T2,377 ;JUST REAL ATTENTIONS
TDNN T2,TKBUNI##(W) ;ATTENTION FOR THIS KDB?
JRST NOATTN ;NO
PUSHJ P,ATTEN ;GO HANDLE IT
POPJ P, ;ASYNC EVENT - RETURN 0 OR -1 TO TAPSER
JUMPE T1,INTREW ;REW COMPLETE IF T1=0
SKIPN T78SNS##(U) ;COMPLETE A SENSE?
TLNN P1,(TB.DAT) ;NO, DATA OPERATION IN PROGRESS?
JRST CHEKIT ;SENSE OR NON-DATA
TLO T1,RB.SDE ;DATA OPERATION + ATTENTION - CANT HAPPEN
JRST DONE ;SO LIGHT AN ERROR AND RETURN
;HERE IF NO ATTENTIONS
NOATTN: TRNN P2,CI.DON ;DONE?
JRST RTZER ;NO, ERROR (NO ATTEN, NOT DONE = RH20 GOOFED)
NOATT1: SKIPE T1,TKBSCH(W) ;SCHEDULE CYCLE?
JRST SCHDON ;YES, TELL TAPSER ABOUT IT
MOVEI T3,CO.CCD!CO.MBE;NO, CLEAR DONE
XCT T78COS##(W)
MOVE U,TKBCUN##(W) ;UNIT WE ARE TALKING TO
MOVE U,(U)
SKIPE T78SNS##(U) ;DOING A SENSE?
TLNN P1,(TB.XSN) ;YES, AN EXTENDED SENSE?
JRST NOATT2 ;NO
MOVE T2,TKBSCW(W) ;YES, RESTORE REAL CHAN GOTO WORD
MOVEM T2,@TKBICP##(W)
SETZM TKBSCW(W) ;INDICATE WE DON'T HAVE A REAL IOWD ANY MORE
PUSHJ P,ATTEN3 ;FINISH UP INTERRUPT PROCESSING
JRST CLRCTL ;ASYNC
JRST CHEKIT ;KEEP ON TRUCKIN
NOATT2: MOVSI T2,(.DOICD) ;GET INTERRUPT CODE
PUSHJ P,RDREG
MOVE P3,T2 ;WHERE ATTEN6 WANT IT
PUSHJ P,T78STS ;READ WLK, BOT, AND DENSITY
PUSHJ P,ATTEN6 ;CHECK IT FOR GOODNESS
PJRST CLRCTL ;ASYNC EVENT (!)
TLNE T4,RB.SER!RB.SED ;IF AN ERROR,
JRST CHEKIT ; DON'T BOTHER CHECKING CHANNEL FOR ERRORS
MOVE T3,TKBICP##(W) ;GET LOC OF LOGOUT AREA
HLL P2,1(T3) ;GET RH20 LH FLAGS
TLC P2,(CS.NAE)
TLNE P2,(CS.SWC) ;IF SHORT WORDCOUNT (RECORD TOO LONG)
TRZ P2,CI.OVR ;THEN OVERRUN CAME UP ERRONEOUSLY
TDNE P2,[CS.ERR!CI.ERR] ;CHANNEL ERROR?
JRST CHNERR ;TOO BAD
CHEKIT: LDB T4,[POINT 4,P1,17] ;GET INDEX INTO FUNCTION TABLE
HLL T1,TRBSTS(T1) ;GET ERROR BITS
TLNN P1,(TB.ERA!TB.REW) ;ERASE OR REWIND?
TLNE T1,RB.SNM!RB.SAP ;NO, ANY TAPE MOTION
JRST NOTM ;DON'T UPDATE TUBREC/FIL
MOVEI T2,1 ;ASSUME FORWARD
TLNE P1,(TB.REV) ;IS IT?
MOVNI T2,1 ;NO
ADDM T2,TUBREC##(U) ;UPDATE TUBREC
TLNN P1,(TB.WTM) ;JUST WRITE AN EOF?
TLNE T1,RB.STM ; OR JUST SEE AN EOF?
CAIA ;YES
JRST NOTM ;NO
ADDM T2,TUBFIL##(U) ;UPDATE TUBFIL
SETZM TUBREC##(U) ;AT 0TH RECORD
NOTM: MOVSI T2,TUSBOT## ;ASSUME NOT AT BOT
ANDCAM T2,TUBSTS##(U)
TLNE T1,RB.SBT ;ARE WE?
IORM T2,TUBSTS##(U) ;YES, TELL THE REST OF THE WORLD
PJRST @INTABL(T4) ;THE LEAP OF FAITH
;SUBROUTINE TO HANDLE ATTENTION INTERRUPTS
;EXIT T1=ERROR BITS,,IORB OR T1=0 IF REWIND JUST FINISHED
;NON-SKIP IF ASYNCHRONOUS EVENT, SKIP-RETURN NORMALLY
ATTEN: MOVSI T2,(.DOICN) ;READ THE INTERRUPT CODE
PUSHJ P,RDREG
MOVE P3,T2 ;SAVE IT (IT DISAPPEARS AFTER CLEARING ATTENTION)
HRRZ T2,TKBUNI##(W) ;GET BIT FOR ATTENTIONS ON THIS UNIT
HRLI T2,(.DOAS)
PUSHJ P,WTREGX ;CLEAR THIS ATTENTION, LEAVE ANY OTHERS ALONE
LDB T1,[POINT 2,P3,27] ;GET UNIT
HRLS T1 ;IN BOTH HALVES
ADD T1,TKBIUN##(W) ;POINT AT RIGHT UDB
SKIPE U,(T1) ;SET UP U TO UDB
JRST ATTEN2 ;YES, PUSH ON
;HERE IF NO UDB IS FOUND FOR THE INTERRUPT ADDRESS
LDB T1,[POINT 5,P3,35] ;GET INTERRUPT CODE
CAIE T1,ICDND1 ;IS IT ONE FOR WHICH THE ADDRESS ISNT VALID?
CAIN T1,ICDND2
SKIPA T1,TKBCUN##(W) ;YES, BLAME IT ON THE CURRENT UNIT
JRST ATTE15 ;NO,NEW UNIT
SKIPN U,(T1) ;SET U TO CURRENT UDB
JRST CLRINT
ATTEN2: SKIPN T78SNS##(U) ;DOING A SENSE?
JRST [PUSHJ P,T78STS ;NO--READ WLK, BOT, AND DENSITY
JRST ATTEN6] ;ONWARD
MOVE P1,T78SNS##(U) ;SET P1 FOR THIS FUNCTION
TLZN P1,(TB.RRG) ;SENSE WHILE READING REGISTERS?
JRST ATTEN4 ;NO, CARRY ON
PUSHJ P,RDREG2 ;YES, READ REGS 7, 10, 11
SKIPGE T78ESD##(U) ;SENSE AFTER AN RH20 ERROR?
JRST ATTEN3 ;NO
MOVE T4,[IC.BST!RB.SED] ;YES, CAUSE AN ERROR BIT TO GET LIT IN IORB
JRST ATTEN9
ATTEN3: MOVE T4,T78ESD##(U) ;RESTORE ERROR BITS
TLNE T4,(IC.XSN) ;NEED EXTENDED SENSE INFO?
TLOE P1,(TB.XSN) ;YES, HAVE WE DONE IT ALREADY?
JRST ATTEN9 ;FINISH UP INTERRUPT
JRST ATTE14 ;GO CRANK UP EXTENDED SENSE
ATTEN4: MOVSI T2,(.DOSR) ;READ THE STATUS REGISTER
PUSHJ P,RDREG
JUMPL P1,ATTEN5 ;GO IF A DATA OP
MOVSI T4,TUSWTL##!TUSBOT## ;NON-DATA, CLEAR WRITE-LOCK BIT, BOT
ANDCAM T4,TUBSTS##(U)
TRNN T2,DI.FPT ;AND SET IT AGAIN IF TAPE REALLY IS WRITE LOCKED
TLZ T4,TUSWTL## ;NOT WRITE-LOCKED
TRNN T2,DI.BOT
TLZ T4,TUSBOT## ;NOT AT LOAD-POINT
IORM T4,TUBSTS##(U)
JRST ATTEN6 ;PUSH ON
;HERE ON SENSE WHILE DOING A DATA OP - AFTER READ OF 1ST RECORD ON TAPE
ATTEN5: MOVE T3,T2 ;PRESERVE STATUS REG
PUSHJ P,CHKIRB## ;SET T1
JRST TAPDIS## ;NONE??????
MOVEI T4,RB.D16
TRNN T3,DI.PE ;SET MODE/DENSITY CORRECTLY
MOVEI T4,RB.D62
DPB T4,PRBDEN## ;AND TELL THE REST OF THE WORLD
;HERE ON NORMAL ATTENTION INTERRUPT
ATTEN6: LDB T2,[POINT 5,P3,35] ;GET INTERRUPT CODE
CAIE T2,ICDND1 ;ASYNC INTERRUPT WHERE REGS NOT READ?
CAIN T2,ICDND2
JRST [MOVEI T1,T78REG##+7(U) ;YES. CLEAR OUT OLD INFO
HRLI T1,-1(T1) ; SO AS NOT TO CONFUSE FIELD-SERVICE
SETZM -1(T1) ; SINCE WE CAN'T GET ANY OTHER INFORMATION
BLT T1,T78REG##+47(U)
MOVEM P3,T78REG##+6+ICNREG(U) ;SAVE INTERRUPT CODE
JRST .+1]
CAILE T2,MAXICD ;LEGAL?
MOVEI T2,0 ;NO
SKIPN P3,T78RRO##(W) ;DOING RETRY OPPOSITE?
JRST ATTEN8 ;NO
TLC P1,(TB.REV) ;YES, THE OPERATION IS REALLY IN THE OTHER DIRECTION
SETZM T78RRO##(W) ;EITHER WIN OR RETRY IN ORIGINAL DIRECTION - CLEAN UP
PUSH P,T2
PUSHJ P,CHKIRB## ;GET IORB
JRST ATTEN7 ;NONE (!)
LDB T3,PRBFCN## ;GET FUNCTION
HLRZ T2,TUBCHR##(U) ;GET WORDCOUNT OF RECORD
SKIPL FNCTBL(T3) ;IF A DATA OPERATION
JRST ATTEN7 ;NOT A DATA OP!
PUSHJ P,REVCCW## ;RE-REVERSE THE IO LIST
HLLM P3,(P3) ;RESTORE ORIGINAL LH OF CHANGED IOWD
ATTEN7: POP P,T2
ATTEN8: SKIPL T4,ICDTBL(T2) ;GET BITS/DISPATCH ADDRESS
JRST ATTEN9 ;NO ERROR, KEEP ON
SKIPE TUBERR##(U) ;ERROR. FIRST TIME WE'VE SEEN IT?
TRNN T4,RB.SAP ;YES. DOES TM REPOSITION ON THIS ERROR?
JRST ATTE13 ;1ST TIME OR NO REPOS, READ REGISTERS
ATTEN9: TLNN T4,(IC.RRG) ;WIN WITH NO ERRORS?
SKIPN TUBERR##(U) ;YES, IN ERROR RETRY?
CAIA
PUSHJ P,RDREG3 ;GOOD RETRY - READ WINNING REGISTERS
TLNN T4,(IC.ASY) ;ASYNC INTERRUPT?
AOS (P) ;NON ASYNC - SKIP RETURN
TLNE T4,(IC.DSP) ;DISPATCH ON THIS CONDITION?
PJRST (T4) ;YES, GO TO SUBROUTINE
ATTE10: TLNN T4,(IC.BST) ;NO, SET A BIT?
TDZA T4,T4 ;NO
HRLZS T4 ;YES
PUSHJ P,CHKIRB## ;NO, POINT T1 AT IORB
SETZ T1, ;NO IORB
MOVE T2,TUBSTS##(U) ;GET STATUS
TLNE T2,TUSREW## ;WAS IT REWINDING?
JRST ATTE11 ;YES, PROBABLY ASYNC INTERRUPT AT BOT
JUMPE T1,ATTE12 ;GO IF NO IORB
IORM T4,TRBSTS(T1) ;LIGHT BIT IN LH(T1)
POPJ P, ;AND RETURN
;HERE IF TUSREW IS ON IN TUB
ATTE11: JUMPE T1,CPOPJ## ;AT BOT IF NO IORB
LDB T2,PRBFCN## ;IORB - IS IT THE REWIND?
CAIE T2,RB.FRU
CAIN T2,RB.FRW
POPJ P, ;YES. REW WHEN WE'RE AT BOT (IMMEDIATE DONE INTERRUPT)
JRST RTZER ;NO, ANOTHER IORB HAS BEEN QUEUED. WE'RE AT BOT
;HERE WITH NO IORB, TAPE WAS NOT REWINDING
ATTE12: SOS (P) ;NON-SKIP RETURN
SETZB T1,T78SNS##(U) ;PROBABLY SENSE AFTER ON-LINE
POPJ P, ;RETURN WITH T1=0
;HERE ON AN ERROR WHICH REQUIRES READING THE DRIVE REGISTERS
ATTE13: SETZM T78RRO##(W) ;CLEAN UP FLAGS
PUSHJ P,RDREGS ;READ REGS (7-10 AREN'T CORRECT)
TLO P1,(TB.RRG) ;INDICATE WHY WE'RE DOING THE SENSE
MOVEM T4,T78ESD##(U) ;SAVE ERROR BITS FOR WHEN SENSE FINISHES
PJRST SENSE ;DO A SENSE SO WE CAN READ REGS 7-10
;HERE WHEN WE NEED TO START AN EXTENDED SENSE OPERATION TO READ ERROR INFO
ATTE14: MOVEM P1,T78SNS##(U) ;UPDATED FLAGS WORD
MOVEI T2,TKBCCL##(W) ;WHERE TO DO THE SENSE
MAP T2,(T2) ;CONVERT TO PHYSICAL ADDRESS
TLZ T2,777760
TLO T2,RH2JMP## ;MAKE AN RH20 JUMP WORD
EXCH T2,@TKBICP##(W) ;SAVE CURRENT ICWA, SET UP JUMP TO TEMP
MOVEM T2,TKBSCW(W)
MOVE T2,T78XIW##(W) ;IOWD TO READ SENSE BYTES INTO TUB
ADDI T2,(U) ;POINT AT RIGHT TUB
HLLZM T2,TKBCCL##(W) ;SAVE WHERE ICWA POINTS
MAP T2,(T2) ;COMPUTE PHYSICAL ADDRESS
TLZ T2,777760 ;CLEAR EXTRANEOUS BITS
IORM T2,TKBCCL(W) ;COMPLETE THE IOWD
LDB T2,[POINT 2,TUBAKA##(U),17]
TRO T2,DO.RC1 ;SET UP FORMAT REGISTER
HRLI T2,(.DOFMT) ; ONLY NEEDS UNIT NUMBER
PUSHJ P,WTREGX
MOVEI T2,DF.XSN ;FUNCTION IS EXTENDED SENSE
PJRST T78SI5 ;GO CRANK IT UP AND RETURN 0 TO TAPSER
;HERE ON AN INTERRUPT OF A NEW (UNKNOWN) UNIT
ATTE15:
IFN FTAUTC,<
LDB T2,[POINT 2,P3,27] ;SLAVE NUMBER
PUSHJ P,INISNS ;IS IT REAL (DRIVE AVAILABLE)?
JRST CLRTMI ;IF WE GOT HERE FOR A REALLY NON-EXISTANT SLAVE,
; WE WILL PROBABLY GET AGAIN AND AGAIN AND ...
; SO REALLY HAVE TO DO SOMETHING DRASTIC TO CLEAR IT
MOVSI T2,(.DIDTR)
PUSHJ P,RDREGX ;READ THE DRIVE TYPE
MOVE T1,T2 ;WHERE AUTCON WANTS IT
LDB T2,[POINT 2,P3,27] ;SLAVE NUMBER
SETZ T3, ;NO SPECIAL BITS IN TUBCNF
PUSHJ P,NEWTAP## ;TELL THE WORLD A NEW TAPE IS HERE
>
JRST RTZER ;AND CHUCK THE INTERRUPT
; HERE TO READ DRIVE STATUS AND SET WLK, BOT, AND DENSITY FOR
; ALL FUNCTIONS EXCEPT REWIND AND UNLOAD IF THE TAPE IS NOT
; ALREADY AT BOT
T78STS: MOVSI T2,TUSBOT## ;BIT TO TEST
TDNN T2,TUBSTS##(U) ;AT BOT?
PUSHJ P,CHKIRB## ;NO--HAVE AN IORB?
POPJ P, ;NOTHING TO DO
LDB T2,PRBFCN## ;GET FUNCTION CODE FROM IORB
CAIE T2,RB.FRW ;REWIND?
CAIN T2,RB.FRU ;UNLOAD?
POPJ P, ;GO AWAY
MOVSI T2,(.DOSR) ;REGISTER
PUSHJ P,RDREG ;READ STATUS
MOVSI T3,TUSWTL##!TUSBOT## ;BITS TO CLEAR
ANDCAM T3,TUBSTS##(U) ;CLEAR WLK AND BOT
TRNN T2,DI.FPT ;WRITE LOCKED?
TLZ T3,TUSWTL## ;NO
TRNN T2,DI.BOT ;AT BOT?
TLZ T3,TUSBOT## ;NO
IORM T3,TUBSTS##(U) ;UPDATE
MOVEI T3,RB.D16 ;ASSUME 1600 BPI
TRNN T2,DI.PE ;PHASE ENCODED?
MOVEI T3,RB.D62 ;NO--MUST BE GCR (6250 BPI)
DPB T3,PRBDEN## ;UPDATE IORB (TAPSER WILL PROPAGET TO TUB)
POPJ P, ;RETURN
;HERE ON READ INTERRUPT
INTRD: SKIPN T78SNS##(U) ;IF WE HAVEN'T DONE A SENSE
TLNE T1,-1 ; AND HAVE HAD NO ERRORS ON THE READ
TDZA T2,T2
MOVE T2,TUBREC##(U) ; IF THIS IS THE 1ST RECORD
SKIPN TUBFIL##(U) ; IN THE FIRST FILE
SOJE T2,SENSE ;DO A SENSE TO GET MODE/DENSITY RIGHT IN TUB
MOVSI T2,(.DOBC) ;READ BYTE COUNT
PUSHJ P,RDREG
MOVEM T2,TRBRCT(T1) ;SAVE BYTE COUNT IN IORB
MOVEM T2,TUBCCR##(U) ; AND IN TUB
TLZ T2,-1 ;CLEAR POSSIBLE FLAG
TLNN T1,-1 ;IF NO ERROR
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
JRST DONE
;HERE ON WRITE INTERRUPT
INTWRT: MOVE T2,TKBCHR(W) ;NO OF FRAMES WE WROTE
ADDM T2,TUBCWR##(U) ;UPDATE STATS
ADDM T2,.CPTFO##
JRST DONE ;AND FINISH UP
;HERE ON A REREAD OPPOSITE INTERRUPT
INTRRO: PUSHJ P,CHKIRB## ;SET T1 TO IORB
JRST INTRR1 ;NONE(!) CALL IT A HARD ERROR
MOVSI T2,(.DOBC) ;READ THE BYTE COUNT REGISTER
PUSHJ P,RDREG
JUMPE T2,INTRR1 ;THE TM78 BLEW IT IF BYTE COUNT IS 0
MOVN T3,T2 ;-VE BYTE COUNT
HRLZM T3,T78UVA##(W) ;TO TELL THE TM78 THE RIGHT BYTE COUNT
LDB T3,PRBMOD## ;MODE
IDIV T2,TMODTB##(T3) ;CONVERT BYTES TO WORDS
JUMPN T3,INTRR1 ;LOSE IF A NON-INTEGRAL NUMBER OF WORDS
PUSHJ P,REVCCW## ;GOODNESS. REVERSE THE IO LIST
MOVEM T2,T78RRO##(W) ;SAVE ORIGINAL IOWD ADDR AND LH
MOVE T4,[IC.BST!RB.SED!RB.SDE!RB.SAP] ;SOME ERROR BITS TO SET
JRST ATTE10 ;AND KEEP GOING WITH ANALYSIS (WILL EVENTUALLY RETRY)
INTRR1: MOVE T4,NRTERD ;CANT RETRY OPPOSITE
JRST ATTEN9 ;READ REGISTERS AND GIVE NON-RECOVERABLE ERROR
INTRWP: MOVSI T2,TUSREW## ;SAY WE'RE REWINDING
IORM T2,TUBSTS##(U)
HRRZ T1,TUBQUE##(U) ;SET T1 TO IORB (OR 0)
TLZ P1,17 ;SO WE DON'T GO TO INTREW NOW
JRST CPOPJ1## ;SKIP RETURN TO T78INT
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: PUSHJ P,REWDON## ;TELL WORLD WE'RE THROUGH REWINDING
SETZM TUBREC##(U) ;CLEAR STATS
SETZM TUBFIL##(U)
JUMPE T1,CLRCTY ;JUST RETURN TO TAPSER IF WE WEREN'T AT BOT ALREADY
JRST DONE ;AND FINISH UP
;HERE ON ANY FLAVOR OF OFF-LINE/NOT AVAILABLE TO THIS MASSBUS INTERRUPT
INTOFL: PUSHJ P,CHKIRB## ;DOING AN OPERATION?
JRST OFLUNI ;NO, ASYNC. RETURN 0 TO TAPSER
MOVSI T2,RB.SOL!RB.SER!RB.SNM ;YES, TELL WORLD NOTHING HAPPENED
IORM T2,TRBSTS(T1)
OFLUNI: MOVSI T2,TKSOFL## ;LET REST OF WORLD KNOW
IORM T2,TUBSTS##(U) ; THAT THE DRIVE IS OFF-LINE
POPJ P,
;HERE ON BAD TAPE INTERRUPT
BADTAP: LDB T1,TUYECD ;PICK UP FAILURE CODE
MOVE T4,NRTERD ;LOAD BAD DATA ERROR
CAIN T1,14 ;BAD TAPE AT OR BEYOND EOT?
TRO T4,RB.SET ;YES, NOTE NEED TO SET EOT AS WELL
PJRST ATTE10 ;AND GO HANDLE SETTING THE BITS
;HERE ON TU FAULT A INTERRUPT
TUFLTA: MOVE T4,NRTERV ;GET BAD DRIVE ERROR BITS
LDB T1,TUYECD ;GET ERROR CODE
CAIE T1,44 ;31/44 (PREVIOUS RECORD DESTROYED)?
JRST ATTEN9 ;NO, JUST SET BITS AS REQUESTED
MOVSI T1,TUSFLT## ;YES, LOAD NEW ERROR BIT
IORM T1,TUBSTS##(U) ;TELL WORLD THAT TU IS BAD
PJRST RTZER ;AND PITCH THE INTERRUPT (USER GETS HUNG DEV)
;HERE ON ON-LINE INTERRUPT
INTONL: MOVSI T2,TKSOFL## ;CLEAR OFF-LINE BIT
ANDCAM T2,TUBSTS##(U)
PUSHJ P,TPMONL## ;TELL MDA A DRIVE JUST CAME UP
MOVEI P1,DF.SNS ;NON-DATA TYPE SENSE
SETZ T1, ;TELL TAPSER THIS IS ASYNC
PJRST SENSE ;GO START A SENSE AND RETURN
SCHDON: SETZM TKBSCH(W)
JRST CLRCTL
;HERE AFTER AN OPERATION IS THROUGH
DONE: HLLZ T2,T1 ;FLAGS WHICH GOT SET AFTER ATTEN6
IORB T2,TRBSTS(T1) ;PLUS FLAGS WHICH GOT SET AT ATTEN6
HLL T1,T2 ;IN LH(T1)
MOVSI T2,RB.EXC
TLZE T1,-1 ;ANY FUNNY THINGS?
IORM T2,TRBLNK(T1) ;YES, AN EXCEPTION HAS OCCURRED
SETZM T78SNS##(U)
CLRCTL: MOVEI T3,CO.CLR
XCT T78COS##(W)
MOVEI T3,CO.MBI
XCT TKBCIS##(W) ;SOMETIMES RAE WON'T CLEAR
TRNE T2,CI.RAE ;IS IT STILL UP?
XCT T78COS##(W) ;YES - ZAP IT
SETZM TKBFLG(W) ;NOTHING HAPPENING NOW
CLRCTY: MOVEI T3,TAPCHN##+CO.AIE+CO.MBE ;ENABLE FOR INTERRUPTS
XCT T78COS##(W)
POPJ P, ;AND RETURN
;HERE TO CLEAR THE TM78
CLRTMI: MOVEI T3,CO.CLR!CO.MBE;CLEAR THE RH20 OF ALL ERRORS, DONE
XCT T78COS##(W)
CAIA
CLRTMO: TAPON
CLRTM: MOVE T2,[.DOTMS!DO.TMC] ;DO AN INIT OF THE TM78
PUSHJ P,WTREG
MOVEI T4,40000 ;HOW LONG TO WAIT
CLRTM1: MOVSI T2,(.DOTMS) ;READ TM78 STATUS
PUSHJ P,RDREGX
TRNN T2,DI.TMR ;TM READY?
SOJG T4,CLRTM1 ;NO, TRY AGAIN
PJRST RTZER ;YES (OR TIMEOUT) RETURN
;HERE ON CONI ERROR BIT
CHNERR: TRNN P2,CI.RAE ;REGISTER ACCESS ERROR?
JRST NORAE ;NO
TLO T1,RB.SNM!RB.SED ;YES, NO TAPE MOTION+ERROR
JRST DONE
NORAE: TLNN P2,(CS.MPE!CS.NXM)
JRST CHNRTY ;NO, JUST RETRY
MOVEI T3,CHNNXM## ;SET TO CALL RIGHT ROUTINE
MOVSI T4,IOCHNX ;ASSUMING NXM
TLNN P2,(CS.NXM) ;NXM?
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
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
CHNRTY: MOVEI T4,-1 ;SET T78ESD=0,,-1 AS A FLAG
JRST ATTE13 ;AND GO CRANK UP A SENSE
SUBTTL INITIALIZATION
;HERE TO INITIALIZE THE TM78
T78INI: PUSHJ P,CLRTMI ;CLEAR THE TM78
PUSHJ P,SAVE2##
SETO P1, ;ASSUME NO TM78
PUSHJ P,T78ONL ;IS THE TM78 WITH US?
JRST T78IN1 ;NO
MOVSI T2,(.DODT) ;MAYBE. READ DRIVE TYPE
PUSHJ P,RDREG
ANDI T2,170377 ;IS IT A TM78
MOVEI P1,-140101(T2) ;P1=0 IF A READY TM78
MOVE T2,[.DOAS!377] ;CLEAR GARBAGE FROM ATTEN SUMMARY REG
PUSHJ P,WTREGX
T78IN1: MOVEI T1,TUCIRD## ;TELL TAPUUO WE GET AN INTERRUPT
MOVE T2,TKBCUN##(W) ; WHEN A REWIND FINISHES
T78IN2: SKIPE T3,(T2) ;NEXT DRIVE
IORM T1,TUBSTS##(T3) ;SET BIT IN IT
AOBJN T2,T78IN2
MOVE T4,TKBIUN##(W) ;SET TO LOOP OVER ALL UNITS
T78IN3: SKIPN U,(T4) ;GET A UNIT
JRST T78IN6 ;NOT THERE
HRRZ T2,TUBADR##(U) ;GET UDB
HRLM T2,TUBAKA##(U) ;WTREG WANTS UNIT HERE
JUMPN P1,T78IN6 ;GO IF THE TM78 ISN'T RUNNING
HLRZ T3,TKBUNI##(W) ;SET UP RH UNIT NUMBER
HRRZ T2,TUBADR##(U) ;UNIT NUMBER
PUSHJ P,INISNS ;SENSE TO SEE IF THE DRIVE IS THERE
JRST T78IN6 ;NO, IT ISNT
MOVSI T2,(.DOSN) ;READ SERIAL NUMBER
PUSHJ P,RDREG ;AND STORE IN UDB
MOVEM T2,T78REG##+14(U) ;FOR DIAGNOSTICS
MOVSI T2,(.DOSR) ;READ STATUS REG
PUSHJ P,RDREG
MOVSI T3,TKSOFL##
TRNN T2,DI.RDY ;IF NOT READY
IORM T3,TUBSTS##(U) ; THE DRIVE IS OFF-LINE
MOVSI T3,TUSWTL##
ANDCAM T3,TUBSTS##(U) ;ASSUME TAPE IS NOT WRITE-LOCKED
TRNE T2,DI.FPT
IORM T3,TUBSTS##(U) ;WRONG - IT IS WRITE LOCKED
MOVE T2,[.DOAS!377] ;CLEAR THE ATTEN BIT WE JUST LIT
PUSHJ P,WTREG
T78IN6: AOBJN T4,T78IN3
T78IN7: PUSHJ P,T78ONL ;IF NOT THERE
JRST T78I13 ; DON'T SET UP CONSO MASK
MOVE U,TKBIUN##(W) ;POINT U AT 1ST UDB ON CONTROLLER
MOVE U,(U)
SKIPE T78REG##(U) ;ALREADY READ ROM REV LEVELS?
JRST T78I12 ;YES, SKIP THIS
PUSHJ P,SETHLD ;SET HOLD IN TM SO WE CAN READ REV LEVELS
JRST T78I12 ;LOSE IF IT DIDNT SET
MOVEI P1,T78REG##(U) ;POINT AT ..U?0 UDB
HRLI P1,441100 ;MAKE A BYTE POINTER
MOVE P2,[.DOIA!3776] ;POINT AT LOC FOR 1ST ROM REV LEVEL
T78IN9: MOVE T2,P2
PUSHJ P,WTREG ;LOC WE WANT TO READ
MOVSI T2,(.DOTMS)
PUSHJ P,RDREG ;READ THE LOCATION
ANDI T2,377 ;ONLY 8 BITS ARE OF INTEREST
IDPB T2,P1 ;SAVE IN ..U?0 UDB
ADDI P2,4000 ;STEP TO NEXT REV LEVEL LOC
TRNN P2,40000
JRST T78IN9 ;GO READ IT
DMOVE T3,[POINT 9,T78REG##(U) ;POINT TO WHAT WE GOT
POINT 9,T78REV] ;AND WHAT WE EXPECT FOR EACH ROM
MOVSI P1,-^D8 ;NUMBER OF ROMS TO CHECK
T78I9A: ILDB T1,T3 ;GET NEXT ROM WE GOT
ILDB T2,T4 ;AND WHAT WE EXPECT
CAML T1,T2 ;SEE IF AT LEAST WHAT WE EXPECT
AOBJN P1,T78I9A ;OK, CONTINUE
SKIPGE P1 ;SKIP IF ALL OK
PUSHJ P,T78I14 ;NO, COMPLAIN ABOUT BEING DOWN REV
PUSHJ P,CLRHLD ;CLEAR HOLD
SKIPA T1,TKBIUN##(W)
T78I10: SKIPN T2,(T1) ;POINT AT NEXT UDB
JRST T78I11
DMOVE T3,T78REG##(U) ;MOVE REV LEVELS FROM 0'S UDB
DMOVEM T3,T78REG##(T2) ; TO THIS UDB
T78I11: AOBJN T1,T78I10 ;DO ALL UDBS
T78I12: MOVEI T3,CO.MBE!CO.RAE ;CLEAR POSSIBLE REG ACCESS ERROR
XCT T78COS##(W) ; (ON IF NON-EX DRIVE)
PUSHJ P,SETIVI ;SET UP INTERRUPT VECTOR
JRST CLRCTL ;CLEAR RH20 AND RETURN
;HERE IF THE CONTROL DIDN'T RAISE ATTENTION
T78I13: MOVSI T1,TKSOFL## ;MARK THE CONTROL AS OFF LINE
IORM T1,TKBSTS##(W)
POPJ P,
;TWO WORDS FOR PATCHING IN NEW TM78 ROM REV LEVELS
T78REV: BYTE (9) 6,5,6,4
BYTE (9) 2,3,8,3
;HERE IF THE CONTROLLER ROM IS BELOW REQUIRED REV LEVELS
T78I14: HRROI T2,[ASCIZ /Ask field service to install the new TM78 microcode ROMs/]
PJRST TAPREV## ;LET TAPSER TYPE A MESSAGE
;HERE ON KONTROLLER ONLINE. SKIP THE CODE TO RESET THE DDB NAMES.
T78INR: PUSHJ P,CLRTMI
JRST T78IN7 ;JOIN COMMON CODE
;SUBROUTINE TO SET HOLD IN THE TM78
;RETURNS CPOPJ IF HOLD DIDN'T SET, CPOPJ1 NORMALLY
SETHLD: PUSHJ P,SAVE1##
MOVE T2,[.DOIA!3776] ;POINT INTERNAL ADDR AT A READ-ONLY LOCATION
PUSHJ P,WTREG ;IN CASE TM78 DECIDES TO WRITE WHEN HOLD SETS
MOVE T2,[.DOTMS!DO.HLD]
PUSHJ P,WTREG ;SET HOLD
MOVEI P1,40000 ;HOW LONG TO WAIT
SETHL1: MOVSI T2,(.DOTMS) ;READ STATUS
PUSHJ P,RDREG
TRNN T2,DO.HLA ;HOLD ACKNOWLEDGED?
SOJG P1,SETHL1 ;NO, WAIT SOME MORE
JUMPN P1,CPOPJ1## ;SKIP-RETURN IF HOLD ACKNOWLEDGED
POPJ P, ;COULDN'T SET HOLD - NON SKIP RETURN
;SUBROUTINE TO CLEAR HOLD
CLRHLD: MOVSI T2,(.DOTMS)
PUSHJ P,WTREG ;CLEAR HOLD
MOVE T2,[.DOTMS!DO.TMC]
PUSHJ P,WTREG ;CLEAR POSSIBLE ERROR
POPJ P, ;AND RETURN
;ROUTINE TO DO A SENSE TO SEE IF A SLAVE IS PRESENT
;ENTER T3=RH UNIT NUMBER, T2= DRIVE NUMBER
;RETURNS CPOPJ IF NOT THERE, CPOPJ1 IF IT IS
INISNS: ADDI T2,<(.DOND0)>_-14 ;SET RIGHT DRIVE
ROT T2,-6
HRRI T2,DF.SNS ;DO A SENSE ON THAT DRIVE
PUSHJ P,WTREGX
MOVEI T1,40000 ;HOW LONG TO WAIT
INISN1: MOVSI T2,(.DOAS)
PUSHJ P,RDREGX ;READ ATTEN SUMMARY
TRNN T2,377 ;SENSE OP COMPLETE?
SOJG T1,INISN1 ;NO, WAIT SOME MORE
JUMPE T1,CPOPJ## ;GO IF WE TIMED OUT
MOVSI T2,(.DOSR) ;READ STATUS REGISTER
PUSHJ P,RDREGX
TRNE T2,DI.AVL+DI.MNT ;IS IT THERE?
AOS (P) ;YES
POPJ P, ;RETURN
IFN FTAUTC,<
;ROUTINE TO DETERMINE WHAT SLAVES ARE PRESENT
;ENTER P3= LAST SLAVE WE'VE SEEN, LH(P2) = RH UNIT NUMBER
;RETURN P3=NEXT SLAVE, 0 IF NO MORE
T78CFG: HLRZ T3,P2 ;SET UP RH20 UNIT NUMBER
JUMPGE P3,T78CF1 ;GO IF NOT THE 1ST TIME
PUSHJ P,CLRTM ;RESET THE TM78
PUSHJ P,T78ONL ;IS THE TM WITH US?
POPJ P, ;NO
T78CF1: AOS T2,P3 ;NEXT UNIT
TRZE P3,4 ;OVER THE TOP?
SOJA P3,T78CF2 ;YES, RETURN P3=-1
PUSHJ P,INISNS ;SEE IF THE NEXT SLAVE IS THERE
TDZA T1,T1 ;NOT THERE
SETO T1, ;YUP, IT'S THERE
MOVE T2,[.DOAS!377] ;CLEAR THE ATTENTION
PUSHJ P,WTREGX
JUMPE T1,T78CF1 ;NOT THERE, TRY NEXT SLAVE
SETZ T3, ;INDICATE NO TUBCNF CHANGES
POPJ P, ;RETURN P3 = SLAVE NUMBER
T78CF2: MOVEI T2,CO.MBI ;DO A MASSBUS INIT
XCT T78COS##(W) ; DO GET RID OF ANYTHING THAT GOT GRONKED
MOVEI T3,CO.MBE ;DO A MASSBUS ENABLE TO LET
XCT T78COS##(W) ; AUTCON TALK TO THE RH AGAIN
POPJ P, ;AND RETURN SAYING NO MORE SLAVES ON THIS UNIT
>
;HERE TO CHECK IF ON-LINE
T78ONL: 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 ALREADY
MOVSI T2,(<DO.DRE>!.DOTMS)
TAPOFF ;PREVENT INTERRUPT CODE FROM CHANGING PREPERATION REGISTER
PUSHJ P,RDREG ;IS THE TM78 ALIVE?
TRNE T2,DO.HLA ;DID WE STOP IT?
JRST T78ON2 ;YES, OFF-LINE
TRNE T2,DI.TMR
JRST T78ON1 ;YES
XCT TKBCIS##(W) ;NO, IS THE UNIT THERE AT ALL?
TRNN T2,CI.RAE
PJRST CLRTMO ;YES, TRY TO GET IT GOING AGAIN
MOVEI T3,CO.RAE+CO.MBE+CO.AIE+TAPCHN## ;NO, CLEAR THE RAE
XCT T78COS##(W) ; (NON-EX UNIT)
CAIA
T78ON1: AOS (P)
T78ON2: TAPON
POPJ P, ;AND TAKE THE NON-SKIP RETURN
;HERE TO CAUSE A SCHEDULE CYCLE
T78SCH: SETOM TKBSCH(W) ;SET FLAG
;HERE TO RESET AN ACTIVE DRIVE (HUNG)
T78RES: SKIPE T2,TKBSCW(W) ;LOSE DURING AN EXTENDED SENSE?
MOVEM T2,@TKBICP##(W) ;YES, RESET ICWA TO WHAT IT SHOULD BE
SETZM TKBSCW(W)
SETZM T78RRO##(W) ;NO LONGER IN READ-OPPOSITE
MOVEI T3,CO.MBE ;MAKE SURE THE
XCT T78COS##(W) ; RH IS LISTENING
PUSHJ P,SETIVI ;SET UP INTERRUPT VECTOR
MOVEI T3,CO.STP!CO.MBE ;CLEAR BUSY, SET DONE
XCT T78COS##(W) ;DO IT
SKIPE TKBSCH(W)
JRST CLRCTY
JRST CLRCTL ;CLEAR RH20 AND RETURN
;HERE ON AN INTERRUPT WHICH REQUIRES RESETING THE TM78
CLRINT: PUSHJ P,CLRTM ;RESET THE CONTROLLER
JUMPE U,CLRIN1
MOVSI T1,(1B1) ;MARK AS A HARD ERROR FOR DAEMON
IORM T1,TUBTRY##(U)
MOVSI T1,T78REG##(U) ;COPY FROM "AT END"
HRRI T1,T78ICS##(U) ; TO "AT ERROR"
BLT T1,T78ISE##(U) ; FOR SYSERR
SKIPN F,TUBCUR##(U) ;IF DDB USE IT
CLRIN1: MOVEI F,MT0DDB## ;NO - USE MT0DDB
MOVEI T1,.ERTAP ;ERROR TYPE TO DAEMON
HRL T1,F ;DDB
PUSHJ P,DAEERR## ;TELL DAEMON
SKIPN P1,TKBFLG(W) ;WAS ANYTHING HAPPENING?
JRST CLRIN2 ;NO, RETURN A ZERO
HRRZ T1,TUBQUE##(U) ;POINT T1 AT IORB
JUMPE T1,CLRIN2 ;NONE????
JUMPL P1,T78SI1 ;RETRY THE COMMAND IF IT WAS A DATA OPERATION
MOVE T4,NRTERV ;POSITIONING OP - CALL IT A HARD DEVICE ERROR
JRST ATTEN9 ;FINISH UP PROCESSING
;HERE IF NOTHING WAS HAPPENING
CLRIN2: AOS T1,T78ACT##(W) ;BUMP ASYNC INTERRUPT COUNT
CAIG T1,T78AMX## ;GONE OVER THE THRESHOLD?
JRST RTZER ;NO, RETURN A ZERO
PUSHJ P,SETHLD ;YES. SET HOLD IN THE TM (STOP THE MICROCODE)
JFCL ; TO STOP THESE INTERRUPTS FROM CLOGGING THE SYSTEM
SETOM T78ACT##(W) ;INDICATE HOLD IS SET
JRST RTZER ;AND KEEP ON GOING (RETURN 0 TO TAPSER)
;READ A REGISTER - ENTER, EXIT WITH FNCN IN T2
;RESPECTS T1,T4
RDREG: HLRZ T3,TKBUNI##(W) ;TM78 UNIT NUMBER
RDREGX: TLO T2,<(DO.DRE)>(T3)
XCT TKBDOS##(W) ;SAY WHAT WE WANT TO READ
XCT TKBDIS##(W) ;READ IT
ANDI T2,177777 ;ONLY 16 BITS
POPJ P, ;AND RETURN
;ROUTINE TO WRITE A REGISTER
;ENTER T2=WHAT TO DO THE DATAO WITH
;RESPECTS T1, T4
WTREG: HLRZ T3,TKBUNI##(W) ;TM78 UNIT NUMBER
WTREGX: TLO T2,<(DO.LDR!DO.DRE)>(T3) ;LIGHT LR AND UNIT
XCT TKBDOS##(W) ;DATAO
POPJ P, ;AND RETURN
;ROUTINE TO READ REGISTERS ON ERROR
RDREGS: MOVEM P2,T78REG##+2(U) ;SAVE CONI
MOVSI T2,(.DOPTC)
PUSHJ P,RDREG
MOVEM T2,T78REG##+3(U) ;DATAI PRIMARY TRANSFER CONTROL REG
MOVSI T2,(.DOPBA)
PUSHJ P,RDREGX
MOVEM T2,T78REG##+4(U) ;DATAI PRIMARY BLOCK ADDR REG
PUSH P,T1
MOVEI T1,T78REG##+6(U) ;(REG+5 = LAST COMMAND)
HRLI T1,-22 ;READ ALL REGISTERS
SETZ T2, ; STARTING AT 0
RDREG1: PUSH P,T2
PUSHJ P,RDREGX
MOVEM T2,(T1) ;STORE DATA IN UDB
POP P,T2
ADD T2,[010000,,0] ;SET FOR NEXT REGISTER
AOBJN T1,RDREG1
JRST TPOPJ##
;ROUTINE TO SET UP INTERRUPT VECTOR, JSR
SETIVI: MOVEI T2,TKBVIN##(W) ;SET UP JSR IN ICWA+3
HRLI T2,(XPCW)
MOVE T3,TKBICP##(W)
MOVEM T2,3(T3) ;FOR VECTORED INTERRUPTS
MOVE T2,TKBIVI##(W) ;RESET INTERRUPT VECTOR ADDRESS
XCT TKBDOS##(W)
POPJ P, ;AND RETURN
;HERE AFTER SENSE COMPLETES WHICH WAS DONE TO READ REGS 7-10
RDREG2: MOVSI T1,T78REG##+6+22(U) ;ZERO THE EXTENDED SENSE AREA
HRRI T1,T78REG##+6+23(U) ; IN CASE WE DONT DO AN EXTENDED SENSE
SETZM -1(T1) ; OR WE DO ONE AND IT FAILS
BLT T1,T78REG##+6+22+16(U)
MOVEI T1,T78REG##+6+7(U)
HRLI T1,-3 ;WHAT TO READ
MOVSI T2,070000
PUSH P,T1 ;RDREG1 EXITS TPOPJ
PJRST RDREG1
;HERE TO READ REGS ON SUCCESSFUL READ
RDREG3: PUSH P,T2
PUSHJ P,RDREGS ;READ (MOST) REGISTERS
MOVSI T2,T78ICS##+6+7(U) ;COPY REGS 7-10 FROM WHERE WE READ THEM
HRRI T2,T78REG##+6+7(U) ; TO THE FEP AREA (ELSE WE HAVE TO SENSE AGAIN)
BLT T2,T78REG##+6+11(U) ; AND THESE REGISTERS DON'T CHANGE
JRST T2POPJ##
;TABLES TO CONTROL IO
TB.DAT==1B0
TB.WRT==1B1
TB.REV==1B2
TB.SPC==1B3
TB.RD==1B4
TB.ERA==1B5
TB.WTM==1B6
TB.REW==1B7
TB.RRG==1B8 ;NOT IN TABLE, LIGHTS ON SENSE FROM RDREG
TB.XSN==1B9 ;NOT IN TABLE, LIGHTS AFTER SENSE IF WE DO EXTENDED SENSE
FNCTBL: 0 ;0 - ILLEGAL
TB.DAT!TB.RD!DF.RED!1B17 ;1 - READ FORWARD
TB.WRT!TB.DAT!DF.WRT!2B17 ;2 - WRITE
TB.DAT!TB.RD!TB.REV!DF.RRV!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!DF.ERG!10B17 ;10 - ERASE
TB.WRT!DF.DSE!11B17 ;11 - DATA SECURITY ERASE
TB.REW!TB.REV!DF.REW!12B17 ;12 - REWIND
DF.UNL!13B17 ;13 - REW, UNLOAD
TB.WRT!TB.WTM!DF.WTM!14B17 ;14 - WRITE TAPE MARK
FNCNOP: TB.SPC!DF.NOP!15B17 ;15 - YELLOW BALL
TB.DAT!TB.RD!DF.RED!16B17 ;16 - CORRECTION READ
TB.DAT!TB.RD!DF.RED!17B17 ;17 - LOW THRESHOLD READ
WT.GCR==2 ;TURN WRITE PE INTO WRITE GCR
;FRAMES/WORD,,MODE BITS
MODTBL: -1 ;0 - ILLEGAL
5,,30000 ;1 - CORE DUMP
4,,20000 ;2 - INDUSTRY COMPAT
-1 ;3 - SIXBIT
-1 ;4 - 7 BIT (ASCII)
-1 ;5 - 7-TRACK CORE DUMP
;MISC BIT DEFINITIONS
;RH20 COMPOSITE BITS
CI.ERR==CI.DBP!CI.LWC!CI.DRE!CI.RAE!CI.OVR ;CONI ERROR BITS
CO.CLR==CO.RAE!CO.TEC!CO.CCD ;CONO BITS TO CLEAR ERRORS
CS.ERR==CS.MPE!CS.NAE!CS.NXM!CS.RHE!CS.OVR ;LOGOUT-AREA ERROR BITS
IC.RRG==1B0 ;READ REGISTERS
IC.BST==1B1 ;SET A BIT IN TKBSTS
IC.DSP==1B2 ;DISPATCH TO AN ADDRESS
IC.ASY==1B3 ;ASYNCH EVENT (RETURN 0 TO TAPSER)
IC.XSN==1B4 ;DO AN EXTENDED SENSE TO GET MORE INFO
ICDTBL: IC.BST!RB.SER!RB.SED ;0 - UNDEFINED
0 ;1 - DONE
IC.BST!RB.STM ;2 - UNEXPECTED TAPE MARK
IC.BST!RB.SBT!RB.SNM ;3 - UNEXPECTED BOT
IC.BST!RB.SET ;4 - END OF TAPE
IC.BST!RB.STM ;5 - UNEXPECTED LOGICAL EOT
IC.BST!RB.SER!RB.SIL ;6 - NO OP COMPLETED
IC.ASY!IC.DSP!INTRWP ;7 - REWIND IN PROGRESS
IC.BST!RB.SLK!RB.SER!RB.SNM ;10 - WRITE TO A WRITE-LOCKED TAPE
IC.DSP!INTOFL!IC.RRG ;11 - NOT READY
IC.DSP!INTOFL!IC.RRG ;12 - DRIVE NOT AVAILABLE (ON OTHER PORT)
IC.DSP!INTOFL!IC.RRG ;13 - OFF LINE
IC.DSP!INTOFL!IC.RRG ;14 - NON-EXISTENT DRIVE
IC.BST!RB.SER!RB.SED!IC.RRG ;15 - NOT CAPABLE
IC.BST!RB.SER!RB.SED!IC.RRG ;16 - UNDEFINED
IC.ASY!IC.DSP!INTONL ;17 - DRIVE HAS COME ON LINE
IC.BST!RB.STL!RB.SER!IC.RRG ;20 - LONG RECORD
0 ;21 - SHORT RECORD
IC.BST!IC.RRG!IC.XSN!RB.SDE!RB.SED!RB.SAP ;22 - RETRY THE INITIAL OPERATION
IC.DSP!INTRRO ;23 - REREAD IN OPPOSITE DIRECTION
NRTERD: IC.BST!RB.SER!RB.SED!RB.SDE!IC.RRG!IC.XSN ;24 - UNREADABLE
NRTERV: IC.BST!RB.SER!RB.SED!IC.RRG!IC.XSN ;25 - ERROR, SER IS SET
IC.BST!RB.SET!RB.SER!RB.SED!IC.RRG!IC.XSN ;26 - ERROR AFTER EOT, SER IS SET
IC.DSP!IC.BST!BADTAP!IC.RRG!IC.XSN ;27 - BAD TAPE
IC.BST!RB.SED!RB.SNM!IC.RRG!IC.XSN ;30 - TM FAULT A
IC.DSP!IC.ASY!TUFLTA!IC.RRG!IC.XSN ;31 - TU FAULT A
IC.ASY!IC.DSP!CLRINT ;32 - TM FAULT B
ICDND1==.-ICDTBL-1
IC.ASY!IC.DSP!CLRINT!IC.RRG!IC.XSN ;33 - TU FAULT B
IC.ASY!IC.DSP!CLRINT ;34 - MASSBUS FAULT
ICDND2==.-ICDTBL-1
MAXICD==.-ICDTBL-1
REVERR==23
INTABL: DONE
INTRD ;(1)READ FORWARD
INTWRT ;(2)WRITE
INTRD ;(3)READ BACKWARDS
DONE ;(4)SKIP RECORD
DONE ;(5)BACKSPACE RECORD
TAPIFI## ;(6)SKIP FILE
TAPIFI## ;(7)BACKSPACE FILE
DONE ;(10)ERASE GAP
DONE ;(11)DATA SECURITY ERASE
INTREW ;(12)REWIND
INTUNL ;(13)UNLOAD
DONE ;(14)WRITE TAPE MARK
DONE ;(15)YELLOW BALL/ILLEGAL FUNCTIONS
INTRD ;(16)CORRECTION READ
INTRD ;(17)LOW-THRESHOLD READ
T78END: END