Trailing-Edge
-
PDP-10 Archives
-
bb-bt99q-bb
-
tm2kon.x23
There is 1 other file named tm2kon.x23 in the archive. Click here to see a list.
TITLE TM2KON - RH10/RH20/RH11 TM02/TM03(TU16/TU46/TU77) DRIVER V172
SUBTTL T WACHS/TW/TL/DPM 16-MAY-89
SEARCH F,S,DEVPRM
FTRH11==FTKS10 ;KEEP TRACK OF WHAT WE'RE DOING
SALL
.DIRECT FLBLST
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1975,1988>
TM2KON::ENTRY TM2KON
XP VTM2KN,172
TM2DMX==4 ;MAXIMUM DRIVES PER KONTROLLER
TM2HDN==TM2DMX-1 ;HIGHEST DRIVE NUMBER ON KONTROLLER
TM2ELN==16 ;SIZE OF FEP TABLE
;DRIVER CHARARCTERISTICS
; TM2 = TM2CNF
; MTA = MAGTAPE
; 0 = MAXIMUM DEVICES IN SYSTEM (NO LIMIT)
; K.TM2 = KONTROLLER TYPE
; TM2DMX = MAXIMUM DRIVES PER KONTROLLER
; TM2HDN = HIGHEST DRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (TM2,MTA,0,K.TM2,TM2DMX,TM2HDN,MDSEC0,MDSEC0,<DR.XAD!DR.MCD!DR.DPU!DR.GCC!DR.DDN>)
.ORG TKBUDB ;START OF TM02 SPECIFIC DATA
TM2UTB:! BLOCK TM2DMX ;TABLE OF POINTERS TO UDBS
TM2UVA:! BLOCK 1 ;TEMP FOR READ BACKWARDS
TM2IUM:! BLOCK TM2DMW ;IGNORE DRIVE MASK
TM2NUM:! BLOCK TM2DMW ;NEW DRIVE MASK
TM2KLN:! ;LENGTH OF KDB
.ORG
.ORG TUBLEN
TM2ICS:! BLOCK TM2ELN ;INITIAL ERROR STATUS
TM2REG:! BLOCK TM2ELN ;FINAL ERROR STATUS
TM2ULN:! ;LENGTH OF UDB
.ORG
TM2KDB: KDBBEG (TM2,TM2KLN)
SETWRD (KDBNAM,<SIXBIT/MT/>) ;KONTROLLER NAME
SETWRD (KDBIUN,<TKBUDB>) ;INITIAL POINTER TO UDBS
SETWRD (KDBCUN,<TKBUDB>) ;CURRENT POINTER TO UDBS
SETWRD (KDBIUM,<TM2IUM>) ;OFFSET TO IGNORE UNIT MASK
SETWRD (KDBNUM,<TM2NUM>) ;OFFSET TO NEW UNIT MASK
SETWRD (KDBSTS,<INSVL.(1,KD.MPT)>) ;INITIALLY ONE PATH
IFN FTMP,<SETWRD (TKBFCT,<TKBICT##>)> ;FAIRNESS COUNTER FOR QUEUED I/O
KDBEND
TM2UDB: UDBBEG (TM2,TM2ULN)
SETWRD (UDBNAM,<SIXBIT/MT/>) ;DRIVE NAME
SETWRD (TUBIEP,<-TM2ELN,,TM2ICS>) ;INITIAL ERROR POINTER
SETWRD (TUBFEP,<-TM2ELN,,TM2REG>) ;FINAL ERROR POINTER
UDBEND
EQUATE (LOCAL,0,<TM2ULP,TM2ULB>)
EQUATE (LOCAL,CPOPJ##,<TM2CMD,TM2EDL,TM2IDL,TM2LOD>)
EQUATE (LOCAL,CPOPJ2##,<TM2BSY>)
TM2ICD==TAPICD## ;PROTOTYPE INTERRUPT CODE ADDRESS
TM2ICL==TAPICL## ;PROTOTYPE INTERRUPT CODE ADDRESS
TM2INT==TAPINT## ;INTERRUPT SERVICE
TM2ELG==TPELGX## ;MAKE AN ERROR LOG ENTRY
TM2DSP: DRVDSP (TM2,TAPCHN##,TDVDDB##,TDVLEN##,TPMDIA##)
TPK (TM2,NO,16K) ;SERVICE DEPENDENT DISPATCH
TM2CKT: EXP K.TM2,0 ;COMPATIBLE KONTROLLER TABLE
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKL10 (7,270,0,0,<MD.KON>) ;RH10 DEVICE CODE 270
MDKL10 (7,274,0,0,<MD.KON>) ;RH10 DEVICE CODE 274
MDKL10 (7,360,0,0,<MD.KON>) ;RH10 DEVICE CODE 360
MDKS10 (7,RH21IV,RH21CA,0,0,<MD.KON>)
MDTERM ;TERMINATE TABLE
;SYSERR REGISTER BLOCK DEFINITIONS
E..CNI==TM2REG+0 ;RH10/20 - CONI AT ERROR
;RH11 - DO.CS2,,DO.CS1 AT ERROR
E..DTI==TM2REG+1 ;RH10/20 - DATAI CONTROL AT ERROR
;RH11 - UBA STATUS REGISTER AT ERROR
E..DT2==TM2REG+2 ;RH10/20 - DATAI DATA BUFFER AT ERROR
;RH11 - UBA MAP ENTRY AT ERROR
E..LCM==TM2REG+3 ;LAST COMMAND ISSUED
E..MBR==TM2REG+4 ;BLOCK OF MASSBUS REGISTERS AT ERRROR
;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/,<DO.'NAME==RH1020'B5> >;;RH10/20 DATAO CODE
IFN FTRH11,< IFNB /RH11/,<DO.'NAME==(RH11)> >;; RH11 WRIO OFFSET
IFNB /RH1020/,<E..'NAME==E..MBR+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
;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,TM2UVA(W) ;REAL IOWD - SAVE IT
MOVE T2,UDBPDN(U) ;PHYSICAL 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,TRBFNC(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,<
PUSH P,T1 ;SAVE IORB
MOVEI T1,CO.MBE ;DONT ALLOW INTERRUPTS (BIT IGNORED IF RH10)
XCT KDBCNO(W) ;(REWINDING DRIVE)
POP P,T1 ;RESTORE IORB
>;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,WTMBR## ;TELL MODE, DENSITY, SLAVE #, PARITY
HRLI T3,-1 ;1ST TIME THROUGH (RH SET BY WTMBR)
TM2SI2: MOVSI T2,(DO.DS) ;READ THE STATUS REGISTER OF THE SLAVE
PUSHJ P,RDMBR##
TRNN T2,DS.BOT ;BOT?
JRST TM2SI1 ;NO
.CREF TB.REV
JUMPGE P1,TM2SI1 ;YES, JUMP IF NO BACKWARD MOVEMENT
MOVSI P1,TUSBOT## ;SAW 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
TM2SI1: 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,<
MOVE T3,KDBCHN(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
HRLI T2,(DO.WC) ;LOAD THE WORD COUNT REGISTER
PUSHJ P,WTMBR##
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
>;FTRH11
MOVS T2,TM2UVA(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,@IRBACC(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,WTMBR## ;TELL IT HOW MUCH TO DO
TM2SI4:
IFE FTRH11,<
.CREF DO.CS1 ;NEXT INSTR SETS UP TO WRITE CS1 FOR SPACE OP
MOVE T2,KDBICP(W) ;ICWA
HRRZ T3,@IRBACC(T1) ;CHAN LIST
SKIPE P2 ;IF AN RH20,
TLO T3,(INSVL.(.CCJMP,CC.OPC)) ; 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,WTMBR## ;GO START UP THE WORLD
MOVEM P1,TKBFLG(W) ;REMEMBER WHAT WE ARE DOING
PUSH P,T1 ;SAVE IORB
MOVEI T3,TAPCHN##+CO.MBE ;PIA
TLNN P1,(TB.DAT) ;DATA OPERATION?
TROA T3,CO.AIE ;NO, ENABLE FOR ATTENTIONS
PUSHJ P,SETIV ;YES, SET UP INTERRUPT VECTOR
JUMPE P2,TM2SI6 ;NO SWEAT IF RH10
XCT KDBCNI(W) ;DID WE WIN IN THE SETUP?
TRNN T1,CI.RAE ;IF RAE IS LIT WE DIDN'T
JRST TM2SI6 ;ALL'S WELL
TRO T3,CO.STP ;NO, CAUSE AN IMMEDIATE INTERRUPT
PUSHJ P,SETIV ;SET UP INTERRUPT VECTOR
TM2SI6: MOVE T1,T3 ;COPY CONO BITS
XCT KDBCNO(W) ;TURN ON RH10 PI
POP P,T1 ;RESTORE IORB
>;FTRH11
IFN FTRH11,<
PUSHJ P,SETIV ;SET INTERRUPT VECTOR
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,WTMBR##
MOVSI T2,(DO.DS) ;IS IT REWINDING?
PUSHJ P,RDMBR## ;READ REGISTER
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: TRNN T2,DS.MOL ;IF OFFLINE,
JRST ILLFNC ;GIVE UP ON GETTING IT TO WORK
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,RDMBR## ;READ REGISTER
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,WTMBR## ;RESTORE TC REG
TLZ T3,-1 ;NO LONGER THE FIRST TIME THROUGH
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
;P4/ ERROR BITS
;U/ TUB FOR IO
;W/ TKB FOR IO
TM2ISR: PUSHJ P,SAVE4## ;SAVE SOME ACS
IFN FTKL10,<PUSHJ P,SVMBR##> ;SAVE CURRENT MBR FOR UUO LEVEL
SETZ P4, ;CLEAR ERROR FLAGS
PUSHJ P,SETP2 ;SET P2=0 IF RH10, =1 IF RH20, CSR IF RH11
MOVE U,@KDBCUN(W) ;UNIT WE'RE TALKING TO (MAYBE)
IFE FTRH11,<
MOVE T1,KDBCSO(W) ;GET CONI BITS AT INTERRUPT
MOVE T1,TAPCII##(T1)
TRNE T1,CI.RAE ;REGISTER ACCESS ERROR?
JRST TM2IN3 ;YES, GO CLEAR IT AND RETRY
>;FTRH11
IFN FTRH11,<
MOVSI T2,(DO.DS) ;READ A TM REGISTER
PUSHJ P,RDMBR##
RDIO T2,<(DO.CS2)>(P2) ;GET TM STATUS
TRNE T2,D2.NXD ;TM 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,RDMBR## ;READ REGISTER
MOVEM T2,E..TC(U) ; SO READ AND SAVE IT NOW
MOVSI T2,(DO.DS) ;READ STATUS REGISTER NOW, TALKING
PUSHJ P,RDMBR## ; TO TC REG LATER MAY CHANGE IT
PUSH P,T2 ;SAVE STATUS REG
MOVSI T2,(DO.AS) ;READ THE ATTN SUMMARY REGISTER
PUSHJ P,RDMBR##
ANDI T2,377 ;JUST THE ATTENTION BITS
TDNN T2,KDBUNI(W) ;ATTEN FOR THIS KDB?
JRST TM2IN2 ;NO
HRRZ T2,KDBUNI(W) ;YES. GET THE CORRECT BIT
HRLI T2,(DO.AS) ;CLEAR THE BIT
PUSHJ P,WTMBR##
PUSHJ P,DRVPLX ;POLL THE DRIVES FOR REW DONE
;HERE AFTER THE ATTENTION (IF ANY) IS HANDLED
TM2IN2: MOVE T2,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
HRLI T2,(DO.TC) ;SET TO RECONNECT TO DRIVE, DRVPOL MIGHT HAVE
PUSHJ P,WTMBR## ; 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 KDBDTI(W) ;DATAI
HLL T3,T2 ;SAVE (DBTO,CBTO)
MOVE T2,T1 ;SAVE T1
XCT KDBCNI(W) ;CONI
EXCH T2,T1 ;RESTORE T1, GET RESULTS
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,KDBICP(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,RDMBR## ;(ONLY CALL RDMBR 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 P4,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 P4,RB.SNM!RB.SED;TAPE DIDN'T MOVE
NOMOVE: TLO P4,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 P4,RB.STM ; TELL TAPUUO WHAT WE SAW
NOTM: TLNE P1,(TB.WRT) ;IF WRITING,
TRNN T4,DS.EOT ;AND WE SAW EOT
CAIA
TLO P4,RB.SET ;TELL TAPUUO
TM2GO: JRST @INTABL(P3) ;GO TO SPECIFIC INTERRUPT HANDLER
INTABL: IFIW TAPIFI## ;(00) ILLEGAL
IFIW INTRD ;(01) READ FORWARD
IFIW INTWRT ;(02) WRITE
IFIW INTRD ;(03) READ BACKWARDS
IFIW INTSPC ;(04) SKIP RECORD
IFIW INTSPC ;(05) BACKSPACE RECORD
IFIW INTSPC ;(06) SKIP FILE
IFIW INTSPC ;(07) BACKSPACE FILE
IFIW INTERA ;(10) ERASE GAP
IFIW TAPIFI## ;(11) DATA SECURITY ERASE
IFIW INTREW ;(12) REWIND
IFIW INTUNL ;(13) UNLOAD
IFIW INTWTM ;(14) WRITE TAPE MARK
IFIW INTNOP ;(15) YELLOW BALL/ILLEGAL FUNCTIONS
IFIW INTRD ;(16) CORRECTION READ
IFIW 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,RDMBR##
MOVEM T2,TRBRCT(T1) ;SAVE CHAR-COUNT OF RECORD
MOVEM T2,TUBCCR(U)
ADDM T2,TUBCRD(U) ;UPDATE TOTAL STATS
ADDM T2,TKBCRD(W)
ADDM T2,.CPTFI##
CAMLE T2,TKBCHR(W) ;TOO LARGE A RECORD?
TLO P4,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,TM2UVA(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 <MOVE T3,@P1> ;GET 2 WORDS
EXCTUX <MOVE T1,@P3>
EXCTXU <MOVSM T3,@P3> ;SWAP HALVES AND INVERT ORDER
EXCTXU <MOVSM T1,@P1>
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 <MOVSS @P1> ; 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: IORM P4,TRBSTS(T1) ;STORE ERROR BITS IN THE IORB
TRBEXC: MOVSI T2,RB.EXC
TLZE P4,-1 ;ANY FUNNY THINGS?
IORM T2,TRBFNC(T1) ;YES, AN EXCEPTION HAS OCCURRED
IFE FTRH11,<
CLRCTL: PUSH P,T1 ;SAVE IORB
MOVE T1,[CO1CLR
CO.CLR+CO.MBE](P2)
MOVE T2,KDBCSO(W) ;GET CONI BITS AT INTERRUPT
MOVE T3,TAPCII##(T2)
TRZE T3,CI.DON ;DONE LIT?
TRO T1,CO.CCD ;YES, CLEAR IT ALSO
MOVEM T3,TAPCII##(T2)
XCT KDBCNO(W)
SKIPA ;ONWARD
CLRCTX: PUSH P,T1 ;SAVE T1
MOVEI T1,TAPCHN##+CO.AIE+CO.MBE ;ENABLE FOR INTERRUPTS
XCT KDBCNO(W)
SETZM TKBFLG(W) ;NOTHING HAPPENING NOW
POP P,T1 ;RESTORE T1
POPJ P, ;AND RETURN
>;FTRH11
IFN FTRH11,<
CLRCTL: MOVEI T2,D2.CLR ;CLEAR ALL ERRORS
WRIO T2,<(DO.CS2)>(P2);
CLRCTX: MOVE T2,[DO.CS1+DC.IE] ;ENABLE FOR INTERRUPTS
PUSHJ P,WTMBR##
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,TKBCWR(W)
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 P4,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,RDMBR## ;THAT WILL HANG SOME TM03'S
TRNN T2,DS.PIP
PUSHJ P,CLRDRV ;CLEAR THE DRIVE
HLLZ P4,TRBSTS(T1) ;GET ERROR BITS
MOVSI T2,TKSOFL## ;DRVPOL MAY HAVE CLEARED TKSOFL
TLNE P4,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 P4,RB.SNM!RB.SED ;YES, NO TAPE MOTION+ERROR
JRST TRBSTO
CHNER1: HRRZ T2,KDBUNI(W) ;YES. GET BIT TO CLEAR
HRLI T2,(DO1CRA) ;CLEAR REG ACCESS ERROR
PUSHJ P,WTMBR##
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,CHENXM## ;SET TO CALL RIGHT ROUTINE
MOVSI T4,IOCHNX ;ASSUMING NXM
TDNN T2,[CI1NXM,,
CS.NXM](P2)
PUSHJ P,[MOVEI T3,CHEMPE## ;NO--SET FOR MEMORY PARITY
MOVSI T4,IOCHMP ; ...
POPJ P,]
MOVE T1,KDBICP(W) ;T1=ICWA
MOVE P1,KDBCHN(W) ;P1=CDB
MOVE 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,<
MOVE T3,KDBCHN(W) ;GET CHANNEL DATA BLOCK
MOVEI T2,UNBTMO!UNBBME
BSIO T2,@CHNUBA(T3) ;CLEAR POSSIBLE UBA ERRORS
>;FTRH11
TLO P4,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 P4,RB.SOL ;OFFLINE IF UNSAFE IS UP
TLO P4,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 P4,RB.SED ;PLAIN ERROR
TLO P4,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,WTMBR##
DRVPOL: PUSH P,T4 ;SAVE T4
PUSHJ P,DRVPLX
PJRST T4POPJ## ;RESTORE T4 AND RETURN
DRVPLX: PUSHJ P,SAVE4## ;SAVE SOME ACS
SETZ P4, ;SET A FLAG
PUSH P,U ;SAVE U
MOVE T4,KDBIUN(W) ;POINTER TO UDB TABLE
ADDI T4,(P1) ;INDEX INTO TABLE
MOVE T4,(T4) ;FETCH ENTRY (UDB ADDRESS)
DRVPL5: MOVSI T2,(DO.DS) ;READ STATUS REG
PUSHJ P,RDMBR##
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,WTMBR##
MOVSI T2,(DO.DT) ;GET THE DRIVE TYPE
PUSHJ P,RDMBR##
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 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,WTMBR##
MOVSI T2,(DO.DT) ;GET THE DRIVE TYPE
PUSHJ P,RDMBR##
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
MOVE T2,KDBCUN(W) ;DONT CLEAR THAT DRIVE
CAMN 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,WTMBR##
MOVSI T2,(DO.DS)
PUSHJ P,RDMBR## ;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,WTMBR##
FNDCL1: AOBJN P1,FNDCLR ;CLEAR NEXT DRIVE
CAIGE P4,3 ;TRIED ENOUGH TIMES?
AOJA P4,DRVPL5 ;NO, KEEP TRYING
IFE FTRH11,<
PUSH P,T1 ;YES, SAVE TM03 NUMBER
MOVEI T1,CO.MBI ;THE TM03 MUST BE HUNG
XCT KDBCNO(W) ;MASSBUS INIT IS THE ONLY WAY
JUMPE P2,DRVPL9 ;EASY IF RH10
MOVEI T1,CO.MBE ;ENABLE MASSBUS TRANSMITTERS
XCT KDBCNO(W) ;BUT DON'T ENABLE INTERRUPTS TILL LATER
PUSHJ P,SETIV ;RESTORE INTERRUPT VECTOR
DRVPL9: POP P,T1 ;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
PUSHJ P,SETIV ;RESTORE INTERRUPT VECTOR
>;FTRH11
DRVPL2: MOVE T4,KDBIUN(W) ;POINTER TO UDB TABLE
DRVPL3: PUSHJ P,DRVKNO ;DO WE KNOW ABOUT THIS DRIVE?
JRST DRVPL4 ;NO
MOVSI P3,TKSOFL## ;BIT TO TEST
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: CAMGE T4,KDBFUN(W) ;FINAL UDB?
AOJA T4,DRVPL3 ;LOOP FOR MORE
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
;HERE TO SEE IF THE DRIVE IN QUESTION IS KNOWN
DRVKNO: MOVE T2,T4 ;COPY UDB TABLE ADDRESS
SUB T2,KDBIUN(W) ;COMPUTE PHYSICAL DRIVE NUMBER
HRLI T2,(DO.TC) ;TAPE TRANSPORT REGISTER
PUSHJ P,WTMBR## ;CONNECT TO THAT DRIVE
MOVSI T2,(DO.DS) ;DRIVE STATUS REGISTER
PUSHJ P,RDMBR## ;READ IT
SKIPE U,(T4) ;POINT TO UDB FOR SELECTED DRIVE
JRST CPOPJ1## ;WE KNOW ABOUT THIS ONE
MOVSI T2,(DO.DT) ;DRIVE TYPE REGISTER
PUSHJ P,RDMBR## ;READ REGISTER
TRNN T2,DT.SPR ;SLAVE PRESENT?
POPJ P, ;NO
MOVE T2,T4 ;COPY UDB TABLE ADDRESS
SUB T2,KDBIUN(W) ;COMPUTE PHYSICAL DRIVE NUMBER
MOVE T2,BITTBL##(T2) ;TRANSLATE TO APPROPRIATE BIT
TDNN T2,TM2IUM(W) ;WANT TO IGNORE THIS DRIVE?
IORM T2,TM2NUM(W) ;MARK NEW DRIVE TO CONFIGURE
HRRZS KDBNUM(W) ;ASSUME NOT THERE
SKIPE TM2NUM(W) ;DRIVES TO CONFIGURE?
HRROS KDBNUM(W) ;FLAG IT
POPJ P, ;SAY NO DRIVE (WILL CONFIGURE LATER)
SUBTTL AUTO-CONFIG
TM2CFG:
IFN FTKL10,<
CAIL T1,FSTICD/4 ;AN RH20?
CAILE T1,LSTICD/4 ;...
JRST TM2CF1 ;PERHAPS AN RH10
TLNE T2,(CI.PPT) ;IPA CHANNEL?
JRST CPOPJ1## ;YES
MOVSI T1,CP.RH2 ;RH20 CHANNEL
JRST TM2CF2 ;ONWARD
TM2CF1:
> ;END IFN FTKL10
XMOVEI T1,TM2MDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;DEFAULT TABLE
MOVSI T3,-1 ;MATCH ON ANY MASSBUS UNIT
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
PUSHJ P,AUTMDT## ;SCAN THE TABLES
JRST CPOPJ1## ;NO MATCHES
IFN FTKL10,<
XCT .CPCNI## ;GET CONI ,T1
TLNN T1,4000 ;CHECK FOR DF10 OR DF10C IN 18-BIT MODE
JRST AUTEBD## ;18-BIT DF10/DF10C, INFORM OF ERROR AND RETURN
MOVSI T1,0 ;RH10 CHANNEL
>; END IFN FTKL10
IFN FTKS10,<MOVSI T1,CP.R11> ;RH11 CHANNEL
TM2CF2: PUSHJ P,AUTCHN## ;BUILD A CHANNEL DATA BLOCK
POPJ P, ;NO CORE
IFN FTKS10,<
LDB T1,[POINT 3,.CPDVC##,17] ;GET UNIBUS ADAPTER NUMBER
MOVEI T2,20 ;NUMBER OF MAPPING REGISTERS REQUIRED
PUSHJ P,AUTAMR## ;ALLOCATE MAPPING REGISTERS
POPJ P, ;OOPS
MOVE T4,.CPCHA## ;GET CHANNEL DATA BLOCK ADDRESS
MOVEM T1,CHNIMR(T4) ;STORE INITIAL MAPPING REGISTERS
MOVEM T2,CHNMRC(T4) ;STORE NUMBER OF MAPPING REGISTERS
MOVEM T3,CHNIEA(T4) ;STORE INITIAL ELEVEN ADDRESS
>; END IFN FTKS10
PUSHJ P,SAVE2## ;SAVE P1-P2
SETZ P1, ;MASSBUS UNIT NUMBER 0, DRIVE 0
TM2CF3: PUSHJ P,TM2UNI ;AUTOCONFIGURE A SINGLE RH20 UNIT
HLLOS P1 ;RESET DRIVE NUMBER
AOBJN P1,.+1 ;ADVANCE TO NEXT MASSBUS UNIT
TLNN P1,10 ;CHECKED ALL UNITS?
JRST TM2CF3 ;LOOP BACK FOR ANOTHER
IFN FTRH11,<PUSHJ P,CLRCTL> ;CLEAR THE RH11
JRST CPOPJ1## ;TRY ANOTHER DEVICE ON SAME CHANNEL
;AUTOCONFIGURE A SINGLE MASSBUS UNIT
TM2UNI: PUSHJ P,RDDTR## ;READ DRIVE TYPE REGISTER
CAIL T2,TY.T2L ;RANGE CHECK
CAILE T2,TY.T2H ; FOR TM02
CAIL T2,TY.T3L ;RANGE CHECK
CAILE T2,TY.T3H ; FOR TM03
POPJ P, ;NOT A TM02/TM03
HLRZ T1,P1 ;GET MASSBUS UNIT NUMBER
PUSHJ P,AUTKDB## ;BUILD A KDB
POPJ P, ;GIVE UP IF NO CORE
PUSHJ P,SETP2 ;SETUP P2 WITH CONTROLLER TYPE
SETZB T1,T2 ;NO KONTROLLER SERIAL NUMBER
PUSHJ P,AUTKSN## ;DUMMY ONE UP AND STORE IT
IFN FTKL10,<
PUSHJ P,TAPCSA## ;SET UP CSO CONI ADDRESS
MOVEI T1,CO.MBI ;CLEAR ANY PENDING INTERRUPTS
XCT KDBCNO(W) ;CONO
MOVEI T1,CO.MBE ;MASSBUS ENABLE
XCT KDBCNO(W) ;CONO
PUSHJ P,TM2ONL ;IF NOT THERE
POPJ P, ; DON'T SET UP CONSO MASK
> ;END IFN FTKL10
PUSHJ P,SETIV ;SET UP INTERRUPT VECTOR
MOVSI T2,(DO.DT) ;GET DRIVE TYPE REGISTER
PUSHJ P,RDMBR## ;...
TRNN T2,TR.DRQ ;DRIVE REQUEST REQUIRED (DUAL PORTED)?
JRST TM2UN1 ;NO
MOVEI T2,2 ;THERE CAN BE TWO PATHS
DPB T2,[POINTR (KDBSTS(W),KD.MPT)] ;STORE COUNT
MOVSI T2,(KD.MPD) ;GET MULTI-PORTED BIT
IORM T2,KDBSTS(W) ;LITE FOR FUTURE REFERENCE
TM2UN1: MOVNI P3,1 ;INIT DRIVE NUMBER
TM2UN2: PUSHJ P,TM2DRV ;AUTOCONFIGURE A SINGLE DRIVE
JFCL ;IGNORE ERRORS
HRRZ T1,P1 ;GET DRIVE NUMBER
CAIGE T1,TM2HDN ;DONE ALL DRIVES?
AOJA P1,TM2UN2 ;LOOP BACK FOR MORE
POPJ P, ;DONE
;AUTOCONFIGURE A SINGLE DRIVE
TM2DRV: HRRZ T1,P1 ;GET UNIT
MOVE T1,BITTBL##(T1) ;AND IT'S BIT
TDNE T1,TM2IUM(W) ;WANT TO IGNORE THIS DRIVE?
POPJ P, ;SAY IT DOESN'T EXIST
IFN FTKL10,<
MOVE T1,KDBCSO(W) ;GET TAPICD BLOCK ADDRESS
SETZM TAPCII##(T1) ;DON'T CONFUSE CLRCTL
>
PUSHJ P,CLRCTL ;RESET CONTROLLER
HRRZ T2,P1 ;DRIVE NUMBER
HRLI T2,(DO.TC) ;SET TO TALK TO THIS DRIVE
PUSHJ P,WTMBR## ;WRITE REGISTER
MOVSI T2,(DO.DT) ;DRIVE TYPE REGISTER
PUSHJ P,RDMBR## ;READ REGISTER
TRNN T2,DT.SPR ;SLAVE PRESENT?
PJRST CLRCTL ;NO, CLEAR CONTROLLER AND RETURN
HRRZ T1,P1 ;GET DRIVE NUMBER
SETCA T1,BITTBL##(W) ;TRANSLATE DRIVE NUMBER TO A BIT
SETZ T2, ;ASSUME NO OTHER NEW DRIVES
SYSPIF ;AVOID RACE WITH INTERRUPT LEVEL
ANDB T1,TM2NUM(W) ;CLEAR SINCE DRIVE IS NO LONGER "NEW"
SKIPE T1 ;WORK PENDING FOR OTHER DRIVES?
MOVNI T2,1 ;YES
HLLM T2,KDBNUM(W) ;UPDATE FLAG
SYSPIN ;RELEASE INTERLOCK
MOVSI T2,(DO.SN) ;MASSBUS REGISTER
PUSHJ P,RDMBR## ;READ DRIVE SERIAL NUMBER
SETZ T1, ;REALLY A ONE WORD QUANTITY
HRRZ T3,P1 ;GET PHYSICAL DRIVE NUMBER
PUSHJ P,AUTDSN## ;FAKE UP S/N IF A ZERO & SAVE TEMPORARILY
HRRZ T3,P1 ;GET PHYSICAL DRIVE NUMBER
PUSHJ P,AUTDPU## ;LINK UP DUAL PORTED DRIVES
JFCL ;MUST PROCEED EVEN IF DUAL PORTED
HRLZ T1,P1 ;PHYSICAL DRIVE NUMBER
HRR T1,P1 ;UDB TABLE INDEX
PUSHJ P,RDDTN## ;GET DRIVE TYPE NAME
MOVE T4,T2 ;COPY TO A BETTER PLACE
MOVEI T2,TUCFOI##+TUCIRD##+TUCD80##+TUCD16##+K.TM2
XMOVEI T3,HNGTBL ;POINT TO HUNG TIMER TABLE
PUSHJ P,TAPDRV## ;BUILD AND LINK UP UDB AND DDB
JFCL ;FAILED
DMOVE T1,.CPTSN## ;RETRIEVE DRIVE SERIAL NUMBER
DMOVEM T1,UDBDSN(U) ;SAVE IN UDB
MOVEM T2,E..SN(U) ;SAVE FOR DIAGNOSTICS
MOVE T2,UDBPDN(U) ;PHSICAL DRIVE NUMBER
HRLI T2,(DO.TC) ;SELECT RIGHT SLAVE
PUSHJ P,WTMBR## ;DATAO
MOVSI T2,(DO.DS) ;READ STATUS REG
PUSHJ P,RDMBR## ;DATAI
MOVSI T3,TKSOFL## ;BIT TO SET
TRNN T2,DS.MOL ;IF NOT MEDIUM-ON-LINE
IORM T3,TUBSTS(U) ; THE DRIVE IS OFF-LINE
PUSHJ P,CLRCTL ;RESET CONTROLLER
JRST CPOPJ1## ;RETURN
SUBTTL CHECK ON-LINE STATUS
;HERE TO CHECK IF ON-LINE
TM2ONL:
IFE FTRH11,<XCT KDBCNI(W)>
PUSHJ P,SAVST2 ;SETUP P2 (IF KL, DOES CONO)
PUSH P,T1 ;SAVE T1
IFN FTRH11,<
MOVE T1,P2 ;GET IO ADDRESS OF RH11
PUSHJ P,UBGOOD## ;BE SURE IT IS THERE
JRST TPOPJ## ;OFF-LINE
MOVSI T2,(DO.DS) ;READ A TM REGISTER
PUSHJ P,RDMBR##
RDIO T2,<(DO.CS2)>(P2) ;GET STATUS REGISTER
TRNN T2,D2.NXD ;IS TM03 THERE?
JRST TM2ON1 ;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
JRST TPOPJ## ;OFF-LINE RETURN
TM2ON1:
>;FTRH11
MOVSI T2,(DO.DT)
PUSHJ P,RDMBR## ;READ DRIVE-TYPE
ANDI T2,730
CAIN T2,10 ;LEGAL?
AOS -1(P) ;YES. SKIP-RETURN
POP P,T3 ;GET SAVED STATUS
IFE FTRH11,<
MOVEI T1,CO.AIE+TAPCHN## ;PIA AND ATTN ENABLE
SKIPE P2
TRO T1,CO.MBE+CO.RAE
TRNN T3,CO.AIE ;WERE ATTENS ENABLED?
TRZ T1,CO.AIE ;NO, DON'T ENABLE THEM NOW
XCT KDBCNO(W)
>;FTRH11
SKIPE T1,TM2NUM(W) ;GET BIT MASK
JFFO T1,TM2ON2 ;FIND FIRST UNIT NUMBER
HRRZS KDBNUM(W) ;INDICATE NO DRIVES TO CONFIGURE
POPJ P, ;DONE
TM2ON2: PUSHJ P,AUTLOK## ;GET AUTCON INTERLOCK
JRST CPOPJ1## ;TRY AGAIN NEXT TIME
MOVEI P1,(T2) ;GET PHYSICAL DRIVE NUMBER
HLL P1,KDBUNI(W) ;INCLUDE MASSBUS UNIT
MOVE T1,KDBDVC(W) ;DEVICE CODE
XMOVEI T2,TM2DSP ;DISPATCH
MOVE T3,KDBCHN(W) ;CHANNEL DATA BLOCK
PUSHJ P,AUTSET## ;SET UP CPU VARIABLES
PUSHJ P,TM2DRV ;TRY TO CONFIGURE A DRIVE
JFCL ;IGNORE ERRORS
PJRST AUTULK## ;RELEASE AUTCON INTERLOCK AND RETURN
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,RDMBR##
MOVEM T2,E..TC(U)
PUSHJ P,RDREGS ;READ OTHER REGS
>;FTRH11
PUSHJ P,CLRDRV
TM2RS1: PUSHJ P,SETIV ;SET UP INTERRUPT VECTOR
IFE FTRH11,<
PUSH P,T1 ;SAVE T1
MOVEI T1,CO.STP ;CLEAR BUSY, SET DONE
XCT KDBCNO(W) ;DO IT
POP P,T1 ;RESTORE T1
>;FTRH11
JRST CLRCTX ;CLEAR RH10 AND RETURN
;ROUTINE TO SET UP INTERRUPT VECTOR
SETIV: PUSH P,T1 ;SAVE T1
IFN FTKL10,<
PUSH P,T2 ;SAVE T2
MOVE T2,KDBIVI(W) ;WHERE TO INTERRUPT TO
XCT KDBDTO(W) ;TELL THE HARDWARE
MOVE T1,KDBVIN(W) ;SET UP VECTORED INTERRUPT ADDRESS
HRLI T1,(XPCW) ;MAKE AN XPCW INSTRUCTION
MOVE T2,KDBICP(W)
MOVEM T1,3(T2) ;IN ICWA+3
POP P,T2 ;RESTORE T2
> ;END IFN FTKL10
IFN FTKS10,<
MOVE T1,KDBVIN(W) ;GET ADDRESS OF VECTOR ROUTINE
HRLI T1,(XPCW) ;INTERRUPT INSTRUCTION IS AN XPCW
MOVEM T1,@KDBIVI(W) ;SAVE IN VECTOR INTERRUPT TABLE
> ;END IFN FTKS10
JRST TPOPJ## ;RESTORE T1 AND RETURN
;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,<
MOVE P2,KDBDVC(W) ;GET DEVICE CODE
CAIL P2,FSTICD/4 ;RH20?
CAILE P2,LSTICD/4
TDZA P2,P2 ;NO, P2=0
MOVEI P2,1 ;YES, P2=1
JUMPE P2,CPOPJ## ;GO IF AN RH10
PUSH P,T1 ;SAVE T1
MOVEI T1,CO.MBE ;RH20, ENSURE THAT MASSBUS IS ENABLED
XCT KDBCNO(W)
POP P,T1 ;RESTORE T1
>;FTRH11
IFN FTRH11,<
MOVE P2,KDBDVC(W) ;GET RH11 REGISTER ADDRESS
>;FTRH11
POPJ P, ;AND RETURN
IFE FTRH11,<
;ROUTINE TO READ REGISTERS ON ERROR
RDREGS: PUSH P,T1 ;SAVE T1
XCT KDBCNI(W)
MOVEM T1,E..CNI(U) ;SAVE CONI
POP P,T1 ;RESTORE T1
MOVE T2,[DO1CRC
.DOPTC](P2)
PUSHJ P,RDMBR##
MOVEM T2,E..DTI(U) ;DATAI RH10 CNTRL REG
MOVE T2,[DO1CDB
.DOPBA](P2)
PUSHJ P,RDMBR##
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-1> (TC READ AT TM2INT)
MOVSI T2,(DO.CS1) ;STARTING HERE
RDREG1: PUSH P,T2 ;SAVE REGISTER NUMBER
PUSHJ P,RDMBR##
MOVEM T2,(T1) ;STORE DATA IN UDB
POP P,T2 ;GET REGISTER NUMBER BACK
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,KDBCHN(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-1> (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),<ZZ==<ZZZ==0>
IRP A,<IFE <ZZ-6>,<EXP ZZZ
ZZ==<ZZZ==0>>
ZZZ==ZZZ!<('A')>B<5+<ZZ*6>>
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 <DO.CS1,DO.DS,DO.ER,DO.MR,DO.AS,DO.FC,DO.DT,DO.CK,DO.SN,DO.TC>
>;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
TB.SPC!DF.SPF!6B17 ;6 - SKIP FILE
TB.SPC!TB.REV!DF.SPR!7B17 ;7 - BACKSPACE FILE
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
;HUNG TIMER TABLE
EXP ^D150 ;MAXIMUM TIMEOUT VALUE
HNGTBL: BYTE(9) ^D000,^D031,^D031,^D031 ;IL,RD,WT,RB
BYTE(9) ^D031,^D031,^D000,^D000 ;SR,BR,SF,BF
BYTE(9) ^D031,^D000,^D150,^D150 ;LG,SE,RW,RU
BYTE(9) ^D031,^D031,^D031,^D031 ;TM,YB,CR,RL
IFN FTRH11,<TRHEND:>
TM2END: END