Google
 

Trailing-Edge - PDP-10 Archives - AP-4178E-RM - swskit-sources/phyx2.mac
There are 47 other files named phyx2.mac in the archive. Click here to see a list.
;<3A.MONITOR>PHYX2.MAC.14,  5-Sep-78 10:33:15, EDIT BY FORTMILLER
;Just read ASYNCHRONOUS Status Register smashed in routine ASYNST
;<3A.MONITOR>PHYX2.MAC.13, 31-Aug-78 23:12:41, EDIT BY FORTMILLER
;Fix KEEP ALIVE CEASED by checking for the DX20 run bit to be set
; in GTSNS
;<3A.MONITOR>PHYX2.MAC.12, 29-Aug-78 10:00:01, EDIT BY FORTMILLER
;No space found error being ignored for PHYALC and PHYUDB
;<3A.MONITOR>PHYX2.MAC.11, 22-Aug-78 14:13:22, EDIT BY FORTMILLER
;Set US.REW in the attention code rather then in START I/O
;<3A.MONITOR>PHYX2.MAC.10, 15-Aug-78 08:59:05, Edit by FORTMILLER
;Fix bug implemented in edit before last associated with off-line
;<3A.MONITOR>PHYX2.MAC.9, 11-Aug-78 08:40:14, Edit by FORTMILLER
;Do a mode set before each WRITE type operation on TU70 and TU72
; drives. This is necessary because a user might write on a tape and
; manually unload it then a another user might decide to write on the
; same drive at a different density but his tape will be written at
; the density of the last user. The reason for having to do a mode set
; is because the MANUAL UNLOAD does NOT cause an attention interrupt
; so the UDB status never gets updated
;<3A.MONITOR>PHYX2.MAC.8, 10-Aug-78 16:39:04, Edit by FORTMILLER
;Don't set the US.OFS (offline) bit in the UDB on an ASYNC interrupt.
; If an unload was done and the drive was powered off we would get an
; attention interrupt and find the drive offline but when the drive
; is powered up again there is no attention interrupt given so the
; offline bit never got cleared in the UDB.
;<3A.MONITOR>PHYX2.MAC.7, 10-Aug-78 08:35:18, Edit by FORTMILLER
;Change NUMDRV from 16 to 8
;<3A.MONITOR>PHYX2.MAC.6,  4-Aug-78 12:15:40, Edit by FORTMILLER
;Add a BUGCHK - DX2HLT If the DX20 is discovered not running and
; print out the contents of DXGP6 which contains an error code
; Only check for legal data mode in Start I/O if a data type operation
;<3A.MONITOR>PHYX2.MAC.5,  1-Aug-78 14:33:10, Edit by FORTMILLER
;Remove BUGCHK at ENDLOD and fix bug in checking whether a mode
; set needs to be done for a TU71
;<3A.MONITOR>PHYX2.MAC.4, 14-Jul-78 09:13:57, Edit by FORTMILLER
;Information printed from AC T1 during BUGCHK DX2NUE is garbage
;<3A.MONITOR>PHYX2.MAC.3, 13-Jul-78 16:04:35, Edit by FORTMILLER
;Add BUGCHK if SYSERR block at ENDLOD doesn't have any beginning data in it
; On some of the BUGs print out interesting AC information
;<3A-NEW>PHYX2.MAC.2,  1-Jun-78 20:19:03, Edit by FORTMILLER
;<3A-NEW>PHYX2.MAC.1, 30-May-78 10:45:29, Edit by FORTMILLER
;MAKE MANY CHANGES FOR 3A
;<DX20-101B-SOURCES>PHYDX2.MAC.4, 14-Jun-77 08:48:05, Edit by OUYANG

	SEARCH PROLOG,PHYPAR,SERCOD ;SYSTEM PARAMETERS
	TTITLE (PHYX2,,< - DEVICE DEPENDENT CODE FOR DX20/TU70S MAGTAPES VER 1>)
	SUBTTL E. OUYANG/Ed Fortmiller  24 FEB 78

	DX2VER==1		;EDIT VERSION

	ENTRY DX2DSP		;FOR LIBRARY SEARCH

;	For information on how to program the DX20/TU7x, see
;	document 105-220-001-00 DX20-v100 Microcode by Steve
;	Paavola.

PHYX2:				;BEGINNING ADDRESS OF PHYX2
	SUBTTL DEVICE DEPENDANT TABLE DEFS

;DX20 STARTING ADDRESS

	STADDR==6		;DX20 STARTING ADDRESS
	NUMDRV==^D8		;NUMBER OF TAPE DRIVES PER DX20

;UDB EXTENSIONS

	U.EPOS==UDBDDP		;ERROR POSITION
	U.EBP==U.EPOS+1		;ERROR BYTE POINTER
	E.EBC==U.EBP+1		;ERROR BYTE COUNTER
	U.ETCF==E.EBC+1		;TAPE CLEANER FLAG
	U.ETIE==U.ETCF+1	;TIE BYTE

	LU.DX2==U.ETIE+1	;LENGTH OF UDB

	UDB.NM==1B17		;BIT SET IN UDBERR TO INDICATE
				; A RECOVERABLE NO MOTION ERROR
;KDB DEVICE DEPENDANT PORTION

	K.DUDB==KDBDDP		;UDB TABLE (NUMDRV DRIVES LONG)
	K.DXAD==K.DUDB+NUMDRV	;MASSBUS ADDRESS OF DX20
	K.SUDB==K.DXAD+1	;CURRENT UDB (0 IF NONE)
	K.DCNI==K.SUDB+1	;CONI OF RH GOES HERE
	K.DCS1==K.DCNI+1	;DATAI RH CONTROL REGISTER
	K.DDBF==K.DCS1+1	;DATAI RH DATA REGISTER
	K.DVER==K.DDBF+1	;MICROCODE VERSION #

	K.DREG==K.DVER+1	;DRIVE REGISTERS GO HERE

DEFINE SAVREG(REGS),<
	IRP REGS,<SAVBIT==SAVBIT!<1_<^D35-REGS>>
	SAVNUM==SAVNUM+1	;COUNT NUMBER OF REGISTERS
	>;END IRP REGS
>;END DEFINE SAVREG

	SAVBIT==0		;INIT TO 0, THIS WILL HAVE A BIT SET
				; FOR EACH DX20 MASSBUS REG TO SAVE
				; IN THE KDB.
	SAVNUM==0		;INIT TO 0, THIS WILL BE A COUNT OF
				; THE NUMBER OF DX20 MASSBUS REGS
				; THAT GET SAVED IN THE KDB

	SAVREG <0,1,2,3,4,5,6,20,21,22,23,24,26,27,30,31,32,33,34,35,36,37>

	LR.DX2==SAVNUM		;NUMBER OF DX20 REGISTERS SAVED IN THE KDB

;FOLLOWING ARE THE 24(OCTAL) WORDS FOR THE EXTENDED STATUS TABLE

	K.DEST==K.DREG+^D22	;EXTENDED STATUS TABLE GOES HERE
	LK.DX2==K.DEST+^D20	;LENGTH OF DX20 KDB
	SUBTTL	MASSBUS-DX20 REGISTER DEFINITIONS

