Google
 

Trailing-Edge - PDP-10 Archives - BB-JR93L-BB_1990 - 10,7/mon/tx1kon.mac
There are 12 other files named tx1kon.mac in the archive. Click here to see a list.
TITLE	TX1KON - TU70 DEVICE DEPENDENT CODE FOR TAPSER V173
SUBTTL L. BOSACK/TAH/TW/DPM	17-APRIL-90

	SEARCH	F,S,DEVPRM
	$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
; 1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988,1990.
;ALL RIGHTS RESERVED.

.CPYRT<1974,1990>


XP VTX1KN,173	;VERSION NUMBER FOR LINKEDIT MAP
	SALL

TX1KON::ENTRY TX1KON
;BIT DEFINITIONS ETC

;DEVICE CONI BITS

CI.RUN==1B17		;MICROPROCESSOR RUN
CI.ICP==^D24		;ICPC BIT POSITION
CI.CSR==1B25		;CSR FLAG
CI.UPE==1B26		;MICROPROCESSOR ERROR
CI.MPE==1B27		;MEMORY PARITY ERROR
CI.NXM==1B28		;NONEX MEMORY
CI.STA==1B29		;STATUS AVAILABLE
CI.CON==1B32		;CONTINUE
CI.ERR==CI.CSR!CI.UPE!CI.MPE!CI.NXM

;DEVICE CONO BITS

CO.ICP==CI.ICP		;ICPC BIT POSITION
CO.ILI==1B25		;INHBIT LOAD ICPC
CO.UPE==CI.UPE		;CLEAR MICROPROCESSOR ERROR
CO.MPE==CI.MPE		;CLEAR MEM PAR ERR
CO.NXM==CI.NXM		;CLEAR NXM
CO.STA==CI.STA		;CLEAR STAT AVAIL
CO.SRQ==1B30		; STATUS REQUEST
CO.CLR==1B31		;CLEAR
CO.CON==CI.CON		;CONTINUE

;DEVICE DATAO BITS

DO.RES==1B16		;LOCAL RESET
DO.LRS==1B17		;LOAD RSEL REGISTER
DO.BCD==0		;BYTE COUNTER AND DAC/CPC HIGH ORDER BITS
DO.DR==1		;DATA REGISTER (READ TWICE, BLECHHH)
DO.TAG==2		;TAG REGISTERS
DO.BUS==3		;BUS REGISTERS
DO.UC0==4		;MICROPROCESSOR CONTROL 0
DO.UC1==5		;MICROPROCESSOR CONTROL 1
DO.RFL==6		;LOW ORDER BITS OF SELECTED REG.FILE REGISTER
DO.RFH==7		;HIGH ORDER ...
DO.MRL==10		;LOW ORDER BITS OF MR
DO.MRH==11		;HIGH ORDER BITS OF MR
DO.DAC==12		;LOW ORDER BITS OF  DAC
DO.CPC==13		;LOW ORDER BITS OF CPC
DO.FR==14		;FR
DO.UPS==15		;MICROPRCESSOR STATES
DO.ICP==16		;ICPC
DU0HLT==1B19		;UP CTL 0 HALT
DU0CON==1B20		;UP CTL 0 CONTINUE
DU0EXM==1B22		;UP CTL 0 FORCE EXAMINE
DU0WRT==1B23		;UP CTL 0 FORCE WRITE
DU0MDP==^D35		;UP CTL 0 MD POSITION
DU0MDS==^D12		;UP CTL 0 MD SIZE

DU1MEM==1B18		;MEMORY USER BIT (0=DAC, 1=CPC)
DU1RUN==1B21		;UP RUN BIT
DU1MAP==^D35		;UP CTL 1 MA POSITION
DU1MAS==^D12		;UP CTL 1 MA SIZE

DOYU0D:	POINT	DU0MDS,T2,DU0MDP	;BYTE POINTER TO MD FIELD IN DATAO UP CTL 0
DOYU1A:	POINT	DU1MAS,T2,DU1MAP	;BYTE POINTER TO MA FIELD UN UP DTL 1

;MICROPROCESSOR PARAMETERS

UP.SA==200		;STARTING ADDRESS IN CTL MEM
UP.RA==201		;RESTART ADDRESS
;OFFSETS IN ICPC BLOCK

CP.ICW==0		;INITIAL COMMAND WORD
CP.ST1==1		;STATUS WORD 1 (DSR,CSR,SEQ.COD,DAR)
CP.ST2==2		;STATUS WORD 2 (CPC,BYTE COUNT)
	CP2BCP==^D13		;RESIDUAL BYTE COUNT POSITION
	CP2BCS==^D14		;RESIDUAL BYTE COUNT SIZE
CP.STS==3		;POINTER TO TERMINATION STATUS
CP.RBC==3		;ACCUMULATED BYTE COUNT (NO ERROR)

;OFFSETS INTO TERMINATION STATUS AREA

XS.RBC==0		;ACCUMULATED BYTE COUNT (ERROR)
XS.TAG==1		;TAGS AND BUS
XS.DAC==2		;DAC
XS.FR==3		;FR,,STATUS
XS.S0==4		;SENSE BYTES  0 -  3
XS.S4==5		;SENSE BYTES  4 -  7
XS.S8==6		;SENSE BYTES  8 - 11
XS.S12==7		;SENSE BYTES 12 - 15
XS.S16==10		;SENSE BYTES 16 - 19
XS.S20==11		;SENSE BYTES 20 - 23
;REMAINING ENTRIES ARE COPIED FROM ELSEWHERE
XS.CNI==12		;CONI
XS.ST1==13		;CP.ST1
XS.ST2==14		;CP.ST2
XS.CPC==15		;CPC
XS.CMD==16		;COPY OF CHL CMD (OR MODE SET)
XS.CM1==17		;COPY OF CHL CMD
XS.MD==20		;MD AND CPMA
XS.DR==21		;DR
XS.DIAG==22		;DIAGNOSTIC ERROR CODE
XS.MR1==23		;MEMORY REGISTER
XS.END==23		;END OF EXTENDED STATUS AREA

CPY2BC:	POINT	CP2BCS,CP.ST2(T4),CP2BCP	;POINTER TO RESIDUAL BYTE COUNT
;BITS IN CP.ST1

;DSR - DEVICE STATUS REGISTER

DS.ATN==1B0		;ATTENTION
DS.STM==1B1		;STATUS MODIFIER
DS.CUE==1B2		;CONTROL UNIT END
DS.BSY==1B3		;BUSY
DS.CHE==1B4		;CHANNEL END
DS.DVE==1B5		;DEVICE END
DS.UCH==1B6		;UNIT CHECK
DS.UEX==1B7		;UNIT EXCEPTION

;CSR - CHANNEL STATUS REGISTER

CS.PGS==1B8		;PROGRAM STATUS
CS.STP==^D10		;STATUS TYPE POSITION
CS.STS==2		;STATUS TYPE SIZE
	CS.STX==0		;INITIAL SELECTION
	CS.STE==1		;ENDING STATUS
	CS.STC==2		;CU INTERRUPT STATUS
	CS.STI==3		;IDLE STATUS
CS.SLE==1B11		;SELECTION ERROR
CS.SQE==1B12		;SEQUENCE ERROR
CS.DPE==1B13		;DEVICE PARITY ERROR
CS.LNE==1B14		;LENGTH ERROR
CS.SLI==1B15		;SUPRESS INCORRECT LENGTH INDICATION
CS.IOP==1B16		;ILLEGAL OPERATION
CS.DSF==1B17		;DSR FLAG

;RANDOM BIT IN STATUS 1
ST1NFG==1B18		;STATUS AND SENSE STORED NO GOOD
ST1INC==1B19		;OP INCOMPLETE (RUNAWAY TAPE)

CP1DIS==^D8		;SIZE OF DARI
CP1DIP==^D35		;POSITION OF DARI
CP1SQS==^D5		;SEQUENCE ERR  CODE
CP1SQP==^D27		;POSITION

CPSBCS==^D14		;BYTE COUNT SIZE
CPSBCP==^D13		;BYTE COUNT POSITION
CPSNSB==^D24		;NUMBER OF SENSE BYTES
CPSNSW==<CPSNSB/4>+4	;WORDS FOR STORAGE PLUS OVERHEAD

;INTO ICPC
STYDAI:	POINT	CP1DIS,CP.ST1(T4),CP1DIP	;DARI
STYTYP:	POINT	CS.STS,CP.ST1(T4),CS.STP	;STATUS TYPE
;BITS IN THE SENSE BYTES

;XS.S0 HAS SENSE BYTES 0 - 3

SB0CMR==1B0		;COMMAND REJECT
SB0IRQ==1B1		;INTERVENTION REQUIRED
SB0BOC==1B2		;BUS OUT CHECK
SB0EQC==1B3		;EQUIPMENT CHECK
SB0DC==1B4		;DATA CHECK
SB0OVR==1B5		;OVERRUN
SB0WCZ==1B6		;WORD COUNT ZERO
SB0DCC==1B7		;DATA CONVERTER CHECK
SB0==SB0CMR!SB0IRQ!SB0BOC!SB0EQC!SB0DC!SB0OVR!SB0WCZ!SB0DCC

SB1NSE==1B8		;NOISE
SB1TUA==1B9		;TU STATUS A
SB1TUB==1B10		;TU STATUS B
SB17TK==1B11		;7 TRACK
SB1BOT==1B12		;LOAD POINT
SB1WRS==1B13		;WRITE STATUS & SELECTED
SB1WTL==1B14		;WRITE LOCK
SB1NC==1B15		;NOT CAPABLE

;SENSE BYTE 2 IS TRACK IN ERROR BYTE


;SENSE BYTE 3
SB3D16==1B29		;1600 BPI TAPE

;SENSE BYTE 5
SB5NSS==1B9		;NEW SUB-SYSTEM (TX02)
SB5PID==1B11		;PE ID BURST CHECK

;SENSE BYTE 6
SB67TK==1B16		;7 TRACK
SB6D62==1B18		;6250 BPI TAPE

;BYTE POINTERS

XSYSB2:	POINT	8,XS.S0(T2),23	;POINTER TO SB2 (TRACK IN ERROR)


TX1MVR==1500,,0		;MINIMUM MICROCODE VERSION ALLOWED

;MAGIC 8A LOCS AND VALUES
LOCVER==3		;WHERE MICROCODE VERSION IS STORED
DXVER==TX1MVR_-30	;WE NEED AT LEAST THIS VERSION OF THE MICROCODE
LOCMAG==17		;MAGIC ADDRESS
DXMAG==4756		;MAGIC VALUE
;CCW BIT AND BYTE DEFNS

CC.OPP==1		;POSITION OF OP CODE FIELD IN CCW
CC.OPS==2		;SIZE OF OP CODE FIELD IN CCW
CCOCHN==0		;CHANNEL CONTROL OP CODE
CCODVC==1		;DEVICE COMMAND
CCODAT==2		;MASK FOR DATA XFR OPERATION

;CHANNEL CONTROL CCW

CCHADS==^D22		;SIZE OF NEW CPC FIELD IN CHAN CTL OP
CCHADP==^D35		;POSITION OF NEW CPC FIELD IN CHAN CTL OP
CCHGO==1B2		;GO BIT IN CHAN CTL OP
CCHJMP==1B3		;JUMP BIT IN CHAN CTL OP
CCHSTS==1B4		;STORE STATUS BIT IN CHAN CTL OP
CCHFRC==1B5		;FORCE SENSE BYTES TO BE STORED
CCHSAV==1B6		;SAVE BYTE COUNT OF PREVIOUS RECORD
CCHJGO==:CCHJMP!CCHGO	;JUMP AND GO FOR REST OF MON

;DEVICE CONTROL CCW

CCDSLI==1B2		;SUPRESS INCORRECT LENGTH INDICATION
CCDAER==1B3		;AUTOMATIC RETRY ON ERROR
CCDISL==1B4		;IGNORE SHORT LENGTH ERROR
CCDREC==1B7		;READ (SOFT) ERROR COUNTER
CCDIGN==1B13		;GUARANTEED IGNORED BY DX10
CCDMDS==2		;SIZE OF MODE FIELD
CCDMDP==6		;POSITION OF MODE FIELD
CCDDCS==^D8		;SIZE OF DEVICE COMMAND FIELD
CCDDCP==^D23		;POSITION OF DEVICE COMMAND FIELD
CCDDAS==^D8		;ADDRESS OF DEVICE ADDRESS FIELD
CCDDAP==^D35		;POSITON OF DEVICE ADDR FIELD

;DATA XFR CCW

CCXBCP==^D13		;POSITION OF BYTE COUNT
CCXBCS==^D13		;SIZE OF BYTE COUNT IN DATA XFR CCW
CCXADS==^D22		;SIZE OF ADDRESS IN DATA XFR CCW
CCXADP==^D35		;POSITION OF ADDRESS IN DATA XFR CCW

;ODD PARITY BIT IN SET MODE DEVICE COMMAND
MS1ODD==20

CCYOP:	POINT	CC.OPS,(T4),CC.OPP	;POINTER TO OP CODE IN CCW
CHYADR:	POINT	CCHADS,(T4),CCHADP	;POINTER TO NEW CPC IN CHAN CTL CCW
CDYMOD:	POINT	CCDMDS,(T4),CCDMDP	;DATA MODE IN DEVICE CTL CCW
CDYDCR:	POINT	CCDDCS,(T4),CCDDCP	;DEVICE COMMAND IN DEVICE CTL OP
CDYDAD:	POINT	CCDDAS,(T4),CCDDAP	;DEVICE ADDRESS IN DEVICE CTL CCW

CXYCNT:	POINT	CCXBCS,(T4),CCXBCP	;BYTE COUNT IN DATA XFR
CXYADR:	POINT	CCXADS,(T4),CCXADP	;ADDRESS IN DATA XFR
	TX1DMX==20			;MAXIMUM DRIVES PER KONTROLLER
	TX1HDN==TX1DMX-1		;HIGHEST DRIVE NUMBER ON KONTROLLER
	TX1ELN==^D20			;SIZE OF FEP TABLE


;DRIVER CHARARCTERISTICS
;	TX1	= TX1CNF
;	MTA	= MAGTAPE
;	0	= MAXIMUM DEVICES IN SYSTEM (NO LIMIT)
;	K.TX1	= KONTROLLER TYPE
;	TX1DMX	= MAXIMUM DRIVES PER KONTROLLER
;	TX1HDN	= HIGHEST DRIVE NUMBER ON KONTROLLER
;	MDSEC0	= SECTION FOR KDB/UDB
;	MDSEC0	= SECTION FOR DDB
DRVCHR (TX1,MTA,0,K.TX1,TX1DMX,TX1HDN,MDSEC0,MDSEC0,<DR.XAD!DR.MCD!DR.DPU!DR.UCK!DR.GCC!DR.DDN>)

	.ORG	TKBUDB		;START OF TX01 SPECIFIC DATA
