Google
 

Trailing-Edge - PDP-10 Archives - BB-J845A-SM - source/hdmc20.p11
There are no other files named hdmc20.p11 in the archive.
.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	HDMC20 - DMC11 SYNCHRONOUS INTERFACE TO 2020

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;Revision history

; 3(001) 17-April-79	Make DMC buffering more efficient
; 3(002) 18-Apr-79	Move some DMC11 definitions to other modules
; 3(003) 23-Apr-79	Fix number of bytes send to 2020.
; 3(004) 23-Apr-79	Unsuspend device when less than 2 msgs queued for 2020
; 3(005) 23-Apr-79	Prevent enabling of a non-existent line
; 3(006) 3-MAY-79	Fix restart code for case that -10 goes away
; 3(007) 3-may-79	Add some error counters in DMC line block
; 3(010) 3-may-79	Increase wait time for data part of DN60 message
;			from 5 to 12 seconds
; 3(011) 7-MAY-79	Fix some bugs in restart code
; 3(012) 7-MAY-79	Change LB.ST1 to LB.STS for DMC lcb
; 3(013) 15-MAY-79	Add line command to set line signature
; 3(014) 27-JUNE-79	Include line flags in device status
; 3(015) 27-June-79	Do not clear activity bit on eof new input permission requested
; 3(016) 27-June-79	Clear device active bit when abort complete acked.
; 3(017) 27-June-79	Add second byte of line flags to line status
;			Add line signature to device status
; 3(020) 27-June-79	Give reject for device status on disabled line
; 3(021) 27-June-79	Reject device command on disabled line
; 3(022) 27-June-79	Reject write data command on disabled line
; 3(023) 27-June-79	Do not delete lcb to prevent kmc11 confusion
; 3(024) 27-June-79	Give rejects for incorrect device numbers hasp/3780/2780
; 3(025) 27-June-79	Clean up line block statistics when line is disabled
; 3(026) 4-Aug-79	Fix RDDATA to do right thing when short of chunks
;			Remove incorrrect register spec for LCB in DLTL01
; 3(027) 21-Sept-79	Fix places where carry not cleared on non-fatal errors.
; 3(030) 21-Sept-79	Remove redundant calls to DTCERR
; 3(031) 28-SEPT-79	Change MOV to ADD at DLGDTA + some.
; 3(032) 11-OCT-79	Make DMCTSK wait a real long time between header and
;			data before  assuming the world is dead

VDMC20=032			;FILE EDIT NUMBER
VEDIT=VEDIT+VDMC20

J=R4					;usually where line block held

.MACRO	JTRACE	ADDR
	MOV	ADDR,#0		;!!;**DEBUG**;!!;
.ENDM

.MACRO	TWIDDL
	INC	#0
.ENDM
;	DMC initialization routine


MC.INI:
	MOV	#DM.SIZ,R0		;SIZE OF LCB FOR THE DMC LINE
	JSR	PC,GETSTG		;GET THE STORAGE FOR THE LCB
	 BCS	99$			;FATAL, NO STORAGE
	MOV	R0,DMCLCB		;SAVE ADDRESS OF LCB
	MOV	R0,J			;HERE TOO
	MOV	DMCSR,LB.SLA(J)		;STORE CSR ADDRESS IN LCB
	MOV	DMCVEC,LB.SLV(J)	;STORE THE INTERRUPT VECTOR ADDRESS TOO
	MOV	DMCVEC,R1		;GET THE VECTOR ADDRESS
	MOV	#BR7,R0			;INTERRUPT LEVEL
	MOV	#MCVA0,(R1)+		;DMC INPUT INTERRUPT PC
	MOV	R0,(R1)+		;THE PS
	MOV	#MCVB0,(R1)+		;DMC OUTPUT INTERRUPT PC
	MOV	R0,(R1)			;THE PS
	MOV	#DMCIBF+DMCOBF,R3	;get number of buffers for this DMC11
	PIOFF				;prevent interrupts
10$:	MOV	CHLST,R0		;
	JSR	PC,GETCHK		;GET A CHUNK
	 BCS	99$			;FATAL
	MOV	#LB.FR,R2		;QUEUE WHERE TO PUT FREE DMC BUFFERS
	ADD	J,R2			;MAKE ABSOLUTE
	MOV	R0,R1			;Put where DMCQUE wants it
	JSR	PC,DMCQUE		;QUEUE TO LIST OF FREE BUFFERS
	SOB	R3,10$			;LOOP TIL ALL BUFFERS ASSIGNED
	PION
	BIC	#LS2DMC,LB.STS(J)	;clear all DMC11 bits
	MOV	#LB.IUC,R2		;displacement of start for zeroing
	ADD	J,R2			;make into address
	MOV	#<<LB.FR-LB.IUC>/2>,R1	;word count of section to zero
20$:					;loop to zero DMC11 specific part of line block
	CLR	(R2)+			;clear next word
	SOB	R1,20$			;till count exhausted
	MOV	#DMCBAS,LB.BAS(J)	;BASE ADDRESS FOR DMC
	RTS	PC
99$:
NOBUFS:
NOCHKS:
	STOPCD	DMA
MC.HDW:	BIS	#MC.MCL,@LB.SLA(J)	;MASTER CLEAR THE DMC
	CLR	LB.IUC(J)		;CLEAR BUFFER COUNT COUNTERS
	CLR	LB.OUC(J)		; ..
	MOV	LB.BAS(J),LB.POR(J)	;BASE TABLE FOR DMC
	CLR	LB.POR+2(J)		;clear RESUME bit
	MOV	#MC.BSI,R0		;BASE IN COMMAND
	JSR	PC,DMCIN		;...
	CLR	LB.POR(J)
	CLR	LB.POR+2(J)		;FULL DUPLEX
	MOV	#MC.CTI,R0		;CNTL I transaction
	JSR	PC,DMCIN		;START THE COMMAND
	BIS	#LS2INI,LB.STS(J)	;MARK DMC AS INITIALIZED
	RTS	PC

MCLDWN:					;HERE WHEN LINE TO 2020 GOES DOWN
	MOV	DMCLCB,J		;MAKE SURE THIS IS SET UP
	MOV	LB.OBF(J),R0		;FLUSH TRANSMIT MSG QUEUE
	BEQ	20$			;NONE, SO DONE
	MOV	CHNXT(R0),LB.OBF(J)	;POINT TO NEXT MSG IN QUEUE
	BNE	10$			;THERE IS MORE
	CLR	LB.OBF+2(J)		;ZERO END POINTER IF NO MORE
