1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-02 09:37:06 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

1336 lines
43 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE TM2KON - RH10/RH20/RH11 TM02/TM03(TU16/TU46/TU77) DRIVER V165
SUBTTL T WACHS/TW/TL/DPM 9-AUGUST-88
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 VTM3KN,165
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,<-1,,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
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,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,<
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,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,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,TRBXCW(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,.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,TRBLNK(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,.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
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: PUSHJ P,RDMBR##
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,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