TX1UTB:! BLOCK	TX1DMX		;TABLE OF POINTERS TO UDBS
TX1TMP:! BLOCK	1		;TEMP LOC FOR DX10
TX1ULB:! BLOCK	.ULLEN		;MICROCODE LOADER BLOCK
TX1SNS:! BLOCK	CPSNSW+1	;SENSE BYTE STORAGE
TX1SUN:! BLOCK	1		;NON-EXISTANT DRIVE BEING SENSED
TX1IUM:! BLOCK	TX1DMW		;IGNORE UNIT MASK
TX1NUM:! BLOCK	TX1DMW		;NEW UNIT MASK
TX1KLN:!			;LENGTH OF KDB
	.ORG

	 .ORG	TUBLEN
TX1IST:! BLOCK	TX1ELN		;LAST ERROR INITIAL STATUS
TX1FST:! BLOCK TX1ELN		;LAST ERROR FINAL STATUS
TX1ULN:!			;LENGTH OF UDB
	 .ORG


TX1KDB:	KDBBEG	(TX1,TX1KLN)
	SETWRD	(KDBNAM,<SIXBIT/MT/>)	;KONTROLLER NAME
	SETWRD	(KDBIUN,<TKBUDB>)	;INITIAL POINTER TO UDBS
	SETWRD	(KDBCUN,<TKBUDB>)	;CURRENT POINTER TO UDBS
	SETWRD	(KDBIUM,<TX1IUM>)	;OFFSET TO IGNORE UNIT MASK
	SETWRD	(KDBNUM,<TX1NUM>)	;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


TX1UDB:	UDBBEG	(TX1,TX1ULN)
	SETWRD	(UDBNAM,<SIXBIT/MT/>)	;DRIVE NAME
	SETWRD	(UDBPCC,< TX1ELN,,TX1FST>) ;PHYSICALLY CONTIGUOUS CORE
	SETWRD	(TUBIEP,<-TX1ELN,,TX1IST>) ;INITIAL ERROR POINTER
	SETWRD	(TUBFEP,<-TX1ELN,,TX1FST>) ;FINAL ERROR POINTER
	UDBEND