10$:
	MOV	TCIDLE,R1		;QUEUE TO IDLE TASK
	JSR	PC,QUECHK		;
	BR	MCLDWN			;LOOP UNTIL ALL DEQUE'D
20$:
	CLR	LB.OBF+4(J)		;message count must be zero
30$:
	MOV	#LB.IB,R2		;NOW FLUSH ALL RECEIVE BUFFERS
	ADD	J,R2			;MAKE ABSOLUTE
	JSR	PC,DMCDEQ		;REMOVE FROM QUEUE
	BCS	34$			;NO MORE
	trace	trcten,r1
	JSR	PC,DMCFRE		;PUT ON DMC FREE QUEUE
	DEC	LB.IUC(J)		;DECREMENT COUNT OF BUFFERS IN DMC
	BR	30$			;CONTINUE TIL ALL DEQUE'D
34$:
	MOV	#LB.IN,R2		;GET BUFFERS STILL IN DMC
	ADD	J,R2			;MAKE ABSOLUTE
	JSR	PC,DMCDEQ		;REMOVE FROM QUEUE
	BCS	35$			;NO MORE
	trace	trcten,r1
	JSR	PC,DMCFRE		;PUT ON DMC FREE QUEUE
	DEC	LB.IUC(J)		;DECREMENT COUNT OF BUFFERS IN DMC
	BR	34$			;CONTINUE TIL ALL DEQUE'D
35$:
	BIC	#LS2DMC,LB.STS(J)	;CLEAR ALL DMC BITS
	BIS	#MC.MCL,@LB.SLA(J)	;DO A MASTER RESET TO DMC
	CLC				;[3(027)]CLEAR ANY ERROR CONDITIONS
	RTS	PC			;RETURN
;Interrupt Level Code
MCVA0:	SAVE	<J>
	MOV	DMCLCB,J		;POINT TO 2020'S LINE BLOCK

DMCAIN:					;RDYI interrupt
	SAVE	<R0,R1>			;SAVE SOME REGISTERS
	MOV	LB.SLA(J),R0		;GET DMC HARDWARE ADDRESS
	TRACE	TRCDMC,<(R0)>
	TRACE	TRCDMC,<2(R0)>
	ADD	#4,R0			;POINT TO SEL4 REGISTER
	MOV	#LB.POR,R1		;ADDRESS OF DATA TO GIVE
	ADD	J,R1			;TO THE DMC
	TRACE	TRCDMC,<(R1)>
	TRACE	TRCDMC,<2(R1)>
	MOV	(R1)+,(R0)+		;COPY FIRST WORD INTO PORT
	MOV	(R1)+,(R0)+		;AND ALSO 2ND
	BIC	#MC.RQI,@LB.SLA(J)	;CLEAR REQUEST
	BIC	#LS2IBY,LB.STS(J)	;CLEAR SOFTWARE INTERLOCK
	RESTORE	<R1,R0,J>		;RESTORE REGISTERS
	RTI				;RETURN FOR INTERRUPT

MCVB0:	SAVE	<J>
	MOV	DMCLCB,J		;POINT TO 2020'S LINE BLOCK

DMCBIN:					;RDYO interrupt
	SAVE	<R0,R1,R2,R5>		;SAVE SOME REGISTERS
	MOV	LB.SLA(J),R0		;DMC11 CSR ADDRESS
	TRACE	TRCDMC,<(R0)>
	TRACE	TRCDMC,<2(R0)>
	TRACE	TRCDMC,<4(R0)>
	TRACE	TRCDMC,<6(R0)>
	TST	(R0)+			;POINT TO SEL2 REGISTER
	MOV	(R0)+,R1		;GET ITS CONTENTS
	BIT	#1,R1			;DID WE GET AN ERROR INTERRUPT?
	BNE	50$			;YES, GO HANDLE THAT CASE
	BIT	#MC.IOO,R1		;HAVE WE RECEIVED INPUT?
	BNE	20$			;YES

;"XMIT DONE" INTERRUPT

	MOV	(R0)+,R1		;GET BUFFER ADDRESS
	SUB	#CHDAT,R1		;POINT TO BEGINNING OF BUFFER
	TRACE	TRCDMC,R1
	JSR	PC,DMCFRE		;JUST THROW AWAY
	DEC	LB.OUC(J)		;ONE LESS DMC XMIT BUFFER OUTSTANDING
	CLR	LB.SE5(J)		;[3(11)]INDICATE WE'VE HEARD FROM 2020
	BR	40$			;FINISH UP

;"RECEIVED DATA" INTERRUPT

20$:
	CLR	LB.SE5(J)		;[3(11)]INDICATE WE'VE HEARD FROM 2020
	MOV	(R0)+,R1		;GET BUFFER ADDRESS
	SUB	#CHDAT,R1		;POINT TO BEGINNING OF BUFFER
	TRACE	TRCDMC,R1
	MOV	#LB.IN,R2		;POINT TO QUEUE OF BUFFERS IN DMC
	ADD	J,R2
	JSR	PC,DMCDEQ		;BUFFER NO LONGER IN DMC
	BCC	27$			;[3(027)]HAS TO WORK
	STOPCD	DMC			;[3(027)]OTHERWISE FATAL
27$:
	MOV	(R0)+,CHLEN(R1)		;DATA COUNT
	BIC	#40000,CHLEN(R1)
	CMP	CHLEN(R1),#MSGMAX	;MESSAGE TOO LONG?
	BLE	33$
	STOPCD	DMC			;FATAL
33$:
	MOV	TCDMDR,R5		;DMC TCB
	BIT	#EBINP,(R5)		;WAITING FOR INPUT?
	BEQ	25$			;NO
	BIC	#EBINP!EBWAIT,(R5)	;UNWAIT DMC TASK
25$:	MOV	#LB.IB,R2		;QUEUE TO INPUT QUEUE
	ADD	J,R2			;...
	JSR	PC,DMCQUE		;...
40$:	MOV	LB.SLA(J),R0		;HERE TO RETURN FROM INTERRUPT
	TST	(R0)+			;POINT TO SEL2
	BIC	#MC.RDO,@R0		;INDICATE WE ARE DONE WITH PORT
	RESTORE	<R5,R2,R1,R0,J>
	RTI