;MASSBUSS DEVICE REGISTER BIT ASSIGNMENTS (REGISTERS 00-37)

	DXCTR==0B5		;CONTROL REGISTER
	DXSTR==1B5		;STATUS REGISTER
	DXERR==2B5		;ERROR REGISTER 
	DXMTR==3B5		;MAINTAINABILITY REGISTER
	DXASR==4B5		;ATTENTION SUMMARY "PSEUDO" REGISTER
	DO.FC==5B5		;FRAME COUNT REGISTER
	DXDTR==6B5		;DRIVE TYPE AND HARDWARE VERSION REGISTER
	MBRA07==7B5		;NOT USED
	MBRA10==10B5		;NOT USED
	MBRA11==11B5		;NOT USED
	MBRA12==12B5		;NOT USED
	MBRA13==13B5		;NOT USED
	MBRA14==14B5		;NOT USED
	MBRA15==15B5		;NOT USED
	MBRA16==16B5		;NOT USED
	MBRA17==17B5		;NOT USED
	DXGP0==20B5		;GENERAL PURPOSE REGISTER 0
	DXGP1==21B5		;GENERAL PURPOSE REGISTER 1
	DXGP2==22B5		;GENERAL PURPOSE REGISTER 2
	DXGP3==23B5		;GENERAL PURPOSE REGISTER 3
	DXGP4==24B5		;GENERAL PURPOSE REGISTER 4
	DXGP5==25B5		;GENERAL PURPOSE REGISTER 5
	DXGP6==26B5		;GENERAL PURPOSE REGISTER 6
	DXGP7==27B5		;GENERAL PURPOSE REGISTER 7
	DXDR0==30B5		;DIAGNOSTICS REGISTER 0
	DXDR1==31B5		;DIAGNOSTICS REGISTER 1
	DXDR2==32B5		;DIAGNOSTICS REGISTER 2
	DXDR3==33B5		;DIAGNOSTICS REGISTER 3
	DXDR4==34B5		;DIAGNOSTICS REGISTER 4
	DXDR5==35B5		;DIAGNOSTICS REGISTER 5
	DXDR6==36B5		;DIAGNOSTICS REGISTER 6
	DXDR7==37B5		;DIAGNOSTICS REGISTER 7
	;CONTROL REGISTER DEFINITIONS (DXCTR REG. 0)

GO==1B35			;GO BIT
DEFSTR(DXFTN,T1,^D35,6)		;DX20 FUNCTON FIELD(INCLUDES GO BIT) AS IN T1

;DX20 FUNCTION CODES(INCLUDING GO BIT)

	XF.NOP==1		;NO OPERATION
	XF.UNL==3		;REWIND AND UNLOAD
	XF.REW==7		;REWIND
	XF.CLR==11		;DRIVE CLEAR
	XF.SRL==13		;SENSE RELEASE
	XF.ERA==25		;ERASE GAP
	XF.WTM==27		;WRITE TAPE MARK
	XF.SPF==31		;FORWARD SPACE RECORD
	XF.SPR==33		;BACK SPACE RECORD
	XF.SBF==35		;FORWARD SPACE BLOCK
	XF.SBR==37		;BACKWARD SPACE BLOCK
	XF.TIO==41		;TEST I/O
	XF.DSE==43		;DATA SECURITY ERASE
	XF.SNS==45		;SENSE
	XF.SNR==47		;SENSE RESERVE
;
;THE FOLLOWING ARE NON IMMEDIATE TYPE OF OPERATIONS
; AND CAUSE A COMMAND DONE INTERRUPT
;
	XF.WTF==61		;WRITE DATA
	XF.DIA==63		;WRITE DIAGNOSTIC
	XF.LWR==65		;LOOP WRITE TO READ
	XF.RDF==71		;READ DATA
	XF.RXS==75		;READ EXTENDED STATUS
	XF.RDR==77		;READ REVERSE

;STATUS REGISTER DEFINITIONS (DXSTR REG. 1)

	SR.ATA==1B20		;ATTENTION ACTIVE (CAUSES ATTN SUMMARY)
	SR.CER==1B21		;COMPOSITE ERROR (MUST CHECK ERROR REG.)
	SR.LP==1B22		;LINK PRESENT
	SR.RUN==1B23		;MICROPROCESSOR RUNNING
;ERROR REGISTER DEFINITIONS (DXERR REG. 2)

DEFSTR(ECC,T1,^D27,^D4)		;STRUCTURE FOR ERROR CLASS CODE
DEFSTR(ESCC,T1,^D23,^D4)	;STRUCTURE FOR ERROR SUB-CLASS CODE
	ER.NEW==1B28		;MICROPROCESSOR DETECTED ERROR
	ER.SPT==1B29		;MICROPROCESSOR STOPED
	ER.MPE==1B30		;MICROBUS PAR. ERROR IN MASSBUSS INTERFACE
	ER.DPE==1B31		;DATA BUFFER PAR. ERROR
	ER.CPE==1B32		;MASSBUS CONTROL BUS PAR. ERROR
	ER.RMR==1B33		;REGISTER MODIFICATION REFUSED
	ER.ILR==1B34		;TRIED TO ACCESS NON-IMPLEMENTED REG.
	ER.ILF==1B35		;TRIED TO ISSUE NON-IMPLEMENTED COMMAND

;*CLASS SUB-CLASS ERROR CODES
; NOTE SUB-CLASS ERROR CODE DEFN.S ARE INDENTED

	ER.UDS==1		;UNUSUAL DEVICE STATUS
		SER.FS==0	;FINAL STATUS SEQUENCE
		SER.IS==1	;INITIAL STATUS SEQUENCE
	ER.SR==2		;SHORT RECORD
	ER.LR==3		;LONG RECORD
	ER.DSE==4		;DRIVE SELECTION ERROR
	ER.RER==5		;RECOVERABLE ERROR(TAPE MOTION STARTED)
		SER.DP==0	;DATA PARITY ERROR
	ER.RE1==6		;RECOVERABLE ERROR(NO TAPE MOTION)
		SER.AM==0	;ADDRESS MISMATCH
		SER.B1==1	;BUS PARITY ERROR FROM DRIVE
		SER.B2==2	;BUS PARITY ERROR FROM INITIAL STATUS
	ER.NRE==7		;NON-RECOVERABLE ERROR
		SER.DP==0	;DATA PATH, MICRO BUS PARITY ERROR
		SER.CB==1	;CHANNEL BUS INTER.,MICRO BUS PARITY ERROR
	ER.FTL==^D8		;FATAL ERROR
		SER.DT==0	;DRIVE TYPE NOT MATCHING BY MICROCODE
		SER.PE==1	;PARITY ERROR DURING CONTROL UNIT INITIAL SEQUENCE
		SER.PE==2	;****SIMILAR AS ABOVE

