Google
 

Trailing-Edge - PDP-10 Archives - BB-T573C-DD_1986 - 10,7/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 V121
SUBTTL L. BOSACK/TAH/TW   10 OCT 85
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1974,1986>
;COPYRIGHT (C) 1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
;

XP VTX1KN,121	;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 - 6
XS.S12==7		;SENSE BYTE 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 SENE BYTE
CPSNSI==^D8		;NUMBER OF SENSE BYTES TO READ FOR AUTO-CONFIG

;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
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
SUBTTL TRANSFER VECTOR

TX1DSP::IFIW	TX1INI		;00 - INITIALIZE
	IFIW	TX1RES		;01 - RESET ACTIVE I/O
	IFIW	TX1SIO		;02 - START I/O
	IFIW	TX1INT		;03 - INTERRUPT SERVICE
	IFIW	TX1CMD		;04 - SET DEVICE COMMAND
	IFIW	CPOPJ##		;05 - KONTROLLER IS IDLE
	IFIW	TX1ONL		;06 - TEST IF CTL ON-LINE
	IFIW	TX1SCH		;07 - FORCE A SCHEDULE CYCLE
	IFIW	TX1INX		;10 - RE-INITIALIZATION
	IFIW	TX1LOD		;11 - LOAD MICROCODE
	IFIW	TX1EDL		;12 - ENABLE/DISABLE MICROCODE LOADING
IFN FTAUTC,<IFIW TX1CFG>	;13 - AUTOCONFIGURE
SUBTTL INTERRUPT SERVICE

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

TX1INT::XCT	TTXCIS##(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
	JUMPE	U,ERRUPE	;NON-EX UNIT
	JRST	@TPIDSP(T1)	;DISPATCH

;DISPATCH TABLE ON STATUS TYPE