;
; HERE ON ERROR INTERRUPT
;
50$:
	INC	LB.SE1(J)		;INCREMENT # ERROR INTERRUPTS
	MOV	@R0,LB.SE2(J)		;SAVE SEL4 CSR FROM LAST INTERRUPT
	TST	(R0)+			;SKIP TO SEL6 REGISTER
	MOV	@R0,R2			;GET THE ERROR BITS
	MOV	R2,LB.SE3(J)		;SAVE SEL6 CSR FROM LAST INTERRUPT
	TRACE	TRCDMC,R2
	BIT	#MC.NXM!MC.ERR,R2	;FATAL?
	BEQ	60$			;NO
	STOPCD	DMC
60$:
	BIT	#MC.RMA,R2		;DID WE GET A MAINTENANCE MESSAGE?
	BNE	93$			;YES, TRY TO RESTART
77$:	BIT	#MC.RST,R2		;RECEIVED A START MESSAGE?
	BNE	93$			;YES, TRY TO RESTART
80$:	BIT	#MC.TMO,R2		;TIMEOUT?
	BEQ	90$			;NO
	DEC	LB.SE1(J)		;DON'T COUNT IN TOTAL ERROR STATISTICS
	TST	LB.OUC(J)		;ANY OUTSTANDING XMIT BUFFERS?
	BEQ	40$			;no, ignore it
	TST	LB.SE5(J)		;SECOND TIME-OUT IN A ROW?
	BEQ	85$			;NO. JUST COUNT IT FOR NOW
	BR	93$			;SECOND IN A ROW, LINE MUST BE DOWN
85$:	INC	LB.SE5(J)		;INCREMENT NUMBER OF TIMEOUTS
	BR	40$			;IGNORE UNLESS ANOTHER COMES
90$:					;check for buffer too small
	BIT	#MC.LOS,R2		;lost data?
	BEQ	40$			;if not, we are done
	STOPCD	DMC

93$:					;ATTEMPT TO RESTART
;!!;	BIS	#LS2RST,LB.STS(J)	;TELL HIGHER LEVEL LINE IS DOWN
	INC	LB.SE6(J)		;INCREMENT # RESTARTS
	BR	40$			;RETURN FROM INTERRUPT
;
; ONCE-A-TIME-UNIT ROUTINES
;
DSPDLS:
DSPDLT:
	RTS	PC


;;!!;;;;;
INITDL:
	STOPCD	DMC			;THIS CAN'T HAPPEN YET
;CALL FROM TRPINT TO RELOAD US.  NOT IMPLEMENTED
DLSTCS:
	RTS	PC
;
;	GETS A BUFFER FROM THE DMC, COPIES TO A CHUNK, AND GIVES CHUNK
;	ADDRESS TO CALLER IN R1

MC.INP:	
	MOV	#LB.IB,R2		;displacement of queue head
	ADD	J,R2			;make absolute
	JSR	PC,DMCDEQ		;get a DMC buffer(put address in R1)
	 BCS	20$			;but you promised there was one!
	TRACE	TRCTEN,R1 ;Trace the DMC buffer for the received data
	JTRACE	R1
10$:	RTS	PC			;return
20$:	STOPCD	DMC			;Tragic!

; THIS ROUTINE CHECKS THE QUEUE POINTER LB.OBF IN THE DMC LINE BLOCK FOR
; SOMETHING TO TRANSMIT. ANYTHING IN THIS QUEUE IS QUEUED UP TO THE DMC
; IMMEDIATELY FOR TRANSMISSION.

XMTCHK:
	MOV	LB.OBF(J),R0		;IS THERE ANYTHING TO TRANSMIT TO 2020?
	BEQ	30$			;NO, JUST RETURN
	CMP	LB.OUC(J),#DMCOBF	;ENOUGH QUEUED TO DMC?
	BLT	13$			;
	STOPCD	DMC			;THIS SHOULD NEVER HAPPEN
13$:					;THERE IS DATA FOR THE 2020
	PIOFF
	MOV	CHNXT(R0),LB.OBF(J)	;delink message
	BNE	20$			;if some more, branch
	CLR	LB.OBF+2(J)		;clear last pointer as well
20$:	DEC	LB.OBF+4(J)		;decrease count
	CLR	CHNXT(R0)
	PION
	MOV	R0,LB.POR(J)		;BUFFER ADDRESS FOR DMC
	ADD	#CHDAT,LB.POR(J)	;POINT TO DATA PART
	MOV	CHLEN(R0),LB.POR+2(J)	;DATA BYTE COUNT
	MOV	#MC.BCI,R0		;indicate BA/CC I
	JSR	PC,DMCIN		;do BA/CC I transaction
	INC	LB.OUC(J)		;INCREMENT NUMBER OF XMIT BUFFERS QUEUED
	BR	XMTCHK			;SEE IF MORE TO SEND
30$:	RTS	PC			;RETURN
DMCGIV:		
	CMP	LB.IUC(J),#DMCIBF	;DOES DMC HAVE ENOUGH BUFFERS?
	BGE	40$			;YES, DON'T GIVE ANY MORE
	JSR	PC,DMCGET		;GET A DMC BUFFER
	BCS	40$			;CANNOT, HOPE DMC HAS ENUF
	TRACE	TRCDMC,R1
	MOV	#LB.IN,R2		;REMEMBER THE BUFFERS WE GIVE TO THE
	ADD	J,R2			;DMC IN CASE WE NEED THEM BACK.
	JSR	PC,DMCQUE		;(E.G. DDCMP LINE RESTART)
	MOV	R1,LB.POR(J)		;ADDRESS OF BUFFER TO GIVE DMC
	ADD	#CHDAT,LB.POR(J)	;POINT DMC TO DATA PART
	MOV	#MSGMAX,LB.POR+2(J)	;LENGTH OF DMC BUFFER
	MOV	#MC.IOI!MC.BCI,R0	;DO A CONTROL IN COMMAND
	JSR	PC,DMCIN		;REQUEST THE DMC PORT
	INC	LB.IUC(J)		;INCREMENT NUMBER OF BUFFERS IN DMC
	BR	DMCGIV			;CAN WE GIVE MORE?
40$:	CLC				;[3(027)]CLEAR ERROR CONDITION
	RTS	PC
;Subroutines

.REPT 0

 The following subroutines assume that the link in the DMC11
buffer is the first word.  If this is not the case, the conditional
below will give an error.

  The standard register convention for these routines is:

R0	address of chunk chain containing message
R1	address of DMC11 buffer
R2	address of queue head and tail pointer entry in line block

.ENDR;.REPT 0