;MAINTENANCE REGISTER DEFINITIONS (DXMTR REG. 3)

	MR.SS==1B31		;SINGLE STEP MICRO CONTROLLER
	MR.WEP==1B32		;WRITE EVEN PARITY BALU
	MR.ST==1B33		;START/STOP MICRO CONTROLLER
	MR.RES==1B34		;RESET MICRO CONTROLLER
;ATTENTION SUMMARY REGISTER DEFINITIONS (DXASR REG. 4)

	AS.7==1B28		;DRIVE-7 NEEDS ATTENTION
	AS.6==1B29		;DRIVE-6 NEEDS ATTENTION
	AS.5==1B30		;DRIVE-5 NEEDS ATTENTION
	AS.4==1B31		;DRIVE-4 NEEDS ATTENTION
	AS.3==1B32		;DRIVE-3 NEEDS ATTENTION
	AT.2==1B33		;DRIVE-2 NEEDS ATTENTION
	AT.1==1B34		;DRIVE-1 NEEDS ATTENTION
	AT.0==1B35		;DRIVE-0 NEEDS ATTENTION

;BYTE REGISTER DEFINITIONS(DO.FC REG. 5)
; USED INTERCHANGEABLY WITH REG. 25

;STATUS INDEX/ENDING STATUS REGISTER DEFINITION(DXGP0 REG.20)

ES.RES==1B28			;BIT TO REQUEST FOR EXTENDED STATUS
ES.UEX==1B27			;UNIT EXCEPTION
ES.UCK==1B26			;UNIT CHECK
ES.DVE==1B25			;DEVICE END
ES.CHE==1B24			;CHANNEL END
ES.BSY==1B23			;CONTROL UNIT OR DEVICE BUSY
ES.CUE==1B22			;CONTROL UNIT END
ES.SM==1B21			;STATUS MODIFIER
ES.ATN==1B20			;ATTENTION

;DRIVE NUMBER/MODE REGISTER DEFINITION(DXGP1 REG. 21)

DEFSTR(DRVNUM,T1,^D35,^D8)	;STRUCTURE DEFN FOR DRIVE NUMBER
DEFSTR(DRVMOD,T1,^D27,^D4)	;DRIVE MODE
DEFSTR(DATMOD,T1,^D23,^D4)	;STRUCTURE FOR DATA MODE

;DRIVE MODE VALUES

	DRV.NM==0		;NO MODE SET TO BE ISSUED
	DRV.O2==1		;7 TRACK, 200 BPI, ODD PARITY
	DRV.O5==2		;7 TRACK, 556 BPI, ODD PARITY
	DRV.O8==3		;7 TRACK, 800 BPI, ODD PARITY
	DRV.E2==5		;7 TRACK, 200 BPI, EVEN PARITY
	DRV.E5==6		;7 TRACK, 556 BPI, EVEN PARITY
	DRV.E8==7		;7 TRACK, 800 BPI, EVEN PARITY
	DRV.NR==13		;9 TRACK, 800 BPI
	DRV.PE==14		;9 TRACK, 1600 BPI
	DRV.GC==15		;9 TRACK, 6250 BPI.
	DRV.IL==77		;ILLEGAL CODE

;DATA MODE VALUES

	DAT.IL==0		;ILLEGAL CODE
	DAT.CD==1		;CORE DUMP FORMAT(9-TRACK)
	DAT.IC==2		;INDUSTRY COMPATIBLE, 4 8-BIT BYTES/WRD
	DAT.SB==3		;6 6-BIT BYTES/WRD
	DAT.AS==4		;7-BIT ASCII MODE
	DAT.HD==5		;HI DENSITY

;EXTENDED STATUS TABLE SIZE REGISTER DEFINITION (DXGP2 REG. 22)

DEFSTR(ESTSZ,T1,^D35,^D8)	;STRUCTURE FOR EXTENDED STATUS TABLE SIZE

;TRACK IN ERROR, FLAGS REGISTER DEFINITIONS (DXGP3 REG. 23)

	TE.TIE==1B27		;=1, IF TIE ERROR RECOVERY ATTEMPTED
	TE.SOP==1B26		;=1, IF SENSE OPERATION REQUIRED
	TE.SAS==1B25		;=1, IF SUPPRESS AUTOMATIC SENSE ON UNIT CHECK.

;ASYNCHRONOUS STATUS REGISTER DEFINITIONS (DXGP4 REG. 24)

;BYTE COUNT REGISTER DEFINITIONS (DXGP5 REG. 25)

	DXGP==177777B35		;MASK FOR 16 DATA BITS IN REGISTER

;EXTENDED STATUS REGISTER 0 DEFINITIONS(DXGP6 REG. 26)

	DXGP==177777B35		;MASK FOR 16 DATA BITS IN REGISTER

;EXTENDED STATUS REGISTER 1 DEFINITIONS (DXGP7 REG. 27)

	DXGP==177777B35		;MASK FOR 16 DATA BITS IN REGISTER
;DIAGNOSTIC REGISTER 0 DEFINITION (DXDR0 REG. 30)

	IR==177777B35		;MASK FOR IR REG.

;DIAGNOSTIC REGISTER 1 DEFINITION (DXDR1 REG. 31)

	D1.IRE==1B20		;ENABLE IR LOAD FROM MICRO-STORE
	D1.MSE==1B21		;ENABLE MICRO-STORE LOAD FROM IR
	D1.PCE==1B22		;ALLOW LOAD/WRITE OF THE PC
	D1.PCI==1B23		;ALLOW AUTO-INCREMENT OF PC 
	D1.PC==7777B35		;MASK FOR 12 BITS IN PC


	DS.BOT==1B35		;BOT SEEN
	DS.EOT==1B34		;EOT SEEN
	DS.TM==1B33		;TAPE MARK SEEN
	DS.WLK==1B32		;WRITE LOCKED
	DS.OFL==1B31		;DRIVE IS OFFLINE
	DS.NMV==1B30		;TAPE DIDN'T MOVE
	DS.DC==1B29		;DATA CHECK IN SENSE BYTES
	DS.RTY==1B28		;RETRIABLE ERROR
	DS.ERR==1B27		;ERROR
;BIT DEFINITIONS FOR SENSE BYTES 0-3

	S0.CR==1B2		;COMMAND REJECT
	S0.IR==1B3		;INTERVENTION REQUIRED
	S0.BOC==1B4		;BUS OUT CHECK
	S0.EC==1B5		;EQUIPMENT CHECK
	S0.DC==1B6		;DATA CHECK
	S0.OR==1B7		;OVERRUN
	S0.WCZ==1B8		;WORD COUNT ZERO
	S0.DCC==1B9		;CONVERTER CHECK
	S1.NSE==1B10		;NOISE
	S1.TUA==1B11		;TU STATUS A
	S1.TUB==1B12		;TU STATUS B
	S1.7TK==1B13		;7 TRACK FEATURE
	S1.BOT==1B14		;BOT - LOAD POINT
	S1.WS==1B15		;WRITE STATUS
	S1.FP==1B16		;WRITE PROTECTED
	S1.NC==1B17		;NOT CAPABLE
	S2.TIE==377B27		;TRACK IN ERROR REGISTER
	S3.VRC==1B28		;R/W VRC
	S3.MTE==1B29		;MTE/LRC
	S3.SKW==1B30		;SKEW ERROR
	S3.CRC==1B31		;CRC ERROR
	S3.ENV==1B32		;VRC ERROR
	S3.D16==1B33		;1600 BPI
	S3.BKW==1B34		;BACKWARD STATUS
	S3.CPC==1B35		;C COMPARE

