Google
 

Trailing-Edge - PDP-10 Archives - BB-J724A-SM_1980 - sources/hdte20.p11
There is 1 other file named hdte20.p11 in the archive. Click here to see a list.
;
.SBTTL	DTE20 - DRIVE A PDP-10 THROUGH A DTE20
;
; THIS MODULE REPLACES THE DL10 MODULE IN THE DN60 FRONT-END
;  PROGRAM TO USE THE DTE20 ON A 2040 CONFIGURATION RATHER
;  THAN THE DTE10 ON THE 1090 OR THE DL10 ON A 1070.
;
; NOTE THAT THE DTE10 AND DTE20 ARE THE SAME HARDWARE; THE
;  DIFFERENCE LIES IN THE PDP-10 SOFTWARE BEHIND THEM.
;  THE DTE10 IS DRIVEN BY D60SER/D6SINT, WHICH INTERFACE
;  TO THE TOPS-10 DTESER MODULE FOR THE DN60.  THE DTE20 IS
;  DRIVEN BY THE TOPS-20 MODULE FESRV WHICH INTERFACES TO
;  DTESRV.  FESRV WAS ENHANCED FOR THE DN60 PROJECT, BUT
;  IT IS NOT SPECIAL-PURPOSE AS D60SER/D6SINT IS.
;
;
.REPT 0


                          COPYRIGHT (c) 1980, 1979
            DIGITAL EQUIPMENT CORPORATION, maynard, mass.

THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
TRANSFERRED.

THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.

DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

.ENDR
;
.SBTTL	DTE20 DRIVER
;
;THIS SECTION CONTAINS THE DTE20 DRIVER AND THE QUEUED PROTOCOL
;INTERFACE CONFORMING TO THE RSX-20F SPECIFICATIONS FOR
;COMMUNICATION BETWEEN THE PDP-11 AND DECSYSTEM-20.
;
; AT THE FRONT ARE SUBROUTINES CALLED FOR INTERRUPT,
;  INITIALIZATION, ONCE-A-CLOCK-TICK PROCESSING AND 
;  ONCE-A-SECOND PROCESSING.  AFTER THESE IS THE TASK.
;
; COPYRIGHT, 1979, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS  01754
;
;
;
;		REVISION HISTORY
;
; 3(001) BS	UNSUSPEND DEVICE WHEN LESS THAN 2 MESSAGES QUEUED TO DTE TASK
;
; 3(002) BS	PREVENT ENABLING OF LINE GREATER THAN WHAT FE IS SET UP FOR
;
; 3(003) BS	ADD LINE COMMAND TO SET LINE SIGNATURE
;
; 3(004) BS	INCLUDE LINE FLAGS IN DEVICE STATUS
;
; 3(005) BS	DO NOT CLEAR ACTIVITY BIT ON EOF NEW INPUT PERMISSION REQUESTED
;
; 3(006) BS	CLEAR DEVICE ACTIVE BIT WHEN ABORT COMPLETE ACKED
;
; 3(007) BS	ADD SECOND BYTE OF LINE FLAGS TO LINE STATUS
;		ADD LINE SIGNATURE TO DEVICE STATUS
;
; 3(010) BS	GIVE REJECT FOR DEVICE STATUS ON DISABLED LINE
;
; 3(011) BS	REJECT DEVICE COMMAND ON DISABLED LINE
;
; 3(012) BS	REJECT WRITE DATA COMMAND ON DISABLED LINE
;
; 3(013) BS	DO NOT DELETE LCB TO PREVENT KMC11 CONFUSION
;
; 3(014) BS	GIVE REJECTS FOR INCORRECT DEVICE NUMBERS HASP/3780/2780
;
; 3(015) BS	CLEAN UP LINE BLOCK STATISTICS WHEN LINE IS DISABLED
;
; 4(016) BS	PREVENT DTE INTERRUPT ROUTINE AND DRIVER FROM LOSING MESSAGES
;
; 4(017) BS	MODIFY TGHA CODE TO HANDLE CHANGE 4(016)
;
; 4(020) BS	ADD SOME MORE DEBUG CODE
;
; 4(021) BS	IMPROVE PERFORMANCE OF DT.INT
;
; 4(022) BS	CHANGE OFFSET INTO COMMUNICATIONS REGION FOR TGHA
;
; 4(023) BS	RAISE PRIORITY OF DLDRVR TASK
;
; 4(024) BS	LOCK OUT DTE20 INTERRUPTS DURING ONCE A SECOND SUBROUTINE
;
; 4(025) BS	CHANGE READ LINE STATUS TO TRANSFER CORRECT NUMBER OF BYTES
;
; 4(026) BS	CORRECT LINE COMMAND ONE TO FIND PROPER OFFSET FOR BSC TASK
;
; 4(027) BS	CORRECT OFFSET TO MESSAGE POINTERS FOR HASP
;
; 4(030) BS	LOWER PRIORITY OF DTE TASK TO PREVENT RECEIVER OVERRUNS
;
;
VDTE20=030
;
;
VEDIT=VEDIT+VDTE20
;
;
;
;
.SBTTL	DTE20 INTERRUPT
;
; THE FOLLOWING SERVICES THE BASIC DTE20 INTERRUPTS BY TURNING
; BITS OFF IN THE TCB OF THE DRIVERS TASK; THE ACTUAL PROCESSING
; IS DONE BY THE TASKS SCHEDULED AS A RESULT OF INDICATION OF 
; ARRIVAL OF HARDWARE INTERRUPTS
; THE LEVEL FOR THE INTERRUPTS IS 6
;
;
DT.INT:	MOV	R0,-(SP)	;SAVE R0
	MOV	R1,-(SP)	;SAVE R1
	MOV	R2,-(SP)	;SAVE R2

	CLR	DBLFLG		;CLEAR DOORBELL FLAG 4(016)

	MOV	DTEBAD,R1	;GET THE BASE ADR OF REGS
11$:	MOV	TE.STW(R1),R0	;LOOK AT THE STATUS WORD TO FIGURE OUT
				; WHY WE ARE HERE.
	BIT	#TS.ETD!TS.XNT!TS.XEE,R0 ;EXIT ONLY IF ALL INTP BITS ARE OFF
	BEQ	18$		;ALL CLEAR,FREE TO LEAVE
	TRACE	TRCTEN,R0	;TRACE STATUS
	MOV	R0,DLSSAV	;SAVE FOR ERROR TRACE
	BIT	#TS.XER!TS.MPE!TS.EPE!TS.EET,R0 ;ANY ERROR BITS  SET?
	BNE	19$		;YES,FATAL ERROR
	MOV	TCDLDR,R2	;POINT R2 TO DTE20 TASK
	BIT	#TS.ETD,R0	 ;IS 11 DONE SET?
	BEQ	12$		;NO
	INC	DTIEDN		;COUNT ELEVEN DONE INTPS
	MOV	#TS.ENT,TE.STW(R1) ;CLEAR INTP CONDITION
	TRACE	TRCTEN,DTIEDN	;ON ELEVEN DONE COUNT
12$:	TST	DTIEDN		;ANY PENDING INTERRUPTS?
	BEQ	13$		;NO
	BIT	#EBTEDN,(R2)	;IS IT WAITING FOR TO11DONE
	BEQ	13$		;NO
	BIC	#EBTEDN!EBWAIT,(R2) ;MAYBE,UNWAIT IT
;
;
; HERE TEST FOR TO TEN DONE INTERRUPT
;
13$:	BIT	#TS.XNT,R0	 ;TEN DONE INTP?
	BEQ	14$		;NO,CHECK FOR OTHERS
	INC	DTIXDN		;COUNT TEN DONE INTERRUPTS
	MOV	#TS.XTS,TE.STW(R1) ;CLEAR INTP CONDITION
	TRACE	TRCTEN,DTIXDN	;ON TEN DONE COUNT
14$:	TST	DTIXDN		;ANY TO-TEN DONE PENDING INTPS?
	BEQ	15$		;NO
	BIT	#EBTXDN,(R2)	;IS IT WAITING FOR TO10DONE?
	BEQ	15$		;NO
	BIC	#EBTXDN!EBWAIT,(R2) ;YES,UNWAIT IT
15$:	BIT	#TS.XEE,R0	 ;DID-10 REQUEST -11 INTERRUPT?
	BEQ	16$		;NO
	INC	DTIDBL		;COUNTS # OF OUTSTANDING
				; DOORBELL INTERRUPTS

	MOV	#1, DBLFLG	;SET THE DOORBELL FLAG 4(016)

	MOV	#TS.EIS,TE.STW(R1) ;CLEAR INTERRUPT CONDITION 
	TRACE	TRCTEN,DTIDBL	;TRACE DOORBELL COUNT
16$:	TST	DTIDBL		;ANY PENDING DOORBELLS?
	BEQ	17$		;NO
	BIT	#EBTENI,(R2) 	;YES,IS IT WAITING FOR DOORBELL INTP
	BEQ	17$		;NO,CHECK FOR OTHER CONDITIONS
;4(021)	BIC	#EBTENI!EBWAIT,(R2) ;MAYBE,UNWAIT IT
;
; RESTORE ALL THE REGS USED AND COMPLETE THE INTERRUPT
;
17$:

	BR	11$		;SEE IF ALL INTP CONDITIONS TAKEN CARE OF
;
;
;

18$:				;WHEN ALL CLEAR COME HERE


	TST	DBLFLG		;DID WE GET A DOORBELL ? 4(016)
	BEQ	21$		;NO, EXIT 4(021)
	CLR	DBLFLG		;YES, CLEAR THE DOORBELL FLAG 4(016)

	JSR	PC, DVLECK	;CHECK FOR TGHA AND VALID EXAM
	TST	TGFLAG		;IS TGHA RUNNING ?
	BEQ	20$		;NO, COUNT AS REGULAR DOORBELL
	DEC	DTIDBL		;YES, CANCEL THIS DOORBELL
	BR	21$		;EXIT WITHOUT WAKING DTE TASK 4(021)
20$:

	TST	DTIDBL		;ANY PENDING DOORBELLS?
	BEQ	22$		;NO
	BIT	#EBTENI,(R2) 	;YES,IS IT WAITING FOR DOORBELL INTP
	BEQ	22$		;NO,CHECK FOR OTHER CONDITIONS

	BIC	#EBTENI!EBWAIT,(R2);WAITING FOR DOORBELL, WAKE DTE TASK 4(021)
22$:

	JSR	PC, DVWAKE	;WAKE THE DTE DRIVER IF WAITING FOR TGHA 4(017)

21$:				;NEW LABEL 4(021)

	MOV	(SP)+,R2	;RESTORE R2
	MOV	(SP)+,R1	;RESTORE R1
	MOV	(SP)+,R0	;RESTORE R0
	RTI			;EXIT THE INTERRUPT
;
; HERE IF THE DTE20 HAS AN ERROR
;
19$:	STOPCD	DL10		;DTE20 ERROR.
;

DBLFLG:	.WORD	0		;DOORBELL FLAG 4(016)
;
; ROUTINE CALLED AT STARTUP TO INITIALIZE THE DTE SOFTWARE INTERFACE
;  (THE HARDWARE NEEDS NO INITIALIZATION). IT WAITS FOR THE -10 TO EXIT
;  PRIMARY PROTOCOL BECAUSE THERE IS NO PRESENT MECHANISM FOR RESTARTING
;  THE QUEUED PROTOCOL. IT MUST BE RESTARTED BECAUSE OTHERWISE WE WOULD
;  NOT KNOW WHAT STATE WE WERE IN WHEN WE GOT RESTARTED AND THEREFORE
;  CANNOT CONTINUE USING THE PRESENT INCARNATION.
;
INITDL:				;INITIALIZE THE COMM AREA'S
	CLR	TGFLAG		;CLEAR TGHA RUNNING FLAG
	MOV	DTEBAD,R0	;GET DTE REGS BASE ADR
	MOV	#50,R2		;NO OF TRIES
	TST	DLACKF		;OUT OF PRIMARY PROTOCOL?
	BEQ	14$		;YES
	MOV	#TS.RST,TE.DG2(R0) ;RESET DTE20
11$:	CLR	TE.XA1(R0)	;TRY TO EXAMINE START OF COMM AREA
	CLR	TE.XA2(R0)	;TO SEE IF QUEUED PROTOCOL IS RUNNING
	MOV	#3000,DTEDTO	;TIME OUT FOR DEP/EXAM
12$:	BIT	#TS.XDN,TE.STW(R0) ;EXAMINE DONE?
	BNE	13$		;YES
	DEC	DTEDTO		;DECREMENT TIME COUNT
	BNE	12$		;LOOP IF TIMER NOT EXPIRED
	BR	14$		;EXAMINE FAILED,MUST BE OUT OF PRIMARY PROTOCOL
;
13$:	BIT	#TS.EPE,TE.STW(R0) ;ANY PARITY ERROR?
	BNE	21$		;YES,GO TO STOP CODE
	TST	TE.XW2(R0)	;DO WE WAIT FOR PRIM PROTO TO GO AWAY?
	BEQ	14$		;IT IS OUT OF PRIMARY PROTOCOL
	DEC	R2		;DONE WITH ALL TRIES
	BNE	11$		;NO,LOOP
	RTS	PC		;GIVE UP AFTER ALL THE TRIES
;
;
; HERE WE ARE OUT OF PRIMARY PROTOCOL, SAFE TO RESTART
;
14$:	CLR	DLACKF		;INDICATE OUT OF PRIMARY PROTOCOL
	MOV	#TS.EEX,TE.STW(R0) ;RING -10'S DOORBELL
;
;NOW TRY TO GET BACK INTO PRIMARY PROTOCOL AGAIN
;
15$:	CLR	TE.XA1(R0)	;TRY TO EXAMINE COMM AREA
	CLR	TE.XA2(R0)
	MOV	#3000,DTEDTO	;TIMEOUT FOR EXAMINE
16$:	BIT	#TS.XDN,TE.STW(R0) ;EXAMINE DONE?
	BNE	17$		;YES
	DEC	DTEDTO		;NO, TIMEOUT YET?
	BNE	16$		;NO, LOOP TILL TIME EXPIRES
	RTS	PC		;GIVE UP
;
;
17$:	TST	TE.XW2(R0)	;IN PRIMARY PROTOCOL?
	BEQ	18$		;NO
	TST	TE.XW3(R0)	;YES,IS  VALID EXAMINE ON?
	BNE	19$		;YES,VALID EXAMINE IS ON
18$:	RTS	PC		;GIVE UP AFTER ALL THE TRIES
;
19$:	MOV	#-1,DLACKF	;IN PRIMARY PROTOCOL
	CLR	DLGONE		;INDICATE TEN IS UP
	CLR	TGFLAG		;CLEAR TGHA RUNNING FLAG
	MOV	#10,R1		;NO OF TRIES
20$:	JSR	PC,DSPDLS	;CHECK FOR TEN TO BE REALLY UP
	TST	DLGONE		;IS TEN STILL UP?
	BNE	18$		;NO
	SOB	R1,20$		;TRY AGAIN
	CLR	DTIDBL		;CLEAR INTERRUPT COUNTERS
	CLR	DTIXDN		;FOR TO-TEN DONE
	CLR	DTIEDN		;TO-ELEVEN DONE
	CLR	DT10AK		;PERMIT TO ACK TO TEN
	CLR	DTPTCT		;COUNT OF PUNTED MESSAGES
.IIF NE,DEBUG,BIS #TRCTEN,TRCBTS ;TRACE -10 INTERACTIONS TO DEBUG EXAMINE/DEPOSIT
	JSR	PC,DLINDB	;SETUP AND INIT THE DATA BASES
	BCS	21$		;INITIALIZATION ERROR
	RTS	PC		;ALL DONE INITIALIZING,EXIT

21$:	STOPCD	DTA20		;DTE20 INITIALIZATION ERROR
;
;
; ROUTINE TO REQUEST -10 TO RELOAD US. DONE SO BY SETTING THE RELOAD
;  FLAG IN OUR STATUS WORD IN THE COMM AREA.
;
DLSTCS:	MOV	DLGONE,R1	;ARE WE TALKING TO -10?
	INC	R1		;IF DLGONE -1,10 IS DOWN
	BEQ	12$		;NO, FORGET IT
.IF NE,DEBUG
	MOV	DTEBAD,R0	;GET BASE ADR OF DTE REGS
	MOV	#20,R2		;NO OF DTE20 REGISTERS TO SAVE
	MOV	#DTESAV,R1	;POINT TO AREA TO BE SAVED
11$:	MOV	(R0)+,(R1)+	;SAVE THE REGISTER
	SOB	R2,11$		;LOOP IF NOT DONE SAVING ALL 20 REGS
.ENDC ;NE,DEBUG
;
;NOW WE CAN CHANGE STATUS AROUND
;
	BIS	#DLLD11,DTSTT	;SET RELOAD REQUEST FLAG
	MOV	DTEPCA,R3	;GET ADDRESS OF COMM AREA DATA BLOCK
	MOV	DTEBAD,R0	;SETUP DTE BASE ADR
	MOV	#DLSTAT-DLPIN,R2 ;INDICATE THAT -11 IS FINISHED
	ADD	DTDMYN(R3),R2	;POINT TO STATUS WORD
	MOV	#TS.DEP,TE.XA1(R0) ;INDICATE WRITE
	MOV	DTSTT,TE.XW1(R0) ;SET UP TO DEPOSIT
	MOV	DTSTT+2,TE.XW2(R0) ;
	MOV	DTSTT+4,TE.XW3(R0) ;
	MOV	R2,TE.XA2(R0)	;START XFER
	MOV	#TS.EEX,TE.STW(R0) ;TELL -10 ABOUT CATASTROPHE
12$:	RTS	PC		;-10 SHOULD RELOAD US IMMEDIATELY
;
.SBTTL	DTE20 ONCE-A-TICK
;
; SUBROUTINE TO CHECK ON THE DTE20 ONCE A JIFFIE
;
DSPDLT:	CLC			;FLAG SUCCESS
	RTS	PC		;RETURN
;
.SBTTL	DTE20 ONCE-A-SECOND
;
; ONCE-A-SECOND SUBROUTINE FOR DTE20 THINGS
;
DSPDLS:
	MFPS	-(SP)		;SAVE OLD PSW 4(024)
	MTPS	#BR3		;LOCK OUT DTE20 INTERRUPTS 4(030)

;	MOV	R1,-(SP)	;SAVE R1
;	MOV	R0,-(SP)	;SAVE R0
	MOV	DTEBAD,R0	;BASE ADR OF REGS
	CLR	TE.XA1(R0)	;LOOK AT HEADER WORD TO FIND
	CLR	TE.XA2(R0)	;IF -10 IS DEAD
	JSR	PC,DLWEDN	;IS TEN TALKING TO US?
	BCS	11$		;-10 IS DOWN
;	TST	TE.XW2(R0)	;GET PROCESSOR #
;	BEQ	11$		;NOT IN PRIMARY PROTOCOL YET
	TST	TE.XW3(R0)	;CHECK FOR VALID EXAMINE?
;	BNE	13$		;-10 IS UP
	BNE	18$		;-10 IS UP, WAKE DL DRIVER TASK
	TST	TGFLAG		;-10 MAY BE DOWN, CHECK FOR TGHA
	BNE	10$		;YES, TGHA HAS BEEN RUNNING
	CLR	TGCNT		;NO, INITIALIZE THE 5 SECOND WAIT
	MOV	#1, TGFLAG	;SET TGHA RUNNING FLAG
10$:	INC	TGCNT		;ADD 1 TO # OF SECONDS WAITING
	CMP	TGCNT, #7	;HAS TIME ELAPSED ?
	BGE	11$		;YES, -10 IS REALLY DEAD
	BR	13$		;NO, UPDATE COUNTERS AND CONTINUE WAITING
;
; HERE WHEN THE PDP-10 HAS GONE DOWN.
;
11$:	MOV	#TS.DEI,TE.STW(R0) ;DONT LISTEN TO TEN
	MOV	#-1,DLGONE	;TELL THE WORLD DTE20 DOWN
	CLR	JIFCLK		;MAKE SURE LOOP CATCHER DOES'NT  GO
	CLR	DLGNTM		;CLEAR TIME SINCE DTE20 GONE
12$:
	MTPS	(SP)+		;RESTORE OLD PSW 4(024)

	SEC			;SET CARRY FOR FAILURE
;	BR	14$		;RETURN
	RTS	PC		;RETURN
13$:	INCB	DTKPLV		;INCREMENT KEEP ALIVE CTR
	MOV	DTEBAD,R0	;PREPARE TO DEPOSIT
	MOV	DTKPLV,TE.XW3(R0) ;THE COUNT TO -20
	MOV	#TS.DEP,TE.XA1(R0);SET DEPOSIT FLAG
	MOV	#DLPW1,TE.XA2(R0) ;START XFER
	JSR	PC,DLWEDN	;WAIT FOR EXAM/DEP
;14$:	MOV	(SP)+,R0	;RESTORE REGS
;	MOV	(SP)+,R1
	MTPS	(SP)+		;RESTORE OLD PSW 4(024)
15$:	RTS	PC		;RETURN
;
;
; HERE TO WAKE DL DRIVER TASK AFTER TGHA HAS RUN


18$:

	TST	TE.XW2(R0)	;GET PROCESSOR #
	BEQ	11$		;NOT IN PRIMARY PROTOCOL
				;THE -10 LIED TO US

	BR	13$		;UPDATE COUNTERS AND CONTINUE 4(017)

DVWAKE:				

	CLR	TGFLAG		;CLEAR TGHA RUNNING FLAG
	MOV	R0, -(SP)	;SAVE R0
	MOV	TCDLDR, R0	;POINT TO DL DRIVER TASK

	BIT	#EBVALE, (R0)	;ARE WE WAITING FOR VALID EXAMINE ? 4(016)
	BEQ	19$		;NO, CONTINUE 4(016)
				;YES, WAKE THE DTE TASK UP 4(016)

	BIC	#EBVALE!EBWAIT, (R0) ;NOT WAITING FOR VALID EXAMINE
19$:				;NEW LABEL 4(016)

	MOV	(SP)+, R0	;RESTORE R0

	RTS	PC		;RETURN 4(017)

;4(017)	BR	13$		;UPDATE COUNTERS AND CONTINUE



; HERE TO CHECK FOR DISABLED LINES
;
DLCKDL:	CLR	R1		;START WITH LINE ZERO
11$:	ASL	R1		;LINE # * 2
	MOV	DQLCB(R1),R0	;POINT TO LCB
	BEQ	12$		;NONE THERE
	BIT	#LS.ENB,(R0)	;LINE DISABLED?
	BNE	12$		;NO.
	BIT	#LF.ABC,LB.FGS(R0) ;YES, CHECK IF ABORT COMPLETE
	BEQ	12$		;NOT YET
	MOV	R0,R4		;LCB PTR IN R4
	MOV	LB.TC1(R4),R0	;POINT TO BSC TCB
;3(013)	BEQ	13$		;ERROR, BSC TCB MISSING
	BEQ	12$		;;++BS-BSC TCB ALREADY DELETED 3(013)
	MOV	R1,-(SP)	;SAVE LINE # * 2
	MOV	TCBP1,R3	;POINT TO START OF CHAIN
	JSR	PC,DLRLTC	;RELEASE THE BSC TCB
	MOV	R3,TCBP1	;UPADTE THE BSC CHAIN PTR
	CLR	LB.TC1(R4)	;;++BS-CLEAR THE POINTER TO BSC TCB 3(013)
;3(013)	MOV	R4,R0		;POINT TO LCB
;3(013)	JSR	PC,FRESTG	;FREE THE LCB ALSO
	MOV	(SP)+,R1	;GET BACK THE LINE # * 2
;3(013)	CLR	DQLCB(R1)	;CLEAR LCB POINTER

	JSR	PC, HSSAVR	;;++BS-SAVE THE REGISTERS 3(015)
	MOV	DQLCB(R1), R2	;;++BS-POINT R2 TO LCB 3(015)
	MOV	R2, R3		;;++BS-POINT R3 TO LCB 3(015)
	ADD	#LB.ST1, R2	;;++BS-POINT TO START OF LINE STATISTICS 3(015)
	ADD	#LB.ST2-2, R3	;;++BS-DO ALL EXCEPT LINE DRIVER TYPE 3(015)
14$:	CLR	(R2)+		;;++BS-CLEAR AN ENTRY 3(015)
	CMP	R2, R3		;;++BS-HAVE WE REACHED THE END ? 3(015)
	BNE	14$		;;++BS-NO 3(015)
	JSR	PC, HSRESR	;;++BS-YES, ALL DONE, RESTORE REGISTERS 3(015)

12$:	ASR	R1		;LINE # BACK
	INC	R1		;FOR NEXT LINE
	CMP	R1,#NLINES	;IF LINE CONFIGURED
	BLO	11$		;LOOP FOR NEXT LINE
	RTS	PC		;RETURN 