DMCFRE:					;free a DMC11 buffer
;Called with
;	R1	containing buffer address
;Returns
;	R2	pointing to Free queue
;	all other registers unchanged
	MOV	#LB.FR,R2		;displacement of free queue
	ADD	DMCLCB,R2			;make into address
;	BR	DMCQUE			;queue it up

;...Falls into DMCQUE

DMCQUE:				;routine to queue DMC11 buffer
;Called with
;	R2	pointing to queue
;	R1	containing address of DMC11 buffer
	TRACE	TRCDMC,R1
	TRACE	TRCDMC,R2
	SAVE	R2			;save queue address
	PIOFF
	CLR	(R1)			;ensure link is 0
	TST	@R2			;is anything already in queue?
	BNE	10$			;yes, must do it the hard way
	MOV	R1,(R2)+		;no, copy buffer address to head
	MOV	R1,(R2)+		;and tail
DMCRET=.
99$:	PION				;re-enable interrupts
	RESTORE	R2			;restore queue address
	TRACE	TRCDMC,R1
	RTS	PC			;return to caller
10$:					;here if something already on queue
	MOV	R1,@2(R2)		;make link of last buffer point to us
	MOV	R1,2(R2)		;and we are now last buffer
	BR	99$			;go exit
;THE DEQUEUE ROUTINE HAS TWO ENTRY POINTS.  DMCDEQ IS THE GENERAL ENTRY POINT
;AND IS USED TO DEQUEUE A BUFFER FROM THE FRONT OF AN ARBITRARY LIST.
;DMCDEQ IS CALL WITH:
;	R2/	ADDRESS OF THE QUEUE
;	   RETURN IS:
;	R1/	ADDRESS OF BUFFER FROM TOP OF QUEUE
;	CC	SUCCESS
;	CS	QUEUE WAS EMPTY
;ENTRY DMCGET IS SPECIALIZED ENTRY POINT AND IS USED TO DEQUEUE A BUFFER
;FROM THE DMC QUEUE OF FREE DMC BUFFERS AT LB.FR.  LIKE DMCDEQ	, THE ADDRESS
;OF RETURNED BUFFER IS IN R1.

DMCGET:
	SAVE	R2			;SAVE REGISTER
	MOV	#LB.FR,R2
	ADD	DMCLCB,R2		;FALL THRU
	BR	DMCDQ0			;JOINT NORMAL DEQUEUE CODE
DMCDEQ:
	SAVE	R2			;SAVE R2
DMCDQ0:	SEC				;ASSUME FAILURE
	TRACE	TRCDMC,<@R2>
	TRACE	TRCDMC,R2
	PIOFF
	MOV	@R2,R1			;GET NEXT ENTRY
	BEQ	DMCRET			;RETURN IF NONE
	BIC	#1,(SP)			;THERE IS ONE, CLEAR CARRY FOR RETURN
	MOV	@R1,(R2)+		;SET NEW HEAD OF QUEUE
	BNE	DMCRET			;EXIT UNLESS QUEUE NOW EMPTY
	CLR	@R2			;CLEAR TAIL IF SO
	BR	DMCRET			;RETURN

DMCIN:					;do an input transaction
;Called with
;	R0	containing request type and IN/OUT bit
;	LB.POR	containing data to be copied to DMC11 port
	BIS	#MC.RUN!MC.RQI!MC.IEI,R0;ensure that request and
					;interrupt enable are set
	TRACE	TRCDMC,<LB.POR(J)>
	SAVE	R0			;save request on stack
	MOV	LB.SLA(J),R0		;get hardware address
	BIS	#LS2IBY,LB.STS(J)	;indcate port in use
	MOV	(SP),(R0)+		;do request
					;when RDYI sets, it will cause
					;an interrupt; the code at
					;DMCAIN will copy data to port, and
					;clear request
	BIS	#MC.IEO,@R0		;also make sure RDYO interrupt enabled
20$:	TSTB	LB.STS(J)		;wait till done
	BMI	20$
	RESTORE	R0
	RTS	PC

; ROUTINES TO COPY DATA BETWEEN CHUNKS AND DMC DATA BUFFERS


DMCBTC:					;copy DMC11 buffer to chunks
					;if none, set carry, and requeue
					;buffer to head of old queue
;Called with
;	R1	buffer address
;	R2	queue
;Returns
;	R0	chunk address
;	C bit	set if not enough chunks, clear otherwise


	SAVE	<R1,R2,R3,R4,R5>	;we need a lot of registers
	MOV	CHLST,R0		;get a chunk
	JSR	PC,GETCHK		;to receive data
	 BCS	99$			;short on chunks
5$:
	MOV	CHLEN(R1),R5		;length of data in buffer
	trace trcspc,r5
	MOV	R5,CHLEN(R0)		;move to chunk
	INC	R5			;to convert to number of words
	ASR	R5			;divide by 2
	MOV	R1,R4			;buffer address
	ADD	#CHDAT,R4		;POINT TO FIRST DATUM
	MOV	R0,R1			;CHUNK ADDRESS
	ADD	#CHDAT,R1		;HERE TOO
25$:	MOV	(R4)+,(R1)+		;TRANSFER FROM DMC BUFFER TO CHUNK
	SOB	R5,25$			;LOOP TIL DONE
99$:	RESTORE	<R5,R4,R3,R2,R1>
	RTS	PC

DMCCTB:					;copy chunk to buffer
;Called with
;	R1	buffer address
;	R0	chunk address
;	CN.LEN(R0) must have length


	SAVE	<R2,R3,R4,R5>
	JTRACE	R0
	JTRACE	R1
	MOV	CHLEN(R0),R5
	MOV	R5,CHLEN(R1)		;MOVE COUNT TO BUFFER
	INC	R5
	ASR	R5			;make into word count
	JTRACE	R5
	MOV	R0,R2			;point to chunk
	ADD	#CHDAT,R2		;point to first datum
	MOV	R1,R3			;point to DMC11 buffer
	ADD	#CHDAT,R3		;point to first datum
21$:					;loop to copy one chunk
	MOV	(R2)+,(R3)+		;copy a word
	SOB	R5,21$			;for whole chunk
	RESTORE	<R5,R4,R3,R2>
	RTS	PC
;
.SBTTL	DMC20 TASK
;
; THIS TASK INTERFACES TO THE PDP-10 THROUGH THE DMC
;
DMCTSK:
	BCC	5$
	STOPCD	DMC		;SOMEONE FORGOT TO CLEAR CARRY