;BIT DEFINITIONS FOR SENSE BYTE 6

	S6.7TK==1B20		;7 TRACK DRIVE
	S6.DD==1B22		;DUAL DENSITY TAPE UNIT
				; TU IS CAPABLE OF BOTH 1600 AND 6250
	S6.TMI==17B27		;MODEL ID FIELD
	S6M.70==1		;TU70 (ONLY WHEN ONLINE)
	S6M.71==1		;TU71 (ONLY WHEN ONLINE)
	S6M.72==3		;TU72
	S6M.73==13		;TU7x (200 IPS GCR DRIVE)
	SUBTTL DX20 ERROR RECOVERY DEFS

;RETRY COUNTS:

	CLNREC==5		;SP REVERSE THIS NR RECORDS TO HIT CLEANER
	RTYOP==4		;RETRY OPERATION THIS MANY TIMES BEFORE TAPE CLEAN SEQUENCE
	RTYCLN==^D10		;RETRY CLEAN SEQUENCE THIS MANY TIMES ON READ
				; BEFORE GIVING UP
				; THE TOTAL NR OF RD RETRIES = RTYOP*(RTYCLN+1)

	RTYWRT==^D14		;# WRITE RETRIES MAXIMUM BEFORE ABORT

	RTY.DN==16		;CODE SIGNAL END OF RETRY
	RTY.CP==17		;CODE TO CHECK POSITION

;ERROR WORDS

;	E.EBC			;ERR BYTE COUNTER (USED IF WE HIT BOT
				;DURING TAPE CLEAN SEQUENCE)
;	U.EBP			;ERR BYTE POINTER
;	U.ETCF			;-1= IN TAPE CLN SEQUENCE, 0= NOT
;	UDBERR(RH)		;CURRENT FUNCTION (1 - 17)
				;ON RETRY OF ORIGINAL OPERATION, THIS LOC
				;MUST BE SET TO THE ORIGINAL OPERATION
;	UDBERC			;RETRY COUNT
				;CONVERTED TO # RETRIES DONE AT END
;	U.EPOS			;WE SHOULD BE HERE WHEN WE'RE
				;READY TO RETRY OPERATION
	SUBTTL	ROUTINE TO MANIPULATE DX20 REGISTERS

;MACROS TO READ AND WRITE A DX20 REGISTER
; ASSUME: P1/ CDB POINTER
;	  Q2/ UNIT NUMBER OF THE DX20
; T1,T4 ARE PRESERVED

DEFINE RDRG (REG),<
	MOVSI T2,(REG)
	 CALL RDREG3
>;END DEFINE RDRG

DEFINE WTRG (REG,DATA),<
	MOVEI T2,DATA		;DATA LESS OR EQUAL TO 16 BITS
	TLO T2,(REG)	
	CALL WTREG3
>;END DEFINE WTRG

;MACRO TO READ AND WRITE DX20 REGISTERS
; ASSUME: P1/ CDB POINTER
;	  P3/ UDB POINTER
; T1,T4 ARE PRESERVED

DEFINE REDRG (REG),<
	MOVSI T2,(REG)
	CALL RDREG
>;END DEFINE REDRG

DEFINE WRTRG (REG,DATA),<
	MOVEI T2,DATA		;;DATA LESS OR EQUAL TO 16 BITS
	TLO T2,(REG)
	CALL WTREG
>;END DEFINE WRTRG
;STDX - STARTS THE MICROCODE IN THE DX20
; T1/ STARTING ADDRESS OF THE CRAM
; P1/ CDB, Q2/ UNIT NUMBER OF THE DX20
;	CALL STDX
; RETURN+1: ALWAYS
; T1 IS NOT PRESERVED

STDX:	PUSH P,T1		;SAVE T1
	MOVX T2,DXMTR!MR.RES	;ISSUE A RESET TO
	CALL WTREG3		; THE DX20. (ALSO STOP IT)
	POP P,T2		;GET BACK THE STARTING ADDR
	ANDI T2,D1.PC		;STRIP
	TXO T2,DXDR1!D1.PCE!D1.PCI!D1.IRE ;LOAD STARTING
	CALL WTREG3		; ADDRESS IN THE DX20
	MOVX T2,DXMTR!MR.ST	;START THE
	CALLRET WTREG3		; DX20 MICROPROCESSOR

;GTVER - GETS THE VERSION NUMBER OF THE MICROCODE FROM
; LOCATION 0 OF THE CRAM IN THE DX20
; P1/CDB, Q2/ UNIT NUMBER OF THE DX20
;	CALL GTVER
; RETURN+1: ALWAYS, AND T1/ CONTENTS OF LOC. 0 OF CRAM

GTVER:	MOVX T2,DXMTR!MR.RES	;STOP THE
	CALL WTREG3		; DX20 MICROPROCESSOR
	MOVX T2,DXDR1!D1.PCE!D1.IRE ;SET THE
	CALL WTREG3		; PC TO 0
	MOVX T2,DXDR0		;READ THE IR
	CALLRET RDREG3		; REGISTER INTO T1
;GTSNS - READS IN SENSE BYTES 0-3 INTO T1
; T4/ DRIVE NUMBER
; P1/ CDB, Q2/ UNIT NUMBER OF DX20
;	CALL GTSNS
; RETURN+1: FAIL
; RETURN+2: GOOD RETURN
; T1/ SENSE BYTES 0 - 3  (0) 2-9 (1) 10-17 (2) 20-27 (3) 28-35

GTSNS:	MOVX T2,DXSTR		;READ THE DX20 STATUS REGISTER
	CALL RDREG3		; TO SEE IF THE DX20 IS RUNNING
	TXNN T1,SR.RUN		;IS IT RUNNING?
	  JRST DX2STP		;NO IT QUIT ON US
	MOVE T2,T4		;GET THE DRIVE NUMBER
	TXO T2,DXGP1		;SET THE DRIVE
	CALL WTREG3		; NUMBER INTO THE DX20
REPEAT 0,<			;IF ITS DESIRED TO DO A NOP TO
				; GET THE SENSE BYTE DELETE THE
				; REPEAT 0 AND THE MOVX FOLLOWING IT

	MOVX T2,DXGP3!TE.SOP	;SET FORCE SENSE BIT
	CALL WTREG3		; LOAD INTO THE FLAGS REG
	MOVX T2,DXCTR!XF.NOP	;DO A