TPIDSP:	ERRCH3		;INITIAL SELECTION STATUS
	TPINT1		;ENDING STATUS
	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,TKBCUN##(W)	;SET U TO RIGHT UNIT
	MOVE	U,(U)
	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
	ADDI	T2,(U)
	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(T2)
	MOVEM	T3,CP.ST1(T4)
	MOVE	T3,XS.ST2(T2)
	MOVEM	T3,CP.ST2(T4)
	MOVE	T3,T1		;STATUS INTO T3
	HRRZS	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
	TLNN	T4,(SB1TUA)	; OR DSE ERROR
	JRST	TPIN2B		;IT WAS UNLOAD
	TLNE	T4,(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	TTXCIS##(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	TTXCOS##(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)	; ...
	TLNE	T4,(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:	XWD	0,-1	;ILLEGAL
	TP1RD		;READ
	TP1WT		;WRITE
	TP1RB		;READ BACKWARDS
	TP1SR		;SKIP RECORD
	TP1BR		;BACKSPACE RECORD
	TAPIFI##	;SKIP FILE
	TAPIFI##	;BACKSPACE FILE
	TP1ERG		;ERASE GAP
	TP1DSE		;DATA SECURITY ERASE
	TP1REW		;REWIND
	TP1RUN		;REWIND AND UNLOAD
	TP1WTM		;WRITE TAPE MARK
	TAPIFI##	;YELLOW BALL
	TP1CR		;CORRECTION READ
	TP1RD		;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
	HRL	T2,XS.S0(T2)	;DENSITY IS IN SENSE BYTES
	TLNE	T2,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
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,.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
IFN FTKL10,<
	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:	HLRZ	T3,TRBSTS(T1)	;SEE IF ANY FLAGS ARE ON
	MOVSI	T2,RB.EXC	;GET BIT
	SKIPE	T3		;ANY FLAGS?
	IORM	T2,TRBLNK(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	RDOK1		;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:	TLNE	T4,(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,.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

T1BR2:	SOSA	TUBREC##(U)	;DECREMENT POSITION
T1SROK:	AOSA	TUBREC##(U)	;INCREMENT POSITION
T1BROK:	TLNN	T4,(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:	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
	MOVSI	T3,TUSWTL##	;WRITE LOCKED STATUS BIT
	TLNE	T4,(SB1WTL)	;WRITE LOCKED?
	IORM	T3,TUBSTS##(U)	;YES, SET THE BIT
	TLNN	T4,(SB1WTL)	;ARE WE WRITE LOCKED
	ANDCAM	T3,TUBSTS##(U)	;NO, CLEAR THE BIT
	TLNE	T4,(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,TRBXCW(T1)	;COUNT IS WHERE XFR LIST WOULD BE
	SUBI	T2,1		;ONE LESS
	HRRM	T2,TRBXCW(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	TTXCOS##(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:	HRRZ	U,TKBCUN##(W)	;GET CURRENT UDB POINTER
	SKIPN	U,(U)		; ...
	POPJ	P,		;NONE - 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
	HRRZ	T1,TKBICP##(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	TTXCOS##(W)	;SEND TO THE DEVICE
	PJRST	TPOPJ##		;RESTORE T1

;HERE TO RESET THE ICPC AREA - PREPARE FOR IDLENESS

CLRICP:	HRRZ	T4,TKBICP##(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	TTXDOS##(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	TTXDIS##(W)	;READ CONTENTS
	POPJ	P,

UPRSEL:	TLOA	T2,(DO.LRS)	;LOAD REG SELECT BIT
UPRES:	MOVSI	T2,(DO.RES)	;ISSUE RESET COMMAND
UPGO:	XCT	TTXDOS##(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	TTXDOS##(W)	;SEND ADDR
	MOVEI	T2,DO.UC0	;SEL CTL 0
	PUSHJ	P,UPRSEL	; ...
	MOVEI	T2,DU0EXM	;FORCE EXAMINE BIT
	XCT	TTXDOS##(W)	;SEND OUT
	XCT	TTXDIS##(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,TRBEXL(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=SENSE BYTE 0&1,,ICPC; T3=CP.ST1,,RH(CONI)

SETXS:	HRRZ	T4,TKBICP##(W)	;GET ICPC
	LDB	T2,STYDAI	;GET THE UNIT NUMBER
	SETZM	U
	CAIGE	T2,10		;RANGE CHECK UNIT NUMBER
	PUSHJ	P,SETUDB##	;GET THE UDB
	  POPJ	P,
	HRRZ	T2,TUBFEP##(U)	;GET FINAL ERROR POINTER
	ADDI	T2,(U)		;OFFSET INTO UDB
	SKIPL	CP.STS(T4)	;EXTENDED STATUS?
	JRST	SETXS1
	HLL	T4,XS.S0(T2)	;AND SET LH(T4)=SENSE BYTES 0, 1
SETXS1:	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,

;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,TRBXCW(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
	MOVE	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 TTXCOS##(W) ;CLEAR ERROR IF IN BOOTDX
		 JRST TPOPJ##]   ;RETURN UP A LEVEL
	JUMPN	U,ERRCHT	;IF NO UNIT
	MOVE	U,TKBCUN##(W)	;GET CURRENT UNIT
	SKIPN	U,(U)
	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
	HRRZ	T1,TKBICP##(W)	;RESET ICPC
	LSH	T1,^D33-CO.ICP	;CORRECT POSITION IN CONO
	IORI	T1,CO.UPE!CO.MPE!CO.NXM!CO.STA
	XCT	TTXCOS##(W)	;OF MICROPROCESSOR
	HLLZS	TKBCSO##(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,TRBLNK(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 MT0DDB IF THERE IS NO DDB FOR THIS UNIT
ERRUP2:	MOVSI	T1,(1B1)	;MDO IS UNRECOVERABLE
	IORM	T1,TUBTRY##(U)	;
	MOVSI	T1,TTXFST##(U)	;COPY FROM "AT END"
	HRRI	T1,TTXIST##(U)	; TO "AT ERROR"
	BLT	T1,TTXISE##(U)	; FOR SYSERR
	SKIPN	F,TUBCUR##(U)	;IF DDB USE IT
	MOVEI	F,MT0DDB##	;NO - USE MT0DDB
	MOVEI	T1,.ERTAP	;ERROR TYPE TO DAEMON
	HRL	T1,F		;DDB
	PUSHJ	P,DAEERR##	;TELL DAEMON
	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
	ADDI	T3,(U)		;STATUS AREA
	HRL	T3,CP.STS(T4)	;..
	HRRZ	P1,TKBCDB##(W)	;GET CHAN DATA BLOCK
	HRRZ	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,CHNNXM##	;ROUTINE TO CALL
	MOVSI	T3,IOCHNX	;ASSUMING NXM
	TRNE	T1,CI.MPE	;UNLESS A MPE
	MOVEI	T2,CHNMPE##	; ...
	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
	ADDI	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
;INITIALIZATION - CALL HERE TO SETUP

TX1INI:	MOVEI	T1,TUCIRD##	;INT ON REW'D DONE BIT
	MOVE	T2,TKBIUN##(W)	;PNTR TO UDB LIST
TX1INL:	SKIPE	T3,0(T2)	;GET UDB PNTR
	IORM	T1,TUBCNF##(T3)	;SET BIT IF UDB FOUND
	AOBJN	T2,TX1INL	;LOOP TILL DONE
TX1INX:	MOVEI	T1,CI.UPE!CI.MPE!CI.NXM!CI.STA ;BITS WHICH CAUSE INTS
	HRRM	T1,TKBCSO##(W)	;STORE IN SKIP CHAIN
	XCT	TTXCIS##(W)	;GET CONI
	TLNE	T1,(CI.RUN)	;UP RUNNING?
	JRST	TX1IN1		;YES - LEAVE ALONE
	PUSHJ	P,UPRES		;RESET
	PUSHJ	P,UPHALT	;SET HALT BIT
	MOVSI	T4,-UPMTBL	;NO - SEE IF MAGIC LOCS OK.
TX1IN0:	HLRZ	T3,UPMTAB(T4)	;GET ADDRESS
	PUSHJ	P,UPMRD		;READ CONTENTS
	HRRZ	T3,UPMTAB(T4)	;GET EXPECTED CONTENTS
	CAME	T2,T3		;SAME?
	JRST	TX1IN1		;NO - LEAVE HALTED
	AOBJN	T4,TX1IN0	;YES - TRY NEXT ONE
	MOVEI	T3,LOCVER
	PUSHJ	P,UPMRD		;READ THE VERSION NUMBER
	CAIL	T2,DXVER	;IS IT AN OK VERSION?
	JRST	TX1IST		;YES, START IT UP
	MOVE	T2,[DXVER,,[ASCIZ/Please reload the DX10 with a minimum microcode version of/]]
	PUSHJ	P,TAPREV##
	JRST	TX1IN1		;DONT START THIS LOSING VERSION
TX1IST:	MOVEI	T3,UP.SA	;NO MORE - START UP
	PUSHJ	P,UPSTRT	; ...
TX1IN1:	PUSHJ	P,CLRICP	;RESET ICPC AREA
	PJRST	CLRCHN		;SET ICPC AND INT CHANNEL
;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	TTXCOS##(W)	;...
	PUSHJ	P,UPHALT	;STOP UP
	HRRZ	T4,TKBICP##(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
	JUMPE	T1,TX1IST	;OK IF NONE
	PUSHJ	P,FXLST		;FIX UP XFER LIST
	PJRST	TX1IST		;AND START '8

;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
IFN FTAUTC,<
TX1CFG::JUMPGE	P3,TX1CF1	;GO IF WE'VE BEEN HERE BEFORE FOR THIS CONTROL
	PUSHJ	P,TX1INI	;GET IT CRANKED UP
	XCT	TTXCIS##(W)	;IS IT RUNNING?
	TLNE	T1,(CI.RUN)
	JRST	TX1CF1		;YES
	PUSHJ	P,TX1LOD	;TRY RELOADING THE MICROCODE
	  POPJ	P,		;FAILED
TX1CF1:	AOS	T2,P3		;NEXT UNIT
	TRZE	P3,10		;OVER THE TOP?
	SOJA	P3,CPOPJ##	;YES, RETURN P3=-1
	MOVEI	T1,TKBCCL##(W)	;POINT TO COMMAND BLOCK
	MOVSI	T3,200000	;DEVICE COMMAND
	TRO	T3,30000(P3)	;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
	HRRZ	T4,TKBICP##(W)	;GET ICPC ADDR
	MOVNI	T2,CPSNSI	;NUMBER OF SENSE BYTE
	LSH	T2,^D35-CPSBCP	;POSITION
	HRRI	T2,INISNS	;STORE SENSE BYTES IN SPECIAL PLACE
	MOVEM	T2,CP.STS(T4)	;STORE IN ICPC AREA
	MOVEI	T2,TKBCCL##(W)	;BUILD INITIAL JUMP
	PUSHJ	P,MAPIT		;CONVERT TKBCCL TO A PHYSICAL ADDRESS
	TLO	T2,(CCHJMP!CCHGO) ;BUILD JUMP
	MOVEM	T2,(T4)		; ...
	HRRZ	T1,TKBICP##(W)	;GET ICPC ADDRS
	LSH	T1,^D33-CO.ICP	;POSITION
	IORI	T1,CO.CLR!CO.CON ;START THE SENSE
	XCT	TTXCOS##(W)
	MOVEI	T2,10000	;HOW LONG TO WAIT
TX1CF2:	XCT	TTXCIS##(W)	;CONI
	TRNN	T1,CI.STA	 ;STATUS AVAILABLE?
	SOJG	T2,TX1CF2	;NO, WAIT SOME MORE
	JUMPE	T2,TX1CF3	;NOT THERE, TRY NEXT DRIVE
	MOVE	T1,XS.S0+INISNS	;SENSE BYTES 0-3
	MOVE	T2,XS.S4+INISNS	;SENSE BYTES 4-7
	TLNN	T1,(SB1TUA+SB1TUB) ;DRIVE THERE?
	JRST	TX1CF3		;NO, GO ON
	SETZ	T3,		;ASSUME 800/1600 BPI DRIVE
	TLNE	T2,(SB67TK)	;7 TRACK?
	MOVEI	T3,TUCDR7##+K.TX1 ;YES
	TRNE	T2,SB6D62	;6250 DRIVE?
	MOVEI	T3,TUCDR5##+K.TX1 ;YES
	MOVEI	T1,CO.ILI!CO.STA ;CLEAR STATUS AVAILABLE
	XCT	TTXCOS##(W)
	HRLM	P3,P2		;WHERE AUTCON WANTS IT
	POPJ	P,		;AND RETURN WITH P3 = NEXT DRIVE NUMBER
TX1CF3:	MOVEI	T1,CO.ILI!CO.STA!CO.UPE ;CLEAR DX10
	XCT	TTXCOS##(W)
	JRST	TX1CF1		;AND TRY NEXT DRIVE
;SUBROUTINE TO INSURE THAT DX10 KDB'S NEVER GET CACHED EVEN WHEN A CPU IS
; REMOVED.
;CALL:	MOVE	W,KDB ADDRESS
;	PUSHJ	P,TX1TCF	;IF A DX10, CLEAR TNCSHB FOR PAGE(S) CONTAINING THE KDB
;	RETURNS ALWAYS .+1
;USES T1-T4

IFN FTMP,<
TX1TCF::HRRZ	T1,TKBDSP##(W)	;KONTROLLER DISPATCH
	CAIE	T1,TX1DSP	;THIS KONTROLLER FOR A DX10?
	POPJ	P,		;NO, NOTHING FOR THIS ROUTINE TO DO
	SE1ENT			;MUST BE IN SECTION 1 FOR PAGTAB REFERENCES
	HRRZ	T1,W		;KDB STARTING ADDRESS
	MOVEI	T2,DXKLEN##(T1)	;KDB ENDING ADDRESS
	LSH	T1,W2PLSH##	;CONVERT TO PAGES
	LSH	T2,W2PLSH##
	HRRZ	T3,T1		;SAVE STARTING VIRTUAL PAGE
	MOVEI	T4,(T1)
	ADD	T4,.CPMAP##
	HRLI	T4,(POINT 36,0)

TX1TC2:	ILDB	T1,T4		;GET CONTENTS OF SLOT
	SKIPN	T1		;MUST BE MAPPED
	STOPCD	CPOPJ,DEBUG,KNM,;++KONTROLLER NOT MAPPED
	ANDI	T1,17777	;GET PHYSICAL PAGE NUMBER
	SSX	T1,MS.MEM	;SECTION NUMBER
	EXCH	T2,PAGTAB(T1)	;GET ENTRY, SAVE T2
	TLZ	T2,TNCSHB	;CAN NEVER CACHED (EVEN IF SPLIT)
	EXCH	T2,PAGTAB(T1)	;STORE NEW SETTING, RESTORE T2
TX1TC3:	CAIE	T3,(T2)		;DID WE JUST DO LAST PAGE?
	AOJA	T3,TX1TC2	;LOOP, WE HAVE MORE TO DO.
	POPJ	P,		;YES, BYE.
>	;END IFN FTMP
>	;END IFN FTAUTC
; ENABLE/DISABLE MICROCODE LOADING
TX1EDL:	SE1ENT			;ENTER SECTION ONE
	HRRZS	W		;REMOVE JUNK IN LH
	MOVE	T2,T1		;COPY BIT
	XMOVEI	T1,TTXULB##(W)	;POINT TO UCODE LOADER BLOCK IN KDB
	PJRST	BTUEDL##	;ENABLE OR DISABLE
; LOAD MICROCODE
TX1LOD:	SE1ENT			;ENTER SECTION ONE
	PUSHJ	P,SAVE4##	;SAVE SOME ACS
	HRRZS	W		;REMOVE POSSIBLE JUNK IN LH
	XMOVEI	P1,TTXULB##(W)	;POINT TO UCODE LOADER BLOCK IN KDB
	LDB	T1,[POINT 7,TTXDOS##(W),9] ;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	LOAD3		;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	TTXDOS##(W)	;DATAO
	MOVEI	T2,0		;PDP-8/A ADDRESS 0
	XCT	TTXDOS##(W)	;DATAO
	MOVE	T2,[DO.LRS!DO.UC0] ;SELECT PDP-8/A CONTROL REGISTER
	XCT	TTXDOS##(W)	;DATAO

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

; THE DX10 IS NOW LOADED
	PUSHJ	P,TX1INI	;INITIALIZE
	XCT	TTXCIS##(W)	;CONI
	TLNE	T1,(CI.RUN)	;RUNNING?
	JRST	LOAD2		;YES
	MOVEI	T1,.UEMPC	;CALL IT A MICROPROCESSOR CHECK
	DPB	T1,ULBEBP##	;STORE
	SKIPA			;ONWARD
LOAD2:	AOS	(P)		;SKIP
LOAD3:	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	TTXCOS##(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
	HRRZ	T4,TKBICP##(W)	;GET ICPC ADDR
	PUSHJ	P,SETXSP	;SETUP EXTENDED STATUS
	MOVSI	T2,(CCHJMP!CCHGO) ;BUILD JUMP
	MOVEM	T2,(T4)		; ...
	MOVEI	T2,TKBCCL##(W)	;GET COMMAND LIST ADDRESS
	PUSHJ	P,MAPIT		;CONVERT TO PHYSICAL ADDRESS
	DPB	T2,CHYADR	;STORE IN COMMAND
	MOVEI	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,TRBXCW(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
	MOVE	T3,[TUSBOT##,,TUCSNS##] ;WANT SENSE BYTES?
	TDNN	T3,TUBCNF##(U)	;OK AS LONG AS TUBCNF=TUBSTS
	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
	HRRZ	T1,TKBICP##(W)	;GET ICPC ADDRS
	LSH	T1,^D33-CO.ICP	;POSITION
	IORI	T1,CO.CLR!CO.CON+TAPCHN## ;START THE IO
	XCT	TTXCOS##(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 TKBCCL TO A PHYSICAL ADDRESS
;ENTER WITH T2=VIRTUAL ADDRESS, EXIT WITH PHYSICAL ADDRESS
MAPIT:
IFN FTKL10,<
	MAP	T2,(T2)		;DX10 WANTS A PHYSICAL ADDRESS
	TLZ	T2,777760
	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,TRBLNK(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) ;SO IT DOESN'T LOOK LIKE RH20 JUMP-WORD
	TLNN	S,IOSRTY##	;ERROR-RETRY?
	TLO	T3,(CCDAER)	;YES, INFORM THE DX TO 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
	HLRZ	T2,TUBAKA##(U)	;GET UNIT ADDRESS
	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:
;	LDB	T2,PRBFCN##	;GET FUNCTION CODE
;	MOVSI	T3,(IOFXS)	;SHOULD EXTENDED STATUS BE REQ?
;	TDNN	T3,IOFTAB(T2)	; ...
;	JRST	STXSP1		;NO - CLEAR OUT STATUS AREA
	HRRZ	T2,TUBFEP##(U)	;GET SENSE INFO ADDR
	ADDI	T2,(U)		;RELOCATE
	PUSH	P,T2
	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

;STXSP1:PUSHJ	P,CLRXS		;ZERO XS AREA
;	SETZM	CP.STS(T4)	;ALSO CLEAR STATUS POINTER
;	POPJ	P,

;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
	ADDI	T2,(U)				;TO XS AREA
	JRST	CPOPJ1##			;DONE
;HERE TO ZERO THE EXTENDED STATUS AREA
;PRESERVES T1

CLRXS:	HRRZ	T2,TUBFEP##(U)	;GET STATUS AREA
	ADDI	T2,(U)		;RELOCATE
	HRRI	T3,1(T2)	;BUILD BLT POINTER
	HRL	T3,T2		; ...
	HLRE	T2,TUBFEP##(U)	;GET LENGTH
	MOVNS	T2		;AS POSITIVE #
	ADDI	T2,-2(T3)	;GET FINAL ADDR
	SETZM	-1(T3)		;CLEAR FIRST WORD
	BLT	T3,(T2)		;CLEAR REST OF AREA
	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
	MOVEI	T2,TTXTMP##(W)	;WHERE TIE BYTE WILL BE
	DPB	T2,CXYADR	;STORE IN CCW
	HRRZ	T2,TUBFEP##(U)	;GET TIE BYTE
	ADDI	T2,(U)		;RELOCATE
	LDB	T2,XSYSB2	;THE BYTE
	ROT	T2,-10		;POSITION AT START OF WORD
	MOVEM	T2,TTXTMP##(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:	MOVEI	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
	-1			;ILLEGAL
XDSE:!	INSDSE			;DSE EXIT
XCR:!	INSCR			;CR EXIT
XRW:!	INSRW			;REWIND EXIT
XRUN:!	INSRUN			;UNLOAD EXIT
XWRT:!	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
;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 ONL AND CMD ENTRIES

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

TX1ONL:	MOVE	T3,TKBSTS##(W)	;ALWAYS ONLINE IF
	TLNE	T3,TKSSEL##!TKSSTD##!TKSSCH## ;THE KONTROLLER
	JRST	CPOPJ1##	;IS GOING
	XCT	TTXCIS##(W)	;GET CONI
	TLNN	T1,(CI.RUN)	;UP RUNNING?
	POPJ	P,		;NO - NON SKIP
IFN FTAUTC,<
	MOVE	T1,TKBIUN##(W)	;YES - SEE IF ANY DRIVES ARE KNOWN
	SKIPN	(T1)		;IS UNIT 0 THERE?
	AOBJP	T1,.+2		;NO, ARE ANY OTHER DRIVES THERE?
	JRST	CPOPJ1##	;SOME UNITS ARE THERE. RETURN
	PUSH	P,P3		;NO TUBS FOUND. SEE IF DX10 HAS BEEN RELOADED
	SETO	P3,		;START AT UNIT 0
TX1ON1:	PUSHJ	P,TX1CFG	;SEE IF A UNIT IS THERE
	JUMPL	P3,TX1ON2	;DONE IF P3=-1
	HRRZ	T2,P3		;NEXT DRIVE NUMBER
	MOVEI	T1,1		;TELL AUTCON ITS A DX10/TU7X
	PUSHJ	P,NEWTAP##	;INFORM THE WORLD THAT A NEW DRIVE APPEARED
	JRST	TX1ON1		;GO FIND ANOTHER DRIVE
TX1ON2:	POP	P,P3
> ;END IFN FTAUTC
	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
IFE FTKL10,<
	PUSHJ	P,CHKMOR##	;ROOM FOR THE COMMAND?
	  POPJ	P,		;NO, LOSE
>
IFN FTKL10,<
	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	TTXCOS##(W)
	POPJ	P,
IFN FTAUTC,<
	$LOW
INISNS:	BLOCK	6	;PLACE TO READ SESE BYTES IN AUTO-CONFIG ROUTINE
	$HIGH
>

TX1END:	END