5$:	MOV	DMCLCB,J	;MAKE SURE THIS IS SET UP
	BIT	#LS2RST,LB.STS(J) ;HAS THE -10 GONE AWAY
	BNE	97$		;YES, GO TRY TO RESTART
	MOV	#EBINP!EBWAIT!EBTIME,(R5) ;WAIT CONDITIONS
	MOV	#<JIFSEC*74*10>,TCTIM(R5) ;WAIT MAXIMUM THIS LONG
	MOV	DMCLCB,J	;GET DMC'S LINE BLOCK
	BIT	#LS2INI,LB.STS(J) ;HAS THE DMC BEEN INITIALIZED YET?
	BNE	13$		;YES
	JSR	PC,MC.HDW	;NO, DO IT NOW
13$:	JSR	PC,DMCGIV	;CHECK IF DMC NEEDS INPUT BUFFERS
	TST	LB.IB(J)	;IS THERE INPUT?
	BEQ	30$		;NO, NO INPUT CURRENTLY
	JSR	PC,RDHDR	;GO READ IN THE HEADER BLOCK
	 BCS	97$		;FATAL ERROR
	TST	DT10AK		;IS THERE DATA FROM -20 TO FOLLOW?
	BEQ	25$		;NO
	MOV	DMCLCB,J	;RDHDR DESTROYS J ALIAS R4
	TST	LB.IB(J)	;IS THE ADDITIONAL DATA HERE YET?
	BNE	20$		;YES
	JSR	PC,WAIT		;WAIT
	MOV	DMCLCB,J	;BE SURE J IS SET UP CORRECTLY
	TST	LB.IB(J)	;ANYTHING NOW?
	BNE	20$		;YES,OKAY
	STOPCD	DMC		;IF IT TAKES THIS LONG, THE 2020 IS DEAD
				;FORCE A RELOAD
20$:	JSR	PC,RDDATA	;READ IN DATA PART FROM -20
	BCS	97$		;FATAL ERROR
25$:	MOV	DMCLCB,J	;RDDATA DESTROYS J ALIAS R4
	JSR	PC,DTSACK	;SEND BACK ACK AND/OR ANSWER
	 BCS	97$
30$:	JSR	PC,XMTCHK	;MAKE SURE ALL OUTPUT GETS OUT
	MOV	#JIFSEC,TCTIM(R5) ;WAIT MAXIMUM THIS LONG
	JSR	PC,WAIT		;WAIT A BIT BEFORE CHECKING AGAIN
	BR	DMCTSK		;LOOP
97$:
;
; HERE ON PDP-10 PROTOCOL ERROR.
;  ABORT ALL STREAMS AND DISABLE ALL LINES.
;
	BIT	#LS2RST,LB.STS(J) ;IS OTHER END DEAD?
	BEQ	21$		;NO, DON'T RE-INIT DMC
	JSR	PC,MCLDWN	;YES, RE-INIT THE DMC
21$:
	JSR	PC,DTCERR	;TRY TO ABORT ALL BSC LINES
	CLC			;[3(027)] RESUME WITH NO ERROR INDICATION
	BR	DMCTSK		; GO WAIT FOR ANOTHER COMMAND
;
;
; 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:	
	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
	TRACE	trcspc,<R1>
	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.
;
;
; 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:
	JSR	PC,DMCGET		;GET A DMC BUFFER FOR DN60 HEADER
	 BCS	90$			;SHOULD NEVER HAPPEN
	JTRACE	R1
	MOV	R1,R0			;SAVE BUFFER ADDRESS
	MOV	#6,CHLEN(R0)		;HEADER SIZE
	ADD	#CHDAT,R0		;POINT TO DATA PORTION
	MOVB	DT11DF(R5),DT10DF(R5)	;DN60 FCN CODE
	MOV	DT11AD(R5),DT10AD(R5)	;ADDRESS OF LINE #
	SWAB	DT10DF(R5)		;SWAP BYTES
	SWAB	DT10AD(R5)		;...
	SWAB	DT10DT(R5)		;...
	MOV	DT10DF(R5),(R0)+	;PUT DATA IN BUFFER
	MOV	DT10AD(R5),(R0)+	;...
	MOV	DT10DT(R5),(R0)		;...
	MOV	#LB.OBF,R2		;POINT TO OUTPUT QUEUE
	ADD	J,R2			;MAKE ABSOLUTE
	JSR	PC,DMCQUE		;QUEUE HEADER TO DMC LCB
	JTRACE	<TCXFR(R5)>
	MOV	DTXADR(R5),R1		;ANY ADDITIONAL DATA?
	BEQ	10$			;NO
	MOV	TCXFR(R5),R0		;GET ITS LENGTH
	BNE	5$			;BETTER NOT BE ZERO!
	STOPCD	DMC
5$:	MOV	R0,CHLEN(R1)		;MAKE SURE IN CHUNK
	JTRACE	R1
	JSR	PC,DMCQUE		;QUEUE THAT TOO
10$:	RTS	PC
90$:	JSR	P,NOBUFS
; ROUTINE TO READ IN THE HEADER BLOCK. IT IS ASSUMED THAT A CHECK HAS
; ALREADY BEEN MADE TO BE SURE THAT INPUT EXISTS.


RDHDR:
	JSR	PC,MC.INP	;GET A CHUNK OF DATA FROM THE DMC
	TRACE	TRCTEN,r1
	MOV	R1,R0		;MAKE COPY OF CHUNK POINTER
	CMP	#6,CHLEN(R0)	;HEADER LENGTH IS 6
	BEQ	10$		;LENGTH OK
	STOPCD	DMC			;BAD HEADER LENGTH
10$:	ADD	#CHDAT,R0	;POINT TO THE DATA PART
	MOV	(R0)+,DT11DF(R5)	;PUT HEADER DATA
	MOV	(R0)+,DT11AD(R5)	;WHERE OTHERS LIKE TO
	MOV	(R0)+,DT11DT(R5)	;HAVE IT
	trace	trcten,r1
	JSR	PC,DMCFRE		;FREE THE DMC BUFFER (ADDRESS IN R1)
	DEC	LB.IUC(J)		;DECREMENT # BUFFERS IN DMC