>;END REPEAT 0
	MOVX T2,<DXCTR!XF.SNS>	;DO A SENSE OPERATION
	CALL WTREG3		; NOP OPERATION
	MOVEI T4,1		;GET MASK BIT
	LSH T4,(Q2)		;ATTENTION MASK FOR THIS DX20
	PUSH P,P4		;USE P4 AS COUNTER
	MOVEI P4,1000		;LOOP COUNT=1000
				; (THIS MUST BE THIS LARGE AS THE
				; FIRST TIME THRU TAKES A LONG TIME)
GTSN1:	RDRG DXASR		;READ ATTENTION SUMMARY REG. IN T1
	TDNE T1,T4		;SKIP IF ATTENTION BIT NOT SET
	JRST GTSN2		;JUMP, GET ATTENTION SET
	SOJG P4,GTSN1		;TRY AGAIN
	POP P,P4		;FAIL, THEN RESTORE P4
	BUG(CHK,DX2FGS,<PHYX2 - FAIL TO GET SENSE BYTES>) ;PUT OUT BUGCHK
	RET			;JUST RETURN
GTSN2:	POP P,P4		;SUCCEED, RESTORE P4
	WTRG DXASR,(T4)		;CLEAR ATTENTION BIT FOR THIS DX20
	CALLRET RDSNS		;GET 4 SENSE BYTES IN T1

;HERE IF THE DX20 IS NOT RUNNING
;
DX2STP:	BUG(CHK,DX2HLT,<PHYX2 - DX20 HALTED>,<T1>)
	RET			;RETURN
;GETEXS - READ IN 4 BYTES OF EXTENDED STATUS
; T1/ INDEX FOR EXTENDED STATUS
; P1/ CDB, Q2/ UNIT NUMBER OF DX20
;	CALL GETEXS
; RETURN+1: FAIL RETURN
; RETURN+2: SUCEED
; T1/ T1 HAS THE 4 BYTES  (1) 2-9 (2) 10-17 (3) 20-27 (4) 28 - 35

GETEXS:	MOVE T2,T1		;GET INDEX FROM T1
	TXO T2,<DXGP0!ES.RES>	;SET BIT TO REQUEST
	CALL WTREG3		; TO REQUEST SENSE BYTES
RDSNS:	MOVX T4,100		;NUMBER OF TIMES TO WAIT
				; FOR ES.RES TO CLEAR BEFORE GIVING UP
RDSNS1:	RDRG DXGP0		;READ BACK REG. 20
	TXNN T1,ES.RES		;REQUEST SENSE BYTE BIT CLEARED?
	JRST RDSNS2		;GO READ REG 26 AND 27
	SOJG T4,RDSNS1		;NO, TRY AGAIN
	BUG(CHK,DX2FUS,<PHYX2 - FAIL TO UPDATE SENSE BYTES>)
	RET			;FAIL, NONSKIP RETURN
RDSNS2:	RDRG DXGP6		;READ IN REG 26
	HRL T4,T1		;PUT REG. 26 IN LEFT HALF
	RDRG DXGP7		;READ IN REG 27
	HRR T4,T1		;PUT REG. 27 IN RIGHT HALF
	MOVE T1,T4		;PUT IN T1
	RETSKP			;SKIP RETURN
;ASYNST - TAKES CARE OF ANY ASYNCHRONOUS STATUS PRESENTED TO DX20,
;  WHICH IS CAUSED BY THE COMPLETION OF A REWIND
; OR AN UNIT BECOMES ON-LINE.
; P1/CDB, P2/KDB
;	CALL ASYNST
; RETURN+1: ALWAYS

ASYNST:	PUSH P,Q2		;SAVE DRIVE STATUS
	MOVE Q2,K.DXAD(P2)	;GET UNIT NUMBER OF DX20
ASYNS1:	RDRG DXGP4		;GET ASYNST STATUS
	JUMPE T1,Q2RET		;NONE, SO RETURN
	LOAD T4,DRVNUM		;GET DRIVE NUMBER IN T4
	PUSH P,P3		;PRESERVE P3
	PUSH P,P4		; AND P4
	MOVX T2,DXGP4		;ZERO THE ASYNC STATUS
	CALL WTREG3		; REGISTER
	ADD T4,P2		;BUILD POINTER TO KDB
	MOVE P3,K.DUDB(T4)	;UDB GIVING ASYN. STATUS IN P3
	SUB T4,P2		;RESUME T4, HAS DRIVE NUMBER OF TU
				; Q2 SETUP BY CALLER**
	CALL GTSNS		;CLEAR ATTN BIT AND GET SENSE BYTES IN T1
	 JRST ASYNS3		;FAILED TO GET THE SENSE BYTES SO RETURN
	MOVX T2,<US.BOT!US.WLK!US.OFS> ;GET MASK
	ANDCAM T2,UDBSTS(P3)	;CLEAR THESE BITS FIRST
;Following instruction removed because tapes coming back
; online after being manually unloaded do not generate an
; interrupt
;	TXNE T1,S1.TUA		;UNIT READY?
	TXZ T2,US.OFS		;YES, CLEAR OFF-LINE BIT
	TXNN T1,S1.BOT		;UNIT AT BOT?
	TXZ T2,US.BOT		;NO, CLEAR BOT BIT
	TXNN T1,S1.FP		;FILE-PROTECTED AS IN SENSE BYTE
	TXZ T2,US.WLK		;NO, CLEAR US.WLK IN MASK
	IORB T2,UDBSTS(P3)	;MARK INTO UDB, AND PUT UDBSTS IN T2
	TXNE T2,US.REW		;REWINDING?
	TXNE T1,S1.TUA		;SKIP IF DRIVE OFFLINE
	CALL PHYRWD		;NO, TELL PHYSIO THIS IS REW. DONE
				; CLEAR US.REW, MAY START IO
	POP P,P4		;RESTORE P4
	POP P,P3		; AND P3
	JRST ASYNS1		;LOOP AND SEE IF ANY MORE ASYNC STATUS
ASYNS3:	POP P,P4		;RESTORE P4
	POP P,P3		; AND P3
Q2RET:	POP P,Q2		;RESTORE Q2
	RET			; AND RETURN TO CALLER
;HARCHK - CHECKS FOR ERRORS AND PUTS THE DRIVE STATUS IN Q2
; P1/CDB, P2/KDB, P3/UDB, Q1/FTN CODE, P4/IORB
;	CALL HARCHK
; RETURN+1: SOME HARD ERROR FOUND
; RETURN+2: GOOD RETURN WITH DRIVE STATUS IN Q2