EQUATE	(LOCAL,CPOPJ##,<TX1IDL>)

TX1ICD==TAPICD##		;PROTOTYPE INTERRUPT CODE ADDRESS
TX1ICL==TAPICL##		;PROTOTYPE INTERRUPT CODE ADDRESS
TX1INT==TAPINT##		;INTERRUPT SERVICE
TX1ELG==TPELGX##		;MAKE AN ERROR LOG ENTRY

TX1DSP:	DRVDSP	(TX1,TAPCHN##,TDVDDB##,TDVLEN##,TPMDIA##)
	TPK	(TX1,YES,377777) ;SERVICE DEPENDENT DISPATCH

TX1CKT:	EXP	K.TX1,K.DX2,K.TS1,0 ;COMPATIBLE KONTROLLER TABLE

TX1NBF:	TPNBF	(RW,RU)		;NON-BLOCKING FUNCTION MASK

;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT:	MDKL10	(7,220,0,0,<MD.KON>)	;DEVICE CODE 220
	MDKL10	(7,224,0,0,<MD.KON>)	;DEVICE CODE 224
	MDKL10	(7,034,0,0,<MD.KON>)	;DEVICE CODE 034
	MDTERM				;TERMINATE TABLE

;PROTOTYPE MICROCODE LOADER BLOCK
TX1ULP:	 EXP	.BTTX1##		;MICROCODE INDEX
	 XWD	0,0			;DEVICE CODE,,MASSBUS UNIT NUMBER
	 SIXBIT	/TX01/			;INTERFACE NAME
	 SIXBIT	/DX10/			;CHANNEL NAME
	 EXP	TX1MVR			;MINIMUM MICROCODE VERSION
	 EXP	0			;DATE/TIME OF LOAD SUCCESS OR FAILURE
	 EXP	0			;MICROCODE VERSION
	 EXP	0			;POINTER TO MAGIC TABLE
	 EXP	0			;MICROCODE LENGTH
	 EXP	0			;MICROCODE ADDRESS
SUBTTL INTERRUPT SERVICE

;CALED HERE FROM TAPSER WHEN AN INTERRUPT HAPPENS FOR THIS KONTROLLER
;W/ KDB ADDRESS

TX1ISR:	XCT	KDBCNI(W)	;GET CONI INTO T1
	PUSHJ	P,SETXS		;SETUP EXTENDED STATUS
				;ON RETURN, T4=ICPC, T3=CP.ST1,,,,RH(CONI)
	TRNE	T1,CI.UPE!CI.MPE!CI.NXM	;CHANNEL ERROR?
	JRST	ERRCH1		;YES, ALAS
	TRNN	T1,CI.STA	;STATUS STORED?
	JRST	ERRUPE		;TREAT AS UP ERROR
	TLNE	T3,(CS.SLE!CS.SQE) ;SELECTION ERROR (ETC.)?
	JRST	ERRCH2		;YES - SICK CHANNEL MAYBE
	LDB	T1,STYTYP	;GET STATUS TYPE
	CAIN	T1,CS.STI	;IDLE STATUS
	JRST	ERRINT		;YES, FAKED-UP INTERRUPT TO HANDLE AN ERROR
	JUMPN	U,@TPIDSP(T1)	;DISPATCH IF WE HAVE A UDB
	LDB	T2,STYDAI	;GET DRIVE WHICH INTERRUPTED
	HRRE	T3,TX1SUN(W)	;AND DRIVE WE MAY HAVE REQUESTED
	CAIN	T2,(T3)		;INTERRUPT FOR NON-EXISTANT DRIVE?
	JRST	ERRCH4		;YES--JUST CLEAR STATUS AVAILABLE AND DISMISS
	JRST	ERRUPE		;ELSE REAL ERROR

;DISPATCH TABLE ON STATUS TYPE

TPIDSP:	IFIW	ERRCH3		;INITIAL SELECTION STATUS
	IFIW	TPINT1		;ENDING STATUS
	IFIW	TPINT2		;CU INTERRUPT STATUS


;HERE ON IDLE-STATUS INTERRUPT.
;THIS WAS GENERATED WHEN WE HAD AN ERROR IN A MULTI-BLOCK XFER
ERRINT:	MOVE	U,@KDBCUN(W)	;SET U TO RIGHT UDB
	SKIPN	T1,TUBCNI(U)	;INTRPT BECAUSE OF AN ERROR?
	SOJA	T1,CLRSTA	;NO, INDICATE TIME FOR A SCHEDULE CYCLE
	HRRZ	T2,TUBFEP(U)	;POINT TO EXTENDED AREA
	ADD	T2,U		;RELOCATE
	MOVE	T1,T2		;COPY EXTENDED AREA ADDRESS
	SKIPL	CP.STS(T4)	;ALREADY NEGATIVE?
	TLOA	T2,(-<CPSNSB>B<CPSBCP>) ;NO, MAKE SURE IT LOOKS THAT WAY
	HLL	T2,CP.STS(T4)
	HLLM	T2,CP.STS(T4)
	MOVE	T3,XS.ST1(T1)
	MOVEM	T3,CP.ST1(T4)
	MOVE	T3,XS.ST2(T1)
	MOVEM	T3,CP.ST2(T4)
	MOVE	T3,TUBCNI(U)	;STATUS INTO T3
	HRRZM	T3,T1		;CONI BITS INTO T1
	SETZM	TUBCNI(U)	;CLEAR THE ERROR-WORD
	JRST	TPINT1		;AND PRETEND ITS A REAL INTERRUPT
;HERE ON AN INTERRUPT WITH CU INT. STATUS STORED

TPINT2:	MOVSI	T1,TKSOFL##	;UNIT ON LINE?
	TDNN	T1,TUBSTS(U)	; ...
	JRST	TPIN2A		;YES - SEE IF RUNL TERMINATION
	TLNN	T3,(DS.DVE)	;DEVICE END?
	JRST	ERRUPE		;NO, CALL IT A MICROPROCESSOR ERROR
	ANDCAM	T1,TUBSTS(U)	;UNIT NOW ON LINE
				;NO - LONGER REWINDING EITHER

;HERE IF CU STORED STATUS AND UNIT WAS ON LINE
;THE ONLY CASES OF THIS ARE THE TERMINATION OF A REWIND OR REWIND  AND UNLOAD
;OR DSE

TPIN2A:	PUSH	P,T3
	MOVSI	T1,TUSREW##	;IF UNIT ISN'T REWINDING
	TDNN	T1,TUBSTS(U)
	PUSHJ	P,TPMONL##	;IT JUST CAME ON-LINE, TELL MDC
	PUSHJ	P,REWDON##	;FLAG AS DONE REWINDING
	POP	P,T3		;RESTORE CONI BITS
	TLNN	T3,(DS.UCH)	;UNLOAD?
	JRST	TPINT3		;NO
	HRRZ	T2,TUBFEP(U)	;OFFSET TO FINAL ERROR POINTER
	ADD	T2,U		;RELOCATE
	MOVE	T2,XS.S0(T2)	;FETCH SENSE BYTES 0 - 3
	TLNN	T2,(SB1TUA)	; OR DSE ERROR
	JRST	TPIN2B		;IT WAS UNLOAD
	TLNE	T2,(SB1TUB)	;NOT READY DURING DSE?
	JRST	ERROFL		;YES
TPIN2B:	MOVSI	T1,TUSBOT##
	ANDCAM	T1,TUBSTS(U)	;TURN OFF BOT
	MOVSI	T1,TKSOFL##
	IORM	T1,TUBSTS(U)	;TURN ON OFL


;HERE ON AN INTERRUPT WITH IDLE STATUS STORED
;ALSO A COMMON EXIT

TPINT3:	MOVNI	T1,1		;ASSUME SCHED CYCLE WANTED
	MOVSI	T2,TKSSEL##	;IF CHANNEL ALREADY SELECTED
	TDNE	T2,TKBSTS(W)	; ...
	MOVEI	T1,0		;SELECTED - NO SCHED CYCLE

				;AND FALL INTO CLRSTA
;HERE TO CLEAR STATUS AVAILABLE ONLY
;IS TRANSPARENT WRT ALL AC'S

CLRSTA:	PUSH	P,T1		;SAVE T1
	XCT	KDBCNI(W)	;GET BITS
	TRZ	T1,-1-CO.CLR!CO.CON ;PRESERVE CLR & CONT
	IORI	T1,CO.ILI!CO.STA+TAPCHN## ;ONLY CLEAR STAT AVAIL
	TLNN	T1,1		;UP STILL RUNNING ?
	TRZ	T1,TAPCHN##	;NO, DON'T LIGHT PI
	XCT	KDBCNO(W)	;SEND TO DEVICE
	JRST	TPOPJ##
;HERE ON ENDING STATUS INTERRUPT

TPINT1:	PUSHJ	P,CHKIRB##	;SANITIZE IORB QUEUE
	  JRST	[PUSHJ P,CLRSTA	;NONE, CLEAR STATUS AVAIL
		 JRST TAPDIS##]	; AND EXIT THE INTERRUPT
	MOVE	T2,CP.ST1(T4)	;GET STATUS WORD
	TRNE	T2,ST1NFG	;WAS EXTENDED STATUS STORED?
	JRST	ERRUPE		;NO - TREAT AS UP ERR
	TRNE	T2,ST1INC	;OPERATION COMPLETE
	JRST	ERROF1		;NO - TREAT AS OFF-LINE
	MOVSI	T2,TUSBOF##	;CLEAR BOT AND OFL
	ANDCAM	T2,TUBSTS(U)	; ...
	HRRZ	T2,TUBFEP(U)	;OFFSET TO FINAL ERROR POINTER
	ADD	T2,U		;RELOCATE
	MOVE	T2,XS.S0(T2)	;FETCH SENSE BYTES 0 - 3
	TLNE	T2,(SB0WCZ)	;WORD COUNT 0 AND NO MOTION?
	JRST	ERRRD0		;YES, SET NO MOTION
	LDB	T2,PRBFCN##	;NO, GET FUNCTION
	JRST	@TP1DSP(T2)	;OK - DISPATCH

;DISPATCH TABLE FOR ENDING STATUS

;WHEN THESE ROUTINES ARE ENTERED, W AND U ARE SETUP WITH KDB AND UDB
;T1 HAS THE IORB ADDRESS
;T4 HAS THE ICPC ADDRESS, T3 HAS CP.ST1 FROM THE ICPC AREA

TP1DSP:	IFIW	TAPIFI##	;(00) ILLEGAL
	IFIW	TP1RD		;(01) READ
	IFIW	TP1WT		;(02) WRITE
	IFIW	TP1RB		;(03) READ BACKWARDS
	IFIW	TP1SR		;(04) SKIP RECORD
	IFIW	TP1BR		;(05) BACKSPACE RECORD
	IFIW	TP1SF		;(06) SKIP FILE
	IFIW	TP1BF		;(07) BACKSPACE FILE
	IFIW	TP1ERG		;(10) ERASE GAP
	IFIW	TP1DSE		;(11) DATA SECURITY ERASE
	IFIW	TP1REW		;(12) REWIND
	IFIW	TP1RUN		;(13) REWIND AND UNLOAD
	IFIW	TP1WTM		;(14) WRITE TAPE MARK
	IFIW	TAPIFI##	;(15) YELLOW BALL
	IFIW	TP1CR		;(16) CORRECTION READ
	IFIW	TP1RD		;(17) JUST PLAIN READ HERE
TPI1MX==.-TP1DSP-1
SUBTTL ENDING INTERRUPT PROCESSING OF A READ AND CORRECTION READ

TP1CR:
TP1RD:	PUSHJ	P,STRDWT	;SETUP
	MOVEI	T2,TUC7TK##
	TDNN	T2,TUBCNF(U)	;IF 7 TRACK
	PUSHJ	P,CHKXSP	;OR NO EXTENDED STATUS
	  JRST	TP1RD2		;CAN'T READ DENSITY
	PUSH	P,T4		;SAVE AN AC
	HRL	T4,XS.S0(T2)	;DENSITY IS IN SENSE BYTES
	TLNE	T4,SB3D16
	JRST	[MOVEI T2,RB.D16
		 JRST TP1RD1]	;1600
	HRL	T2,XS.S4(T2)
	HRRI	T2,RB.D8	;ASSUME 800
	TLNE	T2,SB6D62
	HRRI	T2,RB.D62	;NO, IT IS 6250
TP1RD1:	DPB	T2,PRBDEN##	;TELL THE WORLD
	POP	P,T4		;RESTORE T4
TP1RD2:	TRNN	T3,CI.CSR	;CSR FLAG UP?
	JRST	RDOK2		;NO, ALL IS WELL
	TLNN	T3,(CS.DSF)	;IS DSR FLAG UP?
	JRST	T1RDOK		;NO - MUST BE LENGTH ERR OR DEV PARITY
	TLNN	T3,(DS.UEX)	;UNIT EXCEPTION?
	JRST	ERRRD2		;NO - JUST ANOTHER ERROR
	PUSHJ	P,NXTFIL	;1 FILE FARTHER ALONG

T1RDOK:	TLNE	T3,(DS.UCH!CS.DPE)	;UNIT CHECK?
	JRST	ERRRD2		;YES - AN ERROR ALONG WITH TPM
	TLNN	T3,(CS.LNE)	;LENGTH ERROR?
	JRST	RDOK2		;NO
	LDB	T2,CPY2BC	;GET RESIDUAL BYTE COUNT
	JUMPN	T2,RDOK1	;IF NON ZERO, RECORD WAS TOO SHORT
	MOVSI	T2,RB.STL!RB.SER	;ELSE TOO LONG
	IORM	T2,TRBSTS(T1)	;FLAG IN IORB
	JRST	RDOK2
RDOK1:	TLNN	T3,(DS.UEX)	;RECORD SHORT - EOF?
	AOS	TUBREC(U)	;NO, COUNT THE RECORD
RDOK2:	PUSHJ	P,CHKRBC	;GET BYTE COUNT
	  MOVE	T2,XS.RBC(T2)	;FROM RIGHT AREA
RDOK3:	MOVEM	T2,TRBRCT(T1)	;STORE IN IORB
;*********PROBLEM WITH MULTIPLE COMMANDS********
	ADDM	T2,TUBCRD(U)	;UPDATE STATISTICS
	ADDM	T2,TKBCRD(W)
	ADDM	T2,.CPTFI##
	LDB	T3,PRBMOD##	;GET MODE
	IDIV	T2,TMODTB##(T3)	;GET NUMBER OF WORDS AND RESIDUE
	HRLM	T2,TUBCHR(U)	;STORE WORD COUNT
	DPB	T3,PMTNCR##	;STORE REMAINDER
	PUSHJ	P,CSDMP##	;MAKE SURE WE GET BYTE COUNTS FROM
				; PHYSICAL MEMORY AND NOT FOR CACHE

;HERE TO EXIT FROM AN INTERRUPT AND RETURN THE IORB ADDR IN T1

DONE:	MOVE	F,TUBCUR(U)	;GET DDB
	MOVSI	T3,IOSRTY##	;GET RETRY BIT
	ANDCAM	T3,DEVIOS(F)	;CLEAR (TAPUUO WILL RESET IF NECESSARY)
	HLRZ	T3,TRBSTS(T1)	;SEE IF ANY FLAGS ARE ON
	MOVSI	T2,RB.EXC	;GET BIT
	SKIPE	T3		;ANY FLAGS?
	IORM	T2,TRBFNC(T1)	;STORE
	PUSHJ	P,FXLST		;BLESS XFER LIST
	PUSHJ	P,CLRICP	;SETUP ICPC AREA FOR IDLENESS
	PJRST	CLRSTA		;CLEAR STATUS AVAILABLE

;ERROR HANDLERS FOR READ AND READ LIKE OPERATIONS

ERRRD0:	MOVSI	T2,RB.SNM!RB.SED ;HERE WHEN NO TAPE MOTION
	IORM	T2,TRBSTS(T1)	;FLAG IN IORB

ERRRD1:	PUSHJ	P,ERRANL	;ANALYZE SENSE BYTE 0 ETC.
	JRST	DONE		;TERMINATE

ERRRD2:	PUSHJ	P,ERRANL	;ANL..
	JRST	RDOK2		;COPY BYTE COUNT
SUBTTL ENDING INTERRUPT PROCESSING OF READ BACKWARDS

TP1RB:	SOS	TUBREC(U)	;DECREMENT RECORD COUNT
	TRNN	T3,CI.CSR	;CSR FLAG UP?
	JRST	T1RBOK		;NO - WIN
	TLNE	T3,(DS.UEX)	;UNIT EXCEPTION?
	PUSHJ	P,LSTFIL	;YES, 1 FEWER FILES
	TLNN	T3,(DS.UCH)	;UNIT CHECK?
	JRST	T1RB2		;NO - LOOK CLOSER
	PUSHJ	P,ITUCOK	;IS THIS UNIT CHECK OK?
	  JRST	ERRRD2		;NO - BOMB
	MOVSI	T2,RB.SBT!RB.SNM ;BOT AND NO MOTION
	SKIPN	TUBREC(U)	;AT BOT PREVIOUSLY?
	SKIPE	TUBFIL(U)	; ???
	SETZ	T2,		;NO - JUST HIT BOT
	IORM	T2,TRBSTS(T1)	; ...
T1RB2:	TLNE	T3,(CS.DPE)	;PAR ERR?
	JRST	ERRRD2		;YES
T1RBOK:	HRRZ	T2,TUBFEP(U)	;OFFSET TO FINAL ERROR POINTER
	ADD	T2,U		;RELOCATE
	MOVE	T2,XS.S0(T2)	;FETCH SENSE BYTES 0 - 3
	TLNE	T2,(SB1BOT)	;AT BOT?
	PUSHJ	P,SETBOT	;FLAG AS BOT
	JRST	T1RDOK		;JOIN READ PROCESSING

;****** ALWAYS CHECK BOT ON ANY BACKWARD-MOVING OPERATION*******


LSTFIL:	SOSA	TUBFIL(U)	;1 LESS FILE
NXTFIL:	AOS	TUBFIL(U)	;1 MORE FILE
	SETZM	TUBREC(U)	;AT ZEROTH RECORD
	MOVSI	T2,RB.STM	;TAPE MARK
	IORM	T2,TRBSTS(T1)	;FLAG IN IORB
	POPJ	P,		;AND RETURN
SUBTTL ENDING INTERRUPT PROCESSING OF A WRITE

TP1WT:	PUSHJ	P,STRDWT	;SETUP
	TRNN	T3,CI.CSR	;IS CSR FLAG UP?
	JRST	T1WTOK		;NO - OK
	TLNN	T3,(DS.UEX)	;UNIT EXCEPTION?
	JRST	ERRWT1		;ERROR
	MOVSI	T2,RB.SET	;SET END OF TAPE BIT IN IORB
	IORM	T2,TRBSTS(T1)	; ...
	TLNE	T3,(DS.UCH!CS.DPE)	;UNIT CHECK
	JRST	ERRWT1		;ERROR

T1WTOK:	PUSHJ	P,CHKRBC	;GET BYTE COUNT FROM THE RIGHT AREA
	  MOVE	T2,XS.RBC(T2)	;GET COUNT FROM THERE
T1WOK2:
;**************PROBLEM***************
	ADDM	T2,TUBCWR(U)	;UPDATE STATS
	ADDM	T2,TKBCWR(W)
	ADDM	T2,.CPTFO##
	JRST	DONE		;EXIT

;ERROR HANDLERS FOR WRITE AND WRITE LIKE OPERATIONS

ERRWT1:	PUSHJ	P,ERRANL	;ANALYZE SENSE BYTE 0 ETC
	TLNN	T4,(SB1WTL)	;WRITE LOCKED?
	JRST	DONE		;NO - TERMINATE
	MOVSI	T2,RB.SLK	;FLAG WRITE LOCK
IRBDON:	IORM	T2,TRBSTS(T1)	;IN IORB
	JRST	DONE		;TERMINATE
;COMMON CODE FROM READ AND WRITE INTERRRUPT ROUTINES

STRDWT:	MOVE	T2,TKBCNT(W)	;NUMBER OF RECS DONE THIS TIME
	SOJLE	T2,STRDW4	;NOTHING FANCY IF ONLY 1
	TRNN	T3,CI.CSR	;MULTIPLE RECS, ANY ERRORS?
	JRST	STRDW5		;NO, EXIT

;HERE IF THERE WAS AN ERROR ON SOME RECORD IN THE CHAIN
	HRRO	F,CP.ST2(T4)	;WHERE DX10 STOPPED
	SUBI	F,1		;IT POINTS 1 PAST NEXT DEV COMMAND WORD
STRDW2:	LDB	T2,[POINT 9,(F),8] ;GET THE OP CODE
	CAIN	T2,<(CCHGO+CCHSAV)>/1000 ;IF A SAVE-WRDCNT WORD
	AOJA	F,STRDW2	; IGNORE IT
	LSH	T2,-7		;GET LEFTMOST 2 BITS
	JUMPE	T2,STRDW3	;GO IF A JUMP-WORD
	SOSN	T2		;IS IT A DEVICE-COMMAND WORD?
	SOSA	TKBCNT(W)	;YES, DECREMENT COUNT OF RECORDS
	AOJA	F,STRDW2	;GO LOOK AT NEXT CHANNEL COMMAND
	TLZN	F,-1		;1ST COMMAND AFTER ERROR RECORD?
	AOJA	F,STRDW2	;NO, PROCEED
	MOVSI	T2,(CCHSTS)	;YES, CONVERT COMMAND TO HALT
	DPB	T2,[POINT 2,(F),1] ; SO IF WE RETRY WITH THIS LIST
	IORM	T2,(F)		; WE WILL ONLY WRITE 1 RECORD
	AOJA	F,STRDW2
STRDW3:	HRRZ	F,(F)		;JUMP-WORD, GET ITS ADDRESS
	JUMPN	F,STRDW2	;CONTINUE IF NOT THE END
	SOS	T2,TKBCNT(W)	;DECR 1 FOR THE ERROR-RECORD
	JUMPE	T2,STRDW6	;ERROR WAS ON 1ST REC IF 0
	MOVEM	T3,TUBCNI(U)	;SOME GOOD RECS - SAVE ERR STATUS
	SETZ	T3,		;PRETEND NO ERRORS FOR THIS BUNCH
	MOVSI	T2,RB.SEN	;TELL TAPUUO TO USE THE WORDCOUNT
	IORM	T2,TRBSTS(T1)	;; FROM THE USER'S BUFFER FOR ALL RECS
	JRST	STRDW5		;UPDATE TUBREC AND EXIT
STRDW4:	SKIPE	CP.STS(T4)	;IS THERE AN EXTENDED STATUS AREA?
	JRST	STRDW5		;YES, USE IT
	HRLI	T2,(-<CPSNSB>B<CPSBCP>)
	HLLM	T2,CP.STS(T4)
STRDW5:	SKIPN	T2,TKBCNT(W)	;GET NUMBER OF BLOCKS XFERRED
STRDW6:	AOSA	TUBREC(U)	;ERROR ON 1ST RECORD
	ADDM	T2,TUBREC(U)	;UPDATE UDB ACCORDINGLY
	POPJ	P,		;RETURN TO CALLER
SUBTTL ENDING INTERRUPT PROCESSING OF A BACKSPACE BLOCK

TP1BR:	TRNN	T3,CI.CSR	;CSR FLAG UP?
	JRST	T1BR2		;NO - NOTHING SPECIAL
	TLNN	T3,(DS.UEX)	;UNIT EXCEPTION?
	JRST	T1BR1		;UNIT CHECK
	SETOM	TUBREC(U)	;AT AN EOF
	SOS	TUBFIL(U)	;ONE FILE LESS
	MOVSI	T2,RB.STM	;SEEN TAPE MARK
	JRST	IRBDON		;SET BIT IN IORB AND DONE

T1BR1:	TLNE	T3,(DS.UCH)	;UNIT CHECK?
	PUSHJ	P,ITUCOK	;IS THIS UNIT CHECK OK?
	  JRST	ERRRD1		;TREAT AS READ ERROR
	SKIPN	TUBREC(U)	;PREVIOUSLY AT BOT?
	SKIPE	TUBFIL(U)	; ???
	JRST	T1BROK		;NO
	PUSHJ	P,SETBOT	;SET LOAD POINT
	MOVSI	T2,RB.SNM	;NM
	JRST	IRBDON		;STORE BIT IN IORB AND DONE

T1SROK:	AOS	TUBREC(U)	;INCREMENT POSITION
	JRST	RPTDON		;CHECK REPEAT
T1BR2:	SOS	TUBREC(U)	;DECREMENT POSITION
T1BROK:	HRRZ	T2,TUBFEP(U)	;OFFSET TO FINAL ERROR POINTER
	ADD	T2,U		;RELOCATE
	MOVE	T2,XS.S0(T2)	;FETCH SENSE BYTES 0 - 3
	TLNN	T2,(SB1BOT)	;LOAD POINT?
	JRST	RPTDON		;NO - ALL DONE BUT CHECK REPEAT
	PUSHJ	P,SETBOT	;FLAG AT BOT
	JRST	DONE		;LEAVE
SUBTTL ENDING INTERRUPT PROCESSING OF A WRITE TAPE MARK

TP1WTM:	TRNN	T3,CI.CSR	;CSR FLAG UP?
	JRST	INCFIL		;NO - WIN EASY
	TLNN	T3,(DS.UEX)	;UNIT EXCEPTION?
	JRST	ERRWT1		;NO - UNIT CHECK OR SOME HORROR
	MOVSI	T2,RB.SET	;FLAG END OF TAPE
	IORM	T2,TRBSTS(T1)	;...
	TLNE	T3,(DS.UCH!CS.DPE) ;ALSO UNIT CHECK?
	JRST	ERRWT1		;YES
INCFIL:	SETZM	TUBREC(U)	;AT ZEROTH RECORD
	AOS	TUBFIL(U)	;AND ONE MORE FILE
	JRST	DONE		;ALL DONE
SUBTTL	ENDING INTERRUPT PROCESSING OF SKIP BLOCK
TP1SR:	TRNN	T3,CI.CSR	;CSR FLAG UP?
	JRST	T1SROK		;NO - ALL IS WELL
	TLNN	T3,(DS.UEX)	;UNIT EXCEPTION?
	JRST	ERRRD1		;NO - MUST BE ERRORS
	PUSHJ	P,NXTFIL	;AT NEXT FILE
	JRST	DONE		;ALL DONE
SUBTTL	ENDING INTERRUPT PROCESSING OF A FORWARD SKIP FILE

TP1SF:	TLNE	T3,(DS.UCH)	;SOME HORROR HAPPEN?
	JRST	ERRRD1		;YES
	PUSHJ	P,NXTFIL	;AT NEXT FILE
	JRST	DONE
SUBTTL	ENDING INTERRUPT PROCESSING OF A BACKSPACE FILE

TP1BF:	TLNN	T3,(DS.UCH)	;SOMETHING MIGHT BE WRONG?
	JRST	TP1BF2		;NO
	PUSHJ	P,ITUCOK	;MAYBE IT'S OK
	JRST	ERRRD1		;ERROR
	SKIPN	TUBFIL(U)	;SHOULD BE AT BOT
	SKIPE	TUBREC(U)	;ARE WE?
	JRST	TP1BF3		;NO?
	PUSHJ	P,SETBOT	;SET AT BOT
	MOVSI	T2,RB.SNM	;NM
	JRST	IRBDON

TP1BF2:	SOS	TUBFIL(U)	;PREVIOUS
	SETOM	TUBREC(U)	;..
TP1BF3:	PUSHJ	P,ITUCOK	;CHECK FOR EXTENDED SENSE BYTES, ETC.
	  JRST	RPTDON		;THERE ARE NONE
	MOVE	T4,XS.S0(T2)	;GET SENSE BYTE WORD
	TLNN	T4,(SB1BOT)	;LOAD POINT?
	JRST	RPTDON		;NO
	PUSHJ	P,SETBOT	;FLAG AT BOT
	JRST	DONE
SUBTTL ENDING INTERRUPT PROCESSING OF A REWIND

TP1RUN:	MOVE	T2,TKBCCL+5(W)	;SOFT ERROR COUNTER STORED BY DX10
	ROT	T2,-^D12
	HRRZM	T2,TUBSWE(U)	;SOFT WRITE ERROR COUNT
	LSH	T2,-^D24
	MOVEM	T2,TUBSRE(U)	;SOFT READ ERROR COUNT
	SETZ	T2,		;CAUSE CAIN TO FAIL
				;FALL INTO TP1REW

TP1REW:	TRNE	T3,CI.CSR	;CSR FLAG UP?
	JRST	ERRREW		;YES - ERROR
	CAIN	T2,RB.FRW	;DONE IF REWIND AND UNLOAD
	SKIPL	CP.STS(T4)	;SEE IF THIS IS THE SENSE CMD
	JRST	T1RWOK		;ITS NOT - OK THEN
	HRRZ	T2,TUBFEP(U)	;OFFSET TO FINAL ERROR POINTER
	ADD	T2,U		;RELOCATE
	MOVE	T2,XS.S0(T2)	;FETCH SENSE BYTES 0 - 3
	MOVSI	T3,TUSWTL##	;WRITE LOCKED STATUS BIT
	TLNE	T2,(SB1WTL)	;WRITE LOCKED?
	IORM	T3,TUBSTS(U)	;YES, SET THE BIT
	TLNN	T2,(SB1WTL)	;ARE WE WRITE LOCKED
	ANDCAM	T3,TUBSTS(U)	;NO, CLEAR THE BIT
	TLNE	T2,(SB1BOT)	;ARE WE AT BOT ALREADY
	JRST	REWFIN		;YES- FINISH UP
	MOVEI	T1,CO.ILI!CO.STA!CO.CON+TAPCHN## ;NO - CONTINUE CHL PGM
	PJRST	RETZC		;TO DO REWIND

T1RWOK:	MOVSI	T2,TUSREW##	;INDICATE REWIND IN PROGRESS
	IORM	T2,TUBSTS(U)
	PJRST	DONE		;AND SIGNAL COMPLETION NOW

;HERE ON AN ERROR STARTING A REWIND OR REWIND AND UNLOAD.
;WE DO NOT HAVE THE LUXURY OF THE SENSE BYTES IN THESE CASES

ERRREW:	MOVSI	T2,RB.SED!RB.SNM!RB.SOL	;ERROR, NO MOTION, OFFLINE
	IORM	T2,TRBSTS(T1)	; FLAG
REWFIN:	PUSHJ	P,REWDON##	;CLR REW STATUS
	JRST	DONE
SUBTTL EIP OF DSE,ERB,YB

;ENDING INTERRUPT PROCESSING OF AN ERASE GAP

TP1ERG:	TRNN	T3,CI.CSR	;CSR FLAG UP?
	JRST	RPTDON		;NO - NO OTHER SIDE EFFECTS
	TLNN	T3,(DS.UEX)	;UNIT EXCEPTION?
	JRST	ERRWT1		;NO - TRY WRITE ERROR ANALYSIS
	MOVSI	T2,RB.SET	;ELSE SAW END OF TAPE
	IORM	T2,TRBSTS(T1)	; ...
	TLNE	T3,(DS.UCH!CS.DPE) ;UNIT CHECK?
	JRST	ERRWT1		;YES - ANALYZE
	JRST	RPTDON		;ELSE RPTDON

;ENDING INTERUPT OF DATA SECURITY ERASE

TP1DSE:	TLNN	T3,(DS.UCH)	;UNIT CHECK?
	JRST	DONE		;NO - OK
	JRST	ERROFL		;YES - OFFLINE THEN
SUBTTL RANDOM SMALL UTILITIES

;HERE TO CHECK IF REPEATED OP SHOULD RESTART OR TERMINATE

RPTDON:	HRRZ	T2,@IRBACC(T1)	;COUNT IS WHERE XFR LIST WOULD BE
	SUBI	T2,1		;ONE LESS
	HRRM	T2,@IRBACC(T1)	;RESTORE
	JUMPLE	T2,DONE		;IF NO MORE TO DO, DONE
	HLRZ	T3,TRBSTS(T1)	;ANYTHING WRONG?
	JUMPN	T3,DONE		;WHICH FORCES TERMINATION
	PUSHJ	P,SETXSP	;SET UP XS AREA
	MOVEI	T1,CO.ILI!CO.STA!CO.CLR!CO.CON+TAPCHN##	;RESTART IO
RETZC:	XCT	KDBCNO(W)
RETZER:	MOVEI	T1,0		;INDICATE ANOTHER INTERRUPT TO COME
	POPJ	P,		;RETURN TO TAPSER

;HERE WHEN A FATAL ERROR IS TO BE SIGNALED

FATAL:	MOVSI	T2,RB.SER!RB.SED ;NON REC + SOME ERROR
	JRST	IRBDON		;SET IN IORB, JOIN OTHER PROCESSING

;HERE TO CHECK IF THERE WAS A TRANSFER ACTIVE ON THE
;UDB POINTED TO BY TKBCUN

WATA:	SKIPN	U,@KDBCUN(W)	;GET CURRENT UDB POINTER
	POPJ	P,		;NONE ACTIVE
	MOVSI	T2,TKSSTD##	;SEE IF SELECTED
	TDNE	T2,TUBSTS(U)	; ...
	AOS	(P)		;YES - SKIP
	POPJ	P,		;NO - CAN'T BE ACTIVE

;HERE TO RESET THE INTERRUPT CAUSING BITS

CLRCHN:	PUSH	P,T1		;BE TRANSPARENT
	MOVE	T1,KDBICP(W)	;GET ICPC ADDRESS
	LSH	T1,^D33-CO.ICP	;POSITION IN CONO
	IORI	T1,CO.UPE!CO.MPE!CO.NXM!CO.STA+TAPCHN##	;RESET
	XCT	KDBCNO(W)	;SEND TO THE DEVICE
	PJRST	TPOPJ##		;RESTORE T1

;HERE TO RESET THE ICPC AREA - PREPARE FOR IDLENESS

CLRICP:	MOVE	T4,KDBICP(W)	;GET ICPC BASE
	SETZM	CP.STS(T4)	;CLEAR XS POINTER
	POPJ	P,		;RETURN

;HERE TO SET BOT

SETBOT:	MOVSI	T2,RB.SBT	;SET BOT
	IORM	T2,TRBSTS(T1)	;IN IORB
	PJRST	UNIBOT##	;SET TUSBOT, CLEAR TUBREC,TUBFIL
;MICROPROCESSOR CONTROL RTNS

UPHALT:	MOVEI	T2,DO.UC0	;SELECT CTL 0
	PUSHJ	P,UPRSEL	; ...
	MOVEI	T2,DU0HLT	;SET HALT
	PJRST	UPGO

UPSTRT:	MOVEI	T2,DO.UC1	;SELECT CTL 1
	PUSHJ	P,UPRSEL	; ...
	SETZ	T2,		;BUILD ADDR
	DPB	T3,DOYU1A	; ...
	XCT	KDBDTO(W)	; SEND OUT
	MOVEI	T2,DO.UC0	;SELECT CTL 0
	PUSHJ	P,UPRSEL	; ...
	MOVEI	T2,DU0CON	;SET CONTINUE
	PJRST	UPGO

;READ AN IBUS REGISTER

UPREAD:	PUSHJ	P,UPRSEL	;SELECT REGISTER
	XCT	KDBDTI(W)	;READ CONTENTS
	POPJ	P,

UPRSEL:	TLOA	T2,(DO.LRS)	;LOAD REG SELECT BIT
UPRES:	MOVSI	T2,(DO.RES)	;ISSUE RESET COMMAND
UPGO:	XCT	KDBDTO(W)	;SELECT REGISTER
	POPJ	P,

;READ UP MEMORY.
;ADDR IN T3, RESULT IN T2

UPMRD:	MOVEI	T2,DO.UC1	;SELECT CTL 1
	PUSHJ	P,UPRSEL	; ...
	MOVEI	T2,0		;BUILD ADDR
	DPB	T3,DOYU1A	; ...
	XCT	KDBDTO(W)	;SEND ADDR
	MOVEI	T2,DO.UC0	;SEL CTL 0
	PUSHJ	P,UPRSEL	; ...
	MOVEI	T2,DU0EXM	;FORCE EXAMINE BIT
	XCT	KDBDTO(W)	;SEND OUT
	XCT	KDBDTI(W)	;GET DATA
	LDB	T2,DOYU0D	; ...
	POPJ	P,
;MORE SMALL UTILITIES

;CALL WITH IORB ADDR IN T1
;SKIP RETURNS END OF LIST IT T4
;NON SKIP RETURN IF NO LIST

GETEXL:	LDB	T2,PRBFCN##	;GET FUNCTION
	SKIPL	IOFTAB(T2)	;IS A DATA XFR LIST NEEDED?
	POPJ	P,		;NO - RETURN NON SKIP
	HLRZ	T4,@IRBACC(T1)	;GET END FROM IORB
	JUMPN	T4,CPOPJ1##	;SKIP RETURN
	POPJ	P,

;HERE TO COPY USEFUL THINGS INTO THE EXTENDED STATUS AREA
;ASSUMES T1=CONI
;EXITS WITH T4=ICPC; T3=CP.ST1,,RH(CONI)

SETXS:	MOVE	T4,KDBICP(W)	;GET ICPC
	LDB	T2,STYDAI	;GET THE UNIT NUMBER
	SETZM	U
	CAIG	T2,TX1HDN	;RANGE CHECK UNIT NUMBER
	PUSHJ	P,SETUDB##	;GET THE UDB
	  JRST	SETXS1		;UNKNOWN DRIVE
	HRRZ	T2,TUBFEP(U)	;GET FINAL ERROR POINTER
	ADD	T2,U		;OFFSET INTO UDB
	MOVE	T3,TKBCCL(W)	;GET CMD(S)
	MOVEM	T3,XS.CMD(T2)
	MOVE	T3,TKBCCL+1(W)	;...
	MOVEM	T3,XS.CM1(T2)	;STORE IN UDB STATUS
	MOVE	T3,CP.ST2(T4)	;GET CP.ST2
	MOVEM	T3,XS.ST2(T2)	;STORE
	MOVE	T3,CP.ST1(T4)	;GET CP.ST1
	MOVEM	T3,XS.ST1(T2)	;STORE
	MOVEM	T1,XS.CNI(T2)	;SAVE CONI
	HRR	T3,T1		;ALSO IN RH(T3)
	POPJ	P,
SETXS1:	CAILE	T2,TX1HDN	;OUT OF RANGE?
	POPJ	P,		;GIVE UP
	MOVE	T1,BITTBL##(T2)	;GET ASSOCIATED BIT
	PUSH	P,T1		;SAVE T1
	TDNN	T1,TX1IUM(W)	;WANT TO IGNORE THIS DRIVE?
	PUSHJ	P,TX1DC2	;NO--BUT DOES DRIVE REALLY EXIST?
	  JRST	SETXS2		;DON'T TRY TO CONFIGURE THIS DRIVE
	MOVE	T1,(P)		;GET BIT BACK
	IORM	T1,TX1NUM(W)	;REMEMBER WHICH NEW DRIVE TO CONFIGURE
	HRROS	KDBNUM(W)	;FLAG IT FOR THE ONCE-A-SECOND CODE
SETXS2:	HRROS	TX1SUN(W)	;OK TO CHECK ANOTHER DRIVE NOW
	POP	P,(P)		;PHASE STACK
	XCT	KDBCNI(W)	;GET DEVICE STATUS BACK
	MOVE	T3,CP.ST1(T4)	;AND CP.ST1
	POPJ	P,		;AND RETURN


;HERE TO DETERMINE IF A UNIT CHECK IS OK.
;RETURNS SKIP IF OK.

ITUCOK:	PUSHJ	P,CHKXSP	;GET STATUS
	JRST	CPOPJ1##	;NONE
	TLNN	T4,(SB0!SB1TUB!SB1NC) ;CAUSES OF ERRORS
	AOS	(P)		;NOT A REAL ERROR
	POPJ	P,		;UNIT CHECK IS A REAL ERROR
;ROUTINE TO CLEAN UP XFER LIST

FXLST:	PUSHJ	P,GETEXL	;GET END OF XFER LIST IN T4
	  POPJ	P,		;NO XFR LIST
	SETZM	(T4)		;RESTORE LAST WORD
	MOVEI	T4,0		;CLEAR CHL JMP WORD
				;AND FALL INTO EXLJMP

;ROUTINE TO FIXUP CHL JMP FOR DX10
;WILL CONVERT EITHER DIRECTION
;C(T4) := DESIRED LH
;T1 SAVED

EXLJMP:	PUSH	P,T1		;SAVE T1
	HRRZ	T1,@IRBACC(T1)	;PNTR TO XFER LIST
	JUMPE	T1,TPOPJ##
EXLJM1:	MOVE	T2,3(T1)	;WORD TO CONSIDER
	JUMPE	T2,TPOPJ##	;ALL DONE IF ZERO
	HLRZ	T3,T2		;ISOLATE LHS
	SKIPE	T3		;OK IF ZERO
	CAIN	T3,(CCHJMP!CCHGO) ;  OR IF CHL JMP
	JRST	EXLJM2		;PROCESS JMP WORD
	ADDI	T1,4		;ADVANCE TO NEXT BLOCK
	JRST	EXLJM1		;TRY AGAIN

EXLJM2:	HLLM	T4,3(T1)	;CHANGE JMP WORD
	HRRZ	T1,T2		;ADVANCE ALONG JMP
	JRST	EXLJM1		;KEEP GOING
SUBTTL ERROR HANDLERS

ERRCH1:	TRNN	T1,7		;CHECK PIA
	JRST	[MOVEI T1,CO.ILI!CO.UPE!CO.MPE!CO.NXM!CO.STA
		 XCT KDBCNO(W) ;CLEAR ERROR IF IN BOOTDX
		 JRST TPOPJ##]   ;RETURN UP A LEVEL
	JUMPN	U,ERRCHT	;IF NO UNIT
	SKIPN	U,@KDBCUN(W)	;GET CURRENT UNIT
	JRST	ERRUPE		;BAIL OUT IF U=0
ERRCHT:	TRNN	T1,CI.UPE	;MICROPROCESSOR ERROR?
	JRST	ERRMEM		;NO - MEMORY ERROR OF SOME SORT
	PUSHJ	P,ERRUP1	;LOG UP ERROR INFO
ERRUPE:	PUSHJ	P,UPRES		;HALT 8
	PUSHJ	P,UPHALT	;STOP UP
	MOVE	T1,KDBICP(W)	;RESET ICPC
	LSH	T1,^D33-CO.ICP	;CORRECT POSITION IN CONO
	IORI	T1,CO.UPE!CO.MPE!CO.NXM!CO.STA
	XCT	KDBCNO(W)	;OF MICROPROCESSOR
	HLLZS	@KDBCSO(W)	;REMOVE FROM INTERRUPT CHAIN
	MOVSI	T1,TKSOFL##	;MARK AS OFFLINE
	IORM	T1,TKBSTS(W)	; ...
	JUMPE	U,RETZER
	PUSHJ	P,ERRCHX	;CHECK ON XFER ACTIVE
	  JRST	ERRUP2		;LOG ERROR - AND RETURN ZERO
	MOVSI	T2,RB.SOL!RB.SMO ;INDICATE MONITOR DIRECTED OFF-LINE
	IORM	T2,TRBSTS(T1)
	POPJ	P,		;YES - RETURN IORB IN T1

;HERE TO CHECK ON ACTIVE XFER AND SET ERROR BITS IF SO

ERRCHX:	PUSHJ	P,WATA		;WAS A TRANSFER ACTIVE?
	  POPJ	P,		;NO -EXIT
	HRRZ	T1,TUBQUE(U)	; ?
	JUMPE	T1,CPOPJ##	;NO ACTIVITY - EXIT
	MOVSI	T2,RB.SER!RB.SED ;NON REC + ERROR DETECTED
	IORM	T2,TRBSTS(T1)	;SET IN IORB
	MOVSI	T2,RB.EXC	;SET EXCEPTION ALSO HERE
	IORM	T2,TRBFNC(T1)	;...
	PUSHJ	P,GETEXL	;FIND END OF LIST
	  JRST	CPOPJ1##	;SKIP RETURN
	SETZM	0(T4)		;CLEAR IT
	MOVEI	T4,0		;CLEAR JMPS
	PUSHJ	P,EXLJMP	;...
	PJRST	CPOPJ1##	;SKIP RETURN
;ROUTINE TO LOG MP ERRORS WHEN THERE ARE NO ACTIVE TRANSFERS
;C(U)  :=UDB (PROBABLY UNIT 0, SINCE CP.ST1 IS ZERO)
;USE PROTOTYPE IF THERE IS NO DDB FOR THIS UNIT
ERRUP2:	MOVSI	T1,(1B1)	;MDO IS UNRECOVERABLE
	IORM	T1,TUBTRY(U)	;
	MOVSI	T1,TX1FST(U)	;COPY FROM "AT END"
	HRRI	T1,TX1IST(U)	; TO "AT ERROR"
	BLT	T1,TX1IST+TX1ELN-1(U) ; FOR SYSERR
	PUSHJ	P,TPELOG##	;LOG THE ERROR
	PJRST	RETZER		;RETURN ZERO
;MEMORY ERRORS COME HERE
;C(T1) :=CONI
;C(U)  :=UDB

ERRMEM:	PUSHJ	P,UPHALT	;STOP UPROCESSOR
	PUSHJ	P,RDIBUS	;STORE SOME IBUS REGISTERS
	PUSHJ	P,UPRES		;ISSUE RESET
	MOVEI	T3,UP.RA	;RESTART ADDR
	PUSHJ	P,UPSTRT	;START
	PUSHJ	P,CLRCHN	;RESET ICPC ETC.
	PUSHJ	P,SAVE3##
	HRRZ	T3,TUBFEP(U)	;PNTR TO EXTENDED
	ADD	T3,U		;STATUS AREA
	MOVE	P1,KDBCHN(W)	;GET CHAN DATA BLOCK
	MOVE	F,TUBCUR(U)	;GET DDB
	MOVE	P2,XS.CPC(T3)	;GET CPC
	MOVE	P3,XS.DAC(T3)	;GET DAC
	MOVE	T1,XS.CNI(T3)	;SEE IF NXM OR MPE
	MOVEI	T2,CHENXM##	;ROUTINE TO CALL
	MOVSI	T3,IOCHNX	;ASSUMING NXM
	TRNE	T1,CI.MPE	;UNLESS A MPE
	MOVEI	T2,CHEMPE##	; ...
	TRNE	T1,CI.MPE	; ...
	MOVSI	T3,IOCHMP	; ...
	IORM	T3,CHNNUM(P1)	;MARK MEMORY ERROR FOR LATER SWEEP
	MOVE	T1,T4		;ICPC NEEDED IN T1
	SKIPN	TUBERR(U)	;CALL ERRCON ON FIRST ERROR ONLY
	PUSHJ	P,(T2)		;CALL
	PUSHJ	P,ERRCHX	;CHECK ACTIVE XFER
	  PJRST	TPINT3		;NO - EXIT
	MOVSI	T2,RB.SER	;UNCORRECTABLE ERROR
	JRST	IRBDON		;MARK IN IORB AND RETURN

;READ SOME IBUS REGISTERS AND STORE IN TUBFEP
;ENTER WITH T4 := ICPC ADDR

RDIBUS:	PUSHJ	P,SETXSP	;GET XS POINTER
	MOVE	T3,T2
	PUSHJ	P,RDCPCA	;GET CPC AND CPMA/CPMD
	MOVEI	T2,DO.DR	;GET DATA REGISTER 0-17
	PUSHJ	P,UPREAD	;IBUS 1
	HRLZM	T2,XS.DR(T3)	;STORE IT
	MOVEI	T2,DO.DR	;GET DATA REGISTER 18-35
	PUSHJ	P,UPREAD	;IBUS 1
	HRRM	T2,XS.DR(T3)	;STORE IT
	MOVEI	T2,DO.DAC	;GET DAC 18-35
	PUSHJ	P,UPREAD	;IBUS 12
	HRRZM	T2,XS.DAC(T3)	;STORE IT
	MOVEI	T2,DO.BCD	;GET DAC 14-17
	PUSHJ	P,UPREAD	;IBUS 0
	ANDI	T2,17		;. . .
	HRLM	T2,XS.DAC(T3)	;STORE IT
	MOVEI	T2,DO.TAG	;GET TAG LINES
	PUSHJ	P,UPREAD	;IBUS 2
	HRLZM	T2,XS.TAG(T3)	;STORE IT
	MOVEI	T2,DO.BUS	;GET BUS LINES
	PUSHJ	P,UPREAD	;IBUS 3
	HRRM	T2,XS.TAG(T3)	;STORE IT
	MOVEI	T2,DO.MRL	;GET MR LOW
	PUSHJ	P,UPREAD	;IBUS 10
	HRLZM	T2,XS.MR1(T3)	;STORE IT
	MOVEI	T2,DO.MRH	;GET MR HIGH
	PUSHJ	P,UPREAD	;IBUS 11
	HRRM	T2,XS.MR1(T3)	;STORE IT
	POPJ	P,0		;RETURN
;HERE ON MICRO-PROCESSOR ERRORS
;C(T1) :=CONI
;C(U)  :=UDB

ERRUP1:	TLNE	T1,(CI.RUN)	;UP RUNNING ?
	PUSHJ	P,UPRES		;YES - RESET IT
	PUSHJ	P,UPHALT	;HALT IT
	HRRZ	T3,TUBFEP(U)	;GET XS POINTER
	ADD	T3,U		;OFFSET INTO UDB
	PUSHJ	P,RDCPCA	;GET CPC AND CPMA/CPMD
	TLNE	T1,(CI.RUN)	;WAS THE -8A RUNNING ?
	POPJ	P,0		;YES - THEN WE ARE DONE
	MOVE	T1,T3		;SAVE XS POINTER
	MOVEI	T3,5		;READ -8A LOCATION 5
	PUSHJ	P,UPMRD		;
	HRRM	T2,XS.DIAG(T1)	;STORE DIAGNOSTIC ERROR CODE
	POPJ	P,0		;RETURN

;HERE TO READ CPC AND CPMA/CPMD
;CALLED FOR MEMORY ERRORS AND UP ERRORS
;C(T3) :=XS POINTER
;DESTROYS T2

RDCPCA:	MOVEI	T2,DO.UC0	;GET MEMORY DATA
	PUSHJ	P,UPREAD	;IBUS 4
	HRRZM	T2,XS.MD(T3)	;STORE IT
	MOVEI	T2,DO.UC1	;GET MEMORY ADDRESS
	PUSHJ	P,UPREAD	;IBUS 5
	HRLM	T2,XS.MD(T3)	;STORE IT
	MOVEI	T2,DO.CPC	;GET LOW ORDER CPC
	PUSHJ	P,UPREAD	;IBUS 13
	HRRZM	T2,XS.CPC(T3)	;STORE IT
	MOVEI	T2,DO.BCD	;GET HIGH ORDER CPC
	PUSHJ	P,UPREAD	;IBUS 0
	ANDI	T2,17		;MASK ADDRESS  14-17
	HRLM	T2,XS.CPC(T3)	;STORE IT
	POPJ	P,0		;RETURN
;HERE ON SELECT ERROR OR SEQ ERROR

ERRCH2:	LDB	T2,STYTYP	;GET STATUS TYPE
	TLNE	T3,(CS.SLE)	;SELECTION ERROR
	CAIN	T2,CS.STI	;AND INITIAL SELECTION STATUS
	JRST	ERRUPE		;NO - SEQ ERR.
ERROFL:	PUSHJ	P,WATA		;WAS A TRANSFER ACTIVE
	  JRST	TPINT3		;NO - GO AWAY
	PUSHJ	P,CHKIRB##	;INSURE GOODNESS
	  JRST	TAPDIS##	;NONE - DISMISS
ERROF1:	MOVSI	T2,TKSOFL##
	IORM	T2,TUBSTS(U)	;MARK UNIT OFF-LINE
	MOVSI	T2,RB.SER!RB.SED!RB.SOL!RB.SNM	;NON REC, ERR, OFL
	JRST	IRBDON		;LIGHT BITS IN IORB AND EXIT

;HERE ON INITIAL SELECTION STATUS
;C(T3) := STATUS WORD CP.ST1

ERRCH3:	PUSHJ	P,CHKIRB##	;BLESS QUEUE
	  JRST	ERRCH4		;NONE
	MOVSI	T2,RB.SNM	;NEVER MOVES TAPE
	IORM	T2,TRBSTS(T1)	;MARK IN IORB
	TLNE	T3,(CS.IOP)	;ILLEGAL OPERATION?
	JRST	ERRILG		;YES - GO HANDLE
	PUSHJ	P,CHKXSP	;ARE SENSE BYTES AVAILABLE?
	  JRST	FATAL		;NO - NO DISTINCTION.
	MOVE	T3,T2		;PUT IN T3
	MOVE	T2,XS.S0(T3)	;GET SB 0 - 3
	TLNN	T2,(SB1TUA)	;UNIT READY?
	JRST	ERROFL		;NO - FLAG AS OFFLINE
	TLNN	T2,(SB1WTL)	;WRITE LOCKED?
	JRST	FATAL		;NO
	MOVSI	T2,RB.SLK	;INDICATE IN IORB
	IORM	T2,TRBSTS(T1)	; ...
	MOVSI	T2,TUSWTL##
	IORM	T2,TUBSTS(U)	;AND IN TUB
	JRST	FATAL
ERRCH4: PUSHJ	P,CLRSTA	;CLEAR STATUS AVAILABLE
	PJRST	TAPDIS##	;AND DISMISS
;ERROR ANALYSIS OF SENSE BYTE 0. THIS ANALYSIS IS THAT
;SUGGESTED BY IBM GA32-0020-3

ERRANL:	PUSH	P,T4		;SAVE T4
	PUSHJ	P,CHKXSP	;GET XS AREA
	  JRST	ERREQC		;NONE - CALL IT  NON-RECOVERABLE
	MOVE	T4,XS.S0(T2)	;GET SB 0 - 3
	SETZ	T2,		;CLEAR OUT T2
	TLNE	T4,(SB0EQC)	;EQUIPMENT CHECK?
	JRST	ERREQC		;YES
	TLNE	T4,(SB0BOC)	;BUS OUT CHECK?
	JRST	ERRBOC		;YES
	TLNE	T4,(SB0IRQ)	;INTERVENTION REQUIRED?
	JRST	ERRIRQ		;YES - MAY CONTINUE ANALYSIS
ERRAN1:	TLNE	T4,(SB0CMR)	;COMMAND REJECT?
	JRST	ERRCMR		;YES
	TLNE	T4,(SB1NC)	;NOT CAPABLE?
	JRST	ERRNC		;YES
	TLNE	T4,(SB0OVR)	;OVERRUN?
	JRST	ERROVR		;YES
	TLNE	T4,(SB0DC)	;DATA CHECK?
	JRST	ERRDC		;YES
	TLNE	T3,(CS.DPE)	;DEVICE PAR ERR?
	TLO	T2,RB.SED	;YES - FLAG ERROR

	SKIPN	T2		;ANYTHING?
				;IF NOTHING, MAKE IT NON-RECOVERABLE
;COMMAND REJECT AND EQUIPMENT CHECK ARE CONSIDERED FATAL
;(NOT TO BE RETRIED) ERRORS.

ERRCMR:
ERREQC:	MOVSI	T2,RB.SER!RB.SED ;NON REC + ERROR
ERRXIT:	MOVE	F,TUBCUR(U)	;DDB
	MOVE	S,DEVIOS(F)	;S
	TLNN	S,IOSRTY##	;IF DX DID ERROR RECOVERY
	TLO	T2,RB.SER	; THEN THIS IS A HARD ERROR
	IORM	T2,TRBSTS(T1)	;SET DEV INDEP ERROR BITS
	JRST	T4POPJ##	;RESTO T4 AND RETURN

;BUS OUT CHECK WITHOUT DEV END MEANS NO TAPE MOTION
;OTHERWISE, RETRY

ERRBOC:	TLNN	T3,(DS.DVE)	;DEVICE END?
	MOVSI	T2,RB.SNM	;NO - DONT REPOSITION
	TLO	T2,RB.SED	;ERROR DETECTED
	JRST	ERRXIT

;INTERVENTION REQUIRED WITHOUT DEVICE END MEANS
;THE DEVICE IS OFFLINE OR NONEX

ERRIRQ:	TLNE	T3,(DS.DVE)	;DEVICE END?
	JRST	ERRAN1		;YES - MORE ANALYSIS
	MOVSI	T2,RB.SOL!RB.SNM ;OFFLINE AND NO MOTION
	JRST	ERRXIT

;MORE OF SENSE BYTE 0 ANALYSIS

;OVERRUN SHOULD CAUSE REPOSITION AND RETRY

ERROVR:	MOVSI	T2,RB.SED	;WHICH IS WHAT NORMALLY HAPPENS
	JRST	ERRXIT		;ON AN ERROR

;DATA CHECK CALLS FORTH A RATHER ELABORATE RETRY PROCEDURE

ERRDC:	MOVSI	T2,RB.SED!RB.SDE ;ERROR + DATA ERROR
	JRST	ERRXIT		;SEE TAPSER

;NOT CAPABLE COMES UP READING 800 BPI ON TU72, DX10 HANGS ON 2ND INPUT
;TUBCNI IS CHECKED AT TX1SIO

ERRNC:	MOVEM	T3,TUBCNI(U)	;NO MORE IO FOR THIS TAPE
	JRST	ERRCMR		;FLAG IT
;DEVICE RESET - CALL HERE TO STOP A HUNG TRANSFER
TX1RES:	MOVSI	T1,TKSOFL##	;IS KON ALREADY OFFLINE?
	TDNE	T1,TKBSTS(W)	; ???
	POPJ	P,		;YES - RETURN
	SETZ	T1,		;DEAS PIA
	XCT	KDBCNO(W)	;...
	PUSHJ	P,UPHALT	;STOP UP
	MOVE	T4,KDBICP(W)	;SETUP T4 FOR RDIBUS
	PUSHJ	P,RDIBUS	;STORE IBUS REGS IN TUBFEP
	PUSHJ	P,UPRES		;RESET
	HRRZ	T1,TUBQUE(U)	;GET HEAD OF Q
	SKIPE	T1		;OK IF NONE
	PUSHJ	P,FXLST		;FIX UP XFER LIST
	MOVEI	T3,UP.SA	;START UP
	PUSHJ	P,UPSTRT	; ...
	PUSHJ	P,CLRICP	;RESET ICPC AREA
	PJRST	CLRCHN		;SET ICPC AND INT CHANNEL

;TABLE OF LOCATIONS TO CHECK IN UCODE

UPMTAB:	XWD	17,4756
	XWD	200,5210
	XWD	210,6007
	XWD	211,3777
	XWD	212,3774
	XWD	215,6502
UPMTBL==.-UPMTAB
TX1CFG:	XMOVEI	T1,TX1MDT##	;MONGEN'ED DEVICE TABLE
	XMOVEI	T2,DEFMDT	;DEFAULT TABLE
	MOVNI	T3,1		;NO MASSBUS UNIT OR DRIVE INFORMATION
	MOVEI	T4,MD.KON	;MATCH ON KONTROLLER DEFINITION
	PUSHJ	P,AUTMDT##	;SCAN THE TABLES
	  JRST	CPOPJ1##	;NO MATCHES
	PUSHJ	P,SAVE2##	;SAVE P1-2
	TRNN	T1,-1		;IF NO PORT INFO,
	HRRI	T1,-1		;SETUP TO TRUST THE TX
	MOVE	P2,T1		;SAVE MDT DATA WORD
	MOVSI	P1,-1		;NOT MULTI-UNIT, DRIVE 0
	MOVSI	T1,CP.DX1	;DX10 CHANNEL
	PUSHJ	P,AUTCHN##	;BUILD A CHANNEL DATA BLOCK
	  POPJ	P,		;NO CORE
	HLRZ	T1,P1		;NOT MULTI-UNIT, BUT MUST DO ANYWAY
	PUSHJ	P,AUTKDB##	;BUILD A KDB
	  POPJ	P,		;GIVE UP IF NO CORE
	PUSHJ	P,TAPCSA##	;SET UP CSO CONI ADDRESS
	PUSHJ	P,TX1LOD	;LOAD THE MICROCODE
	  POPJ	P,		;FAILED
	SETOM	TX1SUN(W)	;NOT SENSING NON-EXISTANT UNITS

TX1CF1:	PUSHJ	P,TX1DRV	;AUTOCONFIGURE A SINGLE DRIVE
	  JFCL			;IGNORE ERRORS
	HRRZ	T1,P1		;GET DRIVE NUMBER
	CAIGE	T1,TX1HDN	;DONE ALL DRIVES?
	AOJA	P1,TX1CF1	;LOOP BACK FOR MORE
	POPJ	P,		;ALL DONE WITH THIS CHANNEL
TX1DRV:	PUSHJ	P,TX1DCK	;CHECK FOR DRIVE EXISTANCE
	  JRST	TX1DR4		;NOT THERE
	MOVE	T1,TX1SNS+XS.S12(W) ;SENSE BYTES 12-15
	LDB	T1,[POINTR (TX1SNS+XS.S12(W),S13TCH)] ;GET HIGH TCU S/N
	LSH	T1,10		;POSITION IT
	LDB	T2,[POINTR (TX1SNS+XS.S12(W),S14TCL)] ;GET LOW TCU S/N
	IOR	T2,T1		;MERGE THE TWO BYTES
	SETZ	T1,		;NO HIGH WORD
	SKIPN	T2		;HAVE A NON-ZERO S/N?
	HRRZ	T2,.CPDVC##	;USE DEVICE CODE
	DMOVEM	T1,KDBSER(W)	;SAVE TCU S/N
	MOVE	T1,TX1SNS+XS.S16(W) ;SENSE BYTES 16-19
	TLNN	T1,(S172CH)	;TWO CHANNEL SWITCH CAPABILITY?
	TLZ	T1,(S17SWF)	;NO, STRIP PORT INFO
	LDB	T1,[POINTR (T1,S17SWF)] ;GET SWITCH FEATURES
	ANDI	T1,3		;STRIP OFF HI/LO UNIT BIT
	AOS	T1		;GET MAXIMUM NUMBER OF PORTS
	LSH	T1,1		;ACCOUNT FOR A/B PATH PER TCU
	CAILE	T1,(P2)		;IF MDT KNOWS BETTER THAN WE DO,
	HRRZ	T1,P2		;TRUST IT
	DPB	T1,[POINTR (KDBSTS(W),KD.MPT)] ;SAVE
	MOVSI	T2,(KD.MPD)	;GET A BIT
	CAIE	T1,1		;IF MORE THAN ONE PATH,
	IORM	T2,KDBSTS(W)	;THEN SAY MULTI-PORTED DEVICE

TX1DR1:	MOVSI	T1,(SB5NSS)	;BIT TO TEST
	TDNN	T1,TX1SNS+XS.S4(W) ;NEW SUBSYSTEM?
	JRST	TX1DR2		;MUST DUMMY UP S/N IF A TX01
	MOVE	T1,TX1SNS+XS.S12(W) ;SENSE BYTES 12-15
	MOVE	T2,TX1SNS+XS.S16(W) ;SENSE BYTES 16-19
	LSH	T1,-4		;POSITION HIGH ORDER S/N BITS
	ANDI	T1,377		;ISOLATE HIGH ORDER S/N BITS
	LSHC	T1,-34		;MERGE HIGH AND LOW BITS
	JUMPN	T2,TX1DR3	;CONTINUE IF S/N IS NON-ZERO

TX1DR2:	DMOVE	T1,KDBSER(W)	;GET TCU SERIAL NUMBER
	IMULI	T2,^D100	;TIMES 100
	ADDI	T2,(P1)		;INCLUDE DRIVE NUMBER

TX1DR3:	DMOVEM	T1,.CPTSN##	;SAVE TEMPORARILY
	HRRZ	T3,P1		;GET PHYSICAL DRIVE NUMBER
	PUSHJ	P,AUTDPU##	;LINK UP DUAL PORTED DRIVES
	  JFCL			;MUST PROCEED EVEN IF DUAL PORTED
	MOVE	T3,TX1SNS+XS.S4(W) ;SENSE BYTES 4-7
	MOVEI	T2,TUCD80##+TUCD16## ;ASSUME TU70
	TLNE	T3,(SB67TK)	;7 TRACK?
	MOVEI	T2,TUCD20##+TUCD55##+TUCD80##+TUC7TK##
	TRNE	T3,SB6D62	;6250 DRIVE?
	MOVEI	T2,TUCD16##+TUCD62##
	TRO	T2,TUCIRD##+K.TX1 ;INCLUDE REWIND INTERRUPT AND KONT TYPE
	HRLZ	T1,P1		;PHYSICAL DRIVE NUMBER
	HRR	T1,P1		;UDB TABLE INDEX
	LDB	T3,[POINT 4,T3,23] ;GET TU MODEL BITS
	SETZ	T4,		;INCASE WE CAN'T FIGURE IT OUT
	CAIN	T3,5		;TU70/71?
	MOVE	T4,['TU70  ']	;YES
	TRNE	T2,TUC7TK##	;BUT IS IT 7-TK?
	TRO	T4,10000	;MAKE IT A TU71
	CAIN	T3,14		;TU72?
	MOVE	T4,['TU72  ']	;YES
	CAIN	T3,15		;TU73?
	MOVE	T4,['TU73  ']	;YES
	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
	AOS	(P)		;SUCCESS

TX1DR4:	MOVEI	T1,CO.ILI!CO.STA!CO.UPE ;CLEAR DX10
	XCT	KDBCNO(W)	;CLEAR STATUS AVAILABLE AND UP ERROR
	POPJ	P,		;AND RETURN
TX1DCK:	HRRZ	T1,P1		;GET UNIT
	MOVE	T1,BITTBL##(T1)	;AND IT'S BIT
	TDNE	T1,TX1IUM(W)	;WANT TO IGNORE THIS DRIVE?
	POPJ	P,		;SAY IT DOESN'T EXIST
	SETZM	TX1SNS(W)	;CLEAR FIRST WORD
	MOVEI	T1,CPSNSW	;WORD COUNT
	XMOVEI	T2,TX1SNS(W)	;START OF SENSE BYTES
	XMOVEI	T3,TX1SNS+1(W)	;BLT POINTER
	EXTEND	T1,[XBLT]	;CLEAR SENSE BYTE STORAGE
	XMOVEI	T1,TKBCCL(W)	;POINT TO COMMAND BLOCK
	MOVSI	T3,200000	;DEVICE COMMAND
	TRO	T3,30000(P1)	;NO-OP, DRIVE NUMBER
	MOVEM	T3,(T1)		;SAVE SENSE
	MOVSI	T3,(CCHSTS!CCHFRC) ;STORE STATUS, FORCE EXTENDED SENSE
	MOVEM	T3,1(T1)	;SECOND CHAN CONTROL WORD
	SETZM	2(T1)		;MAKE SURE WE TERMINATE
	MOVE	T4,KDBICP(W)	;GET ICPC ADDR
	XMOVEI	T2,TX1SNS(W)	;SENSE BYTE STORAGE
	PUSHJ	P,MAPIT		;TRANSLATE TO PHYSICAL ADDRESS
	TLO	T2,(<-CPSNSB_<^D35-CPSBCP>>) ;NUMBER OF SENSE BYTES
	MOVEM	T2,CP.STS(T4)	;STORE IN ICPC AREA
	XMOVEI	T2,TKBCCL(W)	;BUILD INITIAL JUMP
	PUSHJ	P,MAPIT		;CONVERT TKBCCL TO A PHYSICAL ADDRESS
	TLO	T2,(CCHJMP!CCHGO) ;BUILD JUMP
	MOVEM	T2,(T4)		; ...
	MOVE	T1,KDBICP(W)	;GET ICPC ADDRS
	LSH	T1,^D33-CO.ICP	;POSITION
	IORI	T1,CO.CLR!CO.CON ;START THE SENSE
	SKIPL	TX1SUN(W)	;SENSING NON-EXISTANT UNITS?
	TRO	T1,TAPCHN##	;YES--WANT AN INTERRUPT WHEN COMPLETED
	XCT	KDBCNO(W)	;START THE SENSE OPERATION
	SKIPL	TX1SUN(W)	;DOING FULL AUTOCONFIGURE?
	POPJ	P,		;NO--NEVER WAIT
	MOVEI	T2,10000	;HOW LONG TO WAIT

TX1DC1:	XCT	KDBCNI(W)	;CONI
	TRNN	T1,CI.STA	;STATUS AVAILABLE?
	SOJG	T2,TX1DC1	;NO, WAIT SOME MORE
	JUMPE	T2,CPOPJ##	;NOT THERE

TX1DC2:	MOVE	T1,TX1SNS+XS.S0(W) ;SENSE BYTES 0-3
	MOVE	T2,TX1SNS+XS.S4(W) ;SENSE BYTES 4-7
	TLNE	T1,(SB1TUA+SB1TUB) ;DRIVE THERE?
	JRST	CPOPJ1##	;YES
	HRRZ	T1,P1		;GET DRIVE NUMBER
	SETCA	T1,BITTBL##(T1)	;TRANSLATE DRIVE NUMBER TO A BIT
	SETZ	T2,		;ASSUME NO OTHER NEW DRIVES
	SYSPIF			;AVOID RACE WITH INTERRUPT LEVEL
	ANDB	T1,TX1NUM(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
	XCT	KDBCNI(W)	;READ DEVICE STATUS
	TLNE	T1,(CI.RUN)	;MICROPROCESSOR RUNNING?
	POPJ	P,		;RETURN
	MOVEI	T3,UP.RA	;RESTART ADDRESS
	PUSHJ	P,UPSTRT	;KICK START THE DX10
	XCT	KDBCNI(W)	;GET NEW CONI
	POPJ	P,		;AND RETURN
;ENABLE/DISABLE MICROCODE LOADING
TX1EDL:	SE1ENT			;ENTER SECTION ONE
	HRRZS	W		;REMOVE JUNK IN LH
	MOVE	T2,T1		;COPY BIT
	XMOVEI	T1,TX1ULB(W)	;POINT TO UCODE LOADER BLOCK IN KDB
	PJRST	BTUEDL##	;ENABLE OR DISABLE
;LOAD MICROCODE
TX1LOD:	SE1ENT			;ENTER SECTION ONE
	HRRZS	W		;REMOVE JUNK IN LH
	PUSHJ	P,SAVE4##	;SAVE SOME ACS
	XMOVEI	P1,TX1ULB(W)	;POINT TO UCODE LOADER BLOCK IN KDB
	MOVE	T1,KDBDVC(W)	;GET DEVICE CODE
	LSH	T1,2		;MAKE 9 BITS
	HRLOM	T1,.ULDEV(P1)	;SAVE
	PUSHJ	P,UPRES		;RESET THE DX10
	PUSHJ	P,UPHALT	;HALT IT TOO
	MOVE	T1,P1		;POINT TO MICROCODE LOADER BLOCK
	PUSHJ	P,BTUCOD##	;FETCH WORD COUNT AND ADDRESS
	  PJRST	LOAD6		;NOT AVAILABLE
	MOVEI	P2,10000	;SIZE OF PDP-8/A MEMORY
	MOVSI	P3,(<POINT 12,,>!1B12) ;2-WORD BYTE POINTER
	MOVE	P4,.ULADR(P1)	;GET ADDRESS OF MICROCODE
	MOVE	T2,[DO.LRS!DO.UC1] ;SELECT CPMA ON IBUS
	XCT	KDBDTO(W)	;DATAO
	MOVEI	T2,0		;PDP-8/A ADDRESS 0
	XCT	KDBDTO(W)	;DATAO
	MOVE	T2,[DO.LRS!DO.UC0] ;SELECT PDP-8/A CONTROL REGISTER
	XCT	KDBDTO(W)	;DATAO

LOAD1:	ILDB	T2,P3		;GET A BYTE
	TRO	T2,DU0WRT	;ENABLE DEPOSIT
	XCT	KDBDTO(W)	;DEPOSIT
	SOJG	P2,LOAD1	;LOOP
	MOVE	T2,[DO.LRS!DO.UC1] ;SELECT CPMA ON IBUS
	XCT	KDBDTO(W)	;DATAO
	MOVEI	T2,LOCMAG	;MAGIC PDP-8/A ADDRESS
	XCT	KDBDTO(W)	;DATAO
	MOVE	T2,[DO.LRS!DO.UC0] ;SELECT PDP-8/A CONTROL REGISTER
	XCT	KDBDTO(W)	;DATAO
	MOVEI	T2,DXMAG!DU0WRT	;GET MAGIC CONSTANT AND ENABLE DEPOSIT
	XCT	KDBDTO(W)	;DATAO

; THE DX10 IS NOW LOADED
LOAD2:	MOVEI	T1,CI.UPE!CI.MPE!CI.NXM!CI.STA ;BITS WHICH CAUSE INTS
	HRRM	T1,@KDBCSO(W)	;STORE IN SKIP CHAIN
	XCT	KDBCNI(W)	;GET CONI
	PUSHJ	P,UPRES		;RESET
	PUSHJ	P,UPHALT	;SET HALT BIT
	MOVSI	T4,-UPMTBL	;NO - SEE IF MAGIC LOCS OK.
LOAD3:	HLRZ	T3,UPMTAB(T4)	;GET ADDRESS
	PUSHJ	P,UPMRD		;READ CONTENTS
	HRRZ	T3,UPMTAB(T4)	;GET EXPECTED CONTENTS
	CAME	T2,T3		;SAME?
	JRST	LOAD4		;NO - LEAVE HALTED
	AOBJN	T4,LOAD3	;YES - TRY NEXT ONE
	MOVEI	T3,UP.SA	;START UP
	PUSHJ	P,UPSTRT	; ...
	PUSHJ	P,CLRICP	;RESET ICPC AREA
	PUSHJ	P,CLRCHN	;SET ICPC AND INT CHANNEL
	XCT	KDBCNI(W)	;CONI
	TLNE	T1,(CI.RUN)	;RUNNING?
	JRST	LOAD5		;YES
LOAD4:	MOVEI	T1,.UEMPC	;CALL IT A MICROPROCESSOR CHECK
	DPB	T1,ULBEBP##	;STORE
	SKIPA			;ONWARD
LOAD5:	AOS	(P)		;SKIP
LOAD6:	MOVE	T1,P1		;POINT TO MICROCODE LOADER BLOCK
	PJRST	BTURPT##	;REPORT LOAD SUCESS OR FAILURE AND RETURN
SUBTTL START IO
;CALL HERE WHEN IO IS TO BE STARTED. THE USER JOB MUST BE LOCKED
TX1SIO:	SKIPN	TUBCNI(U)	;ERROR ON LAST GLUMP OF RECORDS?
	JRST	SIO0		;NO
	MOVEI	T1,CO.ILI!CO.SRQ+TAPCHN##
	XCT	KDBCNO(W)	;YES, JUST FAKE AN INTERRUPT
	POPJ	P,
SIO0:	MOVSI	T2,TUSWTL##	;CLEAR WRITE-LOCK
	ANDCAM	T2,TUBSTS(U)	;WILL SET IF WE REALLY ARE
	MOVE	T4,KDBICP(W)	;GET ICPC ADDR
	PUSHJ	P,SETXSP	;SETUP EXTENDED STATUS
	MOVSI	T2,(CCHJMP!CCHGO) ;BUILD JUMP
	MOVEM	T2,(T4)		; ...
	XMOVEI	T2,TKBCCL(W)	;GET COMMAND LIST ADDRESS
	PUSHJ	P,MAPIT		;CONVERT TO PHYSICAL ADDRESS
	DPB	T2,CHYADR	;STORE IN COMMAND
	XMOVEI	T4,TKBCCL(W)	;MOVE TO CCW LIST
	SETZM	(T4)		;CLEAR WORD
	LDB	T2,PRBFCN##	;CHECK ODDBALL
	SKIPN	IOFTAB(T2)	;CHECK LEGAL FCN
	JRST	ERRILG		;NO - SET ILLEGAL
	PUSHJ	P,INSMOD	;BUILD SET MODE IF NEEDED
	  AOJ	T4,		;BUMP POINTER
	SETZM	(T4)		;CLEAR WORD
	PUSHJ	P,INSSPC	;CALL EXIT ROUTINE IF NEEDED
	PUSHJ	P,INSDVC	;BUILD DEVICE COMMAND
	AOJ	T4,		;BUMP POINTER
	SETZM	(T4)		;CLEAR WORD
	PUSH	P,T4		;SAVE EOL
	PUSHJ	P,GETEXL	;GET END OF XFR LIST
	  JRST	SIO1		;NO LIST PRESENT
	EXCH	T4,(P)		;SAVE END OF LIST AND RESTORE CURRENT CCW LIST PTR
	HRRZ	T2,@IRBACC(T1)	;GET XFR LIST ADDR
	DPB	T2,CHYADR	;STORE IN COMMAND
	MOVSI	T2,(CCHJMP!CCHGO) ;BUILD JUMP
	IORM	T2,(T4)		; ...
	MOVSI	T4,(CCHJMP!CCHGO)  ;DESIRED LHS
	PUSHJ	P,EXLJMP	;BUILD JMPS
	MOVE	T4,(P)		;RESTORE END OF XFR LIST
SIO1:	MOVSI	T2,(CCHSTS)	;STORE STATUS
	HLLZ	T3,TUBSTS(U)	;GET STATUS
	HRR	T3,TUBCNF(U)	;AND CONFIG INFO
	TDNN	T3,[TUSBOT##,,TUCSNS##] ;AT BOT OR FORCED USER SENSE?
	JRST	SIO2		;NO - SKIP
	LDB	T3,PRBFCN##	;GET FUNCTION
	CAIE	T3,RB.FRW	;IS IT A REW?
	CAIN	T3,RB.FRU	;...
	JRST	SIO2		;REW/UNL - NO SENSE
	TLO	T2,(CCHFRC)	;OK - SET FORCE SENSE
SIO2:	IORM	T2,(T4)		;AND HALT
	MOVE	T1,KDBICP(W)	;GET ICPC ADDRS
	LSH	T1,^D33-CO.ICP	;POSITION
	IORI	T1,CO.CLR!CO.CON+TAPCHN## ;START THE IO
	XCT	KDBCNO(W)	; ...
	JRST	T2POPJ##	;REMOVE JUNK FROM PDL AND RETURN

;HERE ON ILLEGAL FUNCTION
ERRILG:	MOVSI	T2,RB.SIL!RB.SER!RB.SNM	; SET COND BITS
	JRST	IRBDON		;SET IN IORB, EXIT WITH ERROR
;ROUTINE TO CONVERT A VIRTUAL ADDRESS TO A PHYSICAL ADDRESS
;ENTER WITH T2=VIRTUAL ADDRESS, EXIT WITH PHYSICAL ADDRESS
MAPIT:	MAP	T2,(T2)		;DX10 WANTS A PHYSICAL ADDRESS
	TLZ	T2,(MP.NAD)
	POPJ	P,

;HERE TO BUILD A SET MODE CCW IF ONE IS NEEDED
;RETURNS NON SKIP IF A COMMAND WAS INSERTED, SKIP IF NONE NEEDED

INSMOD:	MOVEI	T2,TUC7TK##	;SEVEN TRACK?
	TDNN	T2,TUBCNF(U)	;??
	JRST	INSMD9		;NO - GO DO 9 TRACK
	LDB	T2,PRBFCN##	;SEE IF MODE SET IS NEEDED
	MOVSI	T3,(IOFMS7)	;...
	TDNN	T3,IOFTAB(T2)	;...
	JRST	CPOPJ1##	;NO - RETURN SKIP
	LDB	T2,PRBDEN##	;GET DENSITY
	CAILE	T2,RB.D8	;HIGHER THAN 800?
	MOVEI	T2,RB.D8	;YES - LOWER TO 800
	DPB	T2,PRBDEN##	;SAVE SELECTED DENSITY
	MOVE	T3,SM7DEN(T2)	;GET DEV CMD FOR THAT DENSITY
	MOVSI	T2,RB.PAR	;CHECK PARITY
	TDNN	T2,TRBFNC(T1)	; ...
	IORI	T3,MS1ODD	;ODD PARITY
	DPB	T3,CDYDCR	;SET DCR
	JRST	INSDC1		;EXIT BUILDING DEV CMD

INSMD9:	LDB	T2,PRBFCN##	;CHECK IF MODE SET NEEDED
	MOVSI	T3,(IOFMS9)	; ...
	TDNN	T3,IOFTAB(T2)	; ...
	JRST	CPOPJ1##	;NONE NEEDED - SKIP RETURN
	MOVSI	T2,TUSBOT##	;SEE IF AT BOT
	TDNN	T2,TUBSTS(U)	;??
	JRST	CPOPJ1##	;NO - NO MODE SET NECESSARY
	LDB	T2,PRBDEN##	;GET DENSITY
	CAIGE	T2,RB.D8	;LOWER THAN 800?
	MOVEI	T2,RB.D8	;YES - RAISE TO 800
	CAILE	T2,RB.D62	;.GT. MAX?
	MOVEI	T2,RB.D62	;YES - SET TO MAX (6250)
	DPB	T2,PRBDEN##	;SAVE SELECTED DENSITY
	SUBI	T2,RB.D8	;TABLE BEGINS AT 800
	MOVE	T2,SM9DEN(T2)	;GET APPROPRIATE MODE SET
	DPB	T2,CDYDCR	;SET DCR IN CCW
	JRST	INSDC1		;EXIT FINISHING COMMAND
;HERE TO INSERT THE DEVICE CONTROL CCW CORRESOPNDING TO THE
;IORB FUNCTION AND MODE

INSDVC:	MOVSI	T3,(CCDIGN+CCDISL+CCDREC+CCDAER) ;NOT RH20 + NO SHORT
				; LENGTH ERRORS + READ SOFT ERROR COUNT
				; + AUTOMATIC ERROR RETRIES
	SKIPN	TUBFIL(U)	;SITTING AT FILE 0
	SKIPE	TUBREC(U)	; AND RECORD 0 (BOT)?
	CAIA			;NO, LEAVE RETRY BIT ALONE
	TLO	S,IOSRTY##	;DIABLE DX10 RETRIES (IT MISSES ERRORS)
	PUSHJ	P,STORS7##	;MAKE BIT AVAILABLE AT INTERRUPT EXIT
	TLNE	S,IOSRTY##	;DID USER REQUEST NO RETRIES?
	TLZ	T3,(CCDAER)	;THEN DISABLE DX10 AUTOMATIC RETRY
	MOVEM	T3,(T4)
	LDB	T3,PRBFCN##	;GET FUNCTION
	MOVE	T3,IOFTAB(T3)	;GET HARDWARE FCN
	DPB	T3,CDYDCR	;STORE DEVICE COMMAND
	JUMPGE	T3,INSDC1	;JUMP IF NO MODE NEEDED
	LDB	T2,PRBMOD##	;GET IORB MODE
	MOVE	T2,IOMTAB(T2)	;TRANSLATE TO WHAT THE HDW WANTS
	DPB	T2,CDYMOD	;STORE
INSDC1:	MOVEI	T2,CCODVC	;DEVICE CONTROL OP
	DPB	T2,CCYOP	;STORE IN CCW
	MOVE	T2,UDBPDN(U)	;PHYSICAL DRIVE NUMBER
	DPB	T2,CDYDAD	;STORE
	TLNE	T3,(IOFAC)	;IS THERE ANOTHER COMMAND ALREADY SET UP?
	ADDI	T4,1		;YES, POINT PAST IT
	POPJ	P,

;HERE TO SETUP CP.STS.  SOME COMMANDS CANNOT REQUEST XS.
;CALL WITH T4 POINTING TO THE ICPC, T1 POINTING TO AN IORB
;RETURN WITH T2 POINTING TO THE (VIRTUAL ADDRESS OF) EXTENDED
;STATUS AREA IN THE UDB
SETXSP:	HRRZ	T2,TUBFEP(U)	;GET SENSE INFO ADDR
	ADD	T2,U		;RELOCATE
	PUSH	P,T2		;PRESERVE VIRTUAL ADDRESS
	PUSHJ	P,MAPIT		;CONVERT TO PHYSICAL ADDRESS
	TLO	T2,(<-CPSNSB>B<CPSBCP>) ;NUMBER OF SENSE BYTES
	MOVEM	T2,CP.STS(T4)	;STORE IN ICPC AREA
	JRST	T2POPJ		;RESTORE T2 AND RETURN


;HERE TO CHECK POINTER TO EXTENDED STATUS AREA OR BYTE COUNT.
;ENTER WITH T4 POINTING TO ICP.  EXIT WITH T2=POINTER TO EXTENDED
;STATUS AREA IF IT EXISTS, OTHERWISE WITH BYTE COUNT

CHKRBC:	SKIPA	T2,[SKIPGE T2,CP.RBC(T4)]	;CHECKING ON CP.RBC POSITIVE
CHKXSP:	MOVE	T2,[SKIPL T2,CP.STS(T4)]	;CHECKING ON CP.STS NEGATIVE
	XCT	T2				;DO THE RIGHT CHECK
	SOS	(P)				;PROPER NON-SKIP RETURN
	JUMPGE	T2,CPOPJ1##			;GIVE IT IF NO MORE TO GET
	HRR	T2,TUBFEP(U)			;ELSE GET VIRTUAL POINTER
	ADD	T2,U				;TO XS AREA
	JRST	CPOPJ1##			;DONE


;HERE TO ZERO THE EXTENDED STATUS AREA
;PRESERVES T1

CLRXS:	PUSH	P,T1		;SAVE T1
	HLRE	T1,TUBFEP(U)	;-LENGTH
	MOVNS	T1		;MAKE POSITIVE
	HRRZ	T2,TUBFEP(U)	;START OF AREA
	MOVEI	T3,1(T2)	;START OF AREA PLUS ONE
	ADD	T2,U		;RELOCATE START
	ADD	T3,U		;COMPLETE BLT POINTER
	SETZM	(T2)		;CLEAR FIRST WORD
	EXTEND	T1,[XBLT]	;ZERO EXTENDED SENSE AREA
	POP	P,T1		;RESTORE T1
	POPJ	P,		;DONE
;HERE TO CALL AN EXIT ROUTINE FOR THOSE WIERD COMMANDS THAT
;REQUIRE ONE.

INSSPC:	LDB	T2,PRBFCN##	;GET FUNCTION
	LDB	T2,IOYXR	;GET XR FIELD
	JUMPE	T2,CPOPJ##	;NONE REQUIRED
	PUSHJ	P,@IOXTAB(T2)	;CALL EXIT RTN
	  AOJ	T4,		;MOVE ALONG IN CCW LIST
	SETZM	(T4)		;CLEAR NEW WORD
	POPJ	P,

;EXIT ROUTINE FOR DATA SECURITY ERASE. DSE MUST BE COMMAND CHAINED
;TO AN ERASE GAP.

INSDSE:	HRRZ	T2,RB.FLG+IOFTAB ;GET DEVICE COMMAND FOR ERASE GAP
	DPB	T2,CDYDCR	;SET DEV COMMAND
	PJRST	INSDC1		;COMPLTE DEVICE COMMAND
				;RETURN AND INSERT DSE ITSELF

;HERE TO DO SETUP FOR CORRECTION READ. THIS INVOLVES TRANSFERRING
;THE TRACK IN ERROR BYTE BACK TO THE CONTROLLER AND THEN DOING
;THE READ. THIS REQUIRES WE SETUP A DATA TRANSFER FOR THE
;TIE BYTE.

;*****TEST SOME BIT SOMEWHERE, DONT DO IF TU4-COMPAT*****

INSCR:	MOVEI	T2,33		;TRACK IN ERROR DEV COMMAND
	DPB	T2,CDYDCR	;SET DCR
	PUSHJ	P,INSDC1	;FINISH COMMAND
	AOJ	T4,		;NEXT WORD IN CCW LIST
	SETZM	(T4)		; ...
	MOVEI	T2,CCODAT	;DATA XFR COMMAND
	DPB	T2,CCYOP	;STORE
	MOVNI	T2,1		;BYTE COUNT
	DPB	T2,CXYCNT	;STORE
	XMOVEI	T2,TX1TMP(W)	;WHERE TIE BYTE WILL BE
	PUSHJ	P,MAPIT		;TRANSLATE TO PHYSICAL ADDRESS
	DPB	T2,CXYADR	;STORE IN CCW
	HRRZ	T2,TUBFEP(U)	;GET TIE BYTE
	ADD	T2,U		;RELOCATE
	LDB	T2,XSYSB2	;THE BYTE
	ROT	T2,-10		;POSITION AT START OF WORD
	MOVEM	T2,TX1TMP(W)	;STORE
	POPJ	P,
;EXIT ROUTINE FOR REWIND. WE WILL ATTEMPT TO DO A NO-OP FOLLOWED
;BY A FORCED STORE STATUS CMD. THIS WILL ALLOW US TO SEE IF THE
;DRIVE IS WRITE-LOCKED OR ALREADY AT BOT...

INSRW:	MOVEI	T2,3		;NO-OP
	DPB	T2,CDYDCR	;SET DCR
	PUSHJ	P,INSDC1	;FINISH COMMAND
	MOVSI	T2,(CCHSTS!CCHFRC)	;FORCE STATUS AND HALT
	MOVEM	T2,1(T4)	;STORE IN NEXT LOC
	AOJA	T4,CPOPJ##	;BUMP T4 AND GENERATE THE REW COMMAND

;EXIT ROUTINE FOR REWIND/UNLOAD
INSRUN:	XMOVEI	T2,TKBCCL+5(W)	;WHERE TO STORE THE COUNTER
	PUSHJ	P,MAPIT		;CONVERT TO PHYSICAL ADDRESS
	TLO	T2,700000	;DATA COMMAND
	MOVEM	T2,1(T4)	;TELL THE DX10 TO READ ERROR COUNTER
	JRST	CPOPJ1##

;ROUTINE TO ALLOW DMS ON WRITE FOR FAULT INSERTION

INSDMS:	MOVEI	T2,TUCDMS##	;BIT TO TEST
	TDNN	T2,TUBCNF(U)	;WANT DMS?
	JRST	CPOPJ1##	;NO-SKIP RETURN

	MOVEI	T2,13		;FCN DMS (0B)
	DPB	T2,CDYDCR	;SET IN DCR
	PJRST	INSDC1		;FINISH CMD

;TABLE OF EXIT ROUTINES

IOXTAB:	PHASE	0
	IFIW	-1		;ILLEGAL
XDSE:!	IFIW	INSDSE		;DSE EXIT
XCR:!	IFIW	INSCR		;CR EXIT
XRW:!	IFIW	INSRW		;REWIND EXIT
XRUN:!	IFIW	INSRUN		;UNLOAD EXIT
XWRT:!	IFIW	INSDMS		;INSERT DIAG MODE SET
	DEPHASE
;TABLES FOR VARIOUS TRANSLATIONS

;TABLE TO TRANSLATE FROM THE MODE IN THE IORB TO
;THE MODE WANTED BY THE HARDWARE

IOMTAB:	EXP	-1		;0 IS ILLEGAL
	EXP	0		;CORE DUMP
	EXP	1		;BYTE
	EXP	3		;SIXBIT
	EXP	2		;SEVEN BIT (MAVELOUS ASCII)
	EXP	3		;SEVEN TRACK CORE DUMP
IOMTMX==.-IOMTAB-1

;TABLES FOR BUILDING MODE SET COMMANDS

SM7DEN:	EXP	-1		;0 IS ILLEGAL
	EXP	043		;200 BPI
	EXP	143		;556 BPI
	EXP	243		;800 BPI

SM9DEN:	EXP	313		;800 BPI NRZI
	EXP	303		;1600 BPI PE
	EXP	323		;6250 BPI GCR
SM9DMX==.-SM9DEN-1		;LARGEST RELATIVE ENTRY


;HUNG TIMER TABLE
	EXP	^D480			;MAXIMUM TIMEOUT VALUE
HNGTBL:	BYTE(9)	^D000,^D046,^D046,^D046	;IL,RD,WT,RB
	BYTE(9)	^D046,^D046,^D480,^D480	;SR,BR,SF,BF
	BYTE(9)	^D046,^D480,^D135,^D135	;LG,SE,RW,RU
	BYTE(9)	^D046,^D046,^D046,^D046	;TM,YB,CR,RL
;MACRO TO BUILD TABLE ENTRIES IN IOFTAB

DEFINE OP(HEX,FLGS,XR<0>)<
	.XCREF
..T==0
IRPC HEX,<
	IFGE	"HEX"-"A",<..T==..T*^D16+^D10+"HEX"-"A">
	IFLE	"HEX"-"9",<..T==..T*^D16+"HEX"-"0">
>
	EXP	FLGS+<XR>B<IOFXRP>+..T
	.CREF
>


;FLAGS IN IOFTAB

IOFDXP==0		;1 IF A DATA XFR LIST IS NEEDED
IOFDX==1B<IOFDXP>
IOFXSP==1		;1 IF EXTENDED STATUS SHOULD BE REQUESTED
IOFXS==1B<IOFXSP>
IOFM7P==2		;1 IF MODE SET NEEDED ON 7 TRACK
IOFMS7==1B<IOFM7P>
IOFM9P==3		;1 IF MODE SET NEEDED ON 9 TRACK
IOFMS9==1B<IOFM9P>
IOFACF==4		;1 IF ANOTHER COMMAND FOLLOWS THIS ONE (AND IS ALREADY SET UP)
IOFAC==1B<IOFACF>
IOFXRP==^D17		;POSITION OF EXIT ROUTINE BYTE
IOFXRS==3		;SIZE

IOYXR:	POINT	IOFXRS,IOFTAB(T2),IOFXRP ;BYTE POINTER

;TABLE TO GET DEVICE COMMAND CODES FROM IORB FUNCTON CODES.
;BIT 0 IS ON IF A DATA XFER LIST IS NEEDED BY THE FUNCTION.

IOFTAB:	0		;ILLEGAL
	OP(02,IOFDX+IOFXS+IOFMS7)	;1 - FORWARD READ
	OP(01,IOFDX+IOFXS+IOFMS7+IOFMS9,XWRT) ;2 - FORWARD WRITE
	OP(0C,IOFDX+IOFXS+IOFMS7)	;3 - READ BACKWARDS
	OP(37,IOFXS+IOFMS7)		;4 - FORWARD SPACE BLOCK
	OP(27,IOFXS+IOFMS7)		;5 - BACKSPACE BLOCK
	OP(3F,IOFXS+IOFMS7)		;6 - FORWARD SPACE FILE
	OP(2F,IOFXS+IOFMS7)		;7 - BACKSPACE FILE
	OP(17,IOFXS+IOFMS7+IOFMS9)	;10 - ERASE GAP
	OP(97,IOFXS,XDSE)		;11 - DATA SECURITY ERASE
	OP(07,IOFXS,XRW)		;12 - REWIND
	OP(0F,IOFXS+IOFAC,XRUN)		;13 - REWIND / UNLOAD
	OP(1F,IOFXS+IOFMS7+IOFMS9)	;14 - WRITE TAPE MARK
	0				;15 - ILLEGAL
	OP(02,IOFDX+IOFXS+IOFMS7,XCR)	;16 - CORRECTION READ
	OP(02,IOFDX+IOFXS+IOFMS7)	;17 - READ LOW THRESHOLD
IOFTMX==.-IOFTAB-1
SUBTTL	CHECK FOR KONTROLLER BUSY


;CHECK FOR KONTROLLER BUSY
;CALL:	MOVE	W, KDB ADDRESS
;	MOVE	U, UDB FOR DRIVE TRYING TO SCHEDULE
;	PUSHJ	P,TX1BSY
;	  <NON-SKIP>		;BUSY
;	<SKIP>			;NOT-BUSY
;
;USES T1 AND T2

TX1BSY:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,U		;SAVE U
	MOVE	P1,KDBIUN(W)	;POINT TO START OF DRIVE TABLE
	MOVSI	P2,-<TX1DMX/2>	;ACTUAL RANGE OF DRIVES PER KONT
	MOVE	T1,UDBPDN(U)	;GET PHYSICAL DRIVE NUMBER
	TRZ	T1,<TX1DMX/2>-1	;MASK OUT DRIVE LEAVING KONTROLLER OFFSET
	ADDI	P1,(T1)		;ADJUST STARTING TABLE INDEX

TX1BS1:	SKIPE	U,(P1)		;GET A TUB ADDRESS
	PUSHJ	P,CHKIRB##	;SEE IF IT HAS A VALID IORB
	  JRST	TX1BS2		;TRY ANOTHER DRIVE
	LDB	T2,PRBFCN##	;GET FUNCTION CODE
	MOVE	T2,BITTBL##	;NOT PICK UP THE ASSOCIATED BIT
	TDNN	T2,TX1NBF	;NON-BLOCKING FUNCTION?
	POPJ	P,		;NO--KONT IS BUSY

TX1BS2:	AOBJN	P2,TX1BS1	;LOOP BACK IF MORE DRIVES TO CHECK
	JRST	UPOPJ1##	;RESTORE U AND RETURN KONT NOT BUSY
SUBTTL ONL AND CMD ENTRIES

;HERE TO CHECK IF THE CONTROLLER WHOSE KDB IS IN W
;IS ON LINE. IF SO, SKIP.

TX1ONL:	XCT	KDBCNI(W)	;GET CONI
	TLNN	T1,(CI.RUN)	;UP RUNNING?
	POPJ	P,		;NO - NON SKIP
	SKIPL	@KDBCHN(W)	;CHANNEL BUSY?
	JRST	CPOPJ1##	;LEAVE IT ALONE
	SKIPE	T1,TX1NUM(W)	;GET BIT MASK
	JFFO	T1,TX1ON3	;FIND FIRST UNIT NUMBER
	HRRZS	KDBNUM(W)	;INDICATE NO DRIVES TO CONFIGURE
	SKIPL	T1,TX1SUN(W)	;GET NON-EXISTANT UNIT BEING SENSED
	JRST	CPOPJ1##	;DO NOTHING IF SENSE IN PROGRESS
	PUSHJ	P,SAVE1##	;SAVE P1
	AOS	T1		;ADVANCE TO NEXT UNIT
	HRRZS	T1		;CLEAR LH FLAG
	CAILE	T1,TX1HDN	;OVERFLOW?
	MOVEI	T1,0		;START WITH DRIVE ZERO
	ADD	T1,KDBIUN(W)	;INDEX INTO TABLE

TX1ON1:	SKIPN	(T1)		;KNOWN UNIT?
	JRST	TX1ON2		;NO
	CAMGE	T1,KDBFUN(W)	;END OF TABLE?
	AOJA	T1,TX1ON1	;TRY ANOTHER
	SETOM	TX1SUN(W)	;RESET COUNTER
	JRST	CPOPJ1##	;AND INDICATE CONTROLLER ONLINE

TX1ON2:	SUB	T1,KDBIUN(W)	;REDUCE TO A DRIVE NUMBER
	MOVEM	T1,TX1SUN(W)	;SAVE FOR NEXT TIME
	HRRO	P1,T1		;GET MASSBUS UNIT (NONE),,DRIVE NUMBER
	PUSHJ	P,TX1DCK	;QUEUE UP SENSE REQUEST
	  JFCL			;SHOULD NEVER SKIP
	JRST	CPOPJ1##	;RETURN

TX1ON3:	PUSHJ	P,AUTLOK##	;GET AUTCON INTERLOCK
	  JRST	CPOPJ1##	;TRY AGAIN NEXT TIME
	HRRO	P1,T2		;GET MASSBUS UNIT (NONE),,DRIVE NUMBER
	MOVE	T1,KDBDVC(W)	;DEVICE CODE
	XMOVEI	T2,TX1DSP	;DISPATCH
	MOVE	T3,KDBCHN(W)	;CHANNEL DATA BLOCK
	PUSHJ	P,AUTSET##	;SET UP CPU VARIABLES
	PUSHJ	P,TX1DRV	;TRY TO CONFIGURE A DRIVE
	  JFCL			;IGNORE ERRORS
	PUSHJ	P,AUTULK##	;RELEASE AUTCON INTERLOCK
	JRST	CPOPJ1##	;TELL TAPSER THE CONTROLLER IS ALIVE


;HERE TO FINISH OFF THIS COMMAND OR START A NEW ONE
;T2 POSITIVE TO INSERT DEVICE COMMAND FOR NEW OPERATION
;	LH(P2)=LOC OF IORB
;T2 NEGATIVE TO FINISH THIS COMMAND (SET FOR STORE WRDCNT)
;	LH(P2)=LOC OF MAPPED IOWD

TX1CMD:	PUSHJ	P,SAVT##	;SAVE ALL REGISTERS
	JUMPL	T2,TX1CM1
	PUSH	P,U		;SAVE U
	SETZ	U,		;IT ISNT AN RH20
	PUSHJ	P,CHKMOR##	;GET IOWD SPACE
	  PJRST	UPOPJ##
	POP	P,U
	HLRZ	T1,P2		;YES, RESTORE L(IORB)
	HRRZ	T4,P1
	PUSHJ	P,INSDVC	;GO OR THE DEV COMMAND INTO THE LIST
	AOBJN	P1,CPOPJ1##	;COUNT THE WORD AND RETURN
	JRST	CPOPJ1##

TX1CM1:	MOVEI	T2,<(CCHGO+CCHSAV)>/100
	HLRZ	T1,P2
	DPB	T2,[POINT 12,(T1),11]
	POPJ	P,

;HERE TO CAUSE AN INTERRUPT ON THE DEVICE TO FORCE A SCHEDULE
;CYCLE

TX1SCH:	MOVEI	T1,CO.ILI!CO.SRQ+TAPCHN## ;REQUEST STATUS
	XCT	KDBCNO(W)
	POPJ	P,


TX1END:	END