;
	SWAB	DT11DF(R5)	;SWAP BYTES
	SWAB	DT11AD(R5)
	SWAB	DT11DT(R5)
	CLR	DT10AK		;CLEAR "EXPECTING MORE DATA" FLAG
	CLR	TCXFR(R5)	;CLEAR BYTE COUNT FOR TO-TEN STATUS BUFFER
	CLR	DTXADR(R5)	;CLEAR ADDRESS OF ADDITIONAL DATA
	CLR	DT11GW(R5)	;CLEAR SHORT OF CHUNK FLAG
	MOV	DT11DT(R5),DLMBCT(R5)	;INITIALIZE MESSAGE BYTE COUNT
	MOV	DT11DT(R5),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
;[3(030)] TWO LINES REMOVED FROM HERE...ERRORS HANDLED ON RETURN TO MAIN LOOP
	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
;
;
RDDATA:
	JSR	PC,MC.INP	;GET FIRST BUFFER OF DATA FROM DMC
	TRACE	TRCTEN,R1
	MOV	R1,DT11Q(R5)	;PUT IT WHERE MOST EXPECT IT TO BE
	TST	DT11GW(R5)	;OPERATION DELAYED OR REJECTED??
	BNE	21$		;[3(026)]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
;
;[3(030)] REMOVE ONE LINE HERE...ERRORS HANDLED ON RETURN TO MAIN LOOP
15$:	RTS	PC		;RETURN
;
;
; HERE IT HAS TO BE A PLAIN SIMPLE WRITE TO - ELEVEN DATA
;
16$:	JSR	PC,DLTEDN	;SETUP CHUNKS TO RECEIVE DATAIN
	TST	DT11GW(R5)	;SHORT OF CHUNKS??
	BNE	21$		;YES
	TRACE	TRCTEN,R0
	JTRACE	R0
	TST	R0		;ANYTHING LEFT TO TRANSFER?
	BEQ	18$		;NOTHING LEFT TO XFER
17$:	JSR	PC,MC.INP	;MORE TO RECEIVE, GET NEXT MSG CHUNK
	MOV	R1,DT11Q(R5)	;PUT WHERE IT SHOULD BE
	BR	16$
;
; 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$:	MOV	DLMBCT(R5),DT10DT(R5)	;TELL -10/20 NUMBER OF BYTES WE GOT
	TRACE	TRCTEN,<DT10DT(R5)>
	MOV	DT11Q(R5),R1	;IS THERE A DMC BUFFER TO RELEASE?
	BEQ	20$		;NO
	MOV	DMCLCB,J	;MAKE SURE J SET UP CORRECTLY
	trace	trcten,r1
	JSR	PC,DMCFRE	;RELEASE THE DMC BUFFER
	DEC	LB.IUC(J)	;DECREMENT # BUFFERS QUEUE TO DMC
20$:	CLC			;SIGNAL SUCCESS
	RTS	PC		;RETURN.
21$:	SUB	DLMCTL(R5),DLMBCT(R5) ;ACTUALLY TRANSFERRED
	MOV	DT11Q(R5),R1	;CHUNK ADDRESS
	CLR	DT11Q(R5)	;MAKE SURE CLEAR
22$:
	TRACE	TRCTEN,<DLMBCT(R5)>
	SUB	CHLEN(R1),DLMCTL(R5) ;DECREMENT # TO TRANSFER
	MOV	DMCLCB,J	;MAKE SURE J SET UP CORRECTLY
	trace	trcten,r1
	JSR	PC,DMCFRE	;FREE UP THE DMC BUFFER
	DEC	LB.IUC(J)	;DECREMENT # OF INPUT BUFFERS TIED UP
	TST	DLMCTL(R5)	;ANY MORE TO TRANSER?
	BEQ	19$		;NO
	TST	LB.IB(J)	;CHECK FOR REST
	BEQ	14$		;SHOULD BE SOMETHING THERE
	JSR	PC,MC.INP	;GET NEXT CHUNK
	BR	22$		;YES, CONTINUE TO FLUSH
	

; 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:	JSR	PC,DLNWCK	;CHECK ABNORMAL CONDITIONS
	BCS	16$		;THERE IS ONE
	MOV	DT11Q(R5),R1	;GET BACK POINTER TO CHUNK
	JSR	PC,DMCBTC	;MOVE DATA FROM BUFFER TO CHUNKS
	 BCS	15$		;NOT ENOUGH CHUNKS
	MOV	DMCLCB,J	;SET UP J
	trace	trcten,r1
	JSR	PC,DMCFRE	;FREE UP THE BUFFER
	DEC	LB.IUC(J)	;DECREMENT COUNT
	CLR	DT11Q(R5)	;INDICATE BUFFER NO LONGER TO BE FREED
	SUB	CHLEN(R0),DLMCTL(R5) ;DECREMENT # BYTES LEFT TO XFER
;
; IF THE COUNT IS -VE OR ZERO, THEN APPEND THE LAST CHUNK DONE 
;  TO THE MESSAGE FOR XLATE TASK
;
	TRACE	TRCTEN,<DLMCTL(R5)>
	MOV	TCXLT(R5),R1	;POINT TO THE XLATE TASK
	JSR	PC,QUECHK	;SEND IT THE CHUNK
	MOV	DLMCTL(R5),R0	;ANYTHING LEFT TO XFER?
	BGT	11$		;YES
	CLR	R0		;NO,INDICATE NOTHING LEFT TO XFER
11$:	TRACE	TRCTEN,R0
	CLC
	RTS	PC		;RETURN
15$:	TWIDDL
16$:
	TWIDDL
	MOV	TCXLT(R5),R1	;POINT TO XLATE TASK
	BIT	#TCOAB,TCFG2(R1) ;ABORT OR DELAY?
	BEQ	DLSDLY		;JUST DELAYED
;
DLSERR:	trace	trcspc,r5
	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:	trace	trcspc,r5
	MOVB	#2,DT10DF+1(R5)	;OPERATION DELAYED
	MOV	#-1,DT11GW(R5)	;FLAG OPERATION DELAYED
	CLC			;NOT A FATAL ERROR
	RTS	PC		;RETURN
;
; 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
;
;
; 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(023)	BEQ	13$		;ERROR, BSC TCB MISSING
	BEQ	12$		;;++BS-BSC TCB ALREADY DELETED 3(023)
	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(023)
;3(023)	MOV	R4,R0		;POINT TO LCB
;3(023)	JSR	PC,FRESTG	;FREE THE LCB ALSO
	MOV	(SP)+,R1	;GET BACK THE LINE # * 2