HARCHK:	MOVX T1,<IS.DVE!IS.DTE>	;CLEAR DEVICE AND DATA
	ANDCAM T1,IRBSTS(P4)	; IN IRBSTS
	MOVX T1,US.WLK		;SEE IF THE UNIT IS
	TDNE T1,UDBSTS(P3)	; WRITE LOCKED?
	MOVX Q2,DS.WLK		;YES, LIGHT A BIT
	TXNE Q1,TB.TM		;WRITE TM OPERATION
	TXO Q2,DS.TM		;YES, SET WHERE IT WILL BE SEEN
	REDRG DXSTR		;READ IN THE DX20 STATUS REGISTER
	TXNN T1,SR.CER		;ANY ERROR TO INVESTIGATE?
	RETSKP			;NO ERRORS
	REDRG DXERR		;READ THE DX20 ERROR REGISTER
	TXNE T1,<ER.SPT!ER.MPE>	;IS THE DX20 HALTED?
	JRST HARCH1		;YES, GO START IT
	TXNE T1,<ER.ILF!ER.ILR!ER.RMR!ER.CPE> ;ILLEGAL FUNCTION, ILLEGAL REG, REG MOD REFUSED,
				; OR CONTROL BUS PARITY ERROR?
	JRST HARCH2		;YES, FATAL ERROR
	LOAD T2,ECC		;GET THE ERROR CLASS CODE
	JUMPLE T2,ECCERR	;0 ERROR CLASS CODE IS A FATAL ERROR
	CAILE T2,ECCSZ		;LEGAL CODE?
	JRST ECCERR		;NO, FATAL ERROR
	JRST @ECCTBL-1(T2)	;DISPATCH TO ERROR CLASS CODE

;HERE IF DX20 IS HALTED
;
HARCH1:	REDRG DXGP6		;READ IN AS THIS MIGHT CONTAIN AN ERROR CODE
	BUG (CHK,DX2DIE,<PHYX2 - DX20 HALTED>,<T1>)
	MOVEI T1,STADDR		;DX20 STARTING ADDRESS
	CALL STDX		;START THE DX20 RUNNING AGAIN
HARCH2:	CALL RDALL		;READ ALL DX20 REGISTERS AND EXTENDED STATUS
HERR:	MOVX T3,<IS.DVE!IS.ERR!IS.NRT> ;FLAG A FATAL
	IORM T3,IRBSTS(P4)	; ERROR IN THE IORB
	MOVX T3,US.REW		;CLEAR REWINDING
	ANDCAM T3,UDBSTS(P3)	; IN THE UDB
	MOVX T1,US.WLK		;IF WRITE LOCKED IS
	TDNE T1,UDBSTS(P3)	; SET IN THE UDB, SET
	IORM T1,IRBSTS(P4)	; WRITE LOCKED IN THE IORB
	TXO Q2,DS.ERR		;FLAG AN ERROR OCCURRED
	RET			;NONSKIP RETURN INDICATES FATAL ERROR
;ERROR CLASS CODE DISPATCH TABLE
;
ECCTBL:	ECC1			;(1) UNUSUAL DEVICE STATUS (EXAMINE ENDING STATUS REG)
	CLRERR			;(2) SHORT RECORD (NOT AN ERROR)
	CLRERR			;(3) LONG RECORD (FATAL)
				; (ERROR BITS WILL BE SET BY CKERR)
	FTLERR			;(4) DRIVE SELECTION ERROR (FATAL)
	CLRERR			;(5) TAPE MOTION (RECOVERABLE)
	NOTMOV			;(6) NO TAPE MOTION (RECOVERABLE)
	FTLERR			;(7) PARITY ERROR (FATAL)
	FTLERR			;(8) FATAL ERROR
	ECCSZ==.-ECCTBL		;LENGTH OF TABLE

;RDALL - READS ALL THE DX20 REGISTERS AND
; THE EXTENDED STATUS INTO THE KDB
; P1/CDB, P2/KDB, P3/UDB
;	CALL RDALL
; RETURN+1: ALWAYS
;
RDALL:	CALL DX2RDR		;READ DX20 REGISTERS
	MOVX T2,DXERR		;ZERO THE DX20
	CALL WTREG		; ERROR REGISTER
	CALLRET DX2REX		;READ THE EXTENDED STATUS
;HERE IF ERROR CLASS 1
;
ECC1:	REDRG DXGP0		;READ THE ENDING STATUS
	TXNN T1,ES.UEX		;UNIT EXCEPTION?
	JRST ECC1A		;NO
	TXNE Q1,TB.RD!TB.SPC	;READ OR SPACE OPERATION?
	TXO Q2,DS.TM		;YES, THEN LIGHT TAPE MARK BIT
	TXNE Q1,TB.WRT		;WRITE OPERATION?
	TXO Q2,DS.EOT		;YES, THEN LIGHT EOT BIT
ECC1A:	TXNN T1,ES.UCK		;UNIT CHECK IN ENDING STATUS?
	JRST CLRERR		;CLEAR ERROR REGISTER AND
				; SKIP RETURN
	PUSH P,T1		;SAVE ENDING STATUS ACROSS SUBROUTINE CALL
	CALL RDALL		;READ ALL DX20 REGISTERS AND EXTENDED STATUS
	POP P,T1		;RESTORE ENDING STATUS
	MOVE T2,K.DEST(P2)	;GET SENSE BYTES 0 - 3
	TXNE T2,S0.EC		;EQUIPMENT CHECK?
	JRST HERR		;YES, FATAL ERROR
	TXNE T2,S0.BOC		;BUS OUT CHECK?
	JRST ERRBOC		;YES, ANALYZE IT FURTHER
	TXNE T2,S0.IR		;INTERVENTION REQUIRED?
	JRST ERRIRQ		;YES, ANALYZE IT FURTHER
ECC1B:	TXNE T2,<S0.CR!S1.NC>	;COMMAND REJECT OR NOT CAPABLE?
	JRST HERR		;YES, FATAL ERROR
	TXNE T2,S0.OR		;OPERATION REJECTED?
	JRST ERROVR		;YES, ANALYZE IT FURTHER
	TXNE T2,S1.BOT		;AT BOT?
	JRST ERRBOT		;YES
	TXNE T2,S0.DC		;DATA CHECK
	JRST ERRDC		;YES, ANALYZE IT FURTHER
	JRST HERR		;FATAL ERROR
;HERE IF AT BOT
;
ERRBOT:	TXO Q2,DS.BOT		;YES, FLAG AT BOT
	RETSKP			;SKIP RETURN

;HERE IF BUS OUT CHECK
;
ERRBOC:	TXNN T1,ES.DVE		;DEVICE END?
	JRST NOTMOV		;NO, REISSUE COMMAND
	TXNN Q1,TB.WRT		;WRITE TYPE OPERATION?
	JRST NOTMOV		;NO, REISSUE COMMAND
	JRST RTYERR		;YES, RETRIABLE ERROR

;HERE IF INTERVENTION REQUIRED
;
ERRIRQ:	TXNN T1,ES.DVE		;DEVICE END?
	JRST HERR		;NO, HARD ERROR
	TXNN Q1,<TB.UNL!TB.REW>	;REWIND OR UNLOAD COMMAND?
	JRST ECC1B		;NO, LOOK AT SOME MORE SENSE BYTES
	JRST RSKP		;YES, JUST CONTINUE

;HERE IF OVERRUN
;
ERROVR:	TXNN Q1,TB.DOP		;DATA OPERATION?
	JRST NOTMOV		;NO, TAPE HASN'T MOVED
	JRST RTYERR		;YES, RETRIABLE ERROR