;
;3(013) 13$:	STOPCD	DTM		;TCB MISSING
;
.SBTTL	DLINDB -- TURN THE DTE20 ON
; AND SETUP PROCESSOR COMMUNICATION DATA BASE
;
; THIS ROUTINE WILL SET UP THE TABLES NECESSARY TO
;  INITIALIZE THE COMMUNICATIONS BETWEEN THE PDP-10
;  AND THE PDP-11.
;
; CALL: JSR PC,DLINDB
;
; ON RETURN:
;		C = 0: R0 = 1 TO INDICATE SUCCESS
;		C = 1: ERROR
;
; NOTE THAT THIS ROUTINE USES R5 IN A NON-STANDARD WAY.
;  THIS IS BECAUSE IT WAS TAKEN FROM THE DN87S CODE AND
;  WE WOULD PREFER NOT TO HAVE TO RE-WRITE IT TO MAKE IT
;  CONFORM TO THE DN60 CODING CONVENTIONS.
;
DLINDB:	MOV	R5,-(SP)
	CLR	-(SP)
	CLR	-(SP)
	MOV	DTEBAD,R0	;FIND THE COMMON DTE20
	CLR	R1		;SET UP TO FIND PROCESSOR NUMBER
	CLR	R2		;START TRANSFER OF ABS WORD 0 OF EPT (MY PROCESSOR NUMBER
	MOV	#DTXTM3,R3	;SET UP ADDRESS TO STORE WORDS
	CLR	R4
	JSR	PC,DLSWED	;WAIT FOR EXAMINE/DEPOSIT
	BCS	11$		;E BOX STOP
	MOV	@R3,R4		;YES --FIND OFFSET TO MY R/W AREA
	MOVB	@#DTXTM2+1,R2	;FIND THE PROCESSOR NUMBER
				; PROCESSOR NUMBER TO LOW ORDER BITS
	BIC	#177760,R2	;MASK OFF JUNK(0.-15. LEGAL)
	MOV	R2,DLMYPN	;SAVE PROCESSOR NUMBER
	INC	R2		;FIND COMMUNICATIONS VIRTUAL 2
	MOV	R2,DLCMBS	;SAVE BASE OF COMMUNICATIONS AREA
	ADD	R4,R2		;ADD OFFSET TO BASE OF COMM AREA
	MOV	R2,DLDPOF	;SET CORRECT OFFSETT
	JSR	PC,DLSWED	;WAIT FOR TRANSFER
11$:	BCS	DLINDR		;
12$:	MOV	@#DTXTM2,R5	;PICK UP THE NUMBER OF 8 TM BLOCKS
	BIC	#177770,R5	;FIND THE NUMBER OF 8 WORD BLOCKS IN MY AREA
	SUB	#2,R5		;ACCOUNT FOR MY GENERAL SECTION
	MOV	R2,2(SP)
;
; CONTINUED ON THE NEXT PAGE
;
;
; CONTINUATION OF DLINDB
;
	MOV	R5,0(SP)	;SAVE	COUNT OF BLOCKS
DLIND1:	ADD	#DLPIN,2(SP)	;LOOK AT A COMMUNICATIONS AREA TO ANOTHER PROCESSOR
	MOV	2(SP),R2
	CLR	R4
	JSR	PC,DLSWED	;WAIT FOR TRANSFER
11$:	BCS	DLINDR		; E BOX STOPPED
	MOV	@R3,R4		;FIND @ROCESSOR NUMBER
	MOV	#DTPIDT,R5	;SET INITIAL POINTER
	BIC	#177770,R4	;MASK OFF JUNK
	BEQ	13$		;YES -- CONTINUE
12$:	ADD	#5*2,R5		;NO -- LOOK AT NEXT ENTRY
	SOB	R4,12$		;TRY UNTIL ALL DONE
13$:	MOV	@#DTXTM2,R4	;FIND NUMBER OF 8 WORD BLOCS
	BIC	#177770,R4	;MASK OFF POSSIBLE GARBAGE
	SUB	R4,@SP		;UPDATE COUNT OF BLOCKS
	CLR	@R5		;SET UP TO CLEAR TABLE IF NO DTE
	MOV	@#DTXTM1,R4	;PICK UP DTE NUMBER
	BIT	#4,R4		;DTE HERE?
	BEQ	15$		;NO -- DON'T ENTER IN TABLE
	SWAB	R4		;MAKE MOD 40 (8)
	ROR	R4
	ROR	R4
	ROR	R4
	BIC	#177637,R4	;MASKOFF JUNK
	ADD	#174400,R4	;POINT TO FIRST BLOCK OF DTE'S
	CMP	R4,DTEBAD	;PRIMARY DTE?
	BNE	14$		;NO -- DON'T SET TABLE POINTER
	MOV	R5,DTEPCA	;SAVE TABLE OFFSET
14$:	MOV	R4,@R5		;SET DTE ADDRESS IN TABLE
	MOV	#37777,@R4	 ;SET UP DELAY COUNTER
	MOV	#TS.EEE,TE.STW(R4) ;YES -- ENABLE INTERRUPT ON IT
15$:	MOV	R2,DTEMYN(R5) 	;SET THE ADDRESS OF EXAMINE MY AREA FOR N
;
; CONTINUED ON NEXT PAGE
;
;
; CONTINUATION OF DLINDR.
;  MAKE ADDRESS OF THE ADDRESS OF DEPOSIT MY AREA FOR N
	MOV	R2,DTDMYN(R5) 	;STORE IT
	SUB	DLDPOF,DTDMYN(R5) ;RESTORE SUBRESS FOR EXAMINE OF THIS BLOCK
	ADD	#DLPCA-DLPIN,R2 ;READ POINTER TO HIS COMM AREA
	CLR	R4
	JSR	PC,DLSWED	;WAIT FOR EXAMINE/DEPOSIT
16$:	BCS	DLINDR		;E BOX STOPPED
	MOV	@R3,R2		;FIND THE EXAMINE ADDRESS
	ADD	DLCMBS,R2	;ADD OFFSET TO COMMON AREA
	MOV	R2,DTEHSG(R5) 	;SET DTEHSG ADDRESS IN TABLE
	ADD	#DLPIN,R2	;POINT TO HIS FIRST TABLE FOR OTHER PROCESSORS
17$:	CLR	R4
	JSR	PC,DLSWED	;WAIT FOR EXAMINE/DEPOSIT
18$:	BCS	DLINDR
	CMPB	DLMYPN,@R3 	;SAME PROCESSOR NUMBER?
	BEQ	19$		;YES -- FOUND MY ENTRY
	MOV	@#DTXTM2,R4	;NO -- FIND NEXT ENTRY IN LIST
	BIC	#177770,R4	;IT IS IN 8 WORD INCREMENTS
;;++KR-FIX FOR TOPS-20 MONITOR PROBLEM
	BNE	20$		;;++KR-NON ZERO IS GOOD
	INC	R4		;;++KR-MAKE IT NON ZERO
20$:
;;++KR-END FIX
	ASL	R4		;SO IT MUST BE SHIFTED LEFT 3 BITS
	ASL	R4		;
	ASL	R4		;
	ADD	R4,R2		;READ NEXT BLOCK
	BR	17$		;AND TRY AGAIN
;
19$:	MOV	R2,DTEHSM(R5)	;STORE DTEHSM ADDRESS
	MOV	@SP,R5		;DONE ALL BLOCKS??
	BHI	DLIND1		;NO -- TRY NEXT BLOCK
	CLR	DTQCNT		;RESET PROTOCOL COUNTERS
	CLR	DTQSTA		;INIT STATE MECHANISM, CLEAR CARRY
DLINDR:	MOV	(SP)+,R5	;RESTORE STACK 
	MOV	(SP)+,R5
	MOV	(SP)+,R5
	RTS	PC
;
.SBTTL	DLSWED -- INTERNAL SUBROUTINE START AND WAIT FOR EX/DEP
;
; THIS SUBROUTINE STARTS A DEPOSIT/EXAMINE SEQUENCE AND WAITS FOR
;  ITS COMPLETION.  IT CHECKS TO SEE IF THE BOOTSTRAP
;  PROTOCOL IS NECESSARY BY CHECKING THE EXAMINE VALID BIT
;  AFTER EVERY EXAMINE/DEPOSIT.  IT IS NOT NECESSARY TO
;  CHECK MORE THAN ANY ONE RANDOM EXAMINE VAILD BIT
;  BECAUSE IF ONE IS 0 THEN THE PROCESSOR HAS
;  TO REVERT TO THE BOOTSTRAP PROTOCOL.
;
; CALL:	JSR	PC,DLSWED
;
;	R0 -- ADDRESS OF DTE20
;	R1 -- HIGH ORDER EXAMINE/DEPOSIT ADDRESS WORD (FOR TE.XA1)
;	R2 -- LOW ORDER EXAMINE/DEPOSIT ADDRESS WORD (FOR TE.XA2)
;	R3 -- ADDRESS TO XFER 3 WORD BLOCK TO OR FROM
;
; ON RETURN:
;
;	C = 0: SUCCESS, NO REGISTERS ALTERED.
;	C = 1: ERROR.
;
DLSWED:	MOV	R3,-(SP)	;SAVE REGISTERS
	BIT	#TS.DEP,R1	;CHECK FOR DEPOSIT
	BNE	12$		;YES -- GO TO DEPOSIT PART OF SUB
	MOV	R1,TE.XA1(R0)	;SET UP ADDRESS OF XFER IN DTE
	MOV	R2,TE.XA2(R0)	;START XFER
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE/DEPOSIT
	BCS	14$		;COMPLAIN ABOUT E BOX STOPPED
	MOV	TE.XW3(R0),(R3)+ ;STORE THE WORD XFERED
	MOV	TE.XW2(R0),(R3)+
	MOV	TE.XW1(R0),(R3)+
11$:	TST	R4		;PRIV EXAMINE/DEP?
	BNE	14$		;YES -- DON'T DO CHECKS
	CLR	TE.XA1(R0)	;SEE IF WE CAN READ ANYTHING
	CLR	TE.XA2(R0)	;START TRANSFER
	JSR	PC,DLWEDN	;WAIT FOR XFER
	BCS	14$		;E BOX STOPPED
	TST	TE.XW3(R0)	;VALID?
	BNE	14$		;YES -- PROCEED
	BR	13$		; NO - JUST SET CARRY AND RETURN
;
;
; HERE TO DO AN EXAMINE.
;
12$:	MOV	(R3)+,TE.XW3(R0) ;TRANSFER TO 10
	MOV	(R3)+,TE.XW2(R0) ;SET UP WORD IN DTE
	MOV	(R3)+,TE.XW1(R0)
	MOV	R1,TE.XA1(R0)	;SET HIGH ORDER ADDRESS
	MOV	R2,TE.XA2(R0)
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE/DEPOSIT
	BCC	11$		;GO TO COMMON EXAMINE VALID BIT CHECK
;
; HERE IF THE 'EXAMINE VALID' BIT IS OFF.  GIVE AN ERROR RETURN.
;
13$:
.IF NE,DEBUG
	STOPCD	DBG		;-10 STOPPED UNEXPECTEDLY
.ENDC
	SEC
14$:	MOV	(SP)+,R3	;RESTORE R3
	RTS	PC		;RETURN TO CALLER
;
.SBTTL	DLWEDN -- INTERNAL SUBROUTINE  WAIT FOR EXAMINE/DEPOSIT
;
; THIS SUBROUTINE WAITS FOR EXAMINE/DEPOSIT TRANSFERS AND
;  CHECKS TO SEE THAT E BOX HAS NOT STOPPED.
;
; CALL:	JSR	PC,DLWEDN
;
;	R0 -- ADDRESS OF DTE20
;
; ON RETURN:
;	C = 0: SUCCESS
;	C = 1: ERROR
;
DLWEDN:	MOV	#3000,DTEDTO	;SET UP TIMEOUT FOR TS.XDNE
11$:	BIT	#TS.XDN,TE.STW(R0) ;WAIT FOR TRANSFER TO COMPLETE
	BNE	12$		;DONE
	DEC	DTEDTO		;TIMEOUT?
	BNE	11$		;NO -- CONTINUE WAITING
	SEC			;YES, ERROR.
	RTS	PC		;RETURN.
;
; HERE WHEN THE TRANSFER IS COMPLETE.
;
12$:	BIT	#TS.EPE,TE.STW(R0) ;CHECK FOR E BUS PARITY ERROR
	BNE	13$		;WE HAVE E-BUS PARITY
	CLC			;CLEAR CC-C
	RTS	PC		;RETURN TO CALLER
;
; WE HAVE AN E-BUS PARITY ERROR.  CALL THIS A FATAL ERROR.
;
13$:	STOPCD	DTE20		;E-BUS PARITY ERROR
;
;
.SBTTL	DTE20 TASK
;
; THIS TASK INTERFACES TO THE PDP-10 THROUGH THE DTE20
;
DLDRVR:				;DRIVER INTERFACE FOR DTE20


	MFPS	-(SP)		;SAVE PSW 4(023)
	MTPS	#BR3		;LOCK OUT DTE INTERRUPTS 4(030)

11$:				;CHK FOR TGHA AND VALID EXAMINE

	TST	TGFLAG		;IS TGHA RUNNING
	BNE	20$		;YES, PUT TASK BACK TO SLEEP



18$:	MOV	#EBTENI!EBTXDN!EBTEDN!EBWAIT,(R5) ;SET UP FOR WAIT
	MOV	#JIFSEC,TCTIM(R5) ;TIME LIMIT FOR WAITING
12$:	TST	DTIEDN		;ANY TO-ELEVEN DONE INTP?
	BEQ	13$		;NONE
	JSR	PC,DLELDN	;YES,GO PROCESS TO ELEVEN DONE
	BCS	16$		;FAILURE
	BR	11$		;SUCCESS, LOOK FOR MORE INTERRUPTS
;
13$:	TST	DTIXDN		;ANY TO TEN DONE INTERRUPTS
	BEQ	14$		;NONE
	TST	DTIEDN		;HAS ANY 11-DONE SNEAKED IN?
	BNE	12$		;YES,IT HAS
	JSR	PC,DLTXDN	;NO,THEN PROCESS TO TEN DONE
	BCS	16$		;FAILURE RETURN
	BR	11$		;LOOK FOR MORE
;
14$:	TST	DTIDBL		;ANY DOORBELL INTERRUPTS?
	BEQ	15$		;NONE
	TST	DTIXDN		;ANY TO-TEN DONE SNEAKED IN?
	BNE	12$		;YES,START OVER
	TST	DTIEDN		;ANY TO-11 DONE SNEAKED IN?
	BNE	12$		;YES,START OVER
	JSR	PC,DLDRBL	;NO,THEN PROCESS DOORBELL
	BCS	16$		;FAILED
	BR	11$		;SUCCESS, LOOK FOR MORE WORK
;
15$:
	MTPS	(SP)+		;RESTORE OLD PSW 4(023)
	JSR	PC,WAIT		;WAIT FOR AN INTERRUPT
	BR	DLDRVR		;
;4(023)	BR	11$		;LOOK FOR WORK TO DO
;
; HERE ON FATAL PROTOCOL ERROR OR 10 CRASHED
;
16$:


.IF NE,DEBUG			;4(020)

	BIT	#TRCTER,TRCHLT	;STOP ON PDP-10 ERROR?
	BEQ	17$		;NO.

	STOPCD	TER		;YES, PDP-10 ERROR

17$:

.ENDC 				;.IF NE,DEBUG 4(020)

;


	TST	TGFLAG			;IS TGHA RUNNING?
	BNE	20$			;YES, PUT TASK TO SLEEP
19$:
	MTPS	(SP)+			;RESTORE OLD PSW 4(023)

	JSR	PC, DTCERR		;DTE ERROR, DISABLE ALL LINES
	JMP	DLDRVR			;WAIT FOR ANOTHER COMMAND



;HERE TO PUT TASK TO SLEEP BECAUSE OF TGHA


20$:	BIS	#EBTENI!EBTXDN!EBTEDN!EBVALE!EBTIME!EBWAIT,(R5)	;WAITING FOR VALID EXAMINE
	MOV	#JIFSEC,TCTIM(R5)	;TIME LIMIT FOR WAITING

	MTPS	(SP)+			;RESTORE OLD PSW 4(023)

	JSR	PC, WAIT		;WAIT FOR VALID EXAMINE AND/OR TGHA TO FINISH
	JMP	DLDRVR			;CHECK CONDITIONS AGAIN 4(023)

;4(023)	JMP	11$			;CHECK CONDITIONS AGAIN
;
; SUBROUTINE TO CHECK FOR VALID EXAMINE BEFORE EXECUTING
; A FUNCTION. THIS IS TO HANDLE TGHA PROTOCOL PAUSE.


DVLECK:

	MOV	R0, -(SP)	;SAVE R0
	MOV	R1, -(SP)	;SAVE R1
	MOV	R2, -(SP)	;SAVE R2
	MOV	R3, -(SP)	;SAVE R3
	MOV	DTEBAD,R0	;GET BASE ADR OF DTE REGS
	MOV	DTEPCA,R3	;SETUP COMMUN ADR
	CLR	TE.XA1(R0)	;READ STATUS WORD
	MOV	#DLSTAT-DLPIN,R2 ;FIND THE ADDRESS OF HIS DLSTAT-TO ME
	ADD	DTEHSM(R3),R2
	MOV	R2,TE.XA2(R0)	;READ THAT STATUS WORD
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE
	BCS	1$		;IGNORE INTERRUPT IF NOT STARTED
	TST	TE.XW1(R0)	;VALID EXAMINE ? 4(022)
;4(022)	TST	TE.XW3(R0)	;VALID EXAMINE ?
	BNE	2$		;YES
1$:	CLR	TGCNT		;NO, SET UP 5 SECOND WAIT
	MOV	#1,TGFLAG	;NO, SET TGHA PROGRAM FLAG
	BR	3$		;EXIT
2$:	CLR	TGFLAG		;CLEAR TGHA PROGRAM FLAG
3$:	MOV	(SP)+, R3	;RESTORE R3
	MOV	(SP)+, R2	;RESTORE R2
	MOV	(SP)+, R1	;RESTORE R1
	MOV	(SP)+, R0	;RESTORE R0
	RTS	PC		;RETURN



TGFLAG:	.WORD	0		;FLAG TO INDICATE TGHA IS RUNNING
TGCNT:	.WORD	0		;5 SECOND COUNTER TO WAIT FOR TGHA
;
;THIS ROUTINE HAS BEEN REMOVED
;ITS FUNCTIONS ARE PERFORMED ELSEWHERE


;; HERE ON PDP-10 PROTOCOL ERROR.
;;  ABORT ALL STREAMS AND DISABLE ALL LINES.
;;
;	CLR	R3		;START WITH LINE NUMBER 0
;18$:	MOV	DQLCB(R3),R0	;GET LCB POINTER
;	BEQ	19$		;NONE.
;	BIC	#LS.ENB,(R0)	;DISABLE THE LINE
;	MOV	LB.TC1(R0),R1	;POINT TO BSC TASK
;	BIS	#TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
;	CMP	#TTHASP,LB.DVT(R0)	;HASP LINE?
;	BEQ	21$		;YES.
;	MOV	LB.TCD(R0),R1	;POINT TO XLATE TASK
;	BIS	#TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
;19$:	ADD	#2,R3		;NEXT LINE NUMBER * 2
;	CMP	#<NLINES*2>,R3	;DONE ALL THE LINES?
;	BNE	18$		;NO, DO THE REST.
;	BR	DLDRVR		;YES, GO WAIT FOR ANOTHER COMMAND
;;
;; HERE TO ABORT ALL DEVICES ON HASP-LINE
;;
;21$:	MOV	LB.NTC(R0),R2	;GET # OF TCBS FOR HASP LINE
;	BNE	22$		;IF IT HAS'NT BEEN SET, MAKE IT 5
;	MOV	#5,R2		;THATS MAX # OF TCBS HASP LINE
;22$:	MOV	R0,R1		;GET LCB PTR
;23$:	ASL	R2		;DEVICE NUMBER * 2
;	ADD	R2,R1		;ADD DEVICE #
;	ASR	R2		;GET ORIGINAL DEV #
;	MOV	LB.TCD(R1),R1	;POINT TO XLATE TCB OF DEVICE
;	BEQ	24$		;NO TCB FOR THE DEVICE
;	BIS	#TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
;24$:	SOB	R2,23$		;DO FOR ALL DEVICES ON HASP LINE
;	BR	19$		;GO TO NEXT LINE
;;
;
; SUBROUTINE TO CALL A SUBROUTINE BASED ON AN INDEX.
;  THIS IS USED AS A DISPATCHER.
;
;	R0 = POINTER TO DISPATCH TABLE.  THE FIRST ENTRY IS
;	     THE MAX INDEX, THE REMAINDER BEING POINTERS
;	     TO SUBROUTINES.
;	R1 = INDEX, 0 BASED.
;
; RETURNS WITH C SET IF THE INDEX IS OUT OF RANGE OR IF THE
;  TABLE ENTRY SELECTED CONTAINS A ZERO.  OTHERWISE RETURNS
;  WITH C AS SPECIFIED BY THE SUBROUTINE.
;
DLDISP:	TRACE	TRCTEN,R1	;TRACE DISPATCH PROCESS
	CMP	R1,(R0)+	;IS INDEX IN RANGE?
	BHI	11$		;NO, FATAL ERROR.
	ASL	R1		;YES, COMPUTE INDEX*2
	ADD	R1,R0		;COMPUTE PLACE IN THE TABLE
	MOV	(R0),R1		;PICK UP SUBROUTINE POINTER
	BEQ	11$		;0 = ERROR
	JSR	PC,(R1)		;NON-ZERO, CALL THE SUBROUTINE
	RTS	PC		;RETURN TO CALLER.
;
; HERE IF THE INDEX IS OUT OF RANGE OR IF THE SUBROUTINE POINTER
;  IS ZERO.
;
;11$:	SEC			;FLAG ERROR
;	RTS	PC		;RETURN.


11$:				;HERE TO FLAG ERROR
;	SEC			;FLAG ERROR--THIS MAY BE NECCESSARY
.IF NE,DEBUG
	STOPCD	TER		;TEN ERROR IN ARGUMENTS
.ENDC ;.IF NE DEBUG
	RTS	PC		;RETURN.
;
;
;
; THE FOLLOWING COMMENTS DESCRIBE THE STATES FOR THE STATE-DRIVEN
;  DTE PROCESSOR.  THERE ARE TWO, LOOSELY COUPLED STATE
;  MACHINES.
;
; ABBREVIATIONS USED IN THE DESCRIPTION BELOW ARE AS FOLLOWS:
;
;  FEH - FRONT-END HEADER.  THIS IS A DIRECT MESSAGE THAT
;	DESCRIBES THE INDIRECT DATA THAT FOLLOWS AS "STRING DATA".
;
;  EH - ED HEADER.  THIS IS AN INDIRECT MESSAGE THAT DESCRIBES THE
;	FOLLOWING INDIRECT MESSAGE (IF ANY) AS "WRITE DATA", 
;	"WRITE LINE COMMAND", "READ DATA", ETC.
;
;  ED - ED DATA.  THIS IS THE INDIRECT MESSAGE DESCRIBED BY
;	THE EH MESSAGE ABOVE.
;
;  ACK - ACKNOWLEDGE.  THIS MESSAGE ACKNOWLEDGES RECEIPT AND
;	PROCESSING OF THE LAST INDIRECT MESSAGE.
;
; A PROPER SEQUENCE CONSISTS OF FEH, EH OR FEH, EH, FEH, ED.
;  WHERE RELAVENT, AN FEH IS REFERED TO AS "FEH FOR EH" OR
;  "FEH FOR ED" BASED ON THE MESSAGE THAT FOLLOWS THE FEH.
;
; EACH MESSAGE IS PRECEEDED BY A DOORBELL.
;
; BEFORE AN FEH MAY BE SENT THE PREVIOUS FEH AND ITS FOLLOWING
;  EH OR ED MUST BE ACKNOWLEDGED.  THIS IS A SIMPLIFICATION OF
;  THE TOPS-20 RULE.
;
; A COMPLETE TRANSACTION IS ALWAYS INITIATED BY THE -20
;  WITH AN FEH FOLLOWED BY AN EH.  DEPENDING ON THE
;  CONTENTS OF THE EH, IT MAY BE FOLLOWED BY FEH, ED.
;  THE PDP-11 REPLIES WITH FEH, EH AND, DEPENDING ON THE
;  CONTENTS OF THE FIRST EH, MAY FOLLOW THIS BY
;  FEH, ED.  EXAMINE AND DEPOSIT DO NOT USE ED IN
;  EITHER DIRECTION.  NO FUNCTIONS USES ED IN BOTH
;  DIRECTIONS.
;
; BELOW THE DESCRIPTION OF EACH STATE IS A BRIEF DESCRIPTION OF
;  THE ACTION TAKEN WHEN THE APPROPRIATE EVENT OCCURS.
;
;
; STATE MACHINE "A" IS DRIVEN BY 11-DONE INTERRUPTS AND BY DOORBELLS.
;
;
;  0: WAITING FOR INITIAL DOORBELL.  11-DONE IS INVALID.
;	READ FEH FOR EH.
;
;  2: WAITING FOR FEH FOR EH.  DOORBELL IS INVALID.
;	IF DEVICE IS WRONG, GO TO STATE 34.
;	IF ALLOCATION MESSAGE, GO TO STATE 34.
;	OTHERWISE, READ EH.
;
;  4: WAITING FOR DOORBELL FOR EH.  11-DONE IS INVALID.
;	READ EH.
;
;  6: WAITING FOR EH.  DOORBELL IS INVALID.
;	IF FLAG DT10AK INDICATES THAT ED IS TO COME, THEN
;	SEND ACK ONLY.  SET MACHINE B FROM STATE 0 TO 2.
;	IF DT10AK INDICATES THAT THERE IS NO ED, GO TO
;	  STATE 20, ELSE GO TO STATE 10.
;
; 10: WAITING FOR DOORBELL FOR FEH FOR ED.  11-DONE IS INVALID.
;	READ FEH FOR ED.
;
; 12: WAITING FOR FEH FOR ED.  DOORBELL IS INVALID.
;	GO TO STATE 14.
;
; 14: WAITING FOR DOORBELL FOR ED.  11-DONE IS INVALID.
;	READ ED.
;
; 16: WAITING FOR ED.  DOORBELL IS INVALID.
;	IF MACHINE "B" IS AT STATE 4, SEND ACK+FEH AND
;	  SET MACHINE "B" TO STATE 10, THEN GO TO STATE 22.
;	IF MACHINE "B" IS NOT AT STATE 4, GO TO STATE 20.
;
; 20: WAITING FOR ACK OF EH TO COMPLETE.  (I.E., FOR MACHINE "B"
;      TO GO FROM STATE 2 TO STATE 6 OR 10.)  NEITHER 11-DONE
;      NOR DOORBELL ARE VALID.
;
;
; 22: WAITING FOR DOORBELL FOR ACK FOR EH.  11-DONE IS INVALID.
;	READ ACK FOR EH.
;
; 24: WAITING FOR ACK FOR EH.  DOORBELL IS INVALID.
;	IF THE EH INDICATES THAT NO ED WILL BE RETURNED, 
;	  AND MACHINE "B" IS IN STATE 14, SET BOTH STATES TO ZERO.
;	  IF MACHINE "B" IS NOT IN STATE 14,
;	  GO TO STATE 32.
;	IF THE EH INDICATES THAT AN ED WILL BE RETURNED,
;	  AND MACHINE "B" IS IN STATE 14,
;	  SEND FEH FOR ED, SET MACHINE "B" TO STATE 16
;	  AND GO TO STATE 26.
;	  IF MACHINE "B" IS NOT IN STATE 14, JUST GO TO STATE 26.
;
; 26: WAITING FOR DOORBELL FOR ACK FOR ED.  11-DONE IS INVALID.
;	READ ACK FOR ED.
;
; 30: WAITING FOR ACK FOR ED.  DOORBELL IS INVALID.
;	IF MACHINE "B" IS IN STATE 22, SET
;	  THE STATES OF BOTH MACHINES TO 0.
;	IF MACHINE "B" IS NOT IN STATE 22, GO TO STATE 32.
;
; 32: GOT FINAL ACK.  11-DONE AND DOORBELL ARE INVALID.
;
; 34: IGNORING 11-DONE.
;	IF WE GET AN 11-DONE, IGNORE IT.
;	IF WE GET A DOORBELL, TREAT IT THE SAME AS FOR STATE 0.
;
;
; STATE MACHINE "B" IS DRIVEN BY 10-DONE.
;
;  0: IDLE.  10-DONE IS INVALID.
;
;  2: WAITING FOR COMPLETION OF ACK (OR ACK+FEH) FOR EH.
;	IF MACHINE "A" IS NOT IN STATE 20, JUST GO TO STATE 4.
;	IF MACHINE "A" IS IN STATE 20, SET IT TO STATE 22.
;	IF DT10AK INDICATES THAT AN ED WILL FOLLOW IT,
;	SEND AN ACK + FEH (MACHINE "A" HAS ALREADY PROCESSED THE ED
;	OR IT WOULD NOT BE IN STATE 20) AND GO TO STATE 10.
;	IF DT10AK INDICATES THAT AN ED WILL NOT FOLLOW IT,
;	SEND EH TO-TEN FOR SENDING RESULTS BACK.
;	AND THEN GO TO STATE 10 TO WAIT FOR EH COMPLETION.
;
;  4: GOT COMPLETION OF ACK FOR EH.  10-DONE IS INVALID.
;
;  6: WAITING FOR COMPLETION OF ACK FOR ED.
;	SEND FEH FOR EH.
;
; 10: WAITING FOR COMPLETION OF FEH FOR EH.
;	SEND EH.
;
; 12: WAITING FOR COMPLETION OF EH.
;	IF MACHINE "A" IS IN STATE 26 THEN
;	  SEND FEH FOR ED AND GO TO STATE 16.
;	IF MACHINE "A" IS NOT IN STATE 26 THEN
;	  GO TO STATE 14.
;
; 14: WAITING FOR ACK FOR EH.  10-DONE IS INVALID.
;
; 16: WAITING FOR COMPLETION OF FEH FOR ED.
;	SEND ED.
;
; 20: WAITING FOR COMPLETION OF ED.
;	IF MACHINE "A" IS IN STATE 32 THEN SET BOTH STATES
;	  TO 0, OTHERWISE GO TO STATE 22.
;
; 22: WAITING FOR ACK FOR ED.  10-DONE IS INVALID.
;
.SBTTL 		TO-TEN DONE INTERRUPT PROCESSING FOR DTE20
;
; THIS ROUTINE DECIDES WHAT TO DO WHEN A TO-TEN DONE INTERRUPT
;  IS RECOGNIZED.  IT IMPLEMENTS MACHINE "B" DESCRIBED ABOVE.
;
DLTXDN:	TRACE	TRCTEN,DTQSTA	;TRACE FOR TEN STATE
	MOV	DTEBAD,R0	;GET BASE ADR OF DTE REGS
	MOV	DTEPCA,R3	;SETUP COMMUNICATION BASE ADR
	DEC	DTIXDN		;DECREMENT INTP COUNT
	MOVB	DT10ST,R1	;FIND WHAT STATE THE TEN IS
	JSR	PC,@11$(R1)	;THEN CALL APPROPRIATE ROUTINE
				;TO PROCESS TO-TEN DONE INTERRUPT
	CLC			;SUCCESSFUL 
	RTS	PC		;RETURN
;
; TO TEN DONE SUBROUTINE CALL TABLE
;
11$:	.WORD	DTXDED		;IDLE STATE
	.WORD	DTXS02		;WAITING FOR COMPLETION OF ACK FOR EH
	.WORD	DTXDED		;GOT COMPLETION OF ACK FOR EH
	.WORD	DTXDED		;THIS IS CURRENTLY UNUSED STATE.
	.WORD	DTXS10		;WAITING FOR COMPLETION OF 
				;ACK + FEH FOR EH
	.WORD	DTXS12		;WAITING FOR COMPLETION OF EH
	.WORD	DTXDED		;WAITING FOR ACK FOR EH
	.WORD	DTXS16		;WAITING FOR COMPLETION OF FEH FOR ED
	.WORD	DTXS20		;WAITING FOR COMPLETION OF ED
	.WORD	DTXDED		;WAITING FOR ACK FOR ED
;
DTXDED:	STOPCD	DTC20		;GOOFY TEN DONE INTERRUPTS
;
;
; HERE ON 10-DONE IN STATE 2.  THE ACK FOR EH IS COMPLETE (WRITES)
; OR WHEN ACK + FEH ARE COMPLETED FOR A READ OPERATION.
;
DTXS02:	CMPB	#20,DT11ST	;IS THE OTHER MACHINE WAITING FOR US?
	BEQ	11$		;YES.
	MOVB	#4,DT10ST	;NO, WE MUST WAIT FOR IT.
	RTS	PC		;RETURN UNTIL IT IS READY.
;
11$:	MOVB	#22,DT11ST	;UNWAIT THE OTHER MACHINE
	TST	DT10AK		;DOES MACHINE "A" WANT ANOTHER ACK (FOR ED)?
	BEQ	DTXS10		;NO.
	JSR	PC,DTSACK	;YES, SEND AN ACK
	MOVB	#10,DT10ST	;WAIT FOR IT TO COMPLETE
	RTS	PC		;RETURN UNTIL IT IS DONE.
;
; HERE WHEN ACK + FEH FOR EH ARE COMPLETE.
;  SEND THE EH.
;
DTXS10:	MOVB	DT10UC(R5),R2	;AMOUNT OF DATA TO BE SENT NOW
	CLRB	DT10UC(R5)	;NO DATA TO FOLLOW THIS
	SWAB	DT10DF(R5)	;SWAP BYTES TO CORRECT DIRECTION IN TEN
	SWAB	DT10AD(R5)	;SWAP DIRECTION OF ADR
	SWAB	DT10DT(R5)	;EXAMINE DATA OR AMT OF XFER
	MOV	R5,R1		;BUILD POINTER TO SECOND PART
	ADD	#DT10DF,R1	; OF HEADER TO TEN
	JSR	PC,DTXISD	;SEND INDIRECT DATA TO TEN
	MOVB	#12,DT10ST	;WAITING FOR EH TO COMPLETE
	RTS	PC		;RETURN
;
;
; HERE WHEN THE EH IS COMPLETE.  WAIT FOR MACHINE "A"
;  IF NECESSARY.  OTHERWISE SEND FEH FOR ED.  IF THERE IS NO
;  ED TO BE RETURNED THEN MACHINE "A" WILL NOT BE IN STATE 26.
;
DTXS12:	CMPB	#26,DT11ST	;IS THE OTHER MACHINE WAITING?
	BEQ	11$		;YES, SEND FEH FOR ED.
	MOVB	#14,DT10ST	;NO, WAIT FOR IT.
	RTS	PC		;RETURN.
;
11$:	MOVB	DT10DT+1(R5),DT10UC(R5)	;BYTE COUNT TO FOLLOW
				;REMEMBER DT10DT WAS SWAPPED EARLIER
	MOV	R5,R1		;BUILD POINTER TO HEADER
	ADD	#DT10HD,R1	;IN TCB AREA
	MOV	#12,R2		;NO OF BYTES TO XFER
	JSR	PC,DTXMSD	;SEND AS DIRECT HEADER
	MOVB	#16,DT10ST	;WAIT FOR FEH FOR ED TO COMPLETE
	RTS	PC		;RETURN
;
; HERE WHEN THE FEH FOR ED IS COMPLETE.  NOW SEND ED.
;
DTXS16:	MOVB	DT10UC(R5),R2	;AMOUNT OF DATA TO XFER NOW
	BIC	#^C<377>,R2	;ONLY 8 BITS PERMITTED IN COUNT
	CLRB	DT10UC(R5)	;NO DATA TO FOLLOW AFTER THIS
	MOV	DTXADR(R5),R1	;R1 PONTS TO DATA TO-TEN
	JSR	PC,DTXISD	;SEND DATA INDIRECT
	MOVB	#20,DT10ST	;WAIT FOR DATA TO COMPLETE
	RTS	PC		;RETURN
;
; HERE WHEN THE ED MESSAGE IS COMPLETE.  BE SURE ITS ACK HAS BEEN PROCESSED
;  (WAIT FOR IT IF NECESSARY).
;
DTXS20:	CMPB	#32,DT11ST	;IS OTHER MACHINE WAITING FOR US?
	BEQ	11$		;YES, MUST BE ALL DONE.
	MOVB	#22,DT10ST	;NO, WE ARE WAITING FOR IT.
	RTS	PC		;RETURN.
;
11$:	JSR	PC,DTCLRS	;CLEAR STATE OF DTE
	RTS	PC		;RETURN.
;
; SUBROUTINE TO CLEAR THE STATE OF THE DTE
;
DTCLRS:	CLRB	DT10ST		;SET TO IDLE STATE
	CLRB	DT11ST		;OTHER MACHINE, TOO.
	CLR	DTXADR(R5)	;INITIALIZE PTR TO IND DATA
	BIC	#DLTHIP!DLTHBM,DTSTT+2 ;CLEAR INDIRECT IN PROGRESS
.IIF NE,DEBUG,CLR DTO10Q(R5)	;DONE WITH SENDING HEADER
	CLR	DT10FN(R5)	;ALL DONE WITH THIS OPERATION
	CLR	DT10AK		;NO EXTRA ACK NEEDED
	RTS	PC		;RETURN
;
;
; SUBROUTINE TO START AN INDIRECT DATA TRANSFER TO - TEN
;
;  R1 = POINTER TO THE DATA TO BE SENT TO TEN
;  R2 = AMOUNT OF DATA TO BE TRANSFERRED
;	(MUST NOT BE LARGER THAN 255)
;
DTXISD:				;START INDIRECT DATA XFER TO-TEN
	MOV	R1,TE.XAD(R0)	;SET THE TO TEN ADDRESS
.IF NE,DEBUG
	MOV	R1,DTXTAS(R5)	;SAVE TO TEN ADR
	MOV	R2,DTXTSZ(R5)	;SAVE SIZE OF XFER
.ENDC
	CLR	TE.XW1(R0)	;DEPOSIT THE WORD COUNT
	CLR	TE.XW2(R0)
.IF NE,DEBUG
	BIT	#^C<377>,R2	;MORE THAN 8 BITS?
	BEQ	11$		;NO.
	STOPCD	DBG		;PROTOCOL CAN'T HANDLE THIS
11$:
.ENDC ;.IF NE,DEBUG
	MOV	R2,TE.XW3(R0)
	MOV	#DLXFSZ-DLPIN,R1 ;DEPOSIT THE SIZE IN 10 MEMORY
	ADD	DTDMYN(R3),R1	;GET OFFSET
	MOV	#TS.DEP,TE.XA1(R0) ;SET DEPOSIT
	MOV	R1,TE.XA2(R0)	;START XFER
	JSR	PC,DLWEDN	;WAIT FOR DEPOSIT
	BCS	12$		;CANNOT
	BIS	#DLTHIP,DTSTT+2	;SAY WE'RE DOING INDIRECT
	MOV	#TS.TBM,TE.DG3(R0) ;AND TELL HARDWARE THAT WE'RE DOING
				; IT IN BYTE MODE
	MOV	DTSTT,TE.XW1(R0);SET IN 10 MEMORY
	MOV	DTSTT+2,TE.XW2(R0)
	MOV	DTSTT+4,TE.XW3(R0)
	ADD	#DLSTAT-DLXFSZ,TE.XA2(R0) ;DEPOSIT IN 10 MEMORY
	JSR	PC,DLWEDN	;WAIT FOR DEPOSIT
	BCS	12$		;CANNOT
	MOV	#TS.EEX,TE.STW(R0) ;RING TENS DOORBELL
	RTS	PC		;RETURN
;
;
; HERE IF EXAMINE OR DEPOSIT FAILED
;
12$:	STOPCD	TER		;UNABLE TO TALK TO THE 10
;
;
; THIS SUBROUTINE HAS TWO ENTRY POINTS . DTSACK TO SEND 
; AN ACK + FEH TO THE TEN AND DTSAK FOR SENDING THE 
; ACK ALONE TO THE TEN TO ACKNOWLEDGE RECEIPT OF DATA.
;
DTSACK:	MOV	#24,R2		;SEND ACK + FEH TOGETHER
	BR	DTSAC		;SET UP ACK HEADER
DTSAK:	MOV	#12,R2		;SEND ONLY THE ACK TO-TEN
DTSAC:
	MOV	#12,DTAKHD(R5)	;LENGTH OF HEADER
	MOV	#DTFSAK,DTAKFN(R5) ;ACK FUNCTION
	MOV	#DLDPFE,DTAKDV(R5) ;FE DEVICE
	CLR	DTAKUC(R5)	;CLEAR BEFORE PUTTING FE#
	MOVB	DT11UC+1(R5),DTAKUC(R5) ;FE# RIGHT JUSTIFIED
	MOV	R5,R1		;GET TCB ADR
	ADD	#DTAKHD,R1	;POINT TO "ACK" BLOCK HEADER
	JSR	PC,DTXMSD	;SEND ACK TO TEN
	RTS	PC		;RETURN
;
.SBTTL		 TO-ELEVEN DONE INTERRUPT PROCESSING
;
; THIS ROUTINE DECIDES WHAT TO DO WHEN A TO-11 DONE
;  INTERRUPT IS RECOGNIZED.  IT IMPLEMENTS PART OF MACHINE "A"
;  DESCRIBED ABOVE.
;
DLELDN:	TRACE	TRCTEN,DTQSTA	;ON ELEVEN DONE STATE
	MOV	DTEBAD,R0	;GET DTE REGS ADR
	MOV	DTEPCA,R3	;PROCESSOR COMM AREA IN R3
	DEC	DTIEDN		;DECREMENT COUNT OF UNPROCESSED INTERRUPTS
	MOVB	DT11ST,R1	;GET PRESENT TO-ELEVEN STATE
	JSR	PC,@11$(R1)	;CALL APPROPRIATE ROUTINE
	RTS	PC		;RETURN
;
11$:	.WORD	DTDED		;IDLE
	.WORD	DTIS02		;WAITING FOR FEH FOR EH
	.WORD	DTDED		;WAITING FOR DOORBELL FOR EH
	.WORD	DTIS06		;WAITING FOR EH
	.WORD	DTDED		;WAITING FOR DOORBELL FOR FEH FOR EH
	.WORD	DTIS12		;WAITING FOR FEH FOR ED
	.WORD	DTDED		;WAITING FOR DOORBELL FOR ED
	.WORD	DTIS16		;WAITING FOR ED
	.WORD	DTDED		;WAITING FOR ACK OF EH TO COMPLETE
	.WORD	DTDED		;WAITING FOR DOORBELL FOR ACK FOR EH
	.WORD	DTIS24		;WAITING FOR ACK FOR EH
	.WORD	DTDED		;WAITING FOR DOORBELL FOR ACK FOR ED
	.WORD	DTIS30		;WAITING FOR ACK FOR ED
	.WORD	DTDED		;GOT FINAL ACK
	.WORD	DTIS34		;IGNORING 11-DONE
;
DTDED:	STOPCD	DTG20		;PROTOCOL BROKEN
;
;
; HERE WHEN FIRST PART OF HEADER IS IN. A CHECK IS MADE FOR FE
;  DEVICE AND IF DEVICE IS INDEED AN FE THEN WE EXPECT A SECOND
;  PART OF HEADER TO FOLLOW; OTHERWISE JUST IGNORE THE HEADER.
;
DTIS02:	SWAB	DT11HD(R5)	;SWAP BYTES TO CORRECT DIRECTION
	SWAB	DT11FN(R5)	;THE PROTOCOL FUNCTION
	SWAB	DT11DV(R5)	;PROTOCOL DEVICE
	SWAB	DT11UC(R5)	;FE#,,COUNT OF BYTES TO FOLLOW
	CMP	#DLDPFE,DT11DV(R5) ;IS THIS HEADER FOR FE DEVICE?
	BNE	11$		;NO,IGNORE THE IRRELEVANT DEVICES
	TST	DT11FN(R5)	;IS IT INDIRECT  DATA
	BMI	12$		;YES,MUST BE STRING DATA
11$:	MOVB	#34,DT11ST	;STATE TO IGNORE 11-DONES.
	RTS	PC		;RETURN
;
12$:	CMPB	#DTFSTR,DT11FN(R5) ;BETTER BE STRING DATA FUNCTION
	BNE	11$		;THROW AWAY OTHER FUNCTIONS
	MOVB	#4,DT11ST	;EXPECT SECOND PART OF HEADER
	RTS	PC		;RETURN
;
;
; HERE WHEN THE EH IS IN.  ACKNOWLEDGE IT AND CONSIDER IT.
;
DTIS06:	SWAB	DT11DF(R5)	;THE DN60 FUNCTION CODE
	SWAB	DT11AD(R5)	;ADDRESS FOR EXAMINE / DEPOSIT
	SWAB	DT11DT(R5)	;DATA FOR DEPOSIT
	TST	DT11FN(R5)	;ALL DATA MUST BE INDIRECT
	BPL	11$		;ITS NOT,PUNISH HIM
	CMPB	#DTFSTR,DT11FN(R5) ;IS IT DN60 FUNCTION?
	BNE	11$		;CANT HANDLE OTHER THAN DN60 FUNCTIONS
	CMP	#DLDPFE,DT11DV(R5) ;LEGAL DEVICE?
	BEQ	12$		;YES, ALL O.K
;
11$:	STOPCD	DTH20		;NO, PROTOCOL BROKEN,ILLEGAL DEVICE
				; OR ILLEGAL FUNCTION
;
12$:	CLR	TCXFR(R5)	;CLEAR BYTE COUNT FOR TO-TEN STATUS BUFFER
	CLR	DT11GW(R5)	;CLEAR SHORT OF CHUNK FLAG
	CLR	DLMBCT(R5)	;INITIALIZE MESSAGE BYTE COUNT
	CLR	DLMCTL(R5)	;AND MESSAGE COUNT LEFT
	MOVB	DT11DF(R5),R1	;GET DN60 FUNCTION-USED AS INDEX
	MOV	#15$,R0		;POINT TO DISPATCH TABLE
	JSR	PC,DLDISP	;DISPATCH
	BCS	14$		;FATAL ERROR
	MOVB	#2,DT10ST	;ARRANGE TO UNDERSTAND WHEN ACK COMPLETES
	TST	DT10AK		;IS THERE AN ED TO COME?
	BNE	13$		;YES.
	JSR	PC,DTSACK	;NO,SEND ACK + FEH TO-TEN
	MOVB	#20,DT11ST	;AND, WAIT FOR ACK TO COMPLETE
	RTS	PC		;RETURN.
;
13$:	JSR	PC,DTSAK	;SEND ACK ALONE TO-TEN
	MOVB	#10,DT11ST	;WAIT FOR DOORBELL FOR THE FEH FOR THE ED
	RTS	PC		;RETURN
;


14$:

;14$:	JSR	PC,DTCERR	;FATAL ERROR

	SEC			;FATAL ERROR

	RTS	PC		;RETURN
;
;
; TABLE FOR PDP-10 INITIATED OPERATIONS
;
15$:	.WORD	<<16$-15$>/2>-2 ;MAXIMUM INDEX
	.WORD	0		;FUNCTION ZERO INVALID
	.WORD	DLTRDT		;1=READ DATA INTO THE PDP-10
	.WORD	DLTWDT		;2=WRITE DATA FROM THE PDP-10
	.WORD	DLTRDS		;3=READ DEVICE STATUS
	.WORD	DLTWDC		;4=WRITE DEVICE COMMAND
	.WORD	DLTRLS		;5=READ LINE STATUS
	.WORD	DLTWLC		;6=WRITE LINE COMMAND
	.WORD	DLTRES		;7=READ DN60 STATUS
	.WORD	DLTWEC		;8=WRITE DN60 COMMAND
	.WORD	DLTEXM		;9=EXAMINE 11 LOCATION
	.WORD	DLTDEP		;10=DEPOSIT IN 11 LOCATION
;
16$:				;END OF TABLE
;
;
; HERE WHEN WE RECEIVE THE FEH FOR THE ED.  NOW WE NEED THE ED.
;
DTIS12:	SWAB	DT11HD(R5)	;SWAP BYTES TO CORRECT DIRECTION
	SWAB	DT11FN(R5)	;PROTOCOL FUNCTION
	SWAB	DT11DV(R5)	;PROTOCOL DEVICE CODE
	SWAB	DT11UC(R5)	;UNIT AND BYTE COUNT
	MOVB	#14,DT11ST	;WAIT FOR ANOTHER DOORBELL
	RTS	PC		;RETURN.
;
; HERE WHEN THE ED HAS ARRIVED.  PROCESS IT.
;
DTIS16:	
.IF NE,DEBUG
	CMPB	#2,DT11DF(R5)	;DOING A WRITE OF DATA?
	BNE	11$		;NO.
	TST	@DT11AS(R5)	;TEST FOR ZERO WORD
	BNE	11$		;NON ZERO, IT IS OK.
.IF NE,PADBUG
	BR	11$		;DON'T STOP, HE TRANSMITS ZERO'S
.ENDC				;IF NE, PADBUG
	STOPCD	DBG		;THIS IS PROBABLY AN ERROR
11$:
.ENDC ;.IF NE,DEBUG
	TST	DT11GW(R5)	;OPERATION DELAYED OR REJECTED??
	BNE	19$		;YES
	CMPB	#2,DT11DF(R5)	;IS IT A WRITE?
	BEQ	16$		;YES
	CMPB	#4,DT11DF(R5)	;WAS IT DATA FOR DEVICE STATUS?
	BNE	12$		;NO
	JSR	PC,DLTWD1	;YES,SETUP DEVICE STATUS
	BCS	15$		;FATAL ERROR
	BR	19$		;UPDATE STATE
;
12$:	CMPB	#6,DT11DF(R5)	;IS IT FOR WRITE LINE STATUS?
	BNE	13$		;NO
	JSR	PC,DLTWL1	;YES,SETUP LINE STATUS
	BCS	15$		;FATAL ERROR
	BR	19$		;UPDATE STATE AND RETURN
;
13$:	CMPB	#10,DT11DF(R5)	;NO,IS IT WRITE DN60 STATUS
	BNE	14$		;NO,
	JSR	PC,DLTWS1	;YES,SETUP DN60 STATUS
	BCS	15$		;FATAL ERROR
	BR	19$		;UPDATE STATE AND RETURN
;
14$:	STOPCD	DTB20		;GOOFY ELEVEN DONE INTP
;




15$:
;15$:	JSR	PC,DTCERR	;COMMON ERROR RETURN

	SEC			;COMMON ERROR RETURN

	RTS	PC		;RETURN
;
;
; HERE IT HAS TO BE A PLAIN SIMPLE WRITE TO - ELEVEN DATA
;
16$:	MOV	R0,R2		;SAVE DTE ADDRESS
	JSR	PC,DLTEDN	;SETUP CHUNKS TO RECEIVE DATAIN
	TST	DT11GW(R5)	;SHORT OF CHUNKS??
	BNE	21$		;YES
	TST	R0		;ANYTHING LEFT TO TRANSFER?
	BEQ	18$		;NOTHING LEFT TO XFER
17$:	JSR	PC,DTSTRT	;MORE TO RECEIVE, START IT
	RTS	PC
;
; HERE WHEN WE APPEAR TO HAVE RUN OUT OF DATA TO TRANSFER.
;
18$:	TST	DLMCTL(R5)	;ANY MORE TO XFER?
	BGT	14$		;BETTER NOT BE!!!
	MOVB	#1,DT10DF+1(R5)	;SUCCESS CODE TO TEN
19$:	JSR	PC,DTCMRT	;SET UP INFO TO RETURN TO THE 10
	CMPB	#4,DT10ST	;IS OTHER MACHINE WAITING FOR US?
	BEQ	20$		;YES, SEND ACK AND ADVANCE IT.
	MOVB	#20,DT11ST	;NO, WAIT FOR IT.
	RTS	PC		;RETURN.
;
; HERE IF THE OTHER STATE MACHINE IS WAITING FOR US.
;
20$:	JSR	PC,DTSACK	;SEND ACK FOR ED
	MOVB	#10,DT10ST	;ARRANGE TO UNDERSTAND THAT ACK
	MOVB	#22,DT11ST	;WAIT FOR DOORBELL FOR ACK FOR EH
	RTS	PC		;RETURN.
;
; HERE IF WE ARE SHORT OF CHUNKS.
;
21$:	MOV	#1,R0		;TRANSFER ONE DUMMY WORD
	MOV	R5,R1		;IN THE TCB
	ADD	#DT11GW,R1	;AT THIS LOCATION
	BR	17$		;AND INTERRUPT BOTH PROCESSORS
;
;
; HERE WHEN WE SHOULD HAVE GOTTEN AN ACK FOR THE EH.
;
DTIS24:	SWAB	DT11HD(R5)	;SWAP BYTES TO CORRECT DIRECTION
	SWAB	DT11FN(R5)	;PROTOCOL FUNCTION
	SWAB	DT11DV(R5)	;PROTOCOL DEVICE CODE
	SWAB	DT11UC(R5)	;BE SURE THEY'RE ALL SWAPPED
	CMPB	#DTFSAK,DT11FN(R5) ;IS IT REALLY AN ACK?
	BEQ	11$		;YES.
	STOPCD	TER		;NO, SOMETHING HAS GONE WRONG.
;
11$:	TST	DTXADR(R5)	;WILL AN ED BE RETURNED?
	BNE	13$		;YES.
	CMPB	#14,DT10ST	;NO, IS OTHER MACHINE WAITING?
	BNE	12$		;NO.
	JSR	PC,DTCLRS	;YES, CLEAR OUT STATE
	RTS	PC		;ALL DONE.
;
; HERE WHEN OTHER SIDE IS NOT WAITING.
;
12$:	MOVB	#32,DT11ST	;WE MUST WAIT FOR IT
	RTS	PC		;RETURN.
;
; HERE WHEN AN ED WILL BE RETURNED
;
13$:	CMPB	#14,DT10ST	;IS THE OTHER MACHINE WAITING?
	BEQ	14$		;YES.
	MOVB	#26,DT11ST	;NO, WAIT FOR IT.
	RTS	PC		;RETURN.
;
; HERE WHEN THE OTHER SIDE IS WAITING FOR US TO START THE ED
;
14$:	MOVB	DT10DT+1(R5),DT10UC(R5)	;ED BYTE COUNT TO FOLLOW
	MOV	R5,R1		;BUILD POINTER TO HEADER
	ADD	#DT10HD,R1	; IN TCB AREA
	MOV	#12,R2		;NO. OF BYTES TO XFER TO TEN
	JSR	PC,DTXMSD	;SEND AS DIRECT HEADER
	MOVB	#16,DT10ST	;ARRANGE TO UNDERSTAND WHEN TO-10 DONE COMES UP
	MOVB	#26,DT11ST	;WAIT FOR ACK OF ED
	RTS	PC		;RETURN.
;
;
; HERE WHEN WE EXPECT AN ACK FOR ED
;
DTIS30:	SWAB	DT11HD(R5)	;SWAP BYTES TO CORRECT DIRECTION
	SWAB	DT11FN(R5)	;PROTOCOL FUNCTION
	SWAB	DT11DV(R5)	;PROTOCOL DEVICE CODE
	SWAB	DT11UC(R5)	;BE SURE THEY'RE ALL SWAPPED
	CMPB	#DTFSAK,DT11FN(R5) ;IS IT REALLY AN ACK?
	BEQ	11$		;YES.
	STOPCD	TER		;NO, SOMETHING HAS GONE WRONG.
;
11$:	CMPB	#22,DT10ST	;IS THE OTHER SIDE WAITING?
	BNE	12$		;NO, WAIT FOR IT.
	JSR	PC,DTCLRS	;YES, CLEAR STATE.
	RTS	PC		;RETURN.
;
; HERE WHEN THE OTHER SIDE IS NOW WAITING.  WAIT FOR IT.
;
12$:	MOVB	#32,DT11ST	;GOT FINAL ACK
	RTS	PC		;RETURN.
;
; HERE WHEN WE ARE IGNORING 11-DONE INTERRUPTS
;
DTIS34:	INC	DTPTCT		;COUNT TIMES 11-DONE IGNORED
	RTS	PC		;RETURN, LEAVING STATE AS IS.
;
.SBTTL		 DOORBELL INTERRUPT PROCESSING FOR DTE20
;
; THIS IS THE REST OF MACHINE "A".
;
DLDRBL:	TRACE	TRCTEN,DTQSTA	;ON THE ELEVEN DONE STATE
	DEC	DTIDBL		;DECREMENT DOORBELL INTP COUNT
	MOV	DTEBAD,R0	;GET BASE ADR OF DTE REGS
	MOV	DTEPCA,R3	;SETUP COMMUN ADR
	CLR	TE.XA1(R0)	;READ STATUS WORD
	MOV	#DLSTAT-DLPIN,R2 ;FIND THE ADDRESS OF HIS DLSTAT-TO ME
	ADD	DTEHSM(R3),R2
	MOV	R2,TE.XA2(R0)	;READ THAT STATUS WORD
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE
	BCS	13$		;IGNORE INTERRUPT IF NOT STARTED
	MOV	TE.XW1(R0),TCSTFX(R5)	;SAVE STATUS
	MOV	TE.XW2(R0),TCSTFX+2(R5)
	MOV	TE.XW3(R0),TCSTFX+4(R5)
	TST	TCSTFX(R5)	;VALID EXAMINE?
	BEQ	13$		;IGNORE WHEN NOT IN PRIMARY PROTOCOL
11$:	BIT	#DLTHIP,TCSTFX+2(R5) ;INDIRECT IN PROGRESS
	BNE	12$		;YES, DONT CHECK COUNTS
	CMPB	TCSTFX+4(R5),DT10QC ;IS THIS THE CORRECT COUNT
	BEQ	13$		;YES -- CONTINUE PROCESSING
12$:	MOVB	DT11ST,R1	;GET STATE OF THIS "MACHINE"
	JSR	PC,@14$(R1)	;CALL APPROPRIATE ROUTINE
13$:	RTS	PC		;RETURN.
;
; DISPATCH TABLE FOR DOORBELL INTERRUPTS, BASED ON STATE OF MACHINE "A"
;
14$:	.WORD	DTIS00		;WAITING FOR INITIAL DOORBELL
	.WORD	15$		;WAITING FOR FEH FOR EH
	.WORD	DTIS04		;WAITING FOR DOORBELL FOR EH
	.WORD	15$		;WAITING FOR EH
	.WORD	DTIS10		;WAITING FOR DOORBELL FOR FEH FOR ED
	.WORD	15$		;WAITING FOR FEH FOR ED
	.WORD	DTIS14		;WAITING FOR DOORBELL FOR ED
	.WORD	15$		;WAITING FOR ED
	.WORD	15$		;WAITING FOR ACK OF EH TO COMPLETE
	.WORD	DTIS22		;WAITING FOR DOORBELL FOR ACK FOR EH
	.WORD	15$		;WAITING FOR ACK FOR EH
	.WORD	DTIS26		;WAITING FOR DOORBELL FOR ACK FOR ED
	.WORD	15$		;WAITING FOR ACK FOR ED
	.WORD	15$		;GOT FINAL ACK
	.WORD	16$		;IGNORING 11-DONE
;
; HERE ON DOORBELL IN INVALID STATE
;
15$:	STOPCD	DTD20		;ERROR
;
;
; HERE ON DOORBELL WHEN IGNORING 11-DONE
;
16$:	JSR	PC,DTCLRS	;CLEAR STATE
;	JMP	DTIS00		;TREAT AS INITIAL DOORBELL
;
; HERE ON DOORBELL INITIALLY
;
DTIS00:	MOV	R5,R1		;BUILD POINTER TO WHERE HEADER
	ADD	#DT11HD,R1	; MUST BE SAVED
	JSR	PC,DTHDST	;START TRANSFER OF HEADER
	MOVB	#2,DT11ST	;UNDERSTAND THE RESULTING 11-DONE
	RTS	PC		;RETURN.
;
; HERE WHEN WE ARE WAITING FOR DOORBELL FOR FEH FOR EH
;
DTIS04:	JSR	PC,DTINDH	;GET SECOND PART OF HEADER
	MOVB	#6,DT11ST	;UNDERSTAND RESULTING 11-DONE
	RTS	PC		;RETURN.
;
; HERE WHEN WE ARE WAITING FOR DOORBELL FOR FEH FOR ED
;
DTIS10:	MOV	R5,R1		;BUILD POINTER TO WHERE HEADER
	ADD	#DT11HD,R1	; SHOULD GO
	JSR	PC,DTHDST	;GET FEH FOR ED IN
	MOVB	#12,DT11ST	;UNDERSTAND RESULTING 11-DONE INTERRUPT
	RTS	PC		;RETURN.
;
; HERE WHEN WE ARE WAITING FOR DOORBELL FOR ED.
;
DTIS14:	JSR	PC,DTINST	;SET UP TO READ REAL DATA (FINALLY!)
	MOVB	#16,DT11ST	;UNDERSTAND RESULTING 11-DONE
	RTS	PC		;RETURN.
;
; HERE WHEN WE ARE WAITING FOR DOORBELL FOR ACK FOR EH.
;
DTIS22:	MOV	R5,R1		;BUILD POINTER TO WHERE HEADER
	ADD	#DT11HD,R1	; SHOULD GO
	JSR	PC,DTHDST	;GET ACK IN
	MOVB	#24,DT11ST	;UNDERSTAND RESULTING 11-DONE
	RTS	PC		;RETURN.
;
; HERE WHEN WE ARE WAITING FOR DOORBELL FOR ACK FOR ED.
;
DTIS26:	MOV	R5,R1		;BUILD POINTER TO WHERE HEADER
	ADD	#DT11HD,R1	; SHOULD GO
	JSR	PC,DTHDST	;GET ACK IN
	MOVB	#30,DT11ST	;UPDATE THE STATE
	RTS	PC		;RETURN.
;
.SBTTL		 QUEUED PROTOCOL INTERFACE FOR DTE20
;
; CALLED TO START THE TRANSFER OF A DIRECT TO-11 MESSAGE.
;
; R1 = ADDRESS OF PLACE TO PUT THE HEADER
;
DTHDST:	BIT	#DLTHIP,TCSTFX+2(R5) ;IS THE MESSAGE DIRECT?
	BEQ	11$		;YES.
	STOPCD	TER		;NO, TEN MADE AN ERROR.
;
11$:	BIS	#DLTOIT,DTSTT+2	;SET QUEUE IN PROGRESS
	INCB	DT10QC		;INDICATE Q UPDATED
	CMPB	TCSTFX+4(R5),DT10QC ;COUNT CORRECT?
	BEQ	12$		;YES -- PROCEED
	STOPCD	DTF20		;COUNT INCORRECT ERROR
;
12$:	MOV	#TS.DEP,TE.XA1(R0) ;SET UP TO DEPOSIT
	MOV	DTSTT,TE.XW1(R0) ;THE STATUS
	MOV	DTSTT+2,TE.XW2(R0) ;IN MY AREA TO HIM
	MOV	DTSTT+4,TE.XW3(R0) ;TO TELL QUE IN PROGRESS
	MOV	#DLSTAT-DLPIN,R2 ;GET STATUS WORD OFFSET
	ADD	DTDMYN(R3),R2 	;IN COMM AREA
	MOV	R2,TE.XA2(R0)	;START THE DEPOSIT
	JSR	PC,DLWEDN	;WAIT FOR DEPOSIT
	BCS	14$		;ERROR
	MOV	#DLXFSZ-DLPIN,R2 ;FIND THE QUEUE SIZE
	ADD	DTEHSM(R3),R2	;EXAMINE HIS FOR ME
	CLR	TE.XA1(R0)	;CLEAR DEPOSIT BIT
	MOV	R2,TE.XA2(R0)	;DO THE EXAMINE FOR SIZE
	MOV	R0,R2		;SAVE BASE ADR OF DTE20
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE/DEPOSIT
	BCS	14$		;EXAMINE FAILED
	MOV	TE.XW3(R0),DTEQSZ(R5) ;SET UP Q SIZE
				;THIS AUTOMATICALLY SETS UP DTEQSZ
	MOV	DTEQSZ(R5),R0	;NO OF BYTES TO XFER FOR HEADER
13$:	MOV	R0,DLMCTL(R5)	;NO OF BYTES LEFT TO XFER
	JSR	PC,DTSTRT	;START TRANSFER
	RTS	PC		;RETURN TO CALLER
;
; HERE IF EXAMINE OR DEPOSIT FAILS
;
14$:	STOPCD	TER		;SOMETHING FAILED
;
;
; HERE ON DOORBELL WHEN WE ARE EXPECTING THE EH.  READ IT
;  INTO THE SECOND PART OF THE HEADER AREA OF THE TCB.
;
DTINDH:	BIS	#DLTOIT,DTSTT+2	;TELL -10 WE SHOULD BE MOVING DATA
	ADD	#DLXFSZ-DLSTAT,TE.XA2(R0) ;READ THE STATUS WORD
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE
	BCS	11$		;CANNOT
	MOV	R0,R2		;WE NEED R0
	MOV	TE.XW3(R2),R0	;GET MESSAGE LENGTH
	MOV	R0,DTEQSZ(R5)	;SAVE LENGTH OF MESSAGE
	MOV	R0,DLMCTL(R5)	;SETUP MESSAGE COUNT LEFT TO XFER
	CMP	R0,#6		;SECOND PART OF HEADER MUST NOT BE GREATER THAN
				; SIX BYTES
	BHI	12$		;SOMETHING VERY WRONG WITH DDT60 OR D60SPD (OR D60SPL?)
	MOV	R5,R1		;POINT TO WHERE SECONDARY HEADER MUST GO
	ADD	#DT11DF,R1	; IN THE TCB AREA
	JSR	PC,DTSTRT	;START THE TRANSFER
	JMP	DTSTIP		;SET STATUS AND RETURN
;
; HERE IF WE CANNOT EXAMINE THE -10'S MEMORY
;
11$:	STOPCD	TER		;PERHAPS IT HAS FAILED
;
; HERE IF THE LENGTH IS MORE THAN 6 BYTES
;
12$:	STOPCD	TER		;ERROR IN DEC-20 USER PROGRAM
;
;
; HERE ON PDP-10 PROTOCOL ERROR.
;  ABORT ALL STREAMS AND DISABLE ALL LINES.
;
DTCERR:				;ERROR RETURN FOR SET DEV AND LINE
.IF NE,DEBUG
	BIT	#TRCTER,TRCHLT	;STOP ON PDP-10 ERRORS?
	BEQ	11$		;NO.
	STOPCD	TER		;YES, PDP-10 ERROR
11$:
.ENDC ;.IF NE,DEBUG
	CLR	R3		;START WITH LINE NUMBER 0
12$:	MOV	DQLCB(R3),R0	;GET LCB POINTER
	BEQ	13$		;NONE.
	BIS	#LF.DIS,LB.FGS(R0) ;DTE DISABLED THE LINE
	MOV	LB.TC1(R0),R1	;POINT TO BSC TASK
	CMP	#TTHASP,LB.DVT(R0)	;HASP LINE?
	BEQ	21$		;YES.
	BIS	#TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
	MOV	LB.TCD(R0),R1	;POINT TO XLATE TASK
	BIS	#TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
13$:	ADD	#2,R3		;NEXT LINE NUMBER * 2
	CMP	#<NLINES*2>,R3	;DONE ALL THE LINES?
	BNE	12$		;NO, DO THE REST.
	SEC			;SIGNAL FAILURE
	RTS	PC		;RETURN
;
;
; HERE TO ABORT ALL DEVICES ON HASP-LINE
;
21$:	BIT	#LF.ENC,LB.FGS(R0) ;LINE ENABLE COMPLETE?
	BEQ	13$		;NO, CHECK NEXT LINE
	MOV	LB.NTC(R0),R2	;GET # OF TCBS FOR HASP LINE
	BNE	22$		;IF IT HAS'NT BEEN SET, MAKE IT 5
	MOV	#5,R2		;THATS MAX # OF TCBS HASP LINE
22$:	MOV	R0,R1		;GET LCB PTR
	ASL	R2		;DEV NO * 2
	ADD	R2,R1		;ADD DEVICE #
	ASR	R2		;GET BACK DEV NO
	MOV	LB.TCD(R1),R1	;POINT TO XLATE TCB OF DEVICE
	BEQ	24$		;NO TCB FOR THE DEVICE
	BIS	#TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
24$:	SOB	R2,22$		;DO FOR ALL DEVICES ON HASP LINE
	BR	13$		;GO TO NEXT LINE
;
;
; CALLED WHEN THE DOORBELL REQUESTING THE START OF THE INDIRECT
;  DATA RINGS. DLEDBL IS NOTIFIED AND RETURNS WHERE THE DATA SHOULD BE
;  SENT. NOTE THAT IT NEED NOT ALLOCATE SPACE FOR THE ENTIRE MESSAGE.
;
DTINST:	BIS	#DLTOIT,DTSTT+2	;TELL -10 WE SHOULD BE XFERRING DATA
	ADD	#DLXFSZ-DLSTAT,TE.XA2(R0) ;READ THE STATUS WORD
	JSR	PC,DLWEDN	;WAIT FOR EXAMINE
	BCS	13$
	MOV	R0,R2		;WE NEED R0
	MOV	TE.XW3(R2),R0	;GET MESSAGE LENGTH
	MOV	R0,DTEQSZ(R5)	;SAVE LENGTH OF MESSAGE
	MOV	R0,DLMBCT(R5)	;SAVE MESSAGE BYTE COUNT
	MOV	R0,DLMCTL(R5)	;SETUP MESSAGE COUNT LEFT TO XFER
	TST	DT11GW(R5)	;OPERATION DELAYED BY XLATE?
	BNE	11$		;YES,TRANSFER ONLY DUMMY WORD
	JSR	PC,DLEDBL	;TELL DN64 INTERFACE THE GOOD NEWS
	BCS	14$		;FATAL ERROR
	TST	DT11GW(R5)	;SHORT OF CHUNKS?
	BEQ	12$		;NO,LOOKS O.K
11$:	MOV	#1,R0		;YES,THEN TRANSFER ONE DUMMY WORD
	MOV	R5,R1		;GET TCB ADR
	ADD	#DT11GW,R1	;AT THIS LOCATION
12$:	JSR	PC,DTSTRT	;START UP THE TRANSFER
	BR	DTSTIP		;STORE STATUS WORD IN COMM 
				;REGION AND DISMISS INTERRUPT
;
13$:	RTS	PC
;
14$:	STOPCD	TER		;ERROR FROM DLEDBL
;
;
; SERVICE ROUTINES FOR INTERRUPT CODE
;
DTIPDN:	BIC	#DLTOIT,DTSTT+2	;CLEAR PROCESSING QUEUE STATUS
DTSTIP:	MOV	DTEBAD,R0	;MAKE SURE THIS IS SETUP
	MOV	#DLSTAT-DLPIN,R2 ;YES -- BETTER INDICATE THAT 11 IS FINISHED
	ADD	DTDMYN(R3),R2	;POINT TO STATUS WORD
	MOV	#TS.DEP,TE.XA1(R0) ;INDICATE WRITE
	MOV	DTSTT,TE.XW1(R0) ;SET UP TO DEPOSIT
	MOV	DTSTT+2,TE.XW2(R0)
	MOV	DTSTT+4,TE.XW3(R0)
	MOV	R2,TE.XA2(R0)	;START XFER
	JSR	PC,DLWEDN	;WAIT FOR DEPOSIT
11$:	RTS	PC		;RETURN TO TOELDN OR DBLRNG
;
;
; ROUTINE TO START A TO-11 BYTE MODE TRANSFER.
;
; CALL:
;
;	R0/	# OF BYTES TO TRANSFER
;	R1/	WHERE TO START DATA
;
DTSTRT:	MOV	R0,DT11QP(R5)	;SAVE AMOUNT TO BE XFERED
	TST	DT11GW(R5)	;NO CHUNK FLAG SET?
	BNE	11$		;YES,BYPASS MANIPULATING COUNT
	SUB	R0,DLMCTL(R5)	;COUNT LEFT FOR NEXT XFER
	ADD	R0,TCXFR(R5)	;TOTAL AMOUNT OF DATA WRITTEN FOR XLATE
11$:	NEG	R0		;MAKE COUNT NEGITIVE
	BIC	#170000,R0	;MASK OFF COUNT
	RORB	R0		;!!!WARNING THIS ASSUMES C BIT IS SET BY NEG R0!!!!^^
	BIT	#DLTHBM,TCSTFX+2(R5) ;WORD MODE?
	BNE	12$		;YES -- DON'T SET BYTE FLAG
	ROLB	R0		;!!^^SEE ABOVE -- RESTORE TO BYTE COUNT!!
	BIS	#TS.EBM,R0	;SET BYTE MODE
	TST	DT11GW(R5)	;DUMMY WORD XFER??
	BNE	13$		;YES,INTERRUPT BOTH
12$:	TST	DLMCTL(R5)	;WILL THIS FINISH MESSAGE?
	BGT	14$		;NO, DON'T INTERRUPT -10
13$:	BIS	#TS.IFB,R0 	;SET INTERRUPT BOTH
14$:	MOV	R1,TE.EAD(R2)	;AND START XFER
	MOV	R0,TE.EBC(R2)	;SET BYTE COUNT
.IF NE,DEBUG
	MOV	R1,DT11AS(R5)
	MOV	R0,DT11BS(R5)
.ENDC
	RTS	PC
;
; ROUTINE CALLED WHEN QPR DOORBELL FINDS IT HAS DATA FOR -11
;
; CALL:
; R0/	# OF BYTES IN MESSAGE
; RETURN:
;	IF C SET, ERROR.  OTHERWISE...
;
; R0/	# OF BYTES TO XFER
; R1/	ADDRESS OF WHERE TO PUT DATA
;
DLEDBL:	TST	DT11FN(R5)	;MUST COME FROM INDIRECT DATA
	BPL	15$		;TROUBLE,DATA NOT INDIRECT
	MOV	R0,DLMBCT(R5)	;SAVE QPR MESSAGE COUNT
	BEQ	14$		;IF ZERO MSG COUNT,THEN NOTHING  TO DO
	CMPB	#2,DT11DF(R5)	;IS IT A WRITE FUNCTION?
	BNE	13$		;NO,FOR STATUS WRITES SETUP AREA
	CLR	R0		;INITIALLY NO CHUNKS TO QUE
;
; THE FOLLOWING CODE GETS A CHUNK AND SETS UP R3 TO DATA
;
11$:	JSR	PC,DLNWCK	;GET A CHUNK
	BCS	16$		;SHORT ON CHUNKS
	MOV	R0,DLCMSG(R5)	;SAVE ADR OF CURRENT MESSAGE
	MOV	DLMBCT(R5),R0	;GET MESSAGE BYTE COUNT
	CMP	#CHDATL,R0	;DOES IT FIT IN ONE CHUNK?
	BHIS	12$		;YES,SET UP RO AND R1
	MOV	#CHDATL,R0	;NO,THEN XFER A CHUNK FULL
12$:	MOV	DLCMSG(R5),R1	;CURRENT CHUNK POINTER
	MOV	R0,CHLEN(R1)	;SETUP THE LENGTH OF DATA IN CHUNK
	MOV	R3,R1		;R1 POINTS TO WHERE DATA GOES
	BR	14$		;WIN RETURN.
;
13$:	MOV	#DTTTSB,R1	;POINT TO AREA WHERE STATUS MUST GO
	MOV	R1,DT11Q(R5)	;JUST IN CASE WE NEED IT
	CMP	DLMBCT(R5),#DTSBLN ;MUST NOT OVERFLOW OUR BUFFER
	BGT	15$		;THROW HIM OUT FOR GIVING TOO MUCH
;
; HERE FOR SUCCESS RETURN.
;
14$:	CLC			;CLEAR C BIT
	RTS	PC		;RETURN.
;
; HERE ON FAILURE RETURN.
;
15$:	SEC			;SET C BIT
	RTS	PC		;RETURN.
;
;
; IF WE ARE SHORT ON CHUNKS WE LAND HERE!!!
;
16$:	MOV	TCXLT(R5),R1	;POINT TO XLATE TASK
	BIT	#TCOAB,TCFG2(R1);HAS STEAM BEEN ABORTED?
	BEQ	DLSDLY		;NO,INDICATE "DELAYED"
;
DLSERR:	MOVB	#3,DT10DF+1(R5)	;OPERATION REJECTED
	MOV	#-1,DT11GW(R5)	;SET FLAG TO INDICATE ERROR OR DELAYED
	CLC			;NOT A FATAL ERROR
	RTS	PC		;RETURN
;
DLSDLY:	MOVB	#2,DT10DF+1(R5)	;OPERATION DELAYED
	MOV	#-1,DT11GW(R5)	;FLAG OPERATION DELAYED
	CLC			;NOT A FATAL ERROR
	RTS	PC		;RETURN
;
;
; ROUTINE CALLED FROM TO-11 DONE ROUTINE TO ADD NEW CHUNK
;  OR PROCESS END OF FRAGMENT
;
; CALL - NO REGISTERS NEEDED
; ON RETURN:
;	R0/	LENGTH OF NEXT FRAGMENT TO TRANSFER
;	R1/	ADDRESS TO STORE DATA
;	PS/	Z BIT SET IF EVERYTHING IN
;
DLTEDN:	MOV	DLMCTL(R5),R0	;CHECK IF ANY THING LEFT TO XFER
	BGT	11$		;FOR +VE COUNT,SETUP CHUNK ADR
;
; IF THE COUNT IS -VE OR ZERO, THEN APPEND THE LAST CHUNK DONE 
;  TO THE MESSAGE FOR XLATE TASK
;
	MOV	TCXLT(R5),R1	;POINT TO THE XLATE TASK
	MOV	DLCMSG(R5),R0	;POINT TO CHUNK TO BE QUED
	JSR	PC,QUECHK	;SEND IT THE CHUNK
	CLR	DLCMSG(R5)	;INITIALIZE MESSAGE PTR
	CLR	R0		;INDICATE NOTHING LEFT TO XFER
	RTS	PC		;RETURN
;
11$:	MOV	DLCMSG(R5),R0	;POINT TO LAST FILLED CHUNK
	JSR	PC,DLNWCK	;GIVE CHUNK TO XLATE AND GET NEW
	BCS	DLSDLY		;SHORT ON CHUNKS
	MOV	R0,DLCMSG(R5)	;SAVE PTR TO CHUNK TO BE FILLED
	MOV	#CHDATL,R0	;CAN WE XFER A CHUNK FULL
	CMP	DLMCTL(R5),R0	;COUNT LEFT LESS THAN CHUNK FULL?
	BGT	12$		;NO, TRANSFER IT ALL.
	MOV	DLMCTL(R5),R0	;YES, AMOUNT LEFT TO XFER FOR NEXT TIME
12$:	MOV	DLCMSG(R5),R1	;GET CURRENT CHUNK PTR
	MOV	R0,CHLEN(R1)	;SETUP THE LENGTH OF DATA
	MOV	R3,R1		;R1 POINTS TO WHERE THE DATA GOES
	CLC			;CLEAR C
	RTS	PC		;RETURN
;
;
; DTXMSD -- SUBROUTINE TO START A DIRECT TO TEN TRANSFER 
;
; R1 = ADDRESS OF PACKET TO BE SENT TO - TEN
; R2 = COUNT OF BYTES GOING TO THE TEN
;
;	ALWAYS RETURNS WITH C CLEAR.
;
DTXMSD:	MOV	R1,-(SP)	;SAVE REGISTERS
	MOV	R0,-(SP)	;
	MOV	DTEBAD,R0	;SET UP ADDRESS OF DTE20
	CLR	TE.XW1(R0)
	CLR	TE.XW2(R0)
.IIF NE,DEBUG,MOV R2,DTXTSZ(R5)
	MOV	R2,TE.XW3(R0)	;SET THE QUEUE SIZE IN MY AREA TO HIM
	MOV	R1,TE.XAD(R0)	;SET UP THE TO 10 ADDRESS
	MOV	#1,TE.DG3(R0)	;SET BYTE MODE
.IIF NE,DEBUG,MOV R1,DTXTAS(R5)
	MOV	DTEPCA,R1	;FIND THE CORRECT DTE
	MOV	DTDMYN(R1),R1	;FIND THE OFFSET INTO MY AREA
	ADD	#DLXFSZ-DLPIN,R1 ; FIND Q SIZE
	MOV	#TS.DEP,TE.XA1(R0) ;SET UP TO DO DEPOSIT
	MOV	R1,TE.XA2(R0)
	JSR	PC,DLWEDN
	INCB	DT11QC		;INCREMENT THE COUNT
	MOV	DTSTT,TE.XW1(R0)
	MOV	DTSTT+2,TE.XW2(R0)
	MOV	DTSTT+4,TE.XW3(R0)
	ADD	#DLSTAT-DLXFSZ,TE.XA2(R0)
	JSR	PC,DLWEDN	;EXAMINE/DEPOSIT
	MOV	#TS.EEX,TE.STW(R0) ;RING UP THE 10
	MOV	(SP)+,R0
	MOV	(SP)+,R1	;RESTORE REGISTERS
	CLC			;INDICATE SUCCESS (ALWAYS)
	RTS	PC		;RETURN
;
;
; THE FOLLOWING SUBROUTINE SETS UP HEADER FOR SENDING MESSAGES TO 
;  THE TEN
;
DTSHDR:	MOV	#12,DT10HD(R5)	;LENGTH OF HEADER IS 12
	MOV	DT11DV(R5),DT10DV(R5) ;SETUP THE DEVICE CODE
	MOV	DT11FN(R5),DT10FN(R5) ;FUNCTION CODE
	MOVB	DT11DF(R5),DT10DF(R5) ;DN60 FUNCTION CODE
	MOV	DT11AD(R5),DT10AD(R5)	;THE ADDRESS OR LINE #
	MOVB	DT11UC+1(R5),DT10UC+1(R5) ;SETUP FE#
	MOVB	#6,DT10UC(R5)	;SET UP NO OF BYTES FOR NEXT XFER
	RTS	PC
;
; THE FOLLOWING ENTRY POINTS ARE SENDING MESSAGES TO THE TEN
; THE FOLLOWING ROUTINES ARE FOR SENDING O.K, DELAYED OR
; ERROR RETURN TO THE TEN IN RESPONSE TO THE OPERATIONS 
; INVOKED BY THE TEN
;
DTDSOK:	MOVB	#1,DT10DF+1(R5)	;SET SUCCESS CODE FOR 10
;
DTCMRT:	JSR	PC,DTSHDR	;SETUP THE HEADER
	JSR	PC,DTIPDN	;SET STATUS FOR INDIRECT DONE
	MOV	DLMBCT(R5),R1	;MESSAGE COUNT
	SUB	DLMCTL(R5),R1	;SUBTACT BYTE COUNT LEFT
	MOV	R1,DT10DT(R5)	;TO GET # OF BYTES XFERRED
	RTS	PC		;RETURN PEACEFULLY
;
;
; SUBROUTINE TO GET A BYTE OF DATA FROM THE PDP-10 THROUGH
;  THE INDIRECT PORTION OF THE MESSAGE.
;
;	R2 = POINTER TO CURRENT BYTE OF MESSAGE
;	R4 = REMAINING COUNT IN THIS MESSAGE
;
; ON RETURN:
;
;	C SET -- END OF DATA
;	C CLEAR -- R1 = NEXT CHARACTER
;
DLGBYT:	TST	R4		;ANY BYTES LEFT IN THIS POINTER?
	BEQ	12$		;NO, TRY NEXT PAIR
11$:	DEC	R4		;YES, COUNT DOWN BYTE COUNTER
	MOVB	(R2)+,R1	;PICK UP BYTE
	INC	TCXFR(R5)	;COUNT A BYTE TRANSFERED
	CLC			;SUCCESS RETURN
	RTS	PC
;
; HERE IF THE COUNT IS DEPLETED.
;
12$:
	SEC			;0 COUNT = EOF
	RTS	PC		;GIVE EOF RETURN.
;
;
; SUBROUTINE TO PUT A BYTE OF DATA INTO PDP-10 MEMORY
;  BY APPENDING TO THE INDIRECT MESSAGE BEING BUILT.
;
; THIS SUBROUTINE MAY BE CALLED ONLY FROM DTE20 SUBROUTINES.
;
;	R1 = BYTE TO STORE
;	R2 = POINTER TO THE INDIRECT MESSAGE
;	R4 = REMAINING COUNT IN THIS MESSAGE
;
; ON RETURN:
;
;	C SET -- THERE IS NO ROOM FOR ANY MORE BYTES
;	C CLEAR -- THERE IS ROOM FOR ANOTHER BYTE
;
DLPBYT:	MOVB	R1,(R2)+	;STORE BYTE IN PDP-10 MEMORY
	INC	TCXFR(R5)	;COUNT A BYTE TRANSFERED
	DEC	R4		;ANY ROOM LEFT IN THIS BYTE POINTER?
	BEQ	12$		;NO, CHECK FOR ANOTHER.
11$:	CLC			;YES, INDICATE MORE ROOM
	RTS	PC		;RETURN.
;
; HERE WHEN THE COUNT RUNS OUT
;
12$:	SEC			;NO MORE ROOM
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO PUT A WORD OF DATA INTO PDP-10 MEMORY,
;  LOW BYTE FIRST.
;
;	R1 = WORD TO STORE
;	R2 = POINTER TO INDIRECT MESSAGE BEING BUILT
;	R4 = REMAINING COUNT IN THIS MESSAGE
;
; ON RETURN:
;
;	C SET -- THERE IS NO ROOM FOR ANY MORE BYTES
;		(POSSIBLY HIGH BYTE WAS NOT STORED)
;	C CLEAR -- THERE IS ROOM FOR ANOTHER BYTE
;
DLPWRD:	JSR	PC,DLPBYT	;STORE LOW BYTE IN PDP-10 MEMORY
	BCS	11$		;NO MORE ROOM
	SWAB	R1		;GET HIGH BYTE
	JSR	PC,DLPBYT	;STORE HIGH BYTE
11$:	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO COPY A STRING OF WORDS OUT THROUGH THE DTE20
;
;	R0 = POINTER TO FIRST WORD
;	R2 = POINTER TO INDIRECT MESSAGE BEING BUILT
;	R3 = POINTER TO LAST WORD + 2
;	R4 = REMAINING COUNT IN THE INDIRECT MESSAGE
;
; ON RETURN:
;
;	C SET -- NO MORE ROOM FOR MORE BYTES
;		(POSSIBLY NOT ALL OF THIS STRING WAS STORED)
;	C CLEAR -- ROOM FOR MORE BYTES
;
DLPSTR:	MOV	(R0)+,R1	;GET WORD TO STORE
	JSR	PC,DLPWRD	;STORE IT
	BCS	11$		;NO MORE ROOM
	CMP	R0,R3		;DONE ALL WORDS YET?
	BNE	DLPSTR		;NO, DO ANOTHER.
	CLC			;YES, ALL DONE.
11$:	RTS	PC		;RETURN.
;
.SBTTL		 DN60 FUNCTIONS INITIATED BY TEN
;
; DLTEXM  SUBROUTINE TO DO THE EXAMINE FUNCTION
; DLTDEP SUBROUTINE TO DO THE DEPOSIT FUNCTION
;
DLTEXM:
DLTDEP:				;SAME ENTRY FOR DEPOSIT FUNCTION
	JSR	PC,DTSHDR	;SET UP HEADER FOR TO-10 MSG
	MOV	R5,R1		;BUILD POINTER TO HEADER IN TCB
	ADD	#DT10HD,R1	;POINT TO HEADER TO BE SENT TO TEN
.IIF NE,DEBUG,MOV R1,DTO10Q(R5)	;SAVE IT FOR REF
	MOV	NXMGO,-(SP)	;SAVE PREV NXMGO ADDRESS
	MOV	#14$,NXMGO	;SET CURRENT NXM PROCESSING ADR
	CMPB	DT11DF(R5),#12	;IS IT A DEPOSIT FUNCTION?
	BEQ	13$		;YES,GO DO DEPOSIT
	MOV	@DT11AD(R5),DT10DT(R5)	;EXAMINE LOCATION PUT DATA IN 10 SIDE
11$:	MOV	(SP)+,NXMGO	;RESTORE XMGO
	MOVB	#1,DT10DF+1(R5)	;SET RESULT CODE =1;SUCCESS
12$:
	CLR	DTXADR(R5)	;NO DATA FOR IND XFER
	RTS	PC		;RETURN
;
13$:	MOV	DT11DT(R5),@DT11AD(R5) ;DEPOSIT THE DATA
	BR	11$		;SEND RESULT TO TEN
;
14$:	MOV	(SP)+,NXMGO	;RESTORE NXMGO
	MOVB	#3,DT10DF+1(R5)	;BAD ADR ;REJECT CODE
	BR	12$
;
;
; DLTRES-SUBROUTINE TO PERFORM THE " READ DN60 STATUS "
;
DLTRES:	JSR	PC,DTSHDR	;SET UP THE HEADER FOR SENDING TO-TEN
	MOV	DT11DT(R5),DT10DT(R5) ;SET COUNT TO BE SENT TO TEN
	BEQ	11$		;ZERO COUNT UNREASONABLE
	MOV	DT11DT(R5),R4	;COUNT OF BYTES IN STATUS
	MOV	#DTTTSB,R2	;POINT TO STATUS BLOCK
	MOV	R2,DTXADR(R5)	;ADR OF INDIRECT DATA SET
	MOV	#D60ST1,R0	;POIN TO THE FIRST WORD OF STATUS
	MOV	#D60ST2+2,R3	;POINT TO LAST WORD+2
	JSR	PC,DLPSTR	;MOVE A WORDS IN BUFFER
	MOV	TCXFR(R5),DT10DT(R5) ;NO OF BYTES TO XFER
	BIS	#B15,DT10FN(R5)	;INDICATE INDIRECT DATA
	MOVB	#1,DT10DF+1(R5)	;SUCCESS CODE TO TEN
	CLC			;SUCCESS ALWAYS
	RTS	PC		;RETURN
;
; HERE IF WE GET A ZERO COUNT ON 'READ DN60 STATUS'.
;  THIS IS UNREASONABLE.
;
11$:
	STOPCD	TER		;ZERO LENGTH INVALID
;
;
; SUBROUTINE TO PERFORM THE "READ DATA" FUNCTION.
;  MESSAGE QUE IS EXAMINED FOR A MESSAGE FROM THAT LINE
;  AND IF ONE IS FOUND IT BECOMES CURRENT MESSAGE. THE
;  USER MAY ASK FOR A MAXIMUM OF ONE CHUNK ONLY,HOWEVER
;  IF ASKED FOR MORE THAN CHUNK HAS CURRENTLY, HE GETS
;  WHATS LEFT IN THE CURRENT CHUNK.
;
DLTRDT:	JSR	PC,DTSHDR	;SETUP HEADER FOR TEN XFER
	MOV	DT11DT(R5),DT10DT(R5) ;LENGTH OF INDIRECT DATA
	BEQ	23$		;ZERO LENGTH UNREASONABLE
	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	CMP	R0,NDQ11S	;IS IT REASONABLE?
	BHIS	23$		;NO.
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R4	;POINT TO LCB
	BEQ	23$		;IT HAS NOT BEEN CREATED
	BIT	#LS.ENB,(R4)	;IS IT ENABLED?
	BEQ	23$		;NO, LOSE.
	MOV	R4,TCLCB(R5)	;AND REMEMBER LCB POINTER
	MOVB	DT11AD(R5),R1	;GET DEVICE #
	BIC	#177770,R1	;EXTRACT DEVICE # FROM RCB

;3(014).IF NE,DEBUG
;3(014)	BNE	10$		;TO TRACK -10 SCREW UPS
;3(014)	CMP	#TTHASP,LB.DVT(R4) ;CHECK DEV FOR HASP
;3(014)	BNE	10$		;
;3(014)	STOPCD	TER		;TEN ERROR
;3(014) 10$:
;3(014).ENDC ;.IF NE,DEBUG

	JSR	PC, DLMCHK	;;++BS- CHECK FOR LEGAL DEVICE NUMBER 3(014)
	BCS	23$		;;++BS- BAD DEVICE NUMBER, REJECT 3(014)

	ASL	R1		;DEVICE * 2
	MOV	R1,R2		;KEEP DEVICE # FOR LATER 
	ADD	R4,R1		;ADD DEVICE #
	MOV	LB.TCD(R1),TCXLT(R5) ; GET XLATE TASK POINTER
11$:	JSR	PC,DLGTCM	;GET CURRENT OR NEW MESSAGE
	BCS	22$		;NO MESSAGE FOR THIS DEVICE
12$:	MOV	MSGLCH(R0),R1	;GET POINTER TO THE CHUNK
13$:	MOV	R1,R3		;BUILD PONTER TO DATA
	BEQ	21$		;END OF MESSAGE FOUND
	MOV	(R3)+,DLPMST(R5) ;SAVE POINTER TO NEXT CHUNK
	MOV	(R3)+,R2	;GET COUNT, POINT TO DATA
;
;
; THE FOLLOWING IS THE REGISTER ALLOCATION:
;
; R0 = POINTS TO THE CURRENT MESSAGE BEING PROCESSED
; R1 = POINTS TO CURRENT CHUNK
; R2 = AMOUNT OF BYTES IN THIS CHUNK
; R3 = POINTS TO DATA IN CURRENT CHUNK
; R5 = POINTER TO DTE20 DRIVER TCB
; MSGLCH(R0) = CURRENT CHUNK TO BE SENT
; MSGPTR(R0) = CURRENT BYTE TO BE SENT
;
14$:	TST	R2		;ANY BYTES LEFT IN THIS CHUNK?
	BEQ	20$		;NO, LOOK FOR ANOTHER.
	ADD	R3,R2		;POINT TO END OF THE CHUNK
	CMP	MSGPTR(R0),R2	;DOES CHAR PTR LIE IN THIS RANGE
	BLOS	15$		;YES,IT DOES
	STOPCD	TER		;ERROR,CHAR PTR OUT OF RANGE
;
15$:	MOV	MSGPTR(R0),DTXADR(R5) ;SET UP INDIRECT DATA ADR
	SUB	MSGPTR(R0),R2	;THIS IS MAX DATA WE HAVE IN CHUNK
	CMP	DT11DT(R5),R2	;IS IT LESS THAN ASKED FOR?
	BLT	19$		;YES
	MOV	R2,DT10DT(R5)	;NO,GIVE HIM WHAT WE HAVE
	MOV	DLPMST(R5),R1	;GET ADR OF NEXT CHUNK IN MESSAGE
	MOV	R1,MSGLCH(R0)	;SAVE IN MESSAGE HEADER
	ADD	#CHDAT,R1	;BUILD DATA POINTER
	MOV	R1,MSGPTR(R0)	;SAVE NEW DATA POINTER
16$:	BIS	#B15,DT10FN(R5)	;SET INDIRECT FLAG
17$:	MOVB	#1,DT10DF+1(R5)	;SUCCESS CODE
18$:	CLC			;NO FATAL ERRORS
	RTS	PC		;RETURN
;
19$:	MOV	DT11DT(R5),DT10DT(R5) ;SET AMOUNT TO BE XFERRED
	ADD	DT11DT(R5),MSGPTR(R0) ;UPDATE CHAR PTR
	BR	16$		;SEND TO TEN
;
;
; HERE WHEN THE CHUNK RUNS OUT.  GO ON TO THE NEXT CHUNK.
;
20$:	MOV	DLPMST(R5),R1	;POINT TO NEXT CHUNK
	BNE	13$		;PROCESS IT, IF ANY.
;
; HERE ON END OF MESSAGE
;
21$:				;R0 DOES POINT TO MESSAGE
	MOV	TCIDLE,R1	;POINT TO IDLE TASK
	JSR	PC,QUEMSG	;SEND IT THE MSG TO FREE
	CLR	DT10DT(R5)	;ZERO BYTES SENT TO TEN
	CMP	#TTHASP,LB.DVT(R4) ;HASP LINE?
	BNE	33$		;NO.
	CLR	@TCPDM(R5)	;CLEAR DEVICE MESSAGE PTR
	BR	11$		;JOIN THE MAIN LOOP
33$:
	MOV	LB.LNU(R4),R1	;GET LINE NUMBER
	ASL	R1		;LINE NUMBER * 2
	ADD	R5,R1		;POINT INTO TCB
	CLR	TCCMSG(R1)	;WE HAVE NO CURRENT MESSAGE
	BR	11$		;FIND NEXT MESSAGE AND SENT TO TEN
;
;
; HERE IF THERE IS NO MESSAGE FOR THAT LINE
;
22$:	CLR	DT10DT(R5)	;NO INDIRECT DATA TO SEND
	MOV	TCXLT(R5),R1	;POINT TO XLATE TASK
	BIT	#TCIAB!TCIEC,TCFG2(R1) ;EOF OR ABORT?
	BEQ	24$		;NO.  "DELAYED" RETURN.
23$:	MOVB	#3,DT10DF+1(R5)	;YES, GIVE "REJECT" RETURN

	BIT	#TCIAB, TCFG2(R1) ;;++BS- ABORT ? 3(005)
	BNE	36$		;;++BS- YES, CLEAR THE ACTIVE BIT 3(005)
	BIT	#TCIPR, TCFG2(R1) ;;++BS- INPUT PERMISSION REQUESTED ? 3(005)
	BNE 	18$		;;++BS- YES, DO NOT CLEAR THE ACTIVE BIT 3(005)
				;;++BS- NO, CLEAR THE ACTIVE BIT 3(005)

36$:				;;++BS-NEW LABEL 3(005)

	JSR	PC, DLRCAB	;CLEAR THE DEVICE ACTIVE BIT
	BR	18$		;SEND REJECT TO TEN
;
24$:	MOVB	#2,DT10DF+1(R5)	;INDICATE "DELAYED"
	JSR	PC, DLRCAB	;CLEAR DEVICE ACTIVE BIT
25$:	BR	18$		;SEND IT TO TEN



;;++BS-CODE TO CLEAR THE DEVICE ACTIVE BIT

DLRCAB:	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOVB	DT11AD+1(R5), R0 ;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	MOVB	DT11AD(R5),R1	;GET DEVICE NUMBER
	BIC	#177400, R1	;CLEAR JUNK
	TST	R1		;CHECK FOR ZERO DEVICE NUMBER
	BNE	35$		;NON ZERO, CONTINUE
	MOV	TCLCB(R5), R2	;POINT TO LCB
	BIT	#LF.SIM, LB.FGS(R2)	;SIMULATION ?
	BNE	34$		;YES
	MOV	#3, R1		;NO, SUPPORT, MUST BE CDR
	BR	35$		;CLEAR DEVICE ACTIVE BIT
34$:	MOV	#4, R1		;SIMULATION, MUST BE LPT
35$:	JSR	PC, HSAMPC	;CLEAR DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN

;;++BS-END OF CODE TO CLEAR THE DEVICE ACTIVE BIT


;
; THIS SUBROUTINE LOOKS FOR A CURRENT MESSAGE AND IF 
; NONE IS FOUND, GETS OLDEST MESSAGE WITH THE ID.
;
DLGTCM:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.LNU(R4),R1	;GET LINE NUMBER
	ASL	R1		;LINE NUMBER * 2
	ADD	R5,R1		;POINT INTO TCB
	CMP	#TTHASP,LB.DVT(R4)	;HASP LINE?
	BEQ	11$		;YES
	MOV	TCCMSG(R1),R0	;IS THERE A CURRENT MESSAGE?
	BNE	16$		;YES, CONTINUE WITH IT.
	BR	13$		;GO GET MESSAGE FOR THE LINE
11$:	MOV	TCCMSG(R1),R1	;GET PTR TO DEV MSG
	BNE	12$		;THERE'S ONE
	STOPCD	HSB		;NONE EXISTS
;
12$:	ADD	R2,R1		;GET DEVICE MSG PTR
	MOV	R1,TCPDM(R5)	;SAVE PTR TO DEV MSG
	MOV	(R1),R0		;ANY DEVICE MESSAGE?
	BNE	17$		;YES.
	MOV	TCXLT(R5),R0	;POINT TO DEVICE'S TCB
	MOV	TCCTP(R0),R1	;GET THE RCB 
	MOV	LB.LNU(R4),R0	;GET LINE #
	SWAB	R0		;PUT IN LEFT BYTE
	ADD	R0,R1		;MAKE I.D. FOR THE MESSAGE
	JSR	PC,DEQMID	;GET OLDEST MSG WITH THAT ID
	BCS	16$		;THERE IS NONE.

;;++BS-CODE TO UNSUSPEND A DEVICE IF LESS THAN 2 MESSAGES QUEUED

	MOV	R3, -(SP)	;;++BS-SAVE R3
	MOV	TCXLT(R5), R3	;;++BS-POINT TO XLATE TASK
	DEC	TCIMC(R3)	;;++BS-DECREMENT COUNT OF INPUT MESSAGES
	CMP	TCIMC(R3), #2	;;++BS-LESS THAN 2 ?
	BGE	31$		;;++BS-NO, CONTINUE
	MOV	R1, -(SP)	;;++BS-YES, SAVE R1
	MOV	TCCTP(R3), R1	;;++BS-GET DEVICE TYPE
	BIC	#177770, R1	;;++BS-GET DEVICE NUMBER
	JSR	PC, HSUNSP	;;++BS-UNSUSPEND THE DEVICE
				;;++BS-TCLCB(R5) POINTS TO XLATE LCB
	MOV	(SP)+, R1	;;++BS-RESTORE R1
31$:	MOV	(SP)+, R3	;;++BS-RESTORE R3

;;++BS-END OF CODE TO UNSUSPEND A DEVICE IF LESS THAN 2 MESSAGES QUEUED

	MOV	R0,@TCPDM(R5)	;SAVE DEVICE MSG PTR
17$:	CLC			;SUCCESSFUL
	RTS	PC		;RETURN
;
13$:	MOV	LB.LNU(R4),R1	;GET LINE # (I.D. FOR 2780/3780)
	JSR	PC,DEQMID	;GET MESSAGE FOR THE I.D.
	BCS	16$		;NO MESSAGE FOR THIS I.D.
	MOV	LB.LNU(R4),R1	;GET LINE NUMBER
	ASL	R1		;LINE NUMBER * 2
	ADD	R5,R1		;POINT INTO TCB
	MOV	R0,TCCMSG(R1)	;REMEMBER CURRENT MESSAGE
	CLC			;SUCCESS
16$:	RTS	PC		;EXIT
;
;
;
; SUBROUTINE TO PERFORM THE "WRITE DATA" FUNCTION.  DATA IS
;  FETCHED THROUGH THE DTE20 AND PLACED IN CHUNKS.  THE CHUNKS
;  ARE SENT TO THE XLATE TASK FOR TRANSLATION AND SUBSEQUENT
;  QUEUEING TO THE DQ11.
;
; ON RETURN:
;
;	C IS SET IF THE DTE20 FAILS OR THERE IS SOME INCONSISTENCY
;	  IN THE PDP-10 INFORMATION.  OTHERWISE, R0 = RESULT CODE.
;
DLTWDT:	TST	DT11FN(R5)	;BETTER BE INDIRECT FUNCTION
	BMI	11$		;YES,CHECK FOR LINE ETC.
	STOPCD	DTI20		;DATA NOT INDIRECT
;
11$:	MOVB	DT11AD+1(R5),R0	;GET LINE NO
	CMP	R0,NDQ11S	;IS IT REASONABLE?
	BHIS	14$		;NO, PARM ERROR.
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R4	;POINT TO LCB
	BEQ	14$		;NOT INITIALIZED
	BIT	#LS.ENB,(R4)	;IS THE LINE ENABLED?
	BEQ	14$		;NO.
	MOVB	DT11AD(R5),R1	;GET RCB OR DEVICE #
	BIC	#177770,R1	;EXTRACT DEVICE # FROM RCB

;3(014).IF NE,DEBUG
;3(014)	BNE	10$		;
;3(014)	CMP	#TTHASP,LB.DVT(R4) ;CHECK FOR HASP
;3(014)	BNE	10$		;ONLY
;3(014)	STOPCD	TER		;TEN ERROR
;3(014) 10$:
;3(014).ENDC

	JSR	PC, DLMCHK	;;++BS- CHECK FOR LEGAL DEVICE NUMBER 3(014)
	BCS	14$		;;++BS- BAD DEVICE NUMBER, REJECT 3(014)

	ASL	R1		;DEVICE * 2
	ADD	R4,R1		;ADD DEVICE #
	MOV	LB.TCD(R1),R0	;POINT TO XLATE TASK
	MOV	R0,TCXLT(R5)	;REMEMBER TCB OF XLATE TASK
	MOV	#-1,DT10AK	;NOTE THAT WE EXPECT ED DATA
	TST	TCCHK1(R0)	;INPUT WAITING FOR XLATE TASK??
	BNE	12$		;YES, WAKE UP PDP-10 WAIT A WHILE

;;;++BS-CODE TO SET DEVICE ACTIVE BIT FOR OUTPUT

;	JSR	PC, HSSAVR	;SAVR THE REGISTERS
;	MOVB	DT11AD+1(R5), R0 ;GET LINE NUMBER
;	BIC	#177770, R0	;CLEAR JUNK
;	MOVB	DT11AD(R5), R1	;GET DEVICE NUMBER-RCB
;	BIC	#177400, R1	;CLEAR JUNK
;	TST	R1		;CHECK FOR ZERO DEVICE NUMBER
;	BNE	35$		;NON ZERO, CONTINUE
;	MOV	TCLCB(R5), R2	;POINT TO LCB
;	BIT	#LF.SIM, LB.FGS(R2)	;SIMULATION ?
;	BNE	34$		;YES
;	MOV	#4, R1		;NO, SUPPORT, MUST BE LPT
;	BR	35$		;SET DEVICE ACTIVE BIT
;34$:	MOV	#3, R1		;SIMULATION, MUST BE CDR
;35$:	JSR	PC, HSACMP	;SET THE DEVICE ACTIVE BIT
;	JSR	PC, HSRESR	;RESTORE THE REGISTERS

;;;++BS-END OF CODE TO SET THE DEVICE ACTIVE BIT

	CLC			;INDICATE SUCCESSFUL RETURN
	RTS	PC		;RETURN
;
;

;;++BS-CODE TO CLEAR DEVICE ACTIVE BIT

12$:
	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOVB	DT11AD+1(R5), R0 ;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	MOVB	DT11AD(R5), R1	;GET DEVICE NUMBER-RCB
	BIC	#177400, R1	;CLEAR JUNK
	TST	R1		;CHECK FOR ZERO DEVICE NUMBER
	BNE	37$		;NON ZERO, CONTINUE
	MOV	TCLCB(R5), R2	;POINT TO LCB
	BIT	#LF.SIM, LB.FGS(R2)	;SIMULATION ?
	BNE	36$		;YES
	MOV	#4, R1		;NO, SUPPORT, MUST BE LPT
	BR	37$		;CLEAR DEVICE ACTIVE BIT
36$:	MOV	#3, R1		;SIMULATION, MUST BE CDR
37$:	JSR	PC, HSAMPC	;CLEAR THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

;;++BS-END OF CODE TO CLEAR THE DEVICE ACTIVE BIT

	MOV	TCXLT(R5),R1	;POINT TO XLATE TASK
	BIT	#TCOAB,TCFG2(R1) ;HAS STREAM BEEN ABORTED?
	BEQ	13$		;NO,INDICATE DELAYED OPERATION
	JMP	DLSERR		;OPERATION REJECTED
;
13$:	JMP	DLSDLY		;OPERATION DELAYED
;
14$:
	MOV	#-1,DT10AK	;;++BS-NOTE THAT WE EXPECT ED DATA 3(012)
	JMP	DLSERR		;;++BS-REJECT THE REQUEST 3(012)
;3(012)	SEC			;FATAL ERROR
;3(012)	RTS	PC		;RETURN
;
;
; SUBROUTINE TO PERFORM THE "READ DEVICE STATUS" FUNCTION.
;  THE STATUS MESSAGE IS ASSEMBLED IN A BUFFER AND SENT TO-TEN
;  AS INDIRECT DATA.  NO EXCEPTIONAL CONDITIONS ARE POSSIBLE.
;
DLTRDS:	JSR	PC,DTSHDR	;SETUP HEADER FOR TEN XFER
	TST	DT11DT(R5)		;ASKING FOR ZERO?
	BEQ	13$		;YES, THROW HIM OFF.
	MOVB	DT11AD+1(R5),R0	;GET LINE NO
	CMP	R0,NDQ11S	;IS IT REASONABLE?
	BHIS	13$		;NO, ERROR.
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R4	;POINT TO SPECIFIED LCB
	BEQ	13$		;NOT INITIALIZED.
	BIT	#LS.ENB,(R4)	;IS THE LINE ENABLED?
	BEQ	13$		;NO.
	MOVB	DT11AD(R5),R1	;GET RCB OR DEVICE #
	BIC	#177770,R1	;EXTRACT DEVICE # FROM RCB

;3(014).IF NE,DEBUG
;3(014)	BNE	10$		;TRACK 10 ERRORS
;3(014)	CMP	#TTHASP,LB.DVT(R4) ;CHECK HASP DEV #
;3(014)	BNE	10$		;ONLY
;3(014)	STOPCD	TER		;
;3(014) 10$:
;3(014).ENDC

	JSR	PC, DLMCHK	;;++BS-CHECK FOR LEGAL DEVICE NUMBER 3(014)
	BCS	13$		;;++BS-BAD DEVICE NUMBER, REJECT 3(014)

;
;
;
	ASL	R1		;DEV NO * 2
	ADD	R4,R1		;ADD DEVICE # TO
	MOV	LB.TCD(R1),TCXLT(R5) ; POINT TO XLATE TASK
	MOV	R4,TCLCB(R5)	;SAVE LCB IN CASE WE NEED IT LATER
	MOV	#DTTTSB,R2	;POINT TO THE STATUS BLOCK
	MOV	R2,DTXADR(R5)	;SAVE IT FOR TO-TEN XFER
	MOV	DT11DT(R5),R4	;SET COUNT PROVIDED BY TEN
	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	MOVB	TCDVT(R0),R1	;GET DEVICE TYPE
	JSR	PC,DLPBYT	;SEND TO PDP-10
	BCS	13$		;MUST BE MORE ROOM
	MOV	TCCTP(R0),R1	;GET COMPONENT TYPE
	JSR	PC,DLPBYT	;SEND TO PDP-10
	BCS	13$		;MUST BE MORE ROOM
	MOV	TCPGC(R0),R1	;GET PAGE COUNT REGISTER
	JSR	PC,DLPWRD	;SEND TO PDP-10
;	BCS	11$		;NO MORE ROOM
	BCS	13$		;;++BS-NO MORE ROOM 3(004)
	MOV	TCFG1(R0),R1	;GET FLAGS WORD 1
	JSR	PC,DLPWRD	;SEND TO PDP-10
	BCS	13$		;MUST BE MORE ROOM
	MOV	TCFG2(R0),R1	;GET FLAGS WORD 2
	JSR	PC,DLPWRD	;SEND TO PDP-10
	BCS	13$		;MUST BE MORE ROOM
	MOV	TCRSZ(R0),R1	;GET RECORD SIZE FOR  THE DEVICE
	JSR	PC,DLPWRD	;SEND TO PDP-10
;	BCS	11$		;NO MORE ROOM
	BCS	13$		;;++BS-NO MORE ROOM 3(004)
	MOV	TCLCB(R5), R1	;;++BS-POINT TO LCB 3(004)
	MOV	LB.FGS(R1), R1	;;++BS-GET THE LINE FLAGS 3(004)
	JSR	PC, DLPWRD	;;++BS-SEND TO PDP-10 3(004)
	BCS	13$		;;++BS-ERROR, NO MORE ROOM 3(007)
	MOV	TCLCB(R5), R1	;;++BS-POINT TO LCB 3(007)
	MOV	LB.SIG(R1), R1	;;++BS-GET THE LINE SIGNATURE 3(007)
	JSR	PC, DLPWRD	;;++BS-SEND TO PDP-10 3(007)
	BCS	11$		;;++BS-SEND THE INDIRECT MESSAGE 3(004)



;
; CONTINUED ON NEXT PAGE
;
;
;
; HERE WHEN THE INDIRECT MESSAGE HAS BEEN BUILT.
;
11$:	BIS	#B15,DT10FN(R5)	;INDICATE INDIRECT DATA FOLLOWS
	MOVB	#1,DT10DF+1(R5)	;SEND SUCCESS CODE
	MOV	TCXFR(R5),DT10DT(R5) ;SETUP INDIRECT DATA LENGTH
	CLC			;INDICATE SUCCESS
12$:	RTS	PC		;RETURN
;
; HERE IF THERE IS ANY ERROR
;
13$:
	CLR	DT10DT(R5)	;;++BS-ZERO DATA LENGTH 3(010)
	BIS	#B15, DT10FN(R5) ;;++BS-NO INDIRECT DATA 3(010)
;3(010)	SEC			;FATAL ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST 3(010)
	RTS	PC		;RETURN
;
;
; SUBROUTINE TO PERFORM THE "WRITE DEVICE COMMAND" FUNCTION.
;  THE FIRST BYTE OF THE DATA IS THE FUNCTION CODE, IF OTHER
;  DATA IS NEEDED IT FOLLOWS THE FUNCTION CODE.
;
; ON RETURN:
;
;	C SET -- DTE20 FAILURE OR BADLY FORMED COMMAND
;	C CLEAR -- R0 = 1 TO MEAN "SUCCESS", 2 TO MEAN "DELAYED"
;
DLTWDC:	TST	DT11FN(R5)	;BETTER BE INDIRECT DATA
	BMI	11$		;YES,IT IS
	STOPCD	DTI20		;DATA NOT INDIRECT ERROR
;
11$:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	CMP	R0,NDQ11S	;IN RANGE?
	BHIS	12$		;NO, ERROR.
	ASL	R0		;YES, LINE NUMBER*2
	MOV	DQLCB(R0),R0	;PICK UP LCB POINTER
	BEQ	12$		;NONE IS ERROR
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	12$		;NO.
	MOV	R0, R4		;;++BS-POINT R4 TO LCB 3(014)
	MOVB	DT11AD(R5),R1	;GET RCB OR DEVICE #
	BIC	#177770,R1	;EXTRACT DEVICE # FROM RCB

;3(014).IF NE,DEBUG
;3(014)	BNE	10$		;TRACK 10 ERRORS
;3(014)	CMP	#TTHASP,LB.DVT(R0) ;HASP DEV 
;3(014)	BNE	10$		;ONLY
;3(014)	STOPCD	TER
;3(014) 10$:
;3(014).ENDC

	JSR	PC, DLMCHK	;;++BS-CHECK FOR LEGAL DEVICE NUMBER 3(014)
	BCS	12$		;;++BS-BAD DEVICE NUMBER, REJECT 3(014)

	ASL	R1		;DEVICE * 2
	ADD	R0,R1		;ADD DEVICE #
	MOV	LB.TCD(R1),TCXLT(R5) ;POINT TO XLATE TASK
13$:				;;++BS-NEW LABEL 3(011)
	MOV	#-1,DT10AK	;NOTE THAT WE EXPECT ED DATA
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
12$:
	CLR	TCXLT(R5)	;;++BS-NO XLATE TASK FOR ERROR 3(011)
	BR	13$		;;++BS-REJECT HIS REQUEST ON ED DATA 3(011)
;3(011)	SEC			;FATAL ERROR
;3(011)	RTS	PC		;RETURN

;
;
;
DLTWD1:	MOV	DT11Q(R5),R2	;POINT TO WHERE STATUS IS
	MOV	DT11DT(R5),R4	;COUNT OF BYTES RECEIVED
	JSR	PC,DLGBYT	;GET COMMAND CODE BYTE INTO R1
	BCS	11$		;NONE, ERROR.
	TST	TCXLT(R5)	;;++BS-IS THERE A XLATE TASK ? 3(011)
	BEQ	14$		;;++BS-NO, REJECT THE REQUEST 3(011)
				;;++BS-YES, CONTINUE 3(011)
	MOV	#12$,R0		;POINT TO DISPATCH TABLE
	MOVB	#1,DT10DF+1(R5)	;SUCCESS CODE
	JSR	PC,DLDISP	;DISPATCH TO HANDLER
11$:	RTS	PC		;RETURN
;
;
;

14$:	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST 3(011)
	BR	11$		;;++BS-CONTINUE 3(011)



;
;
;
; DISPATCH TABLE
;
12$:	.WORD	<<13$-12$>/2>-2	;MAX TABLE INDEX
	.WORD	0		;0 = INVALID
	.WORD	DLTD01		;1 = SET CHARACTERISTICS
	.WORD	0		;2 = RESERVED
	.WORD	DLTD03		;3 = DUMP OUTPUT [1(627)]
	.WORD	DLTD04		;4 = CLEAR "INPUT PERMISSION WAS REQUESTED"
	.WORD	0		;5 = RESERVED
	.WORD	DLTD06		;6 = INTERPRET CC ON INPUT
	.WORD	DLTD07		;7 = DONT
	.WORD	DLTD08		;8 = INTERPRET CC ON OUTPUT
	.WORD	DLTD09		;9 = DONT
	.WORD	0		; RESERVED
	.WORD	0		; RESERVED
	.WORD	DLTD12		;12 = DO COMPONENT SELECTION
	.WORD	DLTD13		;13 = DONT
	.WORD	DLTD14		;14 = ENABLE PAGE COUNTER
	.WORD	DLTD15		;15 = DISABLE IT
	.WORD	0		;16 = RESERVED
	.WORD	DLTD17		;17 = DO SPACE COMPRESSION
	.WORD	DLTD18		;18 = DONT
	.WORD	DLTD19		;19 = USE OLD BSC PROTOCOL
	.WORD	DLTD20		;20 = DONT
	.WORD	DLTD21		;21 = REQUEST OUTPUT PERMISSION
	.WORD	DLTD22		;22 = GRANT INPUT PERMISSION
	.WORD	DLTD23		;23 = SIGNAL OUTPUT EOF
	.WORD	DLTD24		;24 = CLEAR OUTPUT EOF COMPLETE
	.WORD	DLTD25		;25 = SIGNAL OUTPUT ABORT
	.WORD	DLTD26		;26 = CLEAR OUTPUT ABORT COMPLETE
	.WORD	DLTD27		;27 = CLEAR INPUT EOF COMPLETE
	.WORD	DLTD28		;28 = SIGNAL INPUT ABORT
	.WORD	DLTD29		;29 = CLEAR INPUT ABORT COMPLETE
	.WORD	DLTD30		;30 = SUSPEND DEVICE (HASP)
	.WORD	DLTD31		;31 = UNSUSPEND DEVICE (HASP)
	.WORD	DLTD32		;32 = SET DEVICE RECORD SIZE
13$:
;
;
; SUBROUTINE TO PERFORM THE "READ LINE STATUS" FUNCTION.
;  IF THE LINE IS NOT INITIALIZED, GIVE A 0-LENGTH REPLY
;
DLTRLS:	JSR	PC,DTSHDR	;SETUP HEADER FOR TO-TEN XFER
	MOV	DT11DT(R5),DT10DT(R5) ;SET LENGTH OF IDIRECT DATA
	BEQ	14$		;ZERO LENGTH UNREASONABLE
	MOVB	DT11AD+1(R5),R0	;GET LINE NO
	MOV	R1,-(SP)	;;++BS-SAVE R1
	MOVB	NDQ11S, R1	;;++BS-GET NUMBER OF DQ11S
	DEC	R1		;;++BS-CONVERT TO LINE NUMBER
	CMPB	R1, R0		;;++BS-EXCEED MAX NUMBER ?
	BGE	31$		;;++BS-NO, CONTINUE
	MOV	(SP)+, R1	;;++BS-YES, RESTORE R1
	BR	32$		;;++BS-REJECT THE REQUEST
;	CMP	R0,NDQ11S	;IS IT REASONABLE?
;	BHIS	14$		;NO, ERROR.
31$:	MOV	(SP)+, R1	;;++BS-RESTORE R1
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R4	;POINT TO SPECIFIED LCB
	BEQ	11$		;NOT INITIALIZED.
	BIT	#LS.ENB,(R4)	;IS THE LINE ENABLED?
	BEQ	11$		;NO.
	MOV	R4,TCLCB(R5)	;SAVE LCB IN CASE WE NEED IT LATER
	MOV	DT11DT(R5),R4	;SET UP COUNT FOR DLPBYT
	MOV	#DTTTSB,R2	;POINT TO THE STATUS BLOCK
	MOV	R2,DTXADR(R5)	;SAVE ADR OF INDIRECT DATA
	MOV	TCLCB(R5),R0	;POINT TO LCB
	MOVB	LB.DVT(R0),R1	;GET TERMINAL TYPE
	JSR	PC,DLPBYT	;STORE IN USER'S BUFFER
	BCS	14$		;ERROR IF NO MORE ROOM
;3(007)	MOVB	LB.FGS(R0),R1	;GET LINE FLAGS
;3(007)	JSR	PC,DLPBYT	;STORE IN USER'S BUFFER
	MOV	LB.FGS(R0), R1	;;++BS-GET LINE FLAGS 3(007)
	JSR	PC, DLPWRD	;;++BS-SEND TO PDP-10 3(007)
	BCS	14$		;ERROR IF NO MORE ROOM
	MOV	#B0,R1		;INDICATE LINE IS ENABLED
	BIT	#LF.TSP,LB.FGS(R0) ;OUTPUT TRANSPARENT?
	BEQ	21$		;NO.
	BIS	#B3,R1		;HOPE NOBODY ELSE USES BIT 3
21$:	JSR	PC,DQMDMS	;SET DTR AND DSR INTO R1
	JSR	PC,DLPBYT	;STORE STATUS BYTE IN USER'S BUFFER
;
; CONTINUED ON NEXT PAGE
;
;
;  INCLUDE BSC STATISTICS IN LINE STATUS
;
	BCS	14$		;ERROR IF NO ROOM
;3(007)	CLR	R1		;SEND RESERVE BYTE ALSO [[RELEASE 4]]
;3(007)	JSR	PC,DLPBYT	;IN USERS BUFFER
;3(007)	BCS	14$		;ERROR IF NO ROOM
	MOV	TCLCB(R5),R0	;POINT R0 TO LCB
	MOV	#LB.ST2,R3	;COMPUTE ADDRESS OF LAST WORD + 2 4(025)
;4(025)	MOV	#LB.ST2+2,R3	;COMPUTE ADDRESS OF LAST WORD + 2
	ADD	R0,R3
	ADD	#LB.ST1,R0	;COMPUTE ADDRESS OF FIRST WORD
	JSR	PC,DLPSTR	;SEND LOTS OF WORDS
11$:	MOV	TCXFR(R5),DT10DT(R5) ;SETUP INDIRECT DATA LENGTH
	BEQ	12$		;DONT SET INDIRECT FOR ZERO LENGTH
	BIS	#B15,DT10FN(R5)	;INDICATE INDIRECT DATA TO FOLLOW
12$:				;JUST SEND THE DIRECT HEADER
	MOVB	#1,DT10DF+1(R5)	;SEND SUCCESS CODE = 1
	CLC			;INDICATE SUCCESS
13$:	RTS	PC		;RETURN
;
; HERE ON A PROTOCOL ERROR
;
14$:	SEC			;FATAL ERROR
	RTS	PC		;RETURN
;
;
; HERE WITH INCORRECT LINE NUMBER
;
32$:	MOV	TCXFR(R5), DT10DT(R5) ;;++BS-SET UP INDIRECT DATA LENGTH
	BEQ	33$		;;++BS-DON'T SET INDIRECT FOR ZERO LENGTH
	BIS	#B15, DT10FN(R5);;++BS-INDICATE INDIRECT DATA TO FOLLOW
33$:				;;++BS-JUST SEND THE DIRECT HEADER
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;;++BS-RETURN
; 
;
; SUBROUTINE TO PERFORM THE "WRITE LINE COMMAND" FUNCTION.
;  THE FIRST BYTE OF THE DATA IS THE FUNCTION CODE, IF OTHER
;  DATA IS NEEDED IT FOLLOWS THE FUNCTION CODE.
;
; ON RETURN:
;
;	C SET -- DTE20 FAILURE OR BADLY FORMED COMMAND
;	C CLEAR -- R0 = 1 TO MEAN "SUCCESS", 2 TO MEAN "DELAYED"
;
DLTWLC:	TST	DT11FN(R5)	;BETTER BE INDIRECT DATA!!
	BMI	11$		;YES,IT IS
	STOPCD	DTI20		;DATA NOT INDIRECT ERROR
;
11$:
	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	CMP	R0,NDQ11S	;IN RANGE?
;	BHIS	12$		;NO, ERROR.
	MOV	#-1,DT10AK	;NOTE THAT WE EXPECT ED DATA
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
12$:	SEC			;FATAL ERROR
	RTS	PC		;RETURN
;
;
; COME HERE WHEN THE INDIRECT DATA HAS ARRIVED.
;
DLTWL1:	MOV	DT11Q(R5),R2	;POINT TO WHERE STATUS IS KEPT
	MOV	DT11DT(R5),R4	;SETUP THE COUNT
	JSR	PC,DLGBYT	;GET COMMAND CODE BYTE
	BCS	11$		;NONE, ERROR.
	MOV	#12$,R0		;POINT TO DISPATCH TABLE
	MOVB	#1,DT10DF+1(R5) ;SET SUCCESS CODE
	JSR	PC,DLDISP	;DISPATCH TO HANDLER
11$:	RTS	PC		;RETURN
;
; DISPATCH TABLE
;
12$:	.WORD	<<13$-12$>/2>-2	;MAX TABLE INDEX
	.WORD	0		;0 = INVALID
	.WORD	DLTL01		;1 = ENABLE
	.WORD	DLTL02		;2 = SET DTR
	.WORD	DLTL03		;3 = ABORT AND HANG UP
	.WORD	DLTL04		;4 = DISABLE
	.WORD	DLTL05		;5 = SET CTS DELAY
	.WORD	DLTL06		;6 = SET LENGTH OF SILO WARNING AREA
	.WORD	DLTL07		;7 = SET OUTPUT IN TRANSPARENT MODE
	.WORD	DLTL08		;8 = SET OUTPUT IN NON-TRANSPARENT MODE
	.WORD	DLTL09		;9 = SET TRANSMISSION BLOCK LENGTH
	.WORD	DLTL10		;10= SET RECORDS PER MESSAGE
	.WORD	DLTL11		;11= SET LINE SIGNATURE (;;++BS-)
13$:
;
;
;
; SUBROUTINE TO PERFORM THE "WRITE DN60 COMMAND" FUNCTION.
;  THE FIRST BYTE OF THE DATA IS THE FUNCTION CODE, IF OTHER
;  DATA IS NEEDED IT FOLLOWS THE FUNCTION CODE.
;
; ON RETURN:
;
;	C SET -- DTE20 FAILURE OR BADLY FORMED COMMAND
;	C CLEAR -- R0 = 1 TO MEAN "SUCCESS", 2 TO MEAN "DELAYED"
;
DLTWEC:
	TST	DT11FN(R5)	;MUST BE INDIRECT
	BMI	11$		;YES,IT IS
	STOPCD	DTI20		;DATA NOT INDIRECT
;
11$:	MOV	#-1,DT10AK	;NOTE THAT WE EXPECT ED DATA
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
;
; COME HERE WHEN THE INDIRECT DATA ARRIVES.
;
DLTWS1:	MOV	DT11Q(R5),R2	;POINT TO STATUS
	MOV	DT11DT(R5),R4	;SETUP COUNT
	JSR	PC,DLGBYT	;GET COMMAND CODE BYTE
	BCS	11$		;NONE, ERROR.
	MOV	#12$,R0		;POINT TO DISPATCH TABLE
	MOVB	#1,DT10DF+1(R5) ;SET SUCCESS CODE
	JSR	PC,DLDISP	;DISPATCH TO HANDLER
11$:	RTS	PC		;RETURN
;
; DISPATCH TABLE
;
12$:	.WORD	<<13$-12$>/2>-2	;MAX TABLE INDEX
	.WORD	0		;0 = INVALID
;	.WORD	DLTE01		;1 = ???
13$:
;
;
; SUBROUTINE FOR LINE COMMAND 1: ENABLE THE LINE
;
DLTL01:	CLR	NWLFLG		;;++BS- ASSUME THIS IS A NEW LINE

	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	MOV	R1,-(SP)	;;++BS-SAVE R1
	MOVB	NDQ11S, R1	;;++BS-GET NUMBER OF DQ11S
	DEC	R1		;;++BS-CONVERT TO LINE NUMBER
	CMPB	R1, R0		;;++BS-EXCEED MAX NUMBER ?
	BGE	29$		;;++BS-NO, CONTINUE
	MOV	(SP)+, R1	;;++BS-YES, RESTORE R1
	JMP	24$		;;++BS-YES, REJECT REQUEST, NOT FATAL
29$:	MOV	(SP)+, R1	;;++BS-RESTORE R1

	ASL	R0		;LINE NUMBER * 2
	TST	DQLCB(R0)	;ALREADY A LINE CONTROL BLOCK?
	BNE	11$		;YES.
	ASR	R0		;NO, PUT LINE NUMBER IN R0
	JSR	PC,DLENLN	;BUILD AN LCB
	BCS	18$		;OUT OF CORE
	MOV	#1, NWLFLG	;;++BS- INDICATE THIS IS A NEW LINE
11$:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;POINT R0 TO LCB
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BNE	17$		;YES, CAN'T ENABLE IT AGAIN.
;3(013)	BIT	#LF.DIP!LF.ABC,LB.FGS(R0) ;DISABLE IN PROGRESS?
	BIT	#LF.DIP, LB.FGS(R0) ;;++BS-DISABLE IN PROGRESS ? 3(013)
	BNE	18$		;YES, GIVE DELAYED RETURN
;
;;++BS- THIS CODE DELETES THE BSC TASK AFTER THE LINE IS DISABLED


	TST	NWLFLG		;IS THIS A NEW LINE ?
	BNE	25$		;YES, THERE WAS NO BSC TASK

	BIT	#LF.DAC, LB.FGS(R0) ;NO, DID BSC DISABLE THE LINE ?
	BEQ	18$		;NO, GIVE DELAYED RETURN

	JSR	PC, HSSAVR	;YES, SAVE THE REGISTERS
	MOV	R0, R4		;PUT POINTER TO LCB IN R4
	MOV	LB.TC1(R4), R0	;GET POINTER TO BSC TASK
	BEQ	26$		;NO BSC, EXIT
	MOV	TCBP1, R3	;R3 MUST POINT TO START OF CHAIN
	JSR	PC, DLRLTC	;RELEASE TCB AND UNLINK FROM CHAIN
	MOV	R3, TCBP1	;UPDATE START OF CHAIN OF TCBS
	CLR	LB.TC1(R4)	;CLEAR BSC TCB POINTER

26$:				;CLEAN UP LCB

	MOV	#NDHASP, R2	;GET NUMBER OF XLATE TCBS
27$:	MOV	R4, R1		;POINT TO LCB 4(026)
;4(026)	MOV	R0, R1		;POINT TO LCB
	CLC			;CLEAR FOR ROTATE
	ASL	R2		;MAKE EVEN FOR WORD OFFSET
	ADD	R2, R1		;OFFSET INTO LCB
	CLC			;CLEAR FOR ROTATE
	ASR	R2		;GET BACK # OF XLATE TCBS
	CLR	LB.TC1(R1)	;CLEAR XLATE TCB POINTER IN LCB
	SOB	R2, 27$		;CLEAR THE REST OF THE XLATE POINTERS
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

25$:

;;++BS- END OF CODE THAT DELETES THE BSC TASK AFTER THE LINE IS DISABLED
;
;
	MOV	R0,TCLCB(R5)	;REMEMBER LCB 
	JSR	PC,DLGBYT	;GET DEVICE TYPE
	BCS	17$		;NONE SPECIFIED
	MOV	R1,LB.DVT(R0)	;STORE DEVICE TYPE
	JSR	PC,DLGBYT	;GET CHARACTERISTICS
	BCS	17$		;NOT SPECIFIED
	MOV	R1,LB.FGS(R0)	;STORE CHARACTERISTICS
	BIT	#LF.PRI,R1	;PRIMARY?
	BNE	12$		;YES.
	MOV	#3*JIFSEC,LB.EQW(R0) ;NO, MAKE SECONDARY
;12$:	JSR	PC,DLBTCB	;BUILD TCB'S FOR XLATE TASKS
12$:
	.IF EQ, XLOPHP		;CHECK IF HASP PRESENT

	CMP	#TTHASP,LB.DVT(R0)	;IS THIS A HASP LINE?
	BNE	20$			;NO, CONTINUE
	BR	19$			;YES, BUT HASP NOT PRESENT- ERROR

20$:

	.ENDC				;.IF EQ, XLOPHP
	JSR	PC,DLBTCB	;BUILD TCB'S FOR XLATE TASKS
	BCS	18$		;OUT OF STORAGE
	MOV	LB.TC1(R0),R1	;POINT TO BSC TASK
	BNE	13$		;MAKE SURE BSC TCB EXISTS
	STOPCD	HSC		;TRAP OTHERWISE
13$:
	CLR	TCST2(R1)	;BE SURE IT IS INITIALIZED
	CLR	TCFG1(R1)	; SO THERE IS NO PROBLEMS WITH
	CLR	TCFG2(R1)	; ANY EARLIER ABORTS
	BIS	#LS.ENB,(R0)	;ENABLE THE LINE
	CLR	R2		;INITIALIZE OFFSET IN TABLE
	MOV	LB.LNU(R0),R1	;NO, INITIALIZE CURRENT MSG PTR
	ASL	R1		;FOR WORD BOUNDARY PTR
	CMP	#TTHASP,LB.DVT(R0)	;HASP LINE?
	BEQ	14$		;YES.
	ADD	R5,R1		;POINT TO CURRENT MSG FOR LINE
	CLR	TCCMSG(R1)	;CLEAR IT
	BR	16$		;AND EXIT
;
;
; HERE FOR HASP LINE, SET DEVICE MSG PTR
;
14$:	JSR	PC,DLGDTA	;GET DEVICE TABLE ADDRESS
	ADD	R5,R2		;R2 IS RETURNED WITH OFFSET
	ADD	R5,R1		;POINT TO PLACE TO SAVE
	MOV	R2,TCCMSG(R1)	;SAVE PTR TO DEVICE MESSAGES
	MOV	#5,R1		;INITIALIZE ALL DEVICE MSG PTRS
15$:	CLR	(R2)		;CLEAR MSG PTR
	ADD	#2,R2		;INCREMENT PTR FOR NEXT MSG
	SOB	R1,15$		;COVER ALL DEVICE MSG PTRS
16$:
	BIS	#LF.ENC,LB.FGS(R0) ;ENABLE COMPLETE
	BIC	#LF.DAC,LB.FGS(R0) ;CLEAR DISABLE COMPLETE
21$:	CLC			; NOT FATAL ERROR
	RTS	PC		; AND RETURN.
;
; HERE ON UNREASONABLE ERROR.
;
17$:	SEC			;INDICATE FATAL ERROR
	RTS	PC		;RETURN.
;
; HERE IF SHORT ON STORAGE
;
18$:	MOVB	#2,DT10DF+1(R5) ;INDICATE OPERATION DELAYED
	CLC			;BUT NOT UTTER FAILURE
	RTS	PC		;RETURN.

;
;HERE IF REQUESTED A LINE WE DO NOT HAVE
;
24$:	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;;++BS-RETURN

	.IF EQ, XLOPHP		;NO HASP BUT HASP LINE INDICATED-ERROR

; HERE IF HASP REQUEST AND NO HASP SUPPORT



19$:	MOVB	#3, DT10DF+1(R5)	;INDICATE REQUEST REJECTED 
	BIS	#LF.DAC, LB.FGS(R0)	;INDCATE LINE HAS BEEN DISABLED BY BSC TASK
	BR 21$			;NO HASP SUPPORT- RETURN

	.ENDC			;.IF EQ, XLOPHP


NWLFLG:	.WORD	0		;FLAG TO INDICATE A NEW LCB WAS BUILT



;
;
; SUBROUTINE TO GET DEVICE TABLE OFFSET FOR MESSAGES
;
DLGDTA:
	MOV	R1,-(SP)	;SAVE LINE # * 2
	ASR	R1		;GET LINE # BACK
	TST	R1		;LOOP FOR NON-ZERO LINE
	BEQ	12$		;SKIP FOR LINE ZERO
11$:	ADD	#2*NDHASP,R2	;GO OVER ONE LINE TABLE FOR DEVICES 4(027)
;4(027)	MOV	#2*NDHASP,R2	;GO OVER ONE LINE TABLE FOR DEVICES
	SOB	R1,11$		;GET OFFSET FOR THE LINE
12$:	ADD	#TCDMSG,R2	;COMPLETE OFFSET IN R2
	MOV	(SP)+,R1	;RESTORE LINE # * 2
	RTS	PC		;AND RETURN
;
;
; SUBROUTINE TO BUILD THE LINE CONTROL BLOCK AND THE
;  TASK CONTROL BLOCKS NEEDED FOR EACH DQ11 LINE.
;
; R0 = LINE NUMBER
;
; ON RETURN:
;
; C CLEAR: LCB ALLOCATED
;
; C SET: OUT OF STORAGE
;
DLENLN:	MOV	R0,-(SP)	;SAVE LINE NUMBER
	MOV	#LB.SIZ,R0	;LENGTH OF A LCB
	JSR	PC,GETSTG	;GET SPACE FOR A LCB
	BCC	11$		;BRANCH IF ENOUGH SPACE
	MOV	(SP)+,R0	;OUT OF SPACE--GET LINE NUMBER
	SEC			;FLAG FAILURE
	RTS	PC		; AND RETURN, NO LCB CREATED.
;
; HERE IF THERE IS ENOUGH STORAGE FOR THE LCB
;
11$:	MOV	(SP)+,R1		;GET LINE NUMBER
	ASL	R1		;LINE NUMBER * 2
	MOV	R0,DQLCB(R1)	;STORE POINTER TO LCB
	MOV	DQCSR(R1),LB.SLA(R0) ;STORE CSR ADDRESS
	MOV	DQVEC(R1),LB.SLV(R0) ;STORE VECTOR ADDRESS
	ASR	R1		;GET LINE NUMBER * 1
	MOV	R1,LB.LNU(R0)	;STORE LINE NUMBER
	MOV	#1*JIFSEC,LB.EQW(R0) ;TIME BETWEEN SENDING ENQ'S
	MOV	#3,LB.EQN(R0)	;NUMBER OF ENQ'S TO SEND BEFORE
				; ASSUMING LINE IS DOWN.
	MOV	#MDMXSD,LB.MDS(R0) ;LENGTH OF SILO WARNING AREA FOR KMC11
	MOV	#DQTYPE,LB.TYP(R0) ;LINE DRIVER TYPE
	CLR	LB.FGS(R0)	;CLEAR LINE FLAGS
	RTS	PC		;RETURN AFTER BULDING LCB
;
;
;THIS SUBROUTINE BUILDS TCB FOR THE BSC AND XLATE TASKS.
; IN 3780/2780 WE NEED ONLY ONE TCB FOR XLATE TASK
; WHILE FOR HASP-MULTILEAVING WE NEED 5 TCB'S IN SIMULATE
; AND 4 TCB'S IN SUPPORT MODE OF OPERATION
;
DLBTCB:	MOV	R0,-(SP)	;SAVE POINTER TO LCB
	MOV	R0,R4		;LCB POINTER IN R4
	MOV	LB.TC1(R0),R0	;POINT TO BSC TCB
	BNE	17$		;ITS ALREADY SET UP
	JSR	PC,GETTCB	;GET A TASK CONTROL BLOCK
	bcc	7$		;got the tcb
	jmp	dlenlo		;out of storage
7$:	MOV	#DQDRVR,TCPC(R0) ;STORE INITIAL ADDRESS
	BIS	#BR3,TCPS(R0)	;SET PRIORITY LEVEL TO 3
	MOV	(SP),R4		;GET POINTER TO LCB
	MOV	R4,TCLCB(R0)	;STORE LCB POINTER
	MOV	R0,LB.TC1(R4)	;STORE BSC TASK POINTER
	MOV	TCBP1,R1	;GET HIGHEST-PRIORITY TCBS
	MOV	R0,TCBP1	;PUT THIS TCB ON THE LIST
	MOV	R1,TCHAIN(R0)	; ...
17$:	CLR	R2		;CLEAR DEVICE # INITIALLY
	CMP	#TTHASP,LB.DVT(R4)	;HASP LINE?
	BEQ	11$		;YES.
	MOV	#1,LB.NTC(R4)	;NO, SET UP FOR 1 TCB FOR 2780/3780
	JSR	PC,GETTCB	;GET A TASK CONTROL BLOCK
	BCS	dlenlo		;NO ROOM.
	MOV	#XLATE,TCPC(R0)	;STORE START ADR OF TASK
	CLR	TCDEV(R0)	;DEVICE IS 0 FOR 2780/3780
	BR	13$		;GO PAST HASP SETTINGS
11$:	MOV	#4,LB.NTC(R4)	;SET UP # OF TCB'S FOR HASP DEVICES
	BIT	#LF.SIM,LB.FGS(R4) ;IN SIMULATE MODE?
	BEQ	12$		;NO.
	INC	LB.NTC(R4)	;5 TCB FOR SIMULATE MODE
12$:	INC	R2		;MAKE R2 DEVICE #
	JSR	PC,GETTCB	;GET TCB FOR XLATE TASK
	BCS	dlenlo		;NO ROOM
	.IF NE, XLOPHP		;HASP PRESENT
	MOV	#XLHASP,TCPC(R0) ;SET UP START ADR OF TASK
	.ENDC			;.IF NE, XLOPHP
	MOV	R2,TCDEV(R0)	;AND DEVICE # IN THE TCB
	CLR	TCFG1(R0)	;CLEAR FLAGS TO AVOID 
	CLR	TCFG2(R0)	;PROBLEMS LATER
13$:	BIS	#BR1,TCPS(R0)	;SET PRIORITY LEVEL TO 1
	MOV	R4,TCLCB(R0)	;STORE LCB POINTER
	MOV	R4,R1		;PRESERVE LCB PTR IN R4
	ASL	R2		;DEVICE # * 2 FOR WORD PTR
	ADD	R2,R1		;ADD DEVICE # TO GET XLATE TCB ADR
	ASR	R2		;RESTORE R2 BACK TO DEVICE #
	MOV	R0,LB.TCD(R1)	;STORE COMP. POINTER
	MOV	TCBP3,R1	;GET LOW-PRIORITY TCBS
	MOV	R0,TCBP3	;PUT THIS TCB ON THE LIST
	MOV	R1,TCHAIN(R0)	; ...
;
; continued on next page
;
;
; here to get storage for line buffer for each device
;
	MOV	#150.,R0	;LENGTH OF LINE BUFFER
	JSR	PC,GETSTG	;GET STORAGE FOR IT
	BCS	dlenlo		;OUT OF STORAGE
	MOV	TCBP3,R1	;GET POINTER TO XLATE TCB
	MOV	R0,TCBFP(R1)	;STORE POINTER TO LINE BUFFER
	MOV	#150.,TCBFC(R1)	;STORE LENGTH OF LINE BUFFER
;
	CMP	#TTHASP,LB.DVT(R4) 	;HASP LINE?
	bne	14$		;all done for 2780/3780
	CMP	LB.NTC(R4),R2	;DONE WITH ALL DEVICES XLATE TCB'S
	BNE	12$		;NO
	jsr	pc,dlsiom	;set device in input/output mode
14$:	MOV	LB.SLV(R4),R1	;GET VECTOR ADDRESS
	MOV	#BR7,R0		;GET INITIAL PS
	ADD	LB.LNU(R4),R0	;ADD LINE NUMBER
.IIF NE,FTRACE,BIS TRCFLG,R0	;ADD TRACE BIT IF REQUESTED
	MOV	#DQAINT,(R1)+	;STORE PC FOR INTERRUPT A
	MOV	R0,(R1)+	;STORE PS FOR INTERRUPT A
	MOV	#DQBINT,(R1)+	;STORE PC FOR INTERRUPT B
	MOV	R0,(R1)+	;STORE PS FOR INTERRUPT B
	MOV	(SP)+,R0	;RESTORE LCB POINTER IN R0
	CLC			;CLEAR C TO FLAG SUCCESS
	RTS	PC		; AND RETURN.
;
;
; HERE IF WE RUN OUT OF STORAGE GETTING A TCB.
;
DLENLO:	MOV	(SP),R4		;GET LCB POINTER
	JSR	PC,DLRTCB	;RELEASE ALL STORAGE FOR TCB AND LCB
	MOV	(SP)+,R0	;GET LCB POINTER
	SEC			;SET C AS A FLAG
	RTS	PC		; AND RETURN.
;
;
; THIS SUBROUTINE SETS A FLAG TO INDICATE WHETHER THE DEVICE
; IS DOING INPUT OR OUTPUT. FLAG IS USED BY XLATE TASKS.
;
DLSIOM:	MOV	R4,R1		;PRESERVE R4
	BIT	#LF.SIM,LB.FGS(R4) ;SIMULATE MODE?
	BEQ	11$		;NO, MUST BE SUPPORT
	ADD	#2,R1		;DEVICE 1 IS CONSOLE INPUT TO IBM
	MOV	LB.TCD(R1),R0	;GET XLATE TCB PTR
	BIS	#TCIOM,TCFG1(R0) ;MARK AS INPUT DEVICE
	JSR	PC,DLFRBF	;DONT NEED BUFFER FOR INPUT
	ADD	#2,R1		;BYPASS CONSOLE OUT
11$:	ADD	#4,R1		;FOR CONSOLE INPUT (SUP), LPT (SIM)
	MOV	LB.TCD(R1),R0	;GET XLATE TCB PTR
	BIS	#TCIOM,TCFG1(R0) ;FLAG INPUT DEVICE
	JSR	PC,DLFRBF	;FREE THE LINE BUFFER
	ADD	#2,R1		;FOR PUNCH DEVICE
	MOV	LB.TCD(R1),R0	;GET PTR TO XLATE TCB
	BIS	#TCIOM,TCFG1(R0) ;FLAG AS INPUT DEVICE
	JSR	PC,DLFRBF	;FREE THE INPUT LINE BUFFER
	RTS	PC		;AND RETURN
;








; THIS SUBROUTINE FREES THE LINE BUFFER STORAGE AND 
; CLEARS THE POINTER IN THE XLATE TCB'S.
;
DLFRBF:	MOV	R0,-(SP)	;SAVE R0
	MOV 	TCBFP(R0),R0	;GET BUFFER POINTER
	BEQ	11$		;ITS ALREADY FREED
	JSR	PC,FRESTG	;FREE THE STORAGE
11$:	MOV	(SP)+,R0	;RESTORE R0
	CLR	TCBFP(R0)	;CLEAR POINTER IN TCB
	RTS	PC		;RETURN
;
;
; SUBROUTINE TO RELEASE BSC AND XLATE TCBS
; NEEDS LCB POINTER IN R4 ON ENTRY
; R4 IS PRESERVED, R0, R2 ARE DESTROYED
;
DLRTCB:	MOV	LB.TC1(R4),R0	;GET PTR TO BSC TASK
	BEQ	DLXTCB		;NO BSC, LOOK FOR XLATE TCB'S
	MOV	TCBP1,R3	;R3 MUST POINT TO START OF CHAIN
	JSR	PC,DLRLTC	;RELEASE TCB AND UNLINK FROM CHAIN
	MOV	R3,TCBP1	;UPDATE START OF CHAIN OF TCBS
	CLR	LB.TC1(R4)	;CLEAR BSC TCB POINTER
DLXTCB:	MOV	LB.NTC(R4),R2	;GET # OF TCBS FOR XLATE
	BEQ	16$		;JUST IN CASE ITS ZERO
	CMP	#1,R2		;2780/3780 MODE
	BNE	11$		;NO.
	CLR	R1		;FOR 2780/3780 MODE
	BR	12$		;BYPASS HASP DEVICE LOGIC
11$:	MOV	R2,R1		;START WITH HIGHEST DEVICE #
	ASL	R1		;DEVICE # MUTLIPLIED BY 2
12$:	ADD	R4,R1		;GET TCB PTR TO DEVICE'S
	MOV	LB.TCD(R1),R0	;XLATE TASK
	BEQ	15$		;NONE FOR THIS, CHECK NEXT DEVICE
	JSR	PC,DLFRBF	;RELAESE LINE BUFFER
	MOV	R0,-(SP)	;SAVE XLATE TCB PTR
	MOV	TCSBF(R0),R0	;ANY COMPRESSED BUFFER TO RELEASE?
	BEQ	14$		;NO.
	JSR	PC,FRESTG	;YES, RELEASE IT
14$:	MOV	(SP)+,R0	;RESTORE XLATE PTR
	CLR	LB.TCD(R1)	;CLEAR POINTER TO TCB
	MOV	TCBP3,R3	;POINT TO START OF TCB CHAIN
	JSR	PC,DLRLTC	;RELEASE AND UNLINK TCB FOR XLATE
	MOV	R3,TCBP3	;UPDATE POINTER TO START OF TCB CHAIN
15$:	SOB	R2,11$		;DO FOR ALL DEVICE XLATE TCB'S
	CLR	LB.TCD(R4)	;CLEAR ANY PREV XLATE POINTER
;
16$:	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
;
;
; THIS SUBROUTINE FREES THE TCB WHOSE ADDRESS IS IN R0 AND
; UNLINKS THE TCB FROM THE CHAIN WHOSE START IS POINTED TO 
; BY R3. R3 IS RETURNED WITH UPDATED POINTER TO START OF CHAIN.
; R1 IS DESTROYED BY THIS ROUTINE. R0 AND R2 ARE PRESERVED.
;
DLRLTC:	MOV	R2,-(SP)	;SAVE R2
	CMP	R3,R0		;IS IT FIRST TCB OF CHAIN?
	BNE	13$		;NO, HUNT THRU THE CHAIN
	MOV	TCHAIN(R0),R3	;YES, UPDATE POINTER TO START OF CHAIN
11$:	JSR	PC,FRETCB	;FREE THE TCB
12$:	MOV	(SP)+,R2	;RESTORE R2
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
13$:	MOV	R3,R1		;MAKE FIRST TCB THE PREVIOUS ONE
14$:	MOV	TCHAIN(R1),R2	;POINT TO NEXT TCB IN CHAIN
	BEQ	16$		;TCB MISSING FROM QUE
	CMP	R0,R2		;MATCH OUR TCB?
	BEQ	15$		;YES.
	MOV	R2,R1		;MAKE CURRENT THE PREV ONE
	BR	14$		;HUNT TILL MATCH
;
15$:	MOV	TCHAIN(R2),TCHAIN(R1) ;UNLINK TCB FROM CHAIN
	BR	11$		;FREE THE TCB AND EXIT
;
; HERE IF TCB IS FOUND MISSING FROM THE QUE
;
16$:	STOPCD	DTM		;TCB MISSING
;
;
; SUBROUTINE TO DO LINE COMMAND 02: SET DTR
;
DLTL02:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB
	BEQ	11$		;SHOULD BE THERE
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO.  CAN'T SET DTR.
	JSR	PC,DQDTR1	;SET DATA TERMINAL READY
	CLC			;NOT FATAL ERROR
	RTS	PC		;RETURN.
;
; HERE IF NO LCB OR NOT ENABLED
;
11$:	;SEC			;INDICATE FATAL ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 03: CLEAR DTR
;
DLTL03:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB
	BEQ	11$		;SHOULD BE THERE
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, CAN'T CLEAR DTR.
	JSR	PC,DQDTR0	;CLEAR DATA TERMINAL READY [1(665)]
	CLC			;NOT FATAL ERROR
	RTS	PC		;RETURN.
;
; HERE IF NO LCB OR NOT ENABLED.
;
11$:	;SEC			;INDICATE FATAL ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 04: DISABLE
;
DLTL04:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	MOV	R1, -(SP)	;;++BS-SAVE R1
	MOVB	NDQ11S, R1	;;++BS-GET NUMBER OF DQ11S
	DEC	R1		;;++BS-CONVERT TO LINE NUMBER
	CMPB	R1, R0		;;++BS-EXCEED MAX NUMBER ?
	BLT	11$		;;++BS-YES, IGNORE
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB POINTER
	BEQ	11$		;DOESN'T MATTER IF NOT THERE
;	BIC	#LS.ENB,(R0)	;THERE, DISABLE IT.
;	MOV	R0,R4		;POINT R4 TO LCB
;	JSR	PC,DLRTCB	;RELEASE BSC AND XLATE TCB'S
	BIT	#LS.ENB,(R0)	;WAS LINE ENABLED?
	BEQ	11$		;NO.
	BIC	#LS.ENB,(R0)	;THERE, DISABLE IT.
11$:	MOV	(SP)+, R1	;;++BS-RESTORE R1
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO DO LINE COMMAND 05: SET CTS DELAY
;
DLTL05:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB POINTER
	BEQ	11$		;SHOULD BE THERE
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, CAN'T SET CTS DELAY
	JSR	PC,DLGBYT	;GET LOW BITS OF CTS DELAY
	BCS	11$		;NOT SPECIFIED
	MOVB	R1,LB.CSD(R0)	;STORE LOW BITS
	JSR	PC,DLGBYT	;GET HIGH BITS
	BCS	11$		;NOT SPECIFIED
	MOVB	R1,LB.CSD+1(R0)	;STORE HIGH BITS
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN.
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT IS
;  NOT COMPLETELY SPECIFIED.
;
11$:	;SEC			;INDICATE ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 06: SET LENGTH OF SILO WARNING AREA
;  (THIS IS ONLY EFFECTIVE IF THE LINE DRIVER INCLUDES A KMC11)
;
DLTL06:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB POINTER
	BEQ	11$		;NONE, ERROR.
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, ERROR.
	JSR	PC,DLGBYT	;GET LOW BITS OF LENGTH OF SILO WARNING AREA
	BCS	11$		;NOT SPECIFIED, ERROR.
	MOVB	R1,LB.MDS(R0)	;STORE LOW BITS
	JSR	PC,DLGBYT	;GET HIGH BITS
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,LB.MDS+1(R0)	;STORE HIGH BITS
	CLR	LB.MDU(R0)	;CLEAR MAX DEPTH USED
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN.
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
;  IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:	;SEC			;FLAG AN ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;
;
;
; SUBROUTINE TO DO LINE COMMAND 07: SET OUTPUT IN TRANSPARENCY
; THIS APPLIES ONLY TO HASP-MULTILEAVING LINES
;
DLTL07:	MOVB	DT11AD+1(R5),R0 ;GET THE LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB POINTER
	BEQ	11$		;NONE, ERROR.
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, ERROR.
	BIS	#LF.TSP,LB.FGS(R0) ;SET FLAG IN LINE CONTROL BLOCK
	MOV	LB.TC1(R0),R1	;GET POINTER TO BSC TCB
	BIS	#TCTSP,TCFG1(R1) ;SET TRASPARENT FLAG FOR BSC
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
;  IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:	;SEC			;FLAG AN ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 08: SET OUTPUT IN NON-TRANSPARENCY
; THIS APPLIES ONLY TO HASP-MULTILEAVING LINES
;
DLTL08:	MOVB	DT11AD+1(R5),R0 ;GET THE LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB POINTER
	BEQ	11$		;NONE, ERROR.
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, ERROR.
	BIC	#LF.TSP,LB.FGS(R0) ;SET FLAG IN LINE CONTROL BLOCK
	MOV	LB.TC1(R0),R1	;POINT TO BSC TCB
	BIC	#TCTSP,TCFG1(R1) ;CLEAR TRANSPARENCY FOR BSC TO LOOK AT
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
;  IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:	;SEC			;FLAG AN ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;

;
; SUBROUTINE TO SET TRANSMISSION BLOCK SIZE
;
DLTL09:	MOVB	DT11AD+1(R5),R0 ;GET THE LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;POINT TO THE LCB
	BEQ	11$		;NONE THERE, ERROR
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, ERROR
	JSR	PC,DLGBYT	;GET LOW ORDER BYTE OF BLOCK SIZE
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,LB.MBL(R0)	;STORE LOW BITS
	JSR	PC,DLGBYT	;GET HIGH ORDER BITS
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,LB.MBL+1(R0)	;STORE HIGH BITS
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
11$:	;SEC			;INDICATE FAILURE
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;AND RETURN
;
; SUBROUTINE TO SET RECORDS PER MESSAGE FOR TRANSMISSION BLOCK
;
DLTL10:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;POINT TO THE LCB
	BEQ	11$		;NONE THERE, ERROR
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, ERROR
	JSR	PC,DLGBYT	;GET LOW ORDER BYTE OF # OF RECORDS
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,LB.MLR(R0)	;STORE LOW BITS
	JSR	PC,DLGBYT	;GET HIGH ORDER BITS
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,LB.MLR+1(R0)	;STORE HIGH BITS
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
11$:	;SEC			;INDICATE FAILURE
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;AND RETURN

;
;
;
; SUBROUTINE TO SET LINE SIGNATURE (;;++BS-)


DLTL11:	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	ASL	R0		;LINE NUMBER * 2
	MOV	DQLCB(R0),R0	;GET LCB POINTER
	BEQ	11$		;NONE, ERROR.
	BIT	#LS.ENB,(R0)	;IS THE LINE ENABLED?
	BEQ	11$		;NO, ERROR.
	JSR	PC,DLGBYT	;GET LOW BITS OF LENGTH OF SILO WARNING AREA
	BCS	11$		;NOT SPECIFIED, ERROR.
	MOVB	R1,LB.SIG(R0)	;STORE LOW BITS
	JSR	PC,DLGBYT	;GET HIGH BITS
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,LB.SIG+1(R0)	;STORE HIGH BITS
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN.
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
;  IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:	;SEC			;FLAG AN ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST
	RTS	PC		;RETURN.
;
; EACH SUBROUTINE OF THE FORM DLTDXX WHERE XX IS A DECIMAL NUMBER
;  PERFORMS THE DEVICE COMMAND NUMBER XX.
;
; SUBROUTINE TO DO DEVICE COMMAND 01: SET CHARACTERISTICS
;
DLTD01:	JSR	PC,DLGBYT	;GET DEVICE TYPE
	BCS	11$		;NONE SPECIFIED
	MOV	TCXLT(R5),R0	;POINT TO XLATE TCB
	MOV	R1,TCDVT(R0)	;STORE DEVICE TYPE
	JMP	DLTDOK		;SUCCESS.
;
11$:	RTS	PC		;ERROR RETURN.
;
;THE SUBROUTINE HAS BEEN NO OPTED. THIS IS NOW A LINE COMMAND FUNCTION
; SUBROUTINE TO DO DEVICE COMMAND 02: SET MAX LOGICAL RECORDS PER BLOCK
;
;DLTD02:	JSR	PC,DLGBYT	;GET LOW BYTE OF NUMBER
;	BCS	11$		;NOT SPECIFIED, ERROR
;	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
;;	MOVB	R1,TCMLR(R0)	;STORE LOW BYTE OF NUMBER
;	MOV	R3, -(SP)	;SAVE R3
;	MOV	TCLCB(R5), R3	;GET LCB POINTER
;	MOVB	R1,LB.MLR(R3)	;STORE LOW BYTE OF NUMBER
;	MOV	(SP)+,R3	;RESTORE R3
;	JSR	PC,DLGBYT	;GET HIGH BYTE
;	BCS	11$		;NOT SPECIFIED, ERROR.
;;	MOVB	R1,TCMLR+1(R0)	;STORE LOW BYTE
;	MOV	R3, -(SP)	;SAVE R3
;	MOV	TCLCB(R5),R3	;GET LCB POINTER
;	MOVB	R1,LB.MLR+1(R3)	;STORE HIGH BYTE OF NUMBER
;	MOV	(SP)+,R3	;RESTORE R3
;	JMP	DLTDOK		;INDICATE SUCCESS
;
;11$:	RTS	PC		;ERROR RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 03: DUMP OUTPUT [1(627)]
;
DLTD03:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK [1(627)]
	BIS	#TCDMP,TCFG1(R0) ;SET "DUMP OUTPUT" [1(627)]
	JMP	DLTDOK		;INDICATE SUCCESS [1(627)]
;
; SUBROUTINE TO DO DEVICE COMMAND 04: CLEAR "INPUT PERMISSION WAS REQUESTED"
;
DLTD04:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK [2(770)]
	BIC	#TCIWR,TCFG2(R0) ;CLEAR "INPUT PERMISSION WAS REQUESTED" [2(770)]
	JMP	DLTDOK		;INDICATE SUCCESS [2(770)]
;
; NOTE THAT COMMAND 05 IS RESERVED.
;
; SUBROUTINE TO DO DEVICE COMMAND 06: SET "INTERPRET CC ON INPUT"
;
DLTD06:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCPRI,TCFG1(R0) ;SET "CC ON INPUT"
	JMP	DLTDOK		;INDICATE SUCCESS
;
;
; SUBROUTINE TO DO DEVICE COMMAND 07: NO INTERPRET CC ON INPUT
;
DLTD07:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCPRI,TCFG1(R0) ;CLEAR "CC ON INPUT"
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 08: INTERPRET CC ON OUTPUT
;
DLTD08:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCPRO,TCFG1(R0) ;SET "CC ON OUTPUT"
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 09: NO CC ON OUTPUT
;
DLTD09:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCPRO,TCFG1(R0) ;CLEAR "CC ON OUTPUT"
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 12: DO COMPONENT SELECTION
; THIS IS USED BY HASP-MULTILEAVING ONLY
;
DLTD12:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCCMP,TCFG1(R0) ;INDICATE "COMPONENT SELECTION"
	JSR	PC,DLGBYT	;GET COMPONENT CODE
	BCS	11$		;NONE SPECIFIED
	MOVB	R1,TCCTP(R0)	;STORE COMPONENT CODE
	JMP	DLTDOK		;INDICATE SUCCESS.
;
11$:	RTS	PC		;ERROR RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 13: NO COMPONENT SELECTION
;
DLTD13:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCCMP,TCFG1(R0) ;INDICATE NO COMPONENT SELECTION
	JMP	DLTDOK		;INDICATE SUCCESS
;
;
; SUBROUTINE TO DO DEVICE COMMAND 14: SET PRINTER PAGE COUNTER
;  (NOT YET COMPLETELY IMPLEMENTED IN XLATE)
;
DLTD14:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCPCE,TCFG1(R0) ;TURN ON PAGE COUNTER
	BIC	#TCPCO,TCFG1(R0) ; AND TURN OFF INTERRUPT FLAG
	JSR	PC,DLGBYT	;GET LOW BYTE OF PAGE COUNTER
	BCS	11$		;NOT SUPPLIED
	MOVB	R1,TCPGC(R0)	;STORE LOW BYTE OF PAGE COUNTER
	JSR	PC,DLGBYT	;GET HIGH BYTE OF PAGE COUNTER
	BCS	11$		;NOT SUPPLIED
	MOVB	R1,TCPGC+1(R0)	;STORE HIGH BYTE OF PAGE COUNTER
	JMP	DLTDOK		;INDICATE SUCCESS
;
11$:	RTS	PC		;ERROR RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 15: NO PRINTER PAGE COUNTING
;
DLTD15:	MOV	TCXLT(R5),R0	;GET POINTER TO XLATE TASK
	BIC	#TCPCE!TCPCO,TCFG1(R0) ;CLEAR PAGE COUNTER BITS
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 16: SET BLOCK SIZE
;
;THIS SUBROUTINE HAS BEEN NO OPTED 
;DLTD16:	JSR	PC,DLGBYT	;GET LOW BYTE OF SIZE
;	BCS	11$		;NONE SPECIFIED
;	MOV	TCXLT(R5),R0	;POINT TO XLATE TCB
;;	MOVB	R1,TCMBL(R0)	;STORE LOW BYTE OF MAX BLOCK LENGTH
;	MOV	R3, -(SP)	;SAVE R3
;	MOV	TCLCB(R5),R3	;GET LCB POINTER
;	MOVB	R1, LB.MBL(R3)	;STORE LOW BYTE OF MAX BLOCK LENGTH
;	MOV	(SP)+,R3	;RESTORE R3
;	JSR	PC,DLGBYT	;GET HIGH BYTE
;	BCS	11$		;NONE SPECIFIED
;;	MOVB	R1,TCMBL+1(R0)	;STORE HIGH BYTE
;	MOV	R3, -(SP)	;SAVE R3
;	MOV	TCLCB(R5),R3	;GET LCB POINTER
;	MOVB	R1,LB.MBL+1(R3)	;STORE HIGH BYTE OF MAX BLOCK LENGTH
;	MOV	(SP)+, R3	;RESTORE R3
;	JMP	DLTDOK		;INDICATE SUCCESS
;;
;11$:	RTS	PC		;ERROR RETURN.
;;
; SUBROUTINE TO DO DEVICE COMMAND 17: DO SPACE COMPRESSION
;
DLTD17:	MOV	TCXLT(R5),R0	;POINT R0 TO XLATE TASK
	BIS	#TCCPS,TCFG1(R0) ;INDICATE DO COMPRESSION
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 18: DON'T DO SPACE COMPRESSION
;
DLTD18:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCCPS,TCFG1(R0) ;INDICATE DONT DO COMPRESSION
	JMP	DLTDOK		;INDICATE SUCCESS
;
;
; SUBROUTINE TO DO DEVICE COMMAND 19: USE OLD BSC PROTOCOL
;
DLTD19:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCOBS,TCFG1(R0) ;INDICATE USE OLD BSC
;	MOV	TCLCB(R5),R0	;POINT TO LCB
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	MOV	LB.TC1(R0),R0	;POINT TO BSC TASK
	BIS	#TCOBS,TCFG1(R0) ;TELL BSC TASK TO USE OLD BSC
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 20: DONT USE OLD BSC
;
DLTD20:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCOBS,TCFG1(R0) ;NO OLD BSC PROTOCOL
;	MOV	TCLCB(R5),R0	;POINT TO LCB
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	MOV	LB.TC1(R0),R0	;POINT TO BSC TASK
	BIC	#TCOBS,TCFG1(R0) ;TELL BSC TASK NOT TO USE OLD BSC PROTOCOL
	JMP	DLTDOK		;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 21: REQUEST OUTPUT PERMISSION
;
DLTD21:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIT	#TCIPR,TCFG2(R0) ;INPUT PERMISSION REQUESTED?
	BNE	11$		;YES, THIS IS A NO-OP.
	BIS	#TCOPR,TCFG2(R0) ;NO, FLAG OUTPUT PERMISSION REQUESTED
;	MOV	TCLCB(R5),R0	;POINT TO LCB
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	CMP	#TTHASP,LB.DVT(R0) ;HASP LINE?
	bne	11$		;no
	MOV	LB.TC1(R0),R0	;POINT TO BSC TASK
	BIS	#TCOPR,TCFG2(R0) ;TELL BSC TASK THERE IS OUTPUT TO DO
11$:	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 22: GRANT INPUT PERMISSION
;
DLTD22:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIT	#TCIPR,TCFG2(R0) ;HAS INPUT PERMISSION BEEN REQUESTED?
	BEQ	11$		;NO, THIS IS A NO-OP.
	BIS	#TCIPG,TCFG2(R0) ;YES, FLAG INPUT PERMISSION GRANTED
11$:	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 23: SIGNAL OUTPUT EOF
;
DLTD23:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCOEF,TCFG2(R0) ;FLAG END-OF-FILE ON OUTPUT
	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 24: CLEAR OUTPUT EOF COMPLETE
;
DLTD24:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCOEF!TCOEC,TCFG2(R0) ;CLEAR OUTPUT EOF FLAGS
	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;
;
; SUBROUTINE TO DO DEVICE COMMAND 25: SIGNAL OUTPUT ABORT
;
;DLTD25:	MOV	TCLCB(R5),R0	;POINT TO LCB
;	MOV	LB.TC1(R0),R0	;POINT TO BSC TASK
DLTD25:	MOV	TCXLT(R5), R0	;;++BS-POINT TO XLATE TASK
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	CMP	#TTHASP,LB.DVT(R0) ;HASP LINE?
	BEQ	11$		;YES, INDICATE ABORT TO DEVICE
	MOV	LB.TC1(R0), R0	;;++BS-POINT TO BSC TASK
	BIS	#TCOAB,TCFG2(R0) ;SIGNAL ABORT TO BSC TASK
11$:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCOAB,TCFG2(R0) ;SIGNAL ABORT TO XLATE TASK
	JMP	DLTWOK		;AWAKEN XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 26: CLEAR OUTPUT ABORT COMPLETE
;
DLTD26:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCOAB!TCOAC,TCFG2(R0) ;CLEAR ABORT BITS
	JSR	PC, HCLAOA	;;++BS-CLEAR ACTIVE BIT 3(006)
	JMP	DLTWOK		;AWAKEN XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 27: CLEAR INPUT EOF COMPLETE
;
DLTD27:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCIEC,TCFG2(R0) ;CLEAR INPUT EOF COMPLETE
	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 28: SIGNAL INPUT ABORT
;
;DLTD28:	MOV	TCLCB(R5),R0	;POINT TO LCB
;	MOV	LB.TC1(R0),R0	;POINT TO BSC TASK
DLTD28:	MOV	TCXLT(R5), R0	;;++BS-POINT TO XLATE TASK
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	CMP	#TTHASP,LB.DVT(R0) ;HASP LINE?
	BEQ	11$		;YES, INDICATE ABORT TO DEVICE
	MOV	LB.TC1(R0), R0	;;++BS-POINT TO BSC TASK
	BIS	#TCIAB,TCFG2(R0) ;SIGNAL ABORT
11$:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIS	#TCIAB,TCFG2(R0) ;SIGNAL ABORT
	JSR	PC,DLDRAI	;DRAIN INPUT QUEUE
	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 29: CLEAR INPUT ABORT COMPLETE
;
DLTD29:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIC	#TCIAB!TCIAC,TCFG2(R0) ;CLEAR ABORT BITS
	JSR	PC, HCLAIA	;;++BS-CLEAR THE ACTIVE BIT 3(006)
	JSR	PC,DLDRAI	;BE SURE THE QUEUE IS DRAINED
	JMP	DLTWOK		;WAKE XLATE AND GIVE OK RETURN.
;




;
; SUBROUTINE TO DO DEVICE COMMAND 30: SUSPEND DEVICE
; HAS MEANING FOR HASP ONLY
;
DLTD30:	MOV	TCXLT(R5),R0	;GET XLATE TASK POINTER
	BIS	#TCDSP,TCFG2(R0) ;MARK DEVICE SUSPENDED
;	BIT	#TCIOM,TCFG1(R1) ;INPUT DEVICE?
	BIT	#TCIOM,TCFG1(R0) ;;++BS-INPUT DEVICE ?
	BEQ	11$		;NO, EXIT
	MOV	TCDEV(R0),R1	;GET DEV #
;	MOV	TCLCB(R5),R0	;POINT TO LCB
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	MOV	LB.TC1(R0),R0	;POINT TO BSC TCB
	ASL	R1		;DEV # * 2
	MOV	SUSTBL(R1),R1	;GET SUSPEND BIT FOR DEVICE
	BIC	R1,TCTFCS(R0)	;R0 STILL POINTS TO BSC
				;THIS INDICATION GOES TO REMOTE
11$:
	BR	DLTWOK		;ALWAYS OK RETURN
;
; THIS SUBROUTINE TO DO DEVICE COMMAND 31: UNSUSPEND DEVICE
;
DLTD31:	MOV	TCXLT(R5),R0	;POINT TO  DEVICE'S XLATE TCB
	BIC	#TCDSP,TCFG2(R0) ;MARK DEVICE UNSUSPENDED
;	BIT	#TCIOM,TCFG1(R1) ;INPUT DEVICE?
	BIT	#TCIOM,TCFG1(R0) ;;++BS-INPUT DEVICE ?
	BEQ	11$		;NO, EXIT
	MOV	TCDEV(R0),R1	;GET DEV #
;	MOV	TCLCB(R5),R0	;POINT TO LCB
	MOV	TCLCB(R0), R0	;;++BS-POINT TO LCB
	MOV	LB.TC1(R0),R0	;POINT TO BSC TCB
	ASL	R1		;DEV # * 2
	MOV	SUSTBL(R1),R1	;GET SUSPEND BIT FOR DEVICE
	BIS	R1,TCTFCS(R0)	;R0 STILL POINTS TO BSC
				;THIS INDICATION GOES TO REMOTE
11$:
	BR	DLTWOK		;ALWAYS SUCCESS
;
; SUBROTINE TO DO DEVICE COMMAND 32: SET DEVICE RECORD SIZE
;
DLTD32:	JSR	PC,DLGBYT	;GET LOW BYTE OF SIZE


	BCS	11$		;NOT SPECIFIED, ERROR
	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	MOVB	R1,TCRSZ(R0)	;STORE LOW BYTE OF SIZE
	JSR	PC,DLGBYT	;GET HIGH BYTE
	BCS	11$		;NOT SPECIFIED, ERROR
	MOVB	R1,TCRSZ+1(R0)	;STORE HIGH BYTE
	JMP	DLTDOK		;INDICATE SUCCESS
;
11$:	RTS	PC		;ERROR RETURN
;
;
; SUBROUTINE TO DRAIN THE INPUT QUEUE ON AN ABORT.
;
DLDRAI:
;11$:	MOV	TCLCB(R5),R4	;POINT TO LCB
11$:	MOV	TCXLT(R5), R4	;;++BS-POINT TO XLATE TASK
	MOV	TCLCB(R4), R4	;;++BS-POINT TO LCB
	MOV	LB.LNU(R4),R1	;GET LINE NUMBER
	CMP	#TTHASP,LB.DVT(R4) ;HASP LINE?
	BNE	12$		;NO, USE LINE NO AS I.D.
	SWAB	R1		;PUT LINE # IN LEFT BYTE
	ADD	TCCTP(R0),R1	;MAKE I.D. FOR HASP DEVICE
12$:	JSR	PC,DEQMID	;GET MESSAGE FROM THIS LINE
	BCS	13$		;NO MORE, ALL DONE.
	MOV	TCIDLE,R1	;POINT TO "IDLE" TASK
	JSR	PC,QUEMSG	;SEND IT THE MESSAGE
	BR	11$		;GET THE REST
;
; HERE WHEN THERE ARE NO MORE MESSAGES FROM THIS LINE
;
13$:	RTS	PC		;RETURN.
;
; HERE TO WAKE THE XLATE TASK AND GIVE OK RETURN.
;
DLTWOK:	MOV	TCXLT(R5),R0	;POINT TO XLATE TASK
	BIT	#EBINTR,(R0)	;WAITING FOR US?
	BEQ	DLTDOK		;NO.
	BIC	#EBINTR!EBWAIT,(R0) ;MAYBE, WAKE IT.
;
; HERE TO SUCCESSFULLY RETURN FROM A DEVICE COMMAND SUBROUTINE
;
DLTDOK:				;SUCCESS RETURN
	CLC			;NO FATAL ERROR
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO SEND THE CURRENT CHUNK TO THE XLATE TASK AND
;  OBTAIN A NEW ONE.
;
;  R0 POINTS TO THE OLD CHUNK, OR CONTAINS 0 IF THERE IS
;   NO OLD CHUNK.
;  TCXLT(R5) POINTS TO THE TRANSLATION TASK TO BE SENT THE CHUNK.
;
; ON RETURN:
;
;  C SET: OUTPUT ABORTED OR SHORT OF CHUNKS.
;  C CLEAR:
;
;	 R0 POINTS TO NEW CHUNK
;	 R3 POINTS TO DATA PORTION OF NEW CHUNK
;	 R1 DESTROYED
;
DLNWCK:	MOV	R2,-(SP)	;PRESERVE R2
	TST	R0		;ANY OLD CHUNK?
	BEQ	11$		;NO.
	MOV	TCXLT(R5),R1	;YES, POINT TO XLATE TASK
	JSR	PC,QUECHK	;SEND IT THE OLD CHUNK
11$:	MOV	TCXLT(R5),R1	;POINT TO XLATE TASK
	BIT	#TCOAB,TCFG2(R1) ;HAS BSC STREAM ABORTED?
	BNE	12$		;YES.
	CMP	CHFREC,#CHLTEN	;NO, HAVE WE ENOUGH FREE CHUNKS?
	BLE	12$		;NO.
	MOV	TCLCB(R1),R0	;YES, POINT TO LCB (R4 MAY BE IN USE)
	CMP	#TTHASP,LB.DVT(R0) ;HASP LINE?
	BNE	13$		;NO
	CMP	TCMSC(R1),#MSGXML ;ALREADY ENOUGH MESSAGES TO XMIT
	BGT	12$		;YES, WAIT BEFORE DOING ANY MORE
	BR	14$		;JOIN MAIN PATH
13$:	CMP	LB.MSC(R0),#MSGXML ;ALREADY ENOUGH MSGS TO XMIT?
	BGT	12$		;YES, WAIT BEFORE DOING ANY MORE.
14$:	CMP	TCXFR(R5),#DLWLMT ;HAVE WE PROCESSED ENOUGH BYTES?
	BGE	12$		;YES, WAIT UNTIL TRANSLATED.
	MOV	CHLST,R0	;NO, GET LAST CHUNK ON FREE LIST.
	JSR	PC,GETCHK	;GET ANOTHER CHUNK FOR PDP-10 DATA
	BCS	12$		;SHORT ON CHUNKS
;
; HERE WHEN WE HAVE GOTTEN THE CHUNK.
;
	MOV	R0,R3		;BUILD POINTER TO DATA SPACE
	ADD	#CHDAT,R3
	MOV	(SP)+,R2	;RESTORE R2
	CLC			;SIGNAL SUCCESS
	RTS	PC		;RETURN.
;
; HERE IF THE STREAM HAS BEEN ABORTED OR WE ARE SHORT OF CHUNKS.
;
12$:	MOV	(SP)+,R2	;RESTORE R2
	SEC			;SIGNAL FAILURE
	RTS	PC		;RETURN.
;
;
;SUBROUTINE TO SET UP A REJECT TO THE PDP-10
;
;
;

DLRJRQ:	MOVB	#3, DT10DF+1(R5) ;;++BS-INDICATE COMMAND REJECTED
	CLC			;;++BS-NOT A FATAL ERROR
	RTS	PC		;;++BS-RETURN
;
;
;
;
;;++BS-3(014) THIS SUBROUTINE CHECKS IF A DEVICE NUMBER IS LEGITIMATE
;;++BS-3(014) FOR THE MODE OF THE LINE. THE DEVICE NUMBER MUST BE ZERO
;;++BS-3(014) FOR 3780/2780. THE DEVICE NUMBER MUST BE BETWEEN ONE AND
;;++BS-3(014) FIVE, INCLUSIVE, FOR HASP. THIS ROUTINE ALSO SAVES THE
;;++BS-3(014) ADDRESS OF THE LAST CALL THAT HAD THE A DEVICE NUMBER.
;
;
; ON ENTRY:
;
;	R1 = DEVICE NUMBER
;
;	R4 = POINTER TO THE LINE CONTROL BLOCK
;
;
; ON RETURN:
;
;	C-BIT CLEAR IMPLIES DEVICE NUMBER OK FOR MODE
;
;	C-BIT SET IMPLIES DEVICE NUMBER ILLEGITIMATE FOR MODE
;
;

DLMCHK:

	BIC	#177770, R1		;EXTRACT THE DEVICE NUMBER
	BEQ	1$			;IF ZERO, BETTER BE 3780/2780

	BIT	#LF.SIM, LB.FGS(R4)	;ARE WE DOING SIMULATION ?
	BNE	4$			;YES, UP TO DEVICE # 5 ALLOWED

	CMP	R1, #4			;NO, SUPPORT, ONLY DEVICE # 4 ALLOWED
	BGT	2$			;ERROR, > THAN 4 FOR HASP SIMULATION
	BR	5$			;NOW MAKE SURE LINE IS IN HASP MODE

4$:	CMP	R1, #5			;GREATER THAN 5 ?
	BGT	2$			;YES, ERROR, NUMBER TO BIG FOR HASP
5$:	CMP	#TTHASP, LB.DVT(R4)	;NO, HASP MODE ?
	BNE	2$			;NO, ERROR, ITS 3780/2780
	BR	3$			;YES, DEVICE NUMBER IS GOOD

1$:	CMP	#TTHASP, LB.DVT(R4)	;HASP MODE ?
	BNE	3$			;NO, 3780/2780, ZERO IS GOOD

2$:	MOV	(SP), DLIMPC		;SAVE THE ADDRESS OF THE CALLER
	SEC				;TELL CALLER HE HAD A BAD DEVICE NUMBER
	RTS	PC			;RETURN TO CALLER

3$:	CLC				;TELL CALLER HIS DEVICE NUMBER IS GOOD
	RTS	PC			;RETURN TO CALLER


DLIMPC:	.WORD	0			;PC OF LAST CALL WITH BAD DEVICE NUMBER


;;++BS-3(014) END OF DLMCHK
;
;
;
;