;3(023)	CLR	DQLCB(R1)	;CLEAR LCB POINTER

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

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(023) 13$:	STOPCD	DTM		;TCB MISSING
;
;
; 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
	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:
	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
	JSR	PC,DMCGET	;GET A DMC BUFFER TO GO TO 2020
	 BCS	90$		;NONE, SHOULD NEVER HAPPEN
	MOV	R1,R2		;SAVE BUFFER ADDRESS
	MOV	R2,DTXADR(R5)	;ADR OF INDIRECT DATA SET
	MOV	DT11DT(R5),CHLEN(R1) ;STORE LENGTH IN CHUNK
	ADD	#CHDAT,R2	;POINT TO DATA PART
	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
9$:	RTS	PC		;RETURN
90$:	JSR	PC,NOBUFS
;
; 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:
	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(024).IF NE,DEBUG
;3(024)	BNE	10$		;TO TRACK -10 SCREW UPS
;3(024)	CMP	#TTHASP,LB.DVT(R4) ;CHECK DEV FOR HASP
;3(024)	BNE	10$		;
;3(024)	STOPCD	TER		;TEN ERROR
;3(024) 10$:
;3(024).ENDC ;.IF NE,DEBUG

	JSR	PC, DLMCHK	;;++BS- CHECK FOR LEGAL DEVICE NUMBER 3(024)
	BCS	23$		;;++BS- BAD DEVICE NUMBER, REJECT 3(024)
	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),R3 ;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$:
17$:	MOVB	#1,DT10DF+1(R5)	;SUCCESS CODE
	JSR	PC,DMCGET	;GET A DMC BUFFER FOR XMISSION TO 2020
	BCC	6$
	 JSR	PC,NOBUFS	;SHOULD ALWAYS HAVE A DMC BUFFER
6$:
	MOV	R1,R0		;SAVE BUFFER ADDRESS
	MOV	DT10DT(R5),R2	;[3(003)]GET AMOUNT TO XFER
	MOV	R2,CHLEN(R0)	;BYTE LENGTH FOR MSG TO 10/20
	MOV	R2,TCXFR(R5)	;PUT FOR DMC DRIVER
	ADD	#CHDAT,R0	;POINT TO DATA PART OF BUFFER
7$:	MOVB	(R3)+,(R0)+
	SOB	R2,7$		;TRANSFER DATA TO BUFFER
	MOV	R1,DTXADR(R5)	;REMEMBER WHERE DATA IS
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(015)
	BNE	36$		;;++BS- YES, CLEAR THE ACTIVE BIT 3(015)
	BIT	#TCIPR, TCFG2(R1) ;;++BS- INPUT PERMISSION REQUESTED ? 3(015)
	BNE 	18$		;;++BS- YES, DO NOT CLEAR THE ACTIVE BIT 3(015)
				;;++BS- NO, CLEAR THE ACTIVE BIT 3(015)

36$:				;;++BS-NEW LABEL 3(015)
	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:
	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(024).IF NE,DEBUG
;3(024)	BNE	10$		;
;3(024)	CMP	#TTHASP,LB.DVT(R4) ;CHECK FOR HASP
;3(024)	BNE	10$		;ONLY
;3(024)	STOPCD	TER		;TEN ERROR
;3(024) 10$:
;3(024).ENDC

	JSR	PC, DLMCHK	;;++BS- CHECK FOR LEGAL DEVICE NUMBER 3(024)
	BCS	14$		;;++BS- BAD DEVICE NUMBER, REJECT 3(024)
	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$:
	TWIDDL
	JMP	DLSDLY		;OPERATION DELAYED
;
14$:
	MOV	#-1,DT10AK	;;++BS-NOTE THAT WE EXPECT ED DATA 3(022)
	JMP	DLSERR		;;++BS-REJECT THE REQUEST 3(022)
;3(022)	SEC			;FATAL ERROR
;3(022)	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:	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(024).IF NE,DEBUG
;3(024)	BNE	10$		;TRACK 10 ERRORS
;3(024)	CMP	#TTHASP,LB.DVT(R4) ;CHECK HASP DEV #
;3(024)	BNE	10$		;ONLY
;3(024)	STOPCD	TER		;
;3(024) 10$:
;3(024).ENDC

	JSR	PC, DLMCHK	;;++BS-CHECK FOR LEGAL DEVICE NUMBER 3(024)
	BCS	13$		;;++BS-BAD DEVICE NUMBER, REJECT 3(024)
	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
	JSR	PC,DMCGET	;GET A DMC BUFFER TO SEND TO 2020
	BCC	5$
	JSR	PC,NOBUFS	;SHOULD ALWAYS BE A DMC BUFFER FREE
5$:
	MOV	R1,R2		;NEED ADDRESS HERE TOO
	MOV	R2,DTXADR(R5)	;SAVE IT FOR TO-TEN XFER
	ADD	#CHDAT,R2	;START OF DATA
	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(014)
	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(014)
	MOV	TCLCB(R5), R1	;;++BS-POINT TO LCB 3(014)
	MOV	LB.FGS(R1), R1	;;++BS-GET THE LINE FLAGS 3(014)
	JSR	PC, DLPWRD	;;++BS-SEND TO PDP-10 3(014)
	BCS	13$		;;++BS-ERROR, NO MORE ROOM 3(017)
	MOV	TCLCB(R5), R1	;;++BS-POINT TO LCB 3(017)
	MOV	LB.SIG(R1), R1	;;++BS-GET THE LINE SIGNATURE 3(017)
	JSR	PC, DLPWRD	;;++BS-SEND TO PDP-10 3(017)
	BCS	11$		;;++BS-SEND THE INDIRECT MESSAGE 3(014)
;
; CONTINUED ON NEXT PAGE
;
;
;
; HERE WHEN THE INDIRECT MESSAGE HAS BEEN BUILT.
;
11$:
	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(020)
	BIS	#B15, DT10FN(R5) ;;++BS-NO INDIRECT DATA 3(020)
;3(020)	SEC			;FATAL ERROR
	JSR	PC, DLRJRQ	;;++BS-REJECT THE REQUEST 3(020)
	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:
	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(024)
	MOVB	DT11AD(R5),R1	;GET RCB OR DEVICE #
	BIC	#177770,R1	;EXTRACT DEVICE # FROM RCB

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

	JSR	PC, DLMCHK	;;++BS-CHECK FOR LEGAL DEVICE NUMBER 3(024)
	BCS	12$		;;++BS-BAD DEVICE NUMBER, REJECT 3(024)
	ASL	R1		;DEVICE * 2
	ADD	R0,R1		;ADD DEVICE #
	MOV	LB.TCD(R1),TCXLT(R5) ;POINT TO XLATE TASK