;HERE IF DATA CHECK
;
ERRDC:	TXO Q2,<DS.DC!DS.RTY!DS.ERR> ;FLAG DATA CHECK
	MOVX T1,<IS.DTE!IS.ERR>	;FLAG DATA ERROR
	IORB T1,IRBSTS(P4)	; IN THE IORB
	TXNN Q1,TB.RD		;READ OPERATION?
	RETSKP			;SKIP RETURN
	LDB T1,[POINTR K.DEST(P2),S2.TIE] ;GET THE TIE BYTE
	HRROM T1,U.ETIE(P3)	;REMEMBER TIE INFO
	RETSKP			;GIVE SKIP RETURN

ECCERR: BUG(CHK,DX2IEC,<PHYX2 - ILLEGAL ERROR CLASS CODE>,<T1>)
	JRST HARCH2

;HERE IF TAPE HASN'T MOVED
;
NOTMOV:	JRST HERR		;CALL IT HARD FOR NOW
	MOVX T1,UDB.NM		;SET FLAG IN
	IORM T1,UDBERR(P3)	; UDB TO INDICATE TAPE HASN'T MOVED
	TXO Q2,<DS.NMV!DS.ERR>	;FLAG NOT MOVED AND ERROR
	MOVX T1,<IS.ERR!IS.DVE>	;DEVICE ERROR
	IORM T1,IRBSTS(P4)	;SET IN THE IORB
	JRST CLRERR		;CLEAR ERROR, AND SKIP RETURN

RTYERR:	TXO Q2,<DS.RTY!DS.ERR>	;FLAG RETRIABLE AND ERROR
	MOVX T1,<IS.DVE!IS.DTE!IS.ERR> ;FLAG AN
	IORM T1,IRBSTS(P4)	; ERROR IN THE IORB
	RETSKP			;SKIP RETURN

FTLERR:	CALL RDALL		;READ ALL REGISTERS
	CALLRET HERR		;FLAG AS HARD ERROR

CLRERR:	MOVX T2,DXERR		;ZERO THE
	CALL WTREG		; ERROR REGISTER
	RETSKP			;SKIP RETURN
;DX2RDR - READS DX20 REGISTERS 0-6,20-24,26-37 INTO K.DREG IN THE KDB
; ALSO, K.DCNI, K.DCS1, AND K.DDBF INTO KDB
; P1/CDB, P2/KDB, P3/UDB
;	CALL DX2RDR
; RETURN+1: ALWAYS

DX2RDR:	SAVEQ			;SAVE ALL Q REGISTERS
	PUSH P,P2		;REMEMBER CURRENT KDB POINTER
	SETZB T4,Q1		;ZERO COUNTER,AC TO TEST AFTER SHIFT
	MOVX Q2,SAVBIT		;A BIT FOR EACH REGISTER TO SAVE
DX2RD1:	LSHC Q1,1		;SHIFT IN A BIT FROM Q2
	JUMPE Q1,DX2RD2		;JUMP IF THIS REG IS NOT TO BE SAVED
	HLLZ T2,T4		;GET REGISTER TO READ
	CALL RDREG		;READ A DX20 REGISTER
	MOVEM T1,K.DREG(P2)	;SAVE REGISTER IN THE KDB
	ADDI P2,1		;UPDATE KDB POINTER FOR NEXT TIME
	SETZ Q1,		;ZERO TEST AC
DX2RD2:	ADD T4,[BYTE (6) 1 (36-6) 1] ;UPDATE REGISTER NUMBER
	JUMPN Q2,DX2RD1		;DONE SAVING ALL REGISTERS?
	POP P,P2		;RESTORE KDB POINTER
	CALL ERRCNI		;GET CONI AND DATAI
	MOVEM T1,K.DCNI(P2)	;SAVE IN KDB
	MOVEM T2,K.DCS1(P2)	; ...
	MOVEM T3,K.DDBF(P2)	; ...
	RET

;DX2REX - READS IN THE EXTENDED STATUS TABLE INTO THE KDB
; P1/CDB, P2/KDB, P3/UDB
;	CALL DX2REX
; RETURN+1:ALWAYS

DX2REX:	PUSH P,Q1		;WILL USE Q1 & Q2
	PUSH P,Q2		;SO, SAVE THEM
	MOVE Q2,K.DXAD(P2)	;GET UNIT # FOR THIS DX20
	MOVSI Q1,-LK.DX2+K.DEST ;Q1 AS COUNTER AND INDEX
DX2RE1:	HRRZ T1,Q1		;GET INDEX FOR EXTENDED STATUS
	CALL GETEXS		;READ IN THE SENSE BYTES
	 JRST DX2RE2		;FAIL
	ADD Q1,P2		;ADD BASE ADDR. OF KDB
	MOVEM T1,K.DEST(Q1)	;STORE SENSE BYTES IN KDB
	SUB Q1,P2		;RESTORE Q1
	AOBJN Q1,DX2RE1		;LOOP BACK FOR THE NEXT 4 BYTES
DX2RE2:	POP P,Q2		;RESTORE Q1&Q2
	POP P,Q1		;
	RET			;RETURN
	SUBTTL DISPATCH FOR DX20

DX2DSP::JRST DX2INI		;0 - INITIALIZATION
	JRST DX2SIO		;1 - START I/O
	JRST DX2INT		;2 - HANDLE INTERRUPT (DATA OPERATION OR SPACE)
	JRST DX2ERR		;3 - ERROR RECOVERY
	JRST DX2HNG		;4 - HUNG DEVICE
	RET			;5 - NOT USED
	RET			;6 - NOT USED
	JRST DX2SIO		;7 - START POSITION OPERATION
	JRST DX2ATN		;10 - ATTENTION INTERRUPT (CALLED AS MANY
				; TIMES AS THERE ARE DX20 DRAS BITS UP)
	JRST DX2PRQ		;11 - SKIP IF POSITION REQUIRED
	RET			;12 - STACK SECOND COMMAND, FAIL FOR DX20

DX2HNG:	MOVX T1,<IS.DVE!IS.ERR!IS.NRT> ;SET FATAL BITS
	IORM T1,IRBSTS(P4)	;AND REFRESH IT
	RET

;HERE TO DETERMINE IF THIS REQUEST SHOULD GO ON PWQ OR TWQ

DX2PRQ:	LDB T1,IRYFCN		;GET FUNCTION
	MOVE T1,DX2FTB(T1)	;GET TABLE ENTRY
	TXNN T1,TB.DOP		;DATA OPERATION?
	RETSKP			;NO - POSITION ALWAYS REQUIRED
	HRRZ T2,UDBPWQ(P3)	;YES - ANY PENDING POSITION OPERATIONS?
	JUMPE T2,R		;NONE - APPEND TO TWQ
	CAIN T2,(P4)		;AT HEAD OF PWQ?
	RET			;YES - NEXT TRANSFER
	RETSKP			;APPEND TO PWQ
	SUBTTL DX20 INITIALIZING ROUTINE