13$:				;;++BS-NEW LABEL 3(021)
	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(021)
	BR	13$		;;++BS-REJECT HIS REQUEST ON ED DATA 3(021)
;3(021)	SEC			;FATAL ERROR
;3(021)	RTS	PC		;RETURN
;
DLTWD1:	MOV	DT11Q(R5),R2	;POINT TO WHERE STATUS IS
	ADD	#CHDAT,R2	;POINT TO DATA PART OF CHUNK
	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(021)
	BEQ	14$		;;++BS-NO, REJECT THE REQUEST 3(021)
				;;++BS-YES, CONTINUE 3(021)
	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(021)
	BR	11$		;;++BS-CONTINUE 3(021)
;
;
; 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:
	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
	JSR	PC,DMCGET	;GET A DMC BUFFER
	BCC	5$
	JSR	PC,NOBUFS	;CANNOT HAPPEN
5$:
	MOV	R1,R2		;NEED ADDRESS HERE TOO
	MOV	R2,DTXADR(R5)	;SAVE ADR OF INDIRECT DATA
	ADD	#CHDAT,R2	;START OF 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(017)	MOVB	LB.FGS(R0),R1	;GET LINE FLAGS
;3(017)	JSR	PC,DLPBYT	;STORE IN USER'S BUFFER
	MOV	LB.FGS(R0), R1	;;++BS-GET LINE FLAGS 3(017)
	JSR	PC, DLPWRD	;;++BS-SEND TO PDP-10 3(017)
	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(017)	CLR	R1		;SEND RESERVE BYTE ALSO [[RELEASE 4]]
;3(017)	JSR	PC,DLPBYT	;IN USERS BUFFER
;3(017)	BCS	14$		;ERROR IF NO ROOM
	MOV	TCLCB(R5),R0	;POINT R0 TO LCB
	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
	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:
	MOVB	DT11AD+1(R5),R0	;GET LINE NUMBER
	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
	ADD	#CHDAT,R2	;POINT TO DATA PART
	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
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:
	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
	ADD	#CHDAT,R2	;POINT TO DATA
	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(023)	BIT	#LF.DIP!LF.ABC,LB.FGS(R0) ;DISABLE IN PROGRESS?
	BIT	#LF.DIP, LB.FGS(R0) ;;++BS-DISABLE IN PROGRESS ? 3(023)
	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		;[3(026)]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	;[3(031)]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$:
	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$:
	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$:
	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$:
	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$:
	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$:
	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$:
	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$:
	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(R0),R0	;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(R0),R0	;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(R0),R0	;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	TCXLT(R5),R0	;POINT TO THE XLATE TASK
	MOV	TCLCB(R0),R0	;POINT TO LCB
	CMP	#TTHASP,LB.DVT(R0) ;HASP LINE?
	BEQ	11$		;YES, INDICATE ABORT TO DEVICE
	MOV	LB.TC1(R0),R0	;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(016)
	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	TCXLT(R5),R0	;POINT TO XLATE TASK
	MOV	TCLCB(R0),R0	;POINT TO LCB
	CMP	#TTHASP,LB.DVT(R0) ;HASP LINE?
	BEQ	11$		;YES, INDICATE ABORT TO DEVICE
	MOV	LB.TC1(R0),R0	;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(016)
	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(R0) ;INPUT DEVICE?
	BEQ	11$		;NO, EXIT
	MOV	TCDEV(R0),R1	;GET DEV #
	MOV	TCLCB(R0),R0	;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(R0) ;INPUT DEVICE?
	BEQ	11$		;NO, EXIT
	MOV	TCDEV(R0),R1	;GET DEV #
	MOV	TCLCB(R0),R0	;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	TCXLT(R5),R4	;POINT TO XLATE TASK
	MOV	TCLCB(R4),R4	;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.
;
;
;
; THIS ROUTINE REDEFINED TO CHECK FOR ABNORMAL CONDITIONS
;(E.G. CHECKS TO SEE IF RUNNING LOW ON CHUNKS OR IF STREAM HAS
;  ABORTED.  )

; INPUTS:
;   TCXLT(R5) POINTS TO THE TRANSLATION TASK
;
; ON RETURN:
;
;  C SET: OUTPUT ABORTED OR SHORT OF CHUNKS.
;  C CLEAR:
;
;	 R1 DESTROYED
;
DLNWCK:	MOV	TCXLT(R5),R1	;POINT TO XLATE TASK
	BIT	#TCOAB,TCFG2(R1) ;HAS BSC STREAM ABORTED?
	BNE	2$		;YES.
	CMP	CHFREC,#CHLTEN	;NO, HAVE WE ENOUGH FREE CHUNKS?
	BLE	3$		;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	4$		;YES, WAIT BEFORE DOING ANY MORE
	BR	14$		;JOIN MAIN PATH
13$:	CMP	LB.MSC(R0),#MSGXML ;ALREADY ENOUGH MSGS TO XMIT?
	BGT	5$		;YES, WAIT BEFORE DOING ANY MORE.
14$:	CMP	TCXFR(R5),#DLWLMT ;HAVE WE PROCESSED ENOUGH BYTES?
	BGE	6$		;YES, WAIT UNTIL TRANSLATED.
	CLC			;SIGNAL SUCCESS
	RTS	PC		;RETURN.
;
; HERE IF THE STREAM HAS BEEN ABORTED OR WE ARE SHORT OF CHUNKS.
;
2$:
	trace	trcspc,<tcfg2(r5)>
	TWIDDL
	BR	12$
3$:
	trace	trcspc,chfrec
	TWIDDL
	BR	12$
4$:
	trace	trcspc,<tcmsc(r1)>
	TWIDDL
	BR	12$
5$:
	trace	trcspc,<lb.msc(r0)>
	TWIDDL
	BR	12$
6$:
	trace	trcspc,<tcxfr(r5)>
	TWIDDL
12$:	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(024) THIS SUBROUTINE CHECKS IF A DEVICE NUMBER IS LEGITIMATE
;;++BS-3(024) FOR THE MODE OF THE LINE. THE DEVICE NUMBER MUST BE ZERO
;;++BS-3(024) FOR 3780/2780. THE DEVICE NUMBER MUST BE BETWEEN ONE AND
;;++BS-3(024) FIVE, INCLUSIVE, FOR HASP. THIS ROUTINE ALSO SAVES THE
;;++BS-3(024) 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(024) END OF DLMCHK
;
;
;
;