;DX2INI - INITIALIZATION ROUTINE
;THIS ROUTINE IS CALLED ONCE PER DX20 DRIVE ON THE SYSTEM
; AND BUILDS A KDB FOR THE DX20 AND A UDB FOR EACH TAPE DRIVE
; THAT HAS TUA OR TUB SET IN SENSE BYTE 1.
; P1/CDB Q2/DX20 NUMBER
;	CALL DX2INI
; RETURN +1: ALWAYS
; T1/KDB

DX2INI:	SAVEQ			;SAVE REGISTERS
	CALL CHKMIC		;CHECK THE MICROCODE IN DX20
	  JRST [BUG(CHK,DX2MCF,<PHYX2 - DX20 MICROCODE CHECK FAILURE>)
		RET]
	MOVX T1,LK.DX2		;LENGTH OF KDB
	CALL PHYALC		;RESERVE SPACE
	  RET			;RETURN IF NO SPACE FOUND
	MOVE P2,T1		;SAVE ADDRESS OF KDB IN PROPER AC
	MOVE P3,T1		;NEED POINTER OF KDB ALSO IN P3
	MOVEI T1,.BTKDB		;MARK AS A KDB
	DPB T1,USYBKT		;SET .BTKDB IN KDB
	CALL GTVER		;PUT MICROCODE VERSION NUMBER IN T2
	MOVEM T1,K.DVER(P2)	;SAVE DX20 MICROCODE VERSION IN THE KDB
	MOVEI T1,STADDR		;STARTING ADDRESS OF DX20
	CALL STDX		;START THE DX20 MICROCODE
	MOVX T1,.UTDX2		;SET UP UNIT TYPE IN KDB
	STOR T1,USTYP,(P2)	;THIS IS A DX20 CONTROLER
	MOVSI T1,-NUMDRV	;SET UP AOBJN INDEX
	HRRI T1,K.DUDB(P2)	;MAKE RH POINT TO UDB ENTRIES IN KDB
	MOVEM T1,KDBIUN(P2)	;INITIAL POINTER
	MOVEM T1,KDBCUN(P2)	;CURRENT POINTER
	HRRZM Q2,K.DXAD(P2)	;SAVE KDB ADDRESS
	MOVEI T1,DX2DSP		;INSERT DISPATCH VECTOR
	MOVEM T1,KDBDSP(P2)	; ...
	MOVSI Q1,-NUMDRV	;SLAVE INDEX
INILP:	HRRZ T4,Q1		;GET CURRENT SLAVE #
	CALL GTSNS		;GET SENSE BYTES(0-3) IN T1
	  JRST NODRV		;FAIL TO GET SENSE BYTES, TRY NEXT
	TXNN T1,S1.TUA+S1.TUB	;IS IT IN EXISTENCE?
	JRST NODRV		;NO, JUMP
	MOVE Q3,T1		;SAVE SENSE BYTES 0-3
	SKIPN T3,MTINDX		;GET AOBJN INDEX TO LOGICAL TABLE
	HRLOI T3,-MTAN-1	;IF 1ST TIME THRU
	AOBJP T3,[BUG(INF,DX2N2S,<PHYX2 - MORE TU70S THAN TABLE SPACE, EXCESS IGNORED>)
		JRST TOORET]	;DON'T INITIALIZE ANY MORE SLAVES
	MOVEM T3,MTINDX		;SAVE CURRENT LOGICAL INDEX
	MOVE T3,[DX2DSP,,LU.DX2] ;YES, SET UP ADDRESS,,LENGTH
	CALL PHYUDB		;AND ASK FOR UDB ALLOCATION
	  RET			;RETURN IF NO SPACE FOUND
	ADD P2,Q1		;POINT TO PROPER KDB ENTRY
	HRRZM P3,K.DUDB(P2)	;SAVE LINK
	SUB P2,Q1		;FUDGE IT BACK
	HRRZM P2,UDBKDB(P3)	;SAVE BKWDS LINK
	MOVE T3,MTINDX		;GET CURRENT LOGICAL INDEX
	HRLZM P1,MTCUTB(T3)	;SAVE LINK TO CDB IN LOGICAL TABLE
	HRRM P3,MTCUTB(T3)	;SAVE LINK TO UDB
	MOVX T3,US.TAP		;T3 AS MASK FOR UDBSTS, ITS TAPE UNIT
;Never declare a unit offline as when they come back online
; they never generate an interrupt
;	TXNN Q3,S1.TUA		;TAPE UNIT READY?
;	TXO T3,US.OFS		;NO, MARK AS OFF-LINE
	TXNE Q3,S1.FP		;WRITE-PROTECTED?
	TXO T3,US.WLK		;YES, MARK IT
	HLLM T3,UDBSTS(P3)	;SAVE STATUS IN UDB
	MOVEI T1,1		;INDEX FOR SENSE BYTES 4 - 7
	CALL GETEXS		;READ IN SENSE BYTES 4 - 7 INTO T1
	 JRST UPERR		;UPDATE FAILED
	MOVX T2,.UTT70		;ASSUME TU70 (800/1600 9 TRK)
	TXNE T1,S6.DD		;IS IT 1600/6250?
	MOVX T2,.UTT72		;CALL IT A TU72 (1600/6250 9TRK)
	TXNE T1,S6.7TK		;IS IT A 7 TRK DRIVE?
	MOVX T2,.UTT71		;CALL IT A TU71 (200/556/800 7TRK)
	STOR T2,USTYP,(P3)	;PUT UNIT TYPE IN UDB
	MOVE T1,[	UC.800!UC.160!UC.CD!UC.AA!UC.IC!UC.HD ;TU70
			UC.200!UC.556!UC.800!UC.6B!UC.7TK ;TU71
			UC.160!UC.625!UC.CD!UC.AA!UC.IC!UC.HD ;TU72
			UC.160!UC.625!UC.CD!UC.AA!UC.IC!UC.HD ]-.UTT70(T2) ;TU73
	MOVEM T1,UDBCHR(P3)	;STORE DENSITYS DRIVE IS CAPABLE OF
				; IN THE UDB
	MOVEI T1,3		;INDEX=3 FOR SENSE BYTES
	CALL GETEXS		;READ IN SENSE BYTES 12 - 15
	  JRST UPERR		;JUMP, ERROR
	ANDI T1,377		;TAKE BYTE 15 ONLY
	MOVE Q3,T1		;TUCK IT AWAY FOR AWHILE
	MOVEI T1,4		;INDEX=4 FOR SENSE BYTES
	CALL GETEXS		;READ IN SENSE BYTES 16 - 19
	  JRST UPERR		;ERROR, JUMP
	LSH T1,-^D26		;BYTE 16 AS LOW ORDER BYTE
	LSH Q3,^D8		;MAKE BYTE 15 HIGH ORDER BYTE
	IOR T1,Q3		;CONCATENATE INTO T1, AS SERIAL NUMBER
	JUMPN T1,GOTSER		;0 IF TU70, OR TU71
	HRRZ T1,Q1		;GET PHYSICAL UNIT NUMBER ON THIS DX20
	HRRZ T2,Q2		;GET DX20 NUMBER ON THIS CHANNEL
	IMULI T2,^D100