Google
 

Trailing-Edge - PDP-10 Archives - BB-J724A-SM_1980 - sources/hbsc.p11
There are 30 other files named hbsc.p11 in the archive. Click here to see a list.
.SBTTL	BSC DRIVER
;
; THIS SECTION CONTAINS THE BSC (OR BISYNC) AND HASP TASK.
;  THIS TASK USES THE DQ11 SUBROUTINES TO COMMUNICATE WITH
;  AN IBM-COMPATABLE BSC DEVICE, POINT-TO-POINT.
;  MANY ERROR AND STATISTICAL COUNTERS ARE KEPT.
;  COMMUNICATION WITH THE TRANSLATE TASK IS BY SENDING AND
;  RECEIVING MESSAGES, AND BY CHANGING AND OBSERVING STATUS
;  BITS IN THE TASK CONTROL BLOCK.
;
.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
;
;
;
;			REVISION HISTORY
;
; 3(001) BS	MODIFY (UN)/SUSPEND ROUTINES TO ALLOW CALLING FROM ANY TASK
;
; 3(002) BS	SUSPEND DEVICE IF MORE THAN 2 MESSAGES QUEUED TO IT
;
; 3(003) BS	CLEAR SYSTEM SUSPEND AFTER ACK RECEIVED FOR EMULATION
;
; 3(004) BS	UNSUSPEND DEVICE ONLY FIRST TIME INPUT PERMISSION IS GRANTED
;
; 3(005) BS	SEND NULL MESSAGE IF DEVICE STATUS CHANGED AND NO MESSAGES 
;
; 3(006) BS	SUSPEND DEVICE AFTER ONE MESSAGE IF FE SHORT ON CHUNKS
;
; 3(007) BS	INCREASE TIME TO SEE IF OTHER SIDE IS BIDDING
;
; 3(010) BS	SEND NULL MESSAGES ONLY AFTER LINE IS SIGNED ON
;
; 3(011) BS	REDUCE THE WAIT TIME BETWEEN SENDING MESSAGES WITH HASP
;
; 3(012) BS	TERMINATE TRANSMISSION IN 2780/3780 IF LINE IS DISABLED
;
;
;
;			REVISION HISTORY CONTINUED
;
;
; 3(013) BS	INDICATE COMMUNICATIONS ESTABLISHED IN  LINE FLAGS
;		SET H/W ABORT IF DSR GOES AWAY AFTER COMMUNICATION ESTABLISHED
;
; 3(014) BS	SET AND CLEAR CDR ACTIVE BIT FOR SIGNON
;
; 3(015) BS	SET H/W ABORT FOR HASP IF RX OR TX TIMES OUT OR ERROR
;
; 3(016) BS	SET H/W ABORT FOR 3780/2780 IF RX OR TX PROBLEM
;
; 3(017) BS	SET ALL DEVICE ACTIVE BITS FOR 2780/3780/HASP H/W ABORT
;
; 3(020) BS	SET DEVICE ACTIVE BIT FOR 3780/2780 DEVICE ABORT
;
; 3(021) BS	CLEAR DEVICE ACTIVE BIT FOR 3780/2780 ABORT ACK FROM PDP-10
;
; 3(022) BS	CLEAR DTR WHEN LINE IS DISABLED TO HANG UP LINE
;
;
;			REVISION HISTORY CONTINUED
;
;
; 3(023) BS	FREE SIGNON MESSAGE SENT TO BSC FROM XLHASP AFTER IT IS PUT IN
;		TRANSMISSION BLOCK
;
; 3(024) KR	If we receive input permission request from HASP while input
;		is already running, set new TCIRH bit to indicate input request
;		was held
;
; 4(025) BS	MODIFY CODE TO ACCEPT TRAILING BCB AND 2 FCS BYTES FROM IBM
;		IN LARGE MESSAGES.
;
; 4(026) BS	MODIFY CODE TO READ AND SEND TRANSPARENT MESSAGES CORRECTLY
;
; 4(027) BS	CORRECT FCS CODE TO TEST AND SET PUNCH STATUS CHANGE
;
; 4(030) BS	SEND NAK INSTEAD OF EOT TO REFUSE INPUT PERMISSION IN 3780 MODE
;
; 4(031) BS	ACCEPT SIGNON CONTROL RCB IN EMULATION TO HANDLE DISCONNECT
;		MESSAGE AND ROUTE MESSAGE TO CONSOLE
;
; 4(032) BS	ACCEPT TRANSMIT ABORT SCB IN HASP MODE AND TREAT AS END OF FILE
;
;
VHBSC=032
;
;
VEDIT=VEDIT+VHBSC
;
;
;
; HERE DEFINE SEPARATE DEBUG SWITCH FOR BSC
;
BSBUG=0
;
; ENTER HERE FROM THE DISPATCHER
;
DQDRVR:	MOV	TCLCB(R5),R4	;POINT R4 TO LCB

	BEQ	1$		;DOES NOT EXIST, EXIT
	BIT	#LS.ENB, (R4)	;IS THE LINE ENABLED ?
	BNE	2$		;YES, INITIALIZE

1$:				;NO, SET UP WAIT AND EXIT
	MOV	#EBTIME!EBWAIT, (R5) ;SET WAIT FLAG
	MOV	#20,TCTIM(R5)	;WAIT FOR A WHILE
	JSR	PC, WAIT	;GO TO SLEEP
	BR	DQDRVR		;CHECK AGAIN

2$:

	JSR	PC,DQINIT	;INITIALIZE THE DQ11
;
; HERE TO BE IN BSC "CONTROL" MODE.
;  WAIT FOR THE LINE TO BE ENABLED AND FOR DATA SET READY.  THEN,
;  IF "OUTPUT PERMISSION REQUESTED" IS SET, BID FOR THE LINE.
;  OTHERWISE JUST LISTEN FOR A BID.  IF A BID ARRIVES WE MUST
;  GET PERMISSION FROM THE PDP-10 BEFORE REPLYING "ACK-0".
;
DQBCTL:	BIC	#TCEOT,TCST2(R5) ;NEW ABORTS WILL NEED EOT AGAIN
	MOV	TCLCB(R5),R4	;POINT R4 TO LCB
	BEQ	22$		;LCB DOES NOT EXIST, EXIT
	BIT	#LF.DAC, LB.FGS(R4) ;LINE DISABLE COMPLETE ?
	BNE	22$		;YES, EXIT

	BIC	#LS.ERR,(R4) 	;CLEAR ERROR BIT (WE ARE STARTING OVER)
	BIT	#LF.DIS,LB.FGS(R4) ;LINE DISABLED BY DTE
	BNE	11$		;WATCH FOR ABORTS
	BIT	#LS.ENB,(R4)	;IS THE LINE ENABLED?
	BEQ	21$		;NO, SEE IF GENUINE DISABLE
	BIT	#TCOAB!TCOAC!TCIAB!TCIAC,TCFG2(R5) ;YES, ABORT IN PROGRESS?
	BNE	11$		;YES.
	JSR	PC,HSCMDS	;CHECK MODEM STATUS
;	BCC	12$		;DSR IS ON
	BCC	DSRON		;DSR IS ON
;
; HERE IF THE LINE IS NOT ENABLED, THERE IS AN ABORT IN
;  PROGRESS OR THE DATA SET IS NOT READY.
;

	BIT	#LF.CME, LB.FGS(R4) ;;++BS- COMMUNICATIONS ESTABLISHED ? 3(013)
	BEQ	11$		;;++BS-NO, CONTINUE 3(013)
	JSR	PC, HSETHA	;;++BS-YES, INDICATE THE H/W ABORT 3(013)

11$:

;3(017)	JSR	PC, DABCLR	;CLEAR DEVICE ACTIVE BITS

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIC	#LF.OFL, LB.FGS(R4) ;CLEAR LINE/DEVICE OFF LINE
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

	JSR	PC,DQFLSM	;FLUSH THE QUEUE
	BR	DQBCTL		; AND TRY AGAIN.
;
21$:	BIT	#LF.ENC,LB.FGS(R4) ;WAS THE LINE ENABLED?
;	BEQ	11$		;THERE IS NO POINT DISABLING

	JSR	PC, DABCLR	;CLEAR DEVICE ACTIVE BITS

	JSR	PC,HSDISL	;START DISABLE SEQUENCE
22$:
	MOV	#EBTIME!EBWAIT,(R5) ;GIVE DTE TASK A CHANCE
	MOV	#20,TCTIM(R5) ;WAIT A WHILE
	JSR	PC,WAIT
	BR	DQBCTL		;TRY AGAIN
;



;THIS SUBROUTINE CLEARS THE DEVICE ACTIVE BITS ON AN ABORT
;OR ON A LINE DISABLE


DABCLR:	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	CLC			;CLEAR FOR ROTATE
	ASL	R0		;MAKE EVEN
	ASL	R0		;POINT TO FIRST WORD OF 2 WORD STATUS
	CLR	D60ACT(R0)	;CLEAR ACTIVE STATUS BITS
	CLR	D60ACT+2(R0)	;CLEAR ACTIVE STATUS BITS
	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN
;
; HERE WHEN WE HAVE DATA-SET-READY AND THE LINE IS ENABLED.
;
; CHECK FOR HASP LINE AND IF NOT DEFAULT IS 2780/3780.
;
DSRON:
12$:	CMPB	#TTHASP,LB.DVT(R4)	;HASP LINE?
	BNE	13$		;NO, MUST BE 2780 OR 3780
	JMP	HSPLIN		;YES, IT IS HASP LINE
;
; HERE THE LINE IS 2780 OR 3780 
;
13$:	

;;++BS- CODE TO CHECK FOR LINE/DEVICE OFF LINE

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIT	#LF.OFL, LB.FGS(R4) ;LINE/DEVICE OFF LINE ?
	BEQ	23$		;NO
	JSR	PC, HSRESR	;YES, RESTORE THE REGISTERS
	BR	DQDTAS		;BID FOR THE LINE
23$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS

;;++BS- END OF CODE TO CHECK FOR LINE/DEVICE OFF LINE

	BIT	#TCOPR,TCFG2(R5) ;HAS OUTPUT PERMISSION BEEN REQUESTED?
	BNE	DQDTAS		;YES, BID FOR THE LINE.
.IF NE,BSBUG
	TST	TCMSG1(R5)	;ANY MESSAGES FOR THIS TASK
	BEQ	14$		;NO, THAT IS GOOD.
	STOPCD	DBG		;YES, WHAT ARE THEY FOR?
14$:
.ENDC ;.IF NE,BSBUG
15$:	JSR	PC,DQREAD	;NO, SEE IF OTHER SIDE IS BIDDING
;	MOV	#JIFSEC,TCTIM(R5) ;CHECK AGAIN ONCE A SECOND
	MOV	#175,TCTIM(R5)	;;++BS- WAIT ABOUT 2 SECONDS TO MAKE SURE
	CLR	R4		;NO DATA AS YET
	JSR	PC,MSGGTC	;GET CHARACTER
	BCS	16$		;NONE.
	CMPB	#EBCENQ,R1	;AN ENQ?
	BNE	16$		;NO, IGNORE IT.
	JSR	PC,MSGGTE	;YES, END OF MESSAGE
	JSR	PC, HSETCE	;;++BS-COMMUNICATIONS ESTABLISHED 3(013)
	JSR	PC,DQRQIP	;REQUEST INPUT PERMISSION
	BCS	17$		;REFUSED, CLEAR THE LINE.
	JSR	PC,DQRECV	;ACCEPTED, RECEIVE DATA
	JMP	DQBCTL		;WHEN DONE, CHECK AGAIN.
;
; HERE IF WE GET AN UNRECOGNIZABLE UNSOLICITED MESSAGE.
;
16$:	JSR	PC,MSGGTT	;END MESSAGE AND WAIT THE SECOND
	JMP	DQBCTL		;LOOK FOR A BID AGAIN.
;
; HERE WHEN INPUT PERMISSION IS REFUSED.  SEND AN EOT (OR NAK) TO CLEAR
;  THE LINE TO AVOID POSSIBLE CONFUSION.
;
17$:				;;++4(030)
	MOV	TCLCB(R5), R1	;POINT TO LCB 4(030)
	CMPB	#TT3780, LB.DVT(R1) ;IS THIS A 3780 LINE ? 4(030)
	BEQ	18$		;YES, SEND NAK 4(030)
				;NO, SEND EOT IN 2780 MODE 4(030)

	JSR	PC,DQSEOT	;SEND EOT 
	JMP	DQBCTL		;START OVER.
	
18$:	JSR	PC, DQSNAK	;SEND NAK WHEN INPUT PERMISSION REFUSED 4(030)
	JMP	DQBCTL		;START OVER. 4(030)
;
; HERE WHEN WE HAVE DATA TO SEND.  BID FOR THE LINE.
;
DQDTAS:	MOV	LB.EQN(R4),LB.RTY(R4) ;NUMBER OF TRIES TO GET THE LINE
11$:	BIT	#TCOAB!TCOAC,TCFG2(R5) ;HAS STREAM BEEN ABORTED?
	BEQ	12$		;NO.
	JSR	PC,DQFLSM	;YES, FLUSH THE QUEUE
	BIC	#TCOPR,TCFG2(R5) ;NO LONGER BIDDING
	JMP	DQBCTL		; AND TRY AGAIN.
;
12$:	MOV	#ENQMSG,R0	;SEND AN ENQ
	MOV	#ENQLEN,R1
	JSR	PC,CTLMSG	;SEND BID MESSAGE AND READ RESPONSE
	BCS	16$		;ERROR, QUIT RIGHT AWAY.
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.EQW(R4),TCTIM(R5) ;TIME TO WAIT FOR REPLY
	CLR	R4		;NO DATA YET
	JSR	PC,MSGGTC	;GET CHARACTER FROM RECEIVER
	BCS	15$		;NOTHING RECEIVED
	CMPB	#EBCENQ,R1	;DID WE GET AN ENQ?
	BNE	14$		;NO, CHECK FOR ACK
	JSR	PC,MSGGTE	;YES, END OF MESSAGE
	BIC	#TCOPR,TCFG2(R5) ;NO LONGER BIDDING
	JSR	PC, HSETCE	;;++BS-COMMUNICATIONS ESTABLISHED 3(013)
	JSR	PC,DQRQIP	;ASK FOR INPUT PERMISSION
	BCS	13$		;REFUSED.
	JSR	PC,DQRECV	;ACCEPTED, GO RECEIVE STUFF
	JMP	DQBCTL		;BACK TO CONTROL MODE
;
; HERE WHEN INPUT PERMISSION IS REFUSED.  SEND EOT (OR NAK) TO CLEAR
;  THE LINE JUST IN CASE THE OTHER SIDE IS OUT OF SYNC.
;
13$:				;;++4(030)
	MOV	TCLCB(R5), R1	;POINT TO LCB 4(030)
	CMPB	#TT3780, LB.DVT(R1) ;IS THIS A 3780 LINE ? 4(030)
	BEQ	18$		;YES, SEND NAK 4(030)
				;NO, SEND EOT IN 2780 MODE 4(030)

	JSR	PC,DQSEOT	;SEND EOT
	JMP	DQBCTL		;START OVER.

18$:	JSR	PC,DQSNAK	;SEND NAK 4(030)
	JMP	DQBCTL		;START OVER. 4(030)
;
;
; COME HERE IF THE RESPONSE TO ENQ IS NOT ENQ
;
14$:	CMPB	#EBCDLE,R1	;IS IT DLE?
	BNE	15$		;NO.
	JSR	PC,MSGGTC	;YES, GET NEXT CHAR
	BCS	15$		;TIMEOUT
	CMPB	#EBCAK0,R1	;IS IT ACK-0?
	BNE	15$		;NO.
;
; WE HAVE ACK-0, GRANTING PERMISSION TO SEND DATA.
;
	JSR	PC,MSGGTE	;END OF MESSAGE
	BIS	#TCOPG,TCFG2(R5) ;NOTE OUTPUT PERMISSION GRANTED
	BIC	#TCOPR,TCFG2(R5) ;NO LONGER BIDDING
	JSR	PC, HSETCE	;;++BS-COMMUNICATIONS ESTABLISHED 3(013)
	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQAWXL	;AWAKEN XLATE TASK
	JSR	PC,DQXMIT	;GO TRANSMIT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQAWXL	;AWAKEN XLATE TASK
	JMP	DQBCTL		;BACK TO BSC CONTROL MODE
;
; HERE WHEN THE RESPONSE TO ENQ IS UNRECOGNIZABLE
;  FINISH WAITING IF NECESSARY AND BID AGAIN.
;
15$:	JSR	PC,MSGGTT	;EMPTY THE RECEIVER AND WAIT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC8(R4)	;RECORD UNRECOGNIZABLE BID RESPONSE
	BIT	#TCOPR,TCFG2(R5) ;STILL WANT TO BID FOR THE LINE?
	BEQ	16$		;NO.
	DEC	LB.RTY(R4)	;YES, HAVE WE TRIED OFTEN ENOUGH?
	BNE	11$		;NO, TRY AGAIN.
16$:	BIC	#TCOPR,TCFG2(R5) ;YES, NO LONGER BIDDING
	JSR	PC,DQAWXL	;AWAKEN THE XLATE TASK
	JSR	PC,DQSEOT	;SEND EOT TO CLEAR THE LINE
	JMP	DQBCTL		;BACK TO CONTROL MODE
;
;
; SUBROUTINE TO FLUSH ALL QUEUED MESSAGES.  THIS IS USED WHEN
;  THE STREAM IS ABORTED AND WHEN DATA SET READY IS NOT UP.
;
DQFLSM:

;;++BS-CODE TO FLUSH THE LAST MESSAGE BEING TRANSMITTED IF DEVICE WAS OFF LINE

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R4	;POINT TO LCB
	CMPB	#TTHASP, LB.DVT(R4) ;CHECK FOR HASP LINE
	BEQ	8$		;YES, CONTINUE
	MOV	LB.MSG(R4), R0	;NO, POINT TO LAST MESSAGE
	BEQ	7$		;NO MESSAGE, CONTINUE
	MOV	TCIDLE, R1	;POINT TO IDLE TASK
	JSR	PC, QUEMSG	;SEND IT TO IDLE TO BE DELETED
	CLR	LB.MSG(R4)	;CLEAR LINE POINTER TO MESSAGE
7$:	BIC	#LF.OFL, LB.FGS(R4) ;DEVICE IS NO LONGER OFF LINE
8$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS

;;++BS-END OF CODE TO FLUSH THE LAST MESSAGE IF DEVICE WAS OFF LINE

11$:	JSR	PC,DEQMSG	;GET A MESSAGE
	BCS	13$		;GOT THEM ALL
12$:	MOV	TCIDLE,R1	;POINT TO BACKGROUND TASK
	JSR	PC,QUEMSG	;SEND IT THE MESSAGE TO FREE
	BR	11$		;GET MORE MESSAGES
;
; HERE WHEN THE MESSAGE QUEUE IS EMPTY.  WAIT A BIT TO BE SURE
;  IT STAYS THAT WAY.
;
13$:	MOV	#EBTIME!EBWAIT,(R5) ;WAIT A SHORT WHILE
	MOV	#3,TCTIM(R5)	;JUST THREE JIFFIES
	JSR	PC,WAIT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DEQMSG	;ANY MESSAGES?
	BCC	12$		;YES, FREE THEM AND WAIT SOME MORE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	CMP	#TTHASP,LB.DVT(R4) ;HASP LINE?
	BNE	21$		;NO.
	BIT	#LF.ENC,LB.FGS(R4) ;LINE ENABLE COMPLETE?
	BNE	16$		;YES, CHECK FOR ABORTS
	JSR	PC,HSWAIT	;WAIT A WHILE
	RTS	PC		;AND RETURN
;
16$:	MOV	LB.NTC(R4),R1	;GET MAX DEV #
	BEQ	23$		;FIELD NOT SETUP
22$:	ASL	R1		;DEV # * 2
	MOV	TCLCB(R5),R4	;POINT TO LCB
	ADD	R1,R4		;GET POINTER
	ASR	R1		;GET BACK DEV #
	MOV	LB.TCD(R4),R4	;POINT TO XLATE TCB
	BIT	#TCIAB!TCOAB,TCFG2(R4) ;DEVICE STREAM ABORTED?
	BNE	27$		;YES.
26$:	SOB	R1,22$		;LOOP FOR ALL DEVICES
	BIC	#TCIAC!TCIAB!TCOAC!TCOAB,TCFG2(R5) ;CLEAR ABORT
27$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,HSWALX	;WAKE ALL XLATE TASKS
	JSR	PC,HSWAIT	;WAIT
23$:	RTS	PC		;RETURN
21$:
	BIT	#TCOAB!TCIAB,TCFG2(R5) ;IS STREAM STILL IN ABORT STATE?
	BEQ	17$		;NO, JUST RETURN.
	BIT	#TCOAB,TCFG2(R5) ;YES, OUTPUT ABORT?
	BEQ	14$		;NO.  CHECK FOR INPUT ABORT.
	BIS	#TCOAC,TCFG2(R5) ;YES, FLAG OUTPUT ABORT COMPLETE
14$:	BIT	#TCIAB,TCFG2(R5) ;INPUT ABORT?
	BEQ	15$		;NO.
	BIS	#TCIAC,TCFG2(R5) ;YES, COMPLETE INPUT ABORT.
15$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQAWXL	;AWAKEN XLATE TASK
	BR	13$		;WAIT FOR "ABORT" TO CLEAR.
;
; HERE WHEN STREAM IS NO LONGER IN THE "ABORT" STATE.
;
17$:	RTS	PC		;RETURN TO CALLER
;
;
; THIS SUBROUTINE DISABLES A LINE AND RELEASES ALL STORAGE.
;
HSDISL:	MOV	TCLCB(R5),R4	;POINT TO LCB
	BIC	#LS.ENB,(R4)	;MARK LINE DISABLED
	BIC	#LF.ABC,LB.FGS(R4) ;LINE ABORT NOT COMPLETE
	BIS	#LF.DIP,LB.FGS(R4) ;MARK DISABLE IN PROGRESS
	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQKILL	;STOP ALL DQ/DUP ACTIVITY
				;TRANSMITTER + RECEIVER
	MOV	TCLCB(R5),R4	;POINT TO LCB
	CMP	#TTHASP,LB.DVT(R4) ;HASP LINE?
	BNE	12$		;NO.
	JSR	PC,HSABTO	;ABORT ALL OUTPUT DEVICES
	JSR	PC,HSABTI	;AND INPUT DEVICES
	JSR	PC,HSWALX	;WAKE ALL XLATE TASKS
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.NTC(R4),R1	;GET MAX DEV #
11$:	ASL	R1		;DEV # * 2
	ADD	R1,R4		;ADD TO LCB POINTER
	ASR	R1		;GET BACK THE DEV #
	MOV	LB.TCD(R4),R4	;GET POINTER TO DEV XLATE TCB
	BEQ	14$		;NONE THERE
	BIT	#TCIAC!TCOAC,TCFG2(R4) ;ABORTS COMPLETE?
	BEQ	14$		;YES, CHECK NEXT DEVICE
13$:	MOV	R1,-(SP)	;SAVE DEV #
	MOV	R4,-(SP)	;AND XLATE TCB PTR
	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,HSAWXL	;AWAKEN THE XLATE TASK
	MOV	#EBTIME!EBWAIT,(R5) ;WAIT A SHORT WHILE FOR XLATE TO NOTICE
	MOV	#20,TCTIM(R5)	;ENOUGH TIME FOR EACH ABORT
	JSR	PC,WAIT		;DO THE WAIT
	MOV	(SP)+,R4	;POINT TO XLATE TCB
	MOV	(SP)+,R1	;DEV # ALSO
	BIT	#TCIAC!TCOAC,TCFG2(R4) ;ABORT COMPLETE?
	BNE	13$		;WAIT TILL DONE
14$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	SOB	R1,11$		;LOOP TILL DONE WITH ALL DEVICES
	BIC	#TCIAC!TCIAB!TCOAC!TCOAB,TCFG2(R5) ;CLEAR BSC ABORT
15$:	JSR	PC,DEQMSG	;GET A MESSAGE
	BCS	19$		;GOT THEM ALL
	MOV	TCIDLE,R1	;POINT TO BACKGROUND TASK
	JSR	PC,QUEMSG	;SEND MESSAGE TO FREE
	BR	15$		;LOOK FOR MORE MESSAGES
19$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DLXTCB	;RELEASE THE XLATE TCB AND STORAGE
	JSR	PC,HSRMRL	;RELEASE ALL RECEIVED MESSAGES
	JSR	PC,HSRLOM	;ALSO ALL OUTGOING MESSAGES
	BIC	#LF.ENC!LF.DIP,LB.FGS(R4) ;DISABLE NO LONGER IN PROGRESS
	BIS	#LF.ABC,LB.FGS(R4) ;LINE ABORT COMPLETE
	BIS	#LF.DAC,LB.FGS(R4) ;LINE DISABLE COMPLETE
	CLR	TCTIM(R5)	;DONT SCHEDULE BSC ANYMORE
	MOV	TCLCB(R5),R0	;;++BS-POINT TO LCB 3(022)
	JSR	PC, DQDTR0	;;++BS-DROP DTR 3(022)
	RTS	PC		;RETURN FINALLY
;
;
; HERE IF IN 3780/2780 MODE
;
12$:	MOV	LB.TCD(R4),R4	;POINT TO XLATE TCB
	BEQ	15$		;NONE THERE
	BIT	#TCIAB!TCIAC!TCOAB!TCOAC,TCFG2(R4) ;ABORTS COMPLETE?
	BEQ	15$		;YES
16$:	MOV	R4,-(SP)	;SAVE XLATE TCB PTR
	MOV	#EBTIME!EBWAIT,(R5) ;WAIT A WHILE
	MOV	#20,TCTIM(R5)	; ABOUT 1/3 SEC
	JSR	PC,WAIT	;DO THE WAITING
	MOV	(SP)+,R4	;RESTORE R4 (XLATE PTR)
	BIT	#TCIAB!TCOAB!TCIAC!TCOAC,TCFG2(R4) ;DONE?
	BEQ	15$		;YES, GO CLEAN REST OF
	BR	16$		;NO, WAIT TILL DONE
;
;
; WE HAVE RECEIVED ACK-0 RESPONSE TO BID ENQ.  SEND MESSAGES.
;
DQXMIT:	BIS	#TCAK1,TCST2(R5) ;NOTE ACK-1 NEEDED NEXT
				; AND DOING OUTPUT.
11$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	#15.,LB.RTY(R4) ;RETRY COUNT IS 15.
	BIC	#TCNRD,TCST2(R5) ;NO "NO RESPONSES" YET
	BIT	#TCOAB,TCFG2(R5) ;HAS TRANSMISSION BEEN ABORTED?
	BNE	16$		;YES, SEND EOT AND EXIT.
	BIT	#LS.ERR,(R4)	;HAVE WE HAD A DQ11 ERROR?
;3(016)	BNE	16$		;YES, TERMINATE.
	BEQ	30$		;;++BS-NO, CONTINUE 3(016)
	JSR	PC, HSETHA	;;++BS-YES, SET H/W ABORT 3(016)
	BR	16$		;;++BS-TERMINATE 3(016)
30$:				;;++BS-NEW LABEL 3(016)

;;++BS- CODE TO SEE IF A DEVICE HAS PREVIOUSLY GONE OFF LINE

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIT	#LF.OFL, LB.FGS(R4) ;DID DEVICE GO OFF LINE BEFORE ?
	BEQ	22$		;NO, CONTINUE AS BEFORE
	BIC	#LF.OFL, LB.FGS(R4) ;YES, CLEAR THE FLAG THAT SAYS IT DID
	TST	LB.MSG(R4)	;ANY MESSAGES READY TO TRANSMIT AGAIN ?
	BEQ	22$		;NO, GET A MESSAGE
	JSR	PC, HSRESR	;YES, RESTORE THE REGISTERS
	BR	13$		;RETRANSMIT MESSAGE
22$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS

;;++BS- END OF CODE TO CHECK IF A DEVICE WENT OFF LINE

	JSR	PC,DEQMSG	;NO, GET MESSAGE TO SEND
	BCC	12$		;GOT ONE.
	JSR	PC,DQXNAV	;WORRY ABOUT NO MSGS AVAILABLE.
	BCS	11$		;NOW TRY FOR A MESSAGE
23$:	BIC	#TCORN!TCOPG,TCFG2(R5) ;NO LONGER DOING OUTPUT
	RTS	PC		;RETURN.
;
; HERE IF THERE IS A MESSAGE AVAILABLE TO SEND.
;
12$:	MOV	R0,LB.MSG(R4)	;STORE MESSAGE POINTER
;
; HERE TO SEND THE MESSAGE AGAIN.
;
13$:	MOV	TCLCB(R5),R4	;POINT TO LCB
.IF NE,FT.CHK
	TST	LB.MSG(R4)	;THERE SHOULD BE A MESSAGE
	BNE	14$		;THERE IS ONE.
	STOPCD	QXC		;TRANSMISSION CONFUSION
14$:
.ENDC ;.IF NE,FT.CHK
;
;
; HERE WITH A MESSAGE TO BE SENT IN LB.MSG
;
	MOV	#EBINTR!EBTIME!EBWAIT,(R5)
				;WE WILL WAIT FOR XMITTER TO FINISH
	MOV	LB.MSG(R4),R0	;POINT TO MESSAGE
	MOV	MSGLEN(R0),TCTIM(R5) ;NO MORE THAN ONE JIFFIE PER CHAR
	ADD	LB.CSD(R4),TCTIM(R5) ;PLUS CLEAR-TO-SEND DELAY
	JSR	PC,DQWRIT	;START SENDING MESSAGE
;3(016)	BCS	16$		;ERROR
	BCC	31$		;;++BS-NO ERROR, CONTINUE 3(016)
	JSR	PC, HSETHA	;;++BS- ERROR, SET H/W ABORT 3(016)
	BR	16$		;;++BS-CONTINUE WITH ERROR 3(016)
31$:				;;++BS-NEW LABEL 3(016)
	JSR	PC,DQREAD	;SET UP TO READ RESPONSE
	JSR	PC,WAIT		;WAIT FOR MESSAGE TO BE SENT
	BIT	#EBINTR,(R5)	;TIMED OUT?
	BEQ	15$		;NO, GOT AN INTERRUPT.
	MOV	TCLCB(R5),R4	;YES, POINT TO LCB
	JSR	PC,DQKILL	;STOP THE TRANSMITTER [1(637)]
	INC	LB.TTO(R4)	;COUNT TRANSMITTER TIMEOUTS
	JSR	PC, HSETHA	;;++BS-SET H/W ABORT 3(016)
	BR	16$		;ABORT THE OPERATION.
;
;
; HERE IF THE TRANSMISSION OF THE DATA MESSAGE WAS SUCCESSFUL.
;
15$:	JSR	PC,DQXRSP	;READ AND ANALYZE RESPONSE
	BCC	19$		;SUCCESSFUL ACKNOWLEDGMENT

;;++BS-CODE TO CHECK IF AN OUTPUT DEVICE WENT OFF LINE

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIT	#LF.OFL, LB.FGS(R4) ;DID DEVICE GO OFF LINE
	BEQ	24$		;NO, CONTINUE 
	JSR	PC, HSRESR	;YES, RESTORE THE REGISTERS
	BR	23$		;STOP TRANSMITTING AND BID FOR THE LINE AGAIN
24$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS

;;++BS- END OF CODE TO CHECK IF OUTPUT DEVICE WENT OFF LINE

	MOV	TCLCB(R5),R4	;POINT TO LCB
	BIT	#TCOAB,TCFG2(R5) ;HAS OPERATION BEEN ABORTED?
	BNE	16$		;YES, ERROR RETURN.
	DEC	LB.RTY(R4)	;NO, DECREMENT RETRY COUNT
	BNE	18$		;SEND ENQ OR DATA
	JSR	PC, HSETHA	;;++BS-GIVE UP, LINE DEAD, SET H/W ABORT 3(016)
;
; HERE TO TERMINATE THE MESSAGE STREAM BECAUSE
;  THE 10 REQUESTED TERMINATION, BECAUSE WE RECEIVED
;  AN EOT IN RESPONSE TO A DATA BLOCK, BECAUSE OF TRANSMITTER 
;  ERROR OR TIMEOUT OR BECAUSE THE RETRY COUNTER RAN OUT.
;
16$:	JSR	PC,DQSEOT	;SEND EOT IF NECESSARY TO CLEAR LINE
	JSR	PC,DQABRO	;FLAG OUTPUT ABORTED.
	BIC	#TCORN!TCOPG,TCFG2(R5) ;NO LONGER DOING OUTPUT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	BIC	#LF.OFL, LB.FGS(R4) ;;++BS-DEVICE NO LONGER CONSIDERED OFF LINE
	MOV	LB.MSG(R4),R0	;IS THERE A MESSAGE TRYING TO GO?
	BEQ	17$		;NO.
	MOV	TCIDLE,R1	;YES, POINT TO IDLE TASK
	JSR	PC,QUEMSG	;SEND IT TO IDLE TO BE DELETED
	CLR	LB.MSG(R4)	;THERE IS NO LONGER A MESSAGE TO GO [1(624)]
17$:	RTS	PC		;RETURN.
;
; HERE TO SEND AN ENQ OR DATA BECAUSE THE RESPONSE WAS UNREASONABLE
;
18$:	CMP	R0,#2		;DQXRSP INDICATES SEND ENQ?
	BEQ	13$		;NO, JUST SEND DATA.
	MOV	#ENQMSG,R0	;YES, SEND ENQ
	MOV	#ENQLEN,R1
	JSR	PC,CTLMSG
;3(016)	BCS	16$		;TRANSMITTER TIMEOUT
;3(016)	BR	15$		;ANALYZE RESPONSE TO ENQ
	BCC	15$		;;++BS-ANALYZE RESPONSE TO ENQ 3(016)
	JSR	PC, HSETHA	;;++BS-TIMEOUT, SET H/W ABORT 3(016)
	BR	16$		;;++BS-ABORT THE STREAM 3(016)

;
;

; HERE WHEN A BLOCK HAS BEEN TRANSMITTED SUCCESSFULLY.
;

19$:	

	JSR	PC, XLCLRM	;CLEAR THE MESSAGE BUFFER
	JMP	11$		;TRY FOR ANOTHER MESSAGE


;THIS SUBROUTINE CLEARS THE TRANSMITTED MESSAGE BUFFER AFTER
;A MESSAGE HAS BEEN SUCCESSFULLY TRANSMITTED

XLCLRM:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.MSG(R4),R0	;POINT TO MESSAGE SENT
	BEQ	29$		;NO MESSAGE, BUFFER HAS BEEN CLEARED
	MOV	TCIDLE,R1	;POINT TO "IDLE" TASK
	JSR	PC,QUEMSG	;SEND IT THE MESSAGE TO FREE
	CLR	LB.MSG(R4)	;NO LONGER A MESSAGE BEING SENT
	BIS	#TCORN,TCFG2(R5) ;FLAG OUTPUT RUNNING
	BIC	#TCOPG,TCFG2(R5) ;CLEAR "OUTPUT PERMISSION GRANTED"
	DEC	LB.MSC(R4)	;ONE FEWER MSG WAITING TO TRANSMIT
	JSR	PC, XLCSAB	;SET OR CLEAR THE DEVICE ACTIVE BIT
29$:	RTS	PC		;RETURN
;	BR	11$		;TRY FOR ANOTHER MESSAGE
;	JMP	11$		;TRY FOR ANOTHER MESSAGE
;
;
; SUBROUTINE TO READ AND ANALYZE THE RESPONSE TO A TEXT BLOCK.
;
; ON RETURN:
;
;	C IS CLEAR IF THE BLOCK IS ACKNOWLEDGED.
;
;	C IS SET IF THE BLOCK IS NOT ACKNOWLEDGED.
;	  IF LS.ABO IS SET, THE OPERATION IS ABORTED.
;	  OTHERWISE:
;	  	R0 = 1, SEND ENQ OR (IF TOO MANY RETRIES) EOT
;		R0 = 2, SEND DATA AGAIN OR (IF TOO MANY RETRIES) EOT
;
;
DQXRSP:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	#EBQCHK!EBTIME!EBWAIT,(R5) ;WAIT FOR A CHUNK OR TIME UP
	MOV	#3*JIFSEC,TCTIM(R5) ;WAIT FOR THREE SECONDS MAX
	CLR	R4		;FLAG NO DATA YET
	JSR	PC,MSGGTC	;GET DATA FROM READER
	BCS	13$		;NOTHING.
	CMPB	#EBCDLE,R1	;START WITH DLE?
	BEQ	14$		;YES, PROBABLY ACK, WACK OR RVI
	CMPB	#EBCNAK,R1	;NO, NAK?
	BEQ	18$		;YES.
	CMPB	#EBCEOT,R1	;NO, EOT?
	BEQ	19$		;YES.
;
; HERE IF THE RESPONSE TO A MESSAGE IS OMITTED OR UNRECOGNIZABLE
;
11$:	JSR	PC,MSGGTT	;FLUSH REMAINDER OF MESSAGE
				; AND WAIT THE THREE SECONDS
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC4(R4)	;RECORD INVALID REPLY TO DATA
12$:	MOV	#1,R0		;INDICATE REPLY WITH "ENQ"
	SEC			;FLAG BLOCK NOT ACKNOWLEDGED
	RTS	PC		;RETURN.
;
; HERE IF TIMEOUT
;
13$:	BIS	#TCNRD,TCST2(R5) ;FLAG TIMEOUT
	BR	11$		;TREAT AS GARBAGE
;
;
; HERE IF THE FIRST CHARACTER OF THE RESPONSE IS "DLE".
;
14$:	JSR	PC,MSGGTC	;GET SECOND CHARACTER
	BCS	11$		;NOT THERE, UNRECOGNIZABLE
	CMPB	#EBCWAK,R1	;IS RESPONSE "WACK"?
	BEQ	20$		;YES.
	CMPB	#EBCRVI,R1	;NO, IS IT "RVI"?
	BEQ	21$		;YES.
	BIT	#TCAK1,TCST2(R5) ;NO, DO WE WANT ACK-1?
	BEQ	15$		;NO.  WE WANT ACK-0
	CMPB	#EBCAK1,R1	;YES, IS THIS ACK-1?
	BEQ	16$		;YES.
	CMPB	#EBCAK0,R1	;NO, ACK-0?
	BEQ	17$		;YES.
	BR	11$		;NO, UNRECOGNIZABLE.
;
; HERE IF WE ARE LOOKING FOR ACK-0
;
15$:	CMPB	#EBCAK0,R1	;IS THIS ACK-0?
	BEQ	16$		;YES.
	CMPB	#EBCAK1,R1	;NO, ACK-1?
	BEQ	17$		;YES.
	BR	11$		;NO, UNRECOGNIZABLE.
;
; HERE WHEN WE HAVE RECEIVED THE PROPER ACK
;
16$:	MOV	#TCAK1,R1	;BIT TO CHANGE
	XOR	R1,TCST2(R5)	;COMPLEMENT ACK-0/ACK-1 BIT
	JSR	PC,MSGGTE	;END OF MESSAGE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC1(R4)	;COUNT MESSAGE SENT SUCCESSFULLY
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN.
;
;
; HERE IF WE HAVE THE WRONG ACK.  IF WE HAVE PREVIOUSLY HAD
;  NO RESPONSE, RESEND THE LAST DATA MESSAGE (I.E., TREAT AS NAK).
;  OTHERWISE, SEND AN ENQ.
;
17$:	BIT	#TCNRD,TCST2(R5) ;HAVE WE TIMED OUT BEFORE?
	BEQ	11$		;NO, SEND AN ENQ.
;
; HERE IF WE RECEIVE A NAK OR WRONG ACK AFTER TIMEOUT
;
18$:	JSR	PC,MSGGTE	;END OF MESSAGE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC2(R4)	;COUNT NAKS RECEIVED
	MOV	#2,R0		;INDICATE DATA TO BE SENT AGAIN
	SEC			;INDICATE FAILURE--SEND MSG AGAIN
	RTS	PC		;RETURN.
;
; HERE ON RECEIVING EOT IN RESPONSE TO A MESSAGE
;
19$:	JSR	PC,MSGGTE	;END OF MESSAGE
	MOV	TCLCB(R5),R4	;GET POINTER TO LCB
	INC	LB.OC7(R4)	;COUNT ABORTS
	BIS	#LF.OFL, LB.FGS(R4) ;;;++BS- DEVICE WENT OFF LINE
;	JSR	PC,DQABRO	;INDICATE TRANSMISSION ABORTED
	SEC			;INDICATE FAILURE
	RTS	PC		; AND RETURN.
;
; HERE ON RECEIVING WACK IN RESPONSE TO A DATA MESSAGE
;
20$:	JSR	PC,MSGGTE	;END OF MESSAGE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC6(R4)	;COUNT WACKS RECEIVED
	INC	LB.RTY(R4)	;DONT DECREMENT RETRY COUNT
	JSR	PC, XLCLRM	;;++BS-CLEAR THE MESSAGE BUFFER
	BR	12$		;ASK FOR THE ACK NOW
;
; HERE IF WE RECEIVE AN RVI IN RESPONSE TO A DATA MESSAGE.
;  SINCE IT IS COMPLICATED TO UNBUFFER AND LATER CONTINUE
;  THE TRANSMISSION, WE DEFINE "UNBUFFERING" AS SENDING
;  ALL OF THE DATA.  THUS WE CAN MEARLY TREAT RVI AS ACK.
;
21$:	MOV	TCLCB(R5),R1	;POINT TO LCB
	INC	LB.OC9(R1)	;COUNT RVIS RECEIVED
	BR	16$		;TREAT AS ACK.
;
;
; SUBROUTINE CALLED WHEN DATA IS NOT AVAILABLE.
;  THIS WILL BE BECAUSE EITHER THE MESSAGE STREAM IS COMPLETE
;  OR BECAUSE THERE IS MORE DATA TO COME BUT IT IS NOT HERE YET.
;
; ON RETURN:
;
;	C CLEAR -- MESSAGE STREAM COMPLETE
;
;	C SET -- MESSAGE STREAM INCOMPLETE, KEEP SENDING.
;	 (UNLESS STREAM HAS BEEN ABORTED)
;
DQXNAV:	BIT	#TCOAB,TCFG2(R5) ;HAS TRANSMISSION BEEN ABORTED?
;	BEQ	11$		;NO. 3(012)
	BNE	10$		;;++BS-YES 3(012)
	MOV	TCLCB(R5), R4	;;++BS-POINT TO LCB 3(012)
	BIT	#LS.ENB, (R4)	;;++BS-IS THE LINE DISABLED 3(012)
	BNE	11$		;;++BS-NO, CONTINUE 3(012)
	CLC			;;++BS-YES, NO MORE MESSAGES 3(012)
	RTS	PC		;;++BS-EXIT 3(012)

10$:				;;++BS-NEW LABEL 3(012)
	SEC			;YES, INDICATE TRANSMISSION INCOMPLETE
	RTS	PC		; AND RETURN.
;
; HERE IF THE TRANSMISSION HAS NOT BEEN ABORTED.
;
11$:	TST	TCMSG1(R5)	;IS DATA AVAILABLE YET? [2(773)]
	BNE	15$		;YES, PROCESS IT. [2(773)]
	BIT	#TCOEF,TCFG2(R5) ;NO, IS THIS THE END OF THE STREAM?
	BEQ	13$		;NO, DATA IS JUST DELAYED.
	JSR	PC,DQSEOT	;YES, SEND EOT.
	BCS	12$		;TRANSMITTER TIMEOUT
	BIS	#TCOEC,TCFG2(R5) ;SET "EOF COMPLETED" BIT
	CLC			;FLAG TRANSMISSION SUCCESSFUL
	RTS	PC		;AND RETURN.
;
; HERE IF WE GOT TRANSMITTER TIMEOUT TRYING TO SEND THE EOT.
;  ITS TOO BAD, BUT THE WHOLE STREAM MUST BE CONSIDERED
;  ABORTED.
; ALSO COME HERE IF WE GOT AN ERROR SENDING THE TTD
;  OR RECEIVING ITS RESPONSE.
;
12$:
	JSR	PC, HSETHA	;;++BS-SET H/W ABORT 3(016)
	JSR	PC,DQABRO	;ABORT THE STREAM
	SEC			;SIGNAL FAILURE
	RTS	PC		;RETURN.
;
;
; HERE IF THE DATA IS JUST DELAYED.  WAIT 2 SECONDS.  IF THERE
;  IS STILL NO DATA, SEND "TTD" AND RECEIVE ITS NAK,
;  THEN CHECK AGAIN.
;
13$:	MOV	#EBTIME!EBQMSG!EBWAIT,(R5) ;WAIT FOR TIME TO EXPIRE
				; OR FOR A MESSAGE
	MOV	#2*JIFSEC,TCTIM(R5) ;MAX OF 2 SECONDS
	JSR	PC,WAIT		;WAIT FOR ONE OR THE OTHER
	TST	TCMSG1(R5)	;IS THERE A MESSAGE?
	BNE	15$		;YES, GO SEND IT.
	MOV	#TTDMSG,R0	;NO, SEND TTD
	MOV	#TTDLEN,R1
	JSR	PC,CTLMSG	;SEND MESSAGE
	BCS	12$		;TRANSMITTER TIMEOUT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC5(R4)	;COUNT TTDS SENT
	MOV	#EBQCHK!EBTIME!EBWAIT,(R5) ;WAIT FOR CHUNK OR TIME
	MOV	#3*JIFSEC,TCTIM(R5) ;MAX OF THREE SECONDS
	CLR	R4		;NO DATA YET
	JSR	PC,MSGGTC	;GET FIRST CHAR OF RESPONSE
	BCS	14$		;NONE.
	CMPB	#EBCEOT,R1	;IS IT EOT?
	BEQ	16$		;YES, RECEIVER ABORTED.
	CMPB	#EBCNAK,R1	;NO, IS IT NAK?
	BNE	14$		;NO.
	JSR	PC,MSGGTE	;YES, END OF MESSAGE
	BR	DQXNAV		;SEND TTD UNLESS ABORT OR EOF.
;
;
; HERE IF THE RESPONSE TO TTD IS NOT "NAK" OR "EOT"
;
14$:	JSR	PC,MSGGTT	;END OF MESSAGE AND WAIT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC3(R4)	;COUNT INVALID RESPONSES TO TTD
	BIT	#LS.ERR,(R4)	;HAS THERE BEEN AN ERROR?
	BNE	12$		;YES, ABORT THE STREAM.
	BR	DQXNAV		;TRY TO SEND ANYWAY.
;
; HERE IF THERE IS NOW A MESSAGE AVAILABLE.
;
15$:	SEC			;FLAG TRANSMISSION NOT COMPLETE
	RTS	PC		;RETURN TO SEND DATA.
;
; HERE IF WE GET EOT IN RESPONSE TO TTD.  THE RECEIVER HAS
;  ABORTED THE TRANSMISSION.
;
16$:	JSR	PC,MSGGTT	;END OF MESSAGE AND WAIT
;	JSR	PC,DQABRO	;FLAG THE MESSAGE STREAM ABORT
;	BIS	#TCEOT,TCST2(R5) ;DONT NEED ANOTHER EOT
;	SEC			;FLAG TRANSMISSION INCOMPLETE
;;++BS- CODE TO INDICATE OUTPUT DEVICE HAS GONE OFF LINE

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIS	#LF.OFL, LB.FGS(R4) ;INDICATE DEVICE IS OFF LINE
	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	CLC			;INDICATE NO MORE TO TRANSMIT NOW

;;++BS- END OF CODE TO INDICATE OUTPUT DEVICE HAS GONE OFF LINE

	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO REQUEST INPUT PERMISSION.
;
; ON RETURN:
;
; C IS SET IF PERMISSION HAS BEEN REFUSED, CLEAR IF GRANTED.
;
DQRQIP:	BIS	#TCIPR!TCIWR,TCFG2(R5) ;REQUEST INPUT PERMISSION
				; AND NOTE IT WAS REQ. [2(770)]

;;++BS-CODE TO SET THE DEVICE ACTIVE BIT WHEN INPUT PERMISSION WAS REQUESTED

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5),R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	BIT	#LF.SIM, LB.FGS(R2) ;SIMULATION OR SUPPORT ?
	BEQ	21$		;SUPPORT
	MOV	#4, R1		;SIMULATION, MUST BE LPT
	BR	22$		;SET DEVICE ACTIVE BIT
21$:	MOV	#3, R1		;SUPPORT, MUST BE CDR
22$:	JSR	PC, HSACMP	;SET THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

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

	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQAWXL	;AWAKEN XLATE TASK
	MOV	#<JIFSEC*2>/3,TCTIM(R5) ;WAIT UP TO 2/3 SEC
11$:	MOV	#EBINTR!EBTIME!EBWAIT,(R5) ; [1(645)]
	JSR	PC,WAIT		;FOR "GRANT" SIGNAL
	MOV	TCLCB(R5),R4	;POINT R4 TO LCB [1(730)]
	BIT	#TCIPG,TCFG2(R5) ;WERE WE GIVEN PERMISSION?
	BNE	12$		;YES, SEND ACK-0
	TST	TCTIM(R5)	;NO, IS TIME UP?
	BNE	11$		;NO, KEEP WAITING.
	BIC	#TCIPR,TCFG2(R5) ;YES, NO LONGER REQUESTING
	JSR	PC,DQAWXL	;WAKE UP XLATE TASK
	SEC			;INDICATE PERMISSION REFUSED
	RTS	PC		;RETURN.
;
; HERE IF PERMISSION HAS BEEN GRANTED.
;
12$:	BIC	#TCIPR,TCFG2(R5) ;NO LONGER REQUESTING

;;++BS-CODE TO CLEAR THE DEVICE ACTIVE BIT WHEN INPUT PERMISSION WAS GRANTED

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5),R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	BIT	#LF.SIM, LB.FGS(R2) ;SIMULATION OR SUPPORT ?
	BEQ	23$		;SUPPORT
	MOV	#4, R1		;SIMULATION, MUST BE LPT
	BR	24$		;SET DEVICE ACTIVE BIT
23$:	MOV	#3, R1		;SUPPORT, MUST BE CDR
24$:	JSR	PC, HSAMPC	;CLEAR THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

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

	JSR	PC,DQAWXL	;WAKE UP XLATE TASK
	CLC			;INDICATE PERMISSION GRANTED
	RTS	PC		;RETURN.
;
; SUBROUTINE TO AWAKEN THE TRANSLATE TASK
;
; R4 POINTS TO THE LCB
;
DQAWXL:	
.IF NE,BSBUG
	CMP	R4,TCLCB(R5) 	;DOES R4 POINT TO LCB? [1(730)]
	BEQ	11$		;YES. [1(730)]
	STOPCD	DBG		;NO, CODING ERROR IN BSC TASK [1(730)]
11$:
.ENDC ;.IF NE,BSBUG
	TST	LB.TCD(R4)	;XLATE TCB EXIST?
	BEQ	12$		;NO, PROBABLY RELAESED
	BIT	#EBINTR,@LB.TCD(R4) ;IS XLATE TASK WAITING FOR US?
	BEQ	12$		;NO.
	BIC	#EBINTR!EBWAIT,@LB.TCD(R4) ;MAYBE, UNWAIT IT.
12$:	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO PROCESS INPUT MESSAGE STREAM.  CALLED WHEN WE
;  RECEIVE AN ENQ IN CONTROL MODE.
;
DQRECV:	CMP	CHFREC,#CHLABD	;HAVE WE PLENTY OF CHUNKS?
;	BGT	11$		;YES.
	BGT	DQREC1		;;++BS-YES
;
; HERE TO REFUSE THE BID BY SENDING "NAK".
;
DQSNAK:
	MOV	#NAKMSG,R0	;REFUSE THE BID.
	MOV	#NAKLEN,R1
	BIS	#LS.LWR,@TCLCB(R5) ;DONT FOLLOW WITH A READ
	JSR	PC,CTLMSG
	RTS	PC		;RETURN.
;
; HERE IF THERE ARE ENOUGH CHUNKS THAT WE CAN ACCEPT THE BID.
;
DQREC1:
11$:	MOV	#AK0MSG,TCCMA(R5) ;ACCEPT THE BID
	MOV	#AK0LEN,TCCMC(R5)
	BIC	#TCAK1,TCST2(R5) ;NEXT ACK WILL BE ACK-1
;
;
; HERE TO RECEIVE THE NEXT TRANSMISSION BLOCK
;
DQRCVB:
11$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	#<<20.*150.>/512.>+1,LB.RTY(R4) ;20 SECONDS WAIT MAX
12$:	BIT	#TCIAB,TCFG2(R5) ;HAS STREAM BEEN ABORTED?
	BNE	15$		;YES.
	MOV	TCLCB(R5),R4	;NO, POINT TO LCB
	BIT	#LS.ENB, (R4)	;;++BS-IS THE LINE DISABLED ? 3(012)
	BEQ	15$		;;++BS-YES, ABORT AND EXIT 3(012)
				;;++BS-NO, CONTINUE 3(012)
	MOV	#EBQCHK!EBTIME!EBWAIT,(R5)
	MOV	#<<600./150.>*JIFSEC>+1,TCTIM(R5) ;MAX MSG TIME FOR
				;MAX SIZE MSG AT SLOWEST SPEED
				; (THIS EXPRESSION ALSO USED AT MSGGT2)
	MOV	TCCMA(R5),R0	;ANY CONTROL MESSAGE TO SEND?
	BEQ	13$		;NO, JUST ISSUE A READ
	MOV	TCCMC(R5),R1	;YES, GET ADDRESS AND COUNT
	ADD	R1,TCTIM(R5)	;INCREASE TIME TO ALLOW FOR TRANSMISSION
	ADD	LB.CSD(R4),TCTIM(R5) ; PLUS CLEAR-TO-SEND DELAY
	JSR	PC,DQCNTL	;SEND THE MESSAGE
;3(016)	BCS	23$		;FATAL ERROR SENDING
	BCC	32$		;;++BS-NO ERROR, CONTINUE 3(016)
	JSR	PC, HSETHA	;;++BS-FATAL ERROR, SET H/W ABORT 3(016)
	BR	23$		;;++BS-CONTINUE ERROR PROCESSING 3(016)
32$:				;;++BS-NEW LABEL 3(016)
	CLR	TCCMA(R5)	;DONT SEND MESSAGE TWICE
;
; HERE IF THERE IS NO PROMPTING CONTROL MESSAGE.
;  JUST ISSUE A READ.
;
13$:	JSR	PC,DQREAD	;READ THE TEXT BLOCK
				; (WILL GET TIMEOUT IF CANNOT READ)
	CLR	R4		;NO DATA YET
	JSR	PC,MSGGTC	;GET INPUT CHARACTER
	BCS	14$		;TIMEOUT
	CMPB	#EBCEOT,R1	;END OF TRANSMISSION?
	BEQ	25$		;YES, END OF FILE OR ABORT
	CMPB	#EBCENQ,R1	;NO, "ENQ"?
	BEQ	20$		;YES, GIVE POSITIVE RESPONSE.
	BIT	#TCXET,TCST2(R5) ;NO, EXPECTING EOT?
	BNE	22$		;YES, SHOULD GET ONE.
	CMPB	#EBCSTX,R1	;NO, START OF TEXT?
	BEQ	16$		;YES, READ NORMAL DATA
	CMPB	#EBCSOH,R1	;START OF HEADER?
	BEQ	16$		;TREAT THE SAME AS STX
	CMPB	#EBCDLE,R1	;NO, DATA LINK ESCAPE?
	BEQ	17$		;YES, READ TRANSPARENT TEXT
;
;
; HERE ON INVALID MESSAGE OR TIMEOUT
;
14$:	JSR	PC,MSGGT2	;END OF MSG AND WAIT 2 SEC FROM START
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC7(R4)	;COUNT INVALID MESSAGES
	BIT	#LS.ERR,(R4)	;HAS THERE BEEN AN ERROR?
;3(016)	BNE	23$		;YES, ABORT THE STREAM.
	BEQ	33$		;;++BS-NO, CONTINUE 3(016)
	JSR	PC, HSETHA	;;++BS-YES, SET THE H/W ABORT 3(016)
	BR	23$		;;++BS-CONTINUE WITH THE ABORT 3(016)
33$:				;;++BS-NEW LABEL 3(016)
	DEC	LB.RTY(R4)	;HAD ENOUGH (20 SEC WORTH?)
	BNE	12$		;NO, TRY AGAIN.
	JSR	PC, HSETHA	;;++BS-YES, SET THE H/W LINE ABORT 3(016)
	BR	23$		;YES, ABORT THE STREAM.
;
; HERE IF THE STREAM HAS BEEN ABORTED, PROBABLY BY THE
;  PDP-10.  SEND EOT AND RETURN.
;
15$:	JSR	PC,DQSEOT	;SEND EOT (UNLESS NOT NEEDED)
	RTS	PC		;RETURN.
;
;
; HERE ON STX TO PROCESS A NORMAL (NON-TRANSPARENT)
;  MESSAGE
;
16$:	JSR	PC,DQRNRM	;PROCESS THE BLOCK
	BR	18$		;ANALYZE C BIT AND R0 VALUE
;
; HERE ON "DLE" TO READ A TRANSPARENT DATA MESSAGE
;
17$:	JSR	PC,DQRXPM	;READ TEXT
;
; HERE AFTER READING A TEXT BLOCK TO RESPOND AS
;  INDICATED BY DQRXRM OR DQRNRM.
;
18$:	BCC	19$		;SUCCESS
	CMP	#2,R0		;SHOULD WE RESPOND TO THE BLOCK?
	BEQ	12$		;NO, LET TIMEOUT HAPPEN.
;
; ERROR IN MESSAGE, SEND NAK OR EOT.
;
	JSR	PC,DQRNRP	;SET UP A NAK
	BCS	24$		;RETRY COUNTER EXHAUSTED, ABORT
	BR	12$		;SEND NAK AND READ DATA AGAIN.
;
; MESSAGE READ SUCCESSFULLY, ACKNOWLEDGE IT.
;
19$:	MOV	#TCAK1,R0	;COMPLEMENT ACK-0/ACK-1 BIT
	XOR	R0,TCST2(R5)
	BIS	#TCIRN,TCFG2(R5) ;FLAG INPUT RUNNING
	BIC	#TCIPG,TCFG2(R5) ;CLEAR "INPUT PERMISSION GRANTED"
	BR	21$		;GIVE NEW POSITIVE RESPONSE
;
; HERE ON ENQ.  GIVE POSITIVE RESPONSE AGAIN.
;
20$:	JSR	PC,MSGGTE	;END OF INPUT TEXT
;
; HERE TO GIVE POSITIVE RESPONSE: ACK-0, ACK-1 OR WACK.
;
21$:	JSR	PC,DQRPRP	;SET UP ACK-0, ACK-1 OR WACK
	BR	11$		;SEND IT AND WAIT FOR 
				; NEXT TRANSMISSION BLOCK
;
;
; HERE IF THE MESSAGE AFTER A MESSAGE ENDING IN ETX
;  (WHICH WAS ACKED) DID NOT START WITH EOT OR ENQ.
;
22$:	JSR	PC,MSGGT2	;END OF INPUT AND WAIT 2 SEC SINCE START
;
; HERE IF THE MESSAGE AFTER THE LAST MESSAGE DID
;  NOT START WITH ENQ OR EOT, OR ON TRANSMITTER TIMEOUT.
;
23$:	JSR	PC,DQSEOT	;SEND EOT IF NECESSARY
;
; HERE TO ABORT THE MESSAGE STREAM.
;
24$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC6(R4)	;COUNT ABORTS
	JSR	PC,DQABRI	;FLAG STREAM ABORTED
	BIC	#TCXET,TCST2(R5) ;DONT EXPECT EOT NEXT
	BR	26$		;CLEAR GRANT AND RUNNING FLAGS AND RETURN.
;
; HERE ON RECEIVING "EOT".  IF THE LAST MESSAGE DID NOT END
;  WITH ETX THIS MEANS ABORT.
;
25$:	JSR	PC,MSGGTE	;END OF MESSAGE
	JSR	PC,DQREOT	;RECEIVE EOT
	BCS	24$		;THIS IS AN ABORT
;
; HERE TO CLEAR GRANT AND RUNNING FLAGS AND RETURN.
;
26$:	BIC	#TCIPG!TCIRN,TCFG2(R5) ;CLEAR GRANT AND RUNNING FLAGS
	RTS	PC		; AND RETURN.
;
;
; SUBROUTINE TO SET UP A POSITIVE RESPONSE, EITHER ACK-0, ACK-1
;  OR WACK.
;
;
DQRPRP:	BIT	#TCXET,TCST2(R5) ;LAST MESSAGE END IN ETX?
	BNE	11$		;YES, ALWAYS SEND ACK.
	CMP	CHFREC,#CHLACK	;NO, PLENTY OF FREE CHUNKS?
	BLT	12$		;NO, SEND WACK
11$:	BIT	#TCAK1,TCST2(R5) ;YES, SEND ACK-1?
	BEQ	13$		;NO, ACK-0.
	MOV	#AK1MSG,R0	;YES.
	MOV	#AK1LEN,R1
	BR	14$
;
; HERE IF THERE ARE NOT MANY CHUNKS LEFT.  SEND "WACK" TO
;  ACKNOWLEDGE THE MESSAGE BUT START AN ENQ-WACK EXCHANGE
;  UNTIL WE HAVE PLENTY OF CHUNKS AGAIN.
;
12$:	MOV	R4,-(SP)	;SAVE R4
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC4(R4)	;COUNT WACKS SENT
	MOV	(SP)+,R4	;RESTORE R4
	MOV	#WAKMSG,R0
	MOV	#WAKLEN,R1
	BR	14$
;
; HERE TO SEND ACK-0
;
13$:	MOV	#AK0MSG,R0
	MOV	#AK0LEN,R1
14$:	MOV	R0,TCCMA(R5)	;STORE CONTROL MESSAGE ADDRESS
	MOV	R1,TCCMC(R5)	; AND COUNT
	RTS	PC		;READ NEXT BLOCK
;
;
; SUBROUTINE TO SET UP A NEGATIVE RESPONSE, EITHER NAK
;  OR EOT.
;
; ON RETURN:
;
;	C CLEAR -- SET UP A NAK
;
;	C SET - RETRY COUNTER EXHAUSTED, ABORT THE STREAM.
;
DQRNRP:	MOV	TCLCB(R5),R4	;POINT TO LCB
	DEC	LB.RTY(R4)	;SHOULD WE SEND NAK AGAIN?
	BEQ	11$		;NO, ABORT THE STREAM.
	INC	LB.IC3(R4)	;YES, INCREMENT NAK COUNTER
	MOV	#NAKMSG,TCCMA(R5) ;SET UP A NAK
	MOV	#NAKLEN,TCCMC(R5)
	CLC			;GIVE SUCCESS RETURN
	RTS	PC		;RETURN.
;
; HERE IF THE RETRY COUNTER IS EXHAUSTED.
;
11$:
	JSR	PC, HSETHA	;;++BS-SET THE H/W ABORT 3(016)
	SEC			;FLAG COUNTER EXHAUSTED
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO PROCESS A RECEIVED EOT.
;
; ON RETURN:
;
;	C CLEAR -- WE HAVE REACHED END OF FILE
;
;	C SET -- THE EOT ABORTED THE STREAM.
;
DQREOT:	BIS	#TCEOT,TCST2(R5) ;NO EOT NEEDED TO ABORT
	BIT	#TCXET,TCST2(R5) ;ARE WE EXPECTING THIS EOT?
	BEQ	11$		;NO, THIS IS AN ABORT.
	BIC	#TCXET,TCST2(R5) ;YES, NO LONGET EXPECTING EOT
	BIS	#TCIEC,TCFG2(R5) ;SUCCESSFULLY REACHED EOF
	BIC	#TCIRN!TCIPG,TCFG2(R5) ;NO LONGER DOING INPUT
	MOV	TCLCB(R5),R4	;POINT R4 TO LCB
	JSR	PC,DQAWXL	;AWAKEN XLATE TASK
	CLC			;SIGNAL EOF
	RTS	PC		;RETURN.
;
; HERE IF THE EOT IS UNEXPECTED.  THIS IS ABORT.
;
11$:	SEC			;SIGNAL ABORT
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO READ A NON-TRANSPARENT TRANSMISSION BLOCK.
;
; ON RETURN:
;
;	C CLEAR - ALL OK, REPLY WITH ACK OR WACK
;
;	C SET - ERROR IN MESSAGE:
;	  R0 = 1 - SEND "NAK" OR (IF TOO MANY RETRIES) "EOT"
;	  R0 = 2 - SEND NOTHING (LET SENDER TIME OUT)
;
DQRNRM:	KGLOAD	#0		;INITIALIZE KG11-A
	BIC	#TCDTA,TCST2(R5) ;NO DATA AS YET
	MOV	R3,-(SP)	;SAVE R3
	MOV	CHLST,R0	;GET A CHUNK
	JSR	PC,GETCHK
	BCC	11$		;GOT ONE.
	MOV	(SP)+,R3	;NO MORE CHUNKS.  RESTORE R3
	JSR	PC,MSGGT2	;TERMINATE READING AND WAIT 2 SEC
	BR	DQRNRE		;GIVE ERROR RETURN.
;
11$:	MOV	(SP)+,R3	;RESTORE R3
	MOV	R0,MSGLCH(R0)	;BUILD MESSAGE HEADER
;
; HERE TO GET NEXT CHARACTER OF BLOCK.
;
DQRNRC:	JSR	PC,MSGGTC	;GET CHARACTER
	BCS	DQRNRT		;TIMEOUT
;
; HERE TO PROCESS THE CHARACTER IN R1
;
DQRNRA:	BIT	#300,R1		;CONTROL CHARACTER?
	BNE	11$		;NO.
	MOVB	EBCSPC(R1),R2	;YES, GET ITS CODE
	MOV	DQRNRD(R2),R2	;GET DISPATCH ADDRESS
	BEQ	11$		;NOT A DATA LINK CONTROL CHAR
	JMP	(R2)		;DATA LINK CONTROL -- DISPATCH
;
;
; HERE IF THE CHARACTER IS NOT A DATA-LINK CONTROL CHARACTER.
;
11$:	KGACUM	R1		;ACCUMULATE BCC
.IF NE,BSBUG
	BIT	#TRCPAD,TRCHLT	;SHOULD WE STOP ON PADS?
	BEQ	12$		;NO, MIGHT BE PART OF DATA
	CMPB	#EBCPAD,R1	;YES, PAD CHARACTER?
	BNE	12$		;NO.
	STOPCD	DBG		;YES, MAY BE A BUG HERE.
12$:
.ENDC ;.IF NE,BSBUG
	BIS	#TCDTA,TCST2(R5) ;WE HAVE SOME REAL DATA
	JSR	PC,MSGAPC	;APPEND TO OUTPUT STRING
	BCS	DQRNRT		;OUT OF CHUNKS
	TST	MSGLEN(R0) 	;IS MESSAGE UNREASONABLY LONG?
	BGT	DQRNRC		;NO, GET ANOTHER CHARACTER.
;
; HERE IF WE RUN OUT OF CHUNKS, GET READ TIMEOUT, OR THE MESSAGE
;  GETS TOO LONG.
;
DQRNRT:	JSR	PC,MSGGT2	;TERMINATE THE READ AND WAIT 2 SEC
	MOV	TCIDLE,R1	;POINT TO "IDLE" TCB
	JSR	PC,QUEMSG	;SEND IT PARTIAL MSG TO FREE
DQRNRE:	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC7(R4)	;COUNT MESSAGE IGNORED
	MOV	#2,R0		;ALLOW TIMEOUT TO HAPPEN
;
; HERE TO GIVE ERROR EXIT FROM DQRNRM.
;
DQRNRX:	BIC	#TCXET,TCST2(R5) ;NOT EXPECTING EOT NEXT
	SEC			;SIGNAL FAILURE
	RTS	PC		;RETURN.
;
; DISPATCH TABLE FOR DATA LINK CONTROL CHARACTERS
;
DQRNRD:	.WORD	0		;CODE 0 = MISCELLANEOUS
	.WORD	DQRNRC		;CODE 2 = SYN
	.WORD	12$		;CODE 4 = ETB
	.WORD	11$		;CODE 6 = ETX
	.WORD	14$		;CODE 10 = IUS
	.WORD	0		;CODE 12 = IRS
	.WORD	18$		;CODE 14 = ENQ
	.WORD	0		;CODE 16 = DLE
;
;
; HERE ON RECEIVING AN ETX.  THIS IS THE LAST MESSAGE IN THE STREAM.
;
11$:	BIS	#TCXET,TCST2(R5) ;FLAG LAST MESSAGE
;
; HERE ON RECEIVING ETB OR, FROM ABOVE, ETX.  THIS IS THE
;  LAST BLOCK IN THE MESSAGE.  ON THE IBM 2780 ETX AND ETB PROVIDE
;  THE IRS FUNCTION.
;
12$:	KGACUM	R1		;ACCUMULATE BCC
	JSR	PC,DQRBCC	;CHECK BCC
	BCS	DQRNRT		;TIMEOUT
	BIT	#TCOBS,TCFG1(R5) ;OLD BSC PROTOCOL?
	BEQ	13$		;NO, IRS ALREADY IN DATA
	MOV	#EBCIRS,R1	;YES, INCLUDE AN EXPLICIT IRS
	JSR	PC,MSGAPC	; TO SIMPLIFY XLATE
	BCS	DQRNRT		;OUT OF CHUNKS
13$:	JSR	PC,MSGGTE	;END OF MESSAGE
	KGTEST			;DID BCC COME OUT ZERO?
	BNE	17$		;NO, THERE IS A BCC ERROR.
	MOV	TCLCB(R5),R4	;YES, POINT TO LCB
	INC	LB.IC1(R4)	;COUNT A BLOCK RECEIVED SUCCESSFULLY
	MOV	LB.TCD(R4),R1	;POINT TO TRANSLATE TASK
	JSR	PC,QUEMSG	;SEND IT THE BLOCK
	CLC			;FLAG SUCCESS 
	RTS	PC		;RETURN TO CALLER.
;
;
; HERE ON RECEIVING AN IUS.  ON THE IBM 2780 THIS ALSO
;  PROVIDES THE IRS FUNCTION.  IN ANY CASE IT IS
;  FOLLOWED BY TWO CHARACTERS OF BCC.
;
14$:	KGACUM	R1		;INCLUDE IUS IN BCC
	JSR	PC,DQRBCC	;INCLUDE NEXT TWO CHARS IN BCC
	BCS	DQRNRT		;TIMEOUT
	KGTEST			;IS BCC RIGHT?
	BNE	16$		;NO.
	BIT	#TCOBS,TCFG1(R5) ;YES, USING OLD BSC?
	BEQ	15$		;NO, NO IRS FUNCTION.
	MOVB	#EBCIRS,R1	;YES, INCLUDE AN IRS
	JSR	PC,MSGAPC	; TO SIMPLIFY XLATE.
	BCS	DQRNRT		;OUT OF CHUNKS.
;
; HERE TO ABSORB THE OPTIONAL SYN'S AND STX THAT
;  MAY APPEAR BETWEEN BLOCKS.
;
15$:	JSR	PC,MSGGTC	;GET NEXT CHARACTER (AFTER BCC)
	BCS	DQRNRT		;TIMEOUT
	CMPB	#EBCSYN,R1	;SKIP SYNCS
	BEQ	15$
	CMPB	#EBCSTX,R1	;IS THIS STX?
	BNE	DQRNRA		;NO, INCLUDE IN DATA
	KGACUM	R1		;YES, INCLUDE IN BCC
	JMP	DQRNRC		;BUT NOT IN DATA
;
; HERE IF THE BCC PROVES TO BE BAD.
;
16$:	JSR	PC,MSGGT2	;TERMINATE READ AND WAIT 2 SEC
17$:	MOV	TCIDLE,R1	;POINT TO BACKGROUND TASK
	JSR	PC,QUEMSG	;SEND IT THE BAD MSG TO BE FREED
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC2(R4)	;COUNT INSTANCES OF BAD BCC
	MOV	#1,R0		;GIVE "NAK" REPLY
	BR	DQRNRX		;GIVE ERROR RETURN.
;
;
; HERE IF WE FIND AN ENQ IN THE DATA.  THIS IS PROBABLY A TTD
;  OR FORWARD ABORT.  IN EITHER CASE, SEND A NAK.
;
18$:	BIT	#TCDTA,TCST2(R5) ;HAVE WE HAD ANY REAL DATA?
	BNE	19$		;YES, THIS IS FORWARD ABORT.
	JSR	PC,MSGGTE	;NO, END OF INPUT.
	MOV	TCIDLE,R1	;POINT TO IDLE TCB
	JSR	PC,QUEMSG	;SEND IT MESSAGE TO FREE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC5(R4)	;COUNT TTD MESSAGES
	INC	LB.RTY(R4)	;DONT COUNT THIS NAK TOWARDS
				; RETRY THRESHOLD
	DEC	LB.IC3(R4)	;OR IN STATISTICS
	MOV	#1,R0		;INDICATE SEND NAK
	JMP	DQRNRX		;GIVE ERROR RETURN
;
; HERE IF THE ENQ IS A FORWARD ABORT RATHER THAN PART OF A TTD.
;
19$:	JSR	PC,MSGGT2	;END OF INPUT AND WAIT 2 SEC
	MOV	TCIDLE,R1	;POINT TO BACKGROUND TASK
	JSR	PC,QUEMSG	;SEND IT THE TRUNCATED MESSAGE
	MOV	#1,R0		;INDICATE SEND NAK
	JMP	DQRNRX		;WILL PROBABLY GET ABORTING EOT
;
;
; SUBROUTINE TO ACCUMULATE A TRANSPARENT MESSAGE.  THE DLE HAS
;  ALREADY BEEN READ.
;
; ON RETURN:
;
;	C CLEAR - ALL OK, REPLY ACK OR WACK
;
;	C SET - FAILURE:
;	  R0 = 1 - SEND NAK OR (IF RETRY COUNTED TO ZERO) ENQ
;	  R0 = 2 - SEND NOTHING (LET SENDER TIME OUT)
;
DQRXPM:	KGLOAD	#0		;INITIALIZE KG11-A
	JSR	PC,MSGGTC	;GET CHAR AFTER DLE
	;[1007]2780/3780 understand SOH as STX so let's do it too.
		CMPB	#EBCSOH,R1	;[1007]IS IT SOH?
		BEQ	11$		;[1007]YES, DO AS THOUGH AN STX.
	CMPB	#EBCSTX,R1	;IS IT STX?
	BEQ	11$		;YES.
	JSR	PC,MSGGT2	;NO, TERMINATE READ, WAIT 2 SEC
	BR	DQRXPE		; AND IGNORE MESSAGE
;
; HERE TO BEGIN READING A RECORD.
;
11$:	MOV	R3,-(SP)	;SAVE R3
	MOV	CHLST,R0	;GET A CHUNK
	JSR	PC,GETCHK
	BCC	12$		;GOT ONE
	MOV	(SP)+,R3	;FAILED, RESTORE R3
	JSR	PC,MSGGT2	;TERMINATE READING AND WAIT 2 SEC
	BR	DQRXPE		;GIVE ERROR RETURN.
;
12$:	MOV	(SP)+,R3	;RESTORE R3
	MOV	R0,MSGLCH(R0)	;SET UP MESSAGE HEADER BLOCK
	BIS	#MSGTSP,MSGFGS(R0) ;FLAG MESSAGE AS TRANSPARENT
	KGLOAD	#0		;INITIALIZE KG11-A
DQRXPC:	JSR	PC,MSGGTC	;GET CHARACTER FROM BLOCK
	BCS	DQRXPT		;TIMEOUT
	CMPB	#EBCDLE,R1	;IS IT DLE?
	BEQ	DQRXPB		;YES.
;
; HERE ON A NON-DLE CHARACTER OR ON A DLE FOLLOWING A DLE.
;  APPEND THE CHARACTER TO THE MESSAGE BEING BUILT.
;
DQRXPG:	KGACUM	R1		;NO, ACCUMULATE IN BCC
	JSR	PC,MSGAPC	;BUILD MESSAGE FOR TRANSLATOR
	BCS	DQRXPT		;OUT OF CHUNKS
	CMP	MSGLEN(R0),#512. ;IS MESSAGE GETTING TO BE TOO LONG?
	BLE	DQRXPC		;NO, GET NEXT CHARACTER.
	JMP	DQRXPT		;YES, TERMINATE THE MESSAGE.
;
;
; HERE ON DLE CHARACTER EXCEPT A DLE FOLLOWING A DLE
;
DQRXPB:	JSR	PC,MSGGTC	;GET NEXT CHARACTER (AFTER DLE)
	BCS	DQRXPT		;TIMEOUT
	BIT	#300,R1		;CONTROL CHARACTER?
	BNE	11$		;NO, INVALID.
	MOVB	EBCSPC(R1),R2	;YES, GET ITS CODE
	MOV	DQRXPD(R2),R2	;GET DISPATCH ADDRESS
	BEQ	11$		;NOT A VALID CHARACTER IN THIS CONTEXT
	JMP	(R2)		;DISPATCH TO CHAR HANDLER
;
; HERE ON INVALID CHARACTER AFTER DLE.
;
11$:	JSR	PC,MSGGT2	;TERMINATE READING AND WAIT 2 SEC
	MOV	TCIDLE,R1	;POINT TO IDLE TCB
	JSR	PC,QUEMSG	;SEND IT MSG TO FREE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC8(R4)	;COUNT INVALID CHARS AFTER DLE
	MOV	#1,R0		;RESPOND WITH NAK
	SEC			;SIGNAL FAILURE
	RTS	PC		;RETURN.
;
; HERE IF WE MUST IGNORE THE MESSAGE BECAUSE OF CHUNK DEPLETION
;  OR RECEIVE TIMEOUT.
;
DQRXPT:	JSR	PC,MSGGT2	;TERMINATE READING AND WAIT 2 SEC
	MOV	TCIDLE,R1	;POINT TO IDLE TASK
	JSR	PC,QUEMSG	;SEND IT MSG TO FREE
DQRXPE:	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC7(R4)	;COUNT MESSAGES IGNORED
	MOV	#2,R0		;INDICATE NO RESPONSE
;
; HERE TO GIVE THE ERROR RETURN FROM DQRXPM.
;
DQRXPX:	BIC	#TCXET,TCST2(R5) ;NOT EXPECTING EOT NEXT
	SEC			;FLAG FAILURE
	RTS	PC		;RETURN.
;
;
; DISPATCH TABLE FOR SPECIAL CHARACTERS AFTER DLE
;
DQRXPD:	.WORD	0		;CODE 0 = MISCELLANEOUS
	.WORD	DQRXPC		;CODE 2 = SYN
	.WORD	12$		;CODE 4 = ETB
	.WORD	11$		;CODE 6 = ETX
	.WORD	13$		;CODE 10 = IUS
	.WORD	0		;CODE 12 = IRS
	.WORD	0		;CODE 14 = ENQ
	.WORD	DQRXPG		;CODE 16 = DLE
;
; HERE ON DLE ETX.  THIS IS THE LAST MESSAGE OF THE STREAM.
;
11$:	BIS	#TCXET,TCST2(R5) ;EXPECT EOT NEXT
;
; HERE ON DLE ETB AND (FROM ABOVE) DLE ETX.  THIS IS THE LAST
;  RECORD IN THE MESSAGE.
;
12$:	KGACUM	R1		;ACCUMULATE BCC
	JSR	PC,DQRBCC	;ACCUMULATE NEXT TWO CHARS, TOO
	BCS	DQRXPT		;TIMEOUT
	JSR	PC,MSGGTE	;TERMINATE READING
	KGTEST			;IS BCC OK?
	BNE	16$		;NO, BCC ERROR.
	MOV	TCLCB(R5),R4	;YES, POINT TO LCB
	INC	LB.IC1(R4)	;COUNT BLOCKS RECEIVED SUCCESSFULLY
	MOV	LB.TCD(R4),R1	;POINT TO TRANSLATE TASK
	JSR	PC,QUEMSG	;SEND IT THE BLOCK
	CLC			;INDICATE SUCCESS
	RTS	PC		;AND RETURN.
;
;
; HERE ON DLE IUS.  THIS SIGNALS THAT A BCC WILL FOLLOW.
;  ON THE IBM 2780 IT ALSO PERFORMS THE IRS FUNCTION.
;
13$:	KGACUM	R1		;ACCUMULATE BCC
	JSR	PC,DQRBCC	;ACCUMULATE NEXT TWO CHARS, TOO
	BCS	DQRXPT		;TIMEOUT
	KGTEST			;IS BCC OK?
	BNE	15$		;NO.
;
; HERE TO ABSORB THE OPTIONAL SYNCS BETWEEN RECORDS.
;
14$:	JSR	PC,MSGGTC	;GET NEXT CHARACTER
	BCS	17$		;TIMEOUT
	CMPB	#EBCSYN,R1	;SYNC?
	BEQ	14$		;YES, IGNORE THEM.
	CMPB	#EBCDLE,R1	;NO, DLE?
	BNE	17$		;NO, INVALID CONTINUATION.
	JSR	PC,MSGGTC	;YES, GET NEXT CHARACTER
	BCS	17$		;TIMEOUT
	CMPB	#EBCSYN,R1	;SYN? (DLE SYN)
	BEQ	14$		;YES, IGNORE IT.
	CMPB	#EBCSTX,R1	;NO, STX?
	BNE	17$		;NO, ERROR: STX MANDATORY
	KGACUM	#EBCDLE		;YES, LOAD "DLE" INTO BCC
	KGACUM	R1		;INCLUDE STX IN BCC
	JMP	DQRXPC		;BUT NOT IN DATA
;
;
; HERE ON BCC ERROR.
;
15$:	JSR	PC,MSGGT2	;TERMINATE READING AND WAIT 2 SEC
16$:	MOV	TCIDLE,R1	;POINT TO BACKGROUND TASK
	JSR	PC,QUEMSG	;SEND IT THE BAD MSG TO FREE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC2(R4)	;RECORD BAD BCC
	MOV	#1,R0		;REPLY WITH A NAK (OR EOT)
	BR	DQRXPX		;GIVE ERROR RETURN.
;
; HERE ON INVALID CHARACTER SEQUENCE BETWEEN BLOCKS
;
17$:	JSR	PC,MSGGT2	;TERMINATE READING AND WAIT 2 SEC
	MOV	TCIDLE,R1	;POINT TO BACKGROUND TASK
	JSR	PC,QUEMSG	;SEND IT THE BAD MSG TO FREE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC9(R4)	;COUNT INVALID SEQUENCES
	MOV	#2,R0		;INDICATE NO REPLY
	JMP	DQRXPX		;GIVE ERROR RETURN.
;
;
; SUBROUTINE TO ACCUMULATE THE NEXT TWO CHARACTERS OF THE
;  MESSAGE INTO THE BCC.
;
; ON RETURN:
;
;	C CLEAR MEANS ALL OK
;
;	C SET MEANS TIMEOUT (SAME AS RETURN FROM MSGGTC)
;
;	THE CRC ACCUMULATION REGISTER WILL BE 0 ONLY IF THE
;	 CRC CHECKS.
;
DQRBCC:	JSR	PC,MSGGTC	;GET NEXT CHARACTER
	BCS	11$		;TIMEOUT
	KGACUM	R1		;ACCUMULATE IN BCC
	JSR	PC,MSGGTC	;GET SECOND CHARACTER
	BCS	11$		;TIMEOUT
	KGACUM	R1		;ACCUMULATE IN BCC
	CLC			;FLAG SUCCESS
11$:	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO SEND A CONTROL MESSAGE AND START READING RESPONSE.  
;
;  R0 POINTS TO THE TEXT OF THE MESSAGE
;  R1 CONTAINS THE LENGTH OF THE MESSAGE
;  R5 POINTS TO THE TCB
;
;  LS.LWR IS SET IF NO RESPONSE IS EXPECTED.
;
; ON RETURN:
;
;	C IS CLEAR IF THE MESSAGE WENT, SET IF WE TIMED OUT
;	  OR HAD AN ERROR.
;
;	ALL REGISTERS BUT R5 ARE DESTROYED.
;
CTLMSG:	MOV	#EBINTR!EBTIME!EBWAIT,(R5) ;WAKE-UP CONDITIONS
	MOV	R1,TCTIM(R5)	;NO MORE THAN 1 TICK PER CHAR
	MOV	TCLCB(R5),R4	;POINT TO LCB
	ADD	LB.CSD(R4),TCTIM(R5) ;PLUS CLEAR-TO-SEND DELAY
	JSR	PC,DQCNTL	;SEND THE MESSAGE
	BCS	14$		;ERROR
	BIT	#LS.LWR,(R4)	;SHOULD WE EXPECT A RESPONSE?
	BNE	11$		;NO.
	JSR	PC,DQREAD	;YES, SET UP TO READ RESPONSE.
11$:	BIC	#LS.LWR,(R4)	;CLEAR "LAST" BIT
	JSR	PC,WAIT		;WAIT FOR TRANSMITTER TO FINISH
	BIT	#EBINTR,(R5)	;DID TRANSMITTER FINISH IN TIME?
	BNE	12$		;NO.
	CLC			;YES, INDICATE SUCCESS
	RTS	PC		; AND RETURN.
;
; HERE WHEN THE TRANSMITTER TIMED OUT.  STOP IT AND
;  INDICATE ERROR.
;
12$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQKILL	;STOP THE TRANSMITTER [1(637)]
	INC	LB.TTO(R4)	;COUNT TIMEOUTS
13$:	SEC			;SIGNAL ERROR
14$:	RTS	PC		; AND RETURN.
;
;
; SUBROUTINE TO STORE INTO A MESSAGE THE BCC VALUE ACCUMULATED
;  IN THE KG11-A SO FAR.
;
; ON RETURN:
;
;	C CLEAR - BCC STORED, KG11-A BCC REGISTER ZERO.
;
;	C SET - OUT OF CHUNKS.
;
;
STOBCC:	KGSAVE	-(SP)		;GET CURRENT BCC
	MOVB	(SP),R1		;GET FIRST BYTE
	KGACUM	R1		;ACCUMULATE IN BCC
	JSR	PC,MSGAPC	;APPEND TO STRING
	BCS	12$		;OUT OF CHUNKS
	MOVB	1(SP),R1	;GET SECOND BYTE OF BCC
	KGACUM	R1		;ACCUMULATE IN BCC
	JSR	PC,MSGAPC	;APPEND TO STRING
	BCS	12$		;OUT OF CHUNKS
.IF NE,FT.CHK
	KGTEST			;IS TOTAL BCC NOW ZERO?
	BEQ	11$		;YES.
	STOPCD	BCE		;NO, BCC ACCUMULATION ERROR.
11$:
.ENDC ;.IF NE,FT.CHK
	MOV	(SP)+,R1	;DELETE BCC FROM STACK
	CLC			;SIGNAL OK
	RTS	PC		;RETURN.
;
; HERE IF WE RUN OUT OF CHUNKS
;
12$:	MOV	TCIDLE,R1	;POINT TO IDLE TASK
	JSR	PC,QUEMSG	;SEND IT THE MESSAGE TO FREE
	MOV	(SP)+,R1	;DELETE BCC FROM STACK
	SEC			;SIGNAL ERROR
	RTS	PC		; AND RETURN.
;
;
; SUBROUTINES TO ABORT THE MESSAGE STREAM DUE TO THE DEVICE
;  AT THE OTHER END OF THE LINE.  FOR EXAMPLE, RUNNING OUT
;  OF RETRIES WILL ABORT THE STREAM.
;
;  TO SIMPLIFY THE CODING OF THE BSC ROUTINES, THESE SUBROUTINES
;  CAN BE CALLED SEVERAL TIMES FOR THE SAME ABORT -- SUBSEQUENT
;  CALLS FOR A MESSAGE STREAM ARE NO-OPS.
;
; SUBROUTINE TO ABORT AN OUTPUT STREAM
;
DQABRO:	TRACE	TRCABO,(SP)	;TRACE ABORT CALL
.IF NE,BSBUG
	BIT	#TRCABO,TRCHLT	;ARE WE ASKED TO STOP ON ABORT?
	BEQ	11$		;NO.
	STOPCD	DBG		;YES, BSBUG STOP.
11$:
.ENDC ;.IF NE,BSBUG
	BIT	#TCOAB,TCFG2(R5) ;ALREADY ABORTED?
	BNE	12$		;YES, DONT DO IT AGAIN.
	MOV	TCLCB(R5),R4	;NO, POINT TO LCB
	MOV	LB.TC1(R4),R1	;POINT TO BSC TCB
	BIS	#TCOAB,TCFG2(R1) ;SIGNAL ABORT
	MOV	LB.TCD(R4),R1	;POINT TO TRANSLATION TASK
	BIS	#TCOAB,TCFG2(R1) ;SIGNAL ABORT, TOO.
	JSR	PC, HSTAOA	;;++BS-SET DEVICE ACTIVE BIT 3(020)
12$:	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO ABORT AN INPUT STREAM
;
DQABRI:	TRACE	TRCABO,(SP)	;TRACE ABORT CALL
.IF NE,BSBUG
	BIT	#TRCABO,TRCHLT	;ARE WE ASKED TO STOP ON ABORT?
	BEQ	11$		;NO.
	STOPCD	DBG		;YES, BSBUG STOP.
11$:
.ENDC ;.IF NE,BSBUG
	BIT	#TCIAB,TCFG2(R5) ;ALREADY ABORTED?
	BNE	12$		;YES, DONT DO IT AGAIN.
	MOV	TCLCB(R5),R4	;NO, POINT TO LCB
	MOV	LB.TC1(R4),R1	;POINT TO BSC TCB
	BIS	#TCIAB,TCFG2(R1) ;SIGNAL ABORT
	MOV	LB.TCD(R4),R1	;POINT TO TRANSLATION TASK
	BIS	#TCIAB,TCFG2(R1) ;SIGNAL ABORT, TOO.
	JSR	PC, HSTAIA	;;++BS-SET DEVICE ACTIVE BIT 3(020)
12$:	RTS	PC		;RETURN.
;
;
;
;
;;++BS-3(020) SUBROUTINE TO SET DEVICE ACTIVE BIT
;;++BS-3(020) FOR OUTPUT ABORT



HSTAOA:	

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5),R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	BIT	#LF.SIM, LB.FGS(R2) ;SIMULATION OR SUPPORT ?
	BEQ	21$		;SUPPORT
	MOV	#3, R1		;SIMULATION, MUST BE CDR
	BR	22$		;SET DEVICE ACTIVE BIT
21$:	MOV	#4, R1		;SUPPORT, MUST BE LPT
22$:	JSR	PC, HSACMP	;SET THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN
	
;;++BS-3(020) END OF HSTAOA
;
;
;
;
;;++BS-3(020) SUBROUTINE TO SET DEVICE ACTIVE BIT
;;++BS-3(020) FOR INPUT ABORT


HSTAIA:	

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5),R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	BIT	#LF.SIM, LB.FGS(R2) ;SIMULATION OR SUPPORT ?
	BEQ	21$		;SUPPORT
	MOV	#4, R1		;SIMULATION, MUST BE LPT
	BR	22$		;SET DEVICE ACTIVE BIT
21$:	MOV	#3, R1		;SUPPORT, MUST BE CDR
22$:	JSR	PC, HSACMP	;SET THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN

;;++BS-3(020) END OF HSTAIA

;
;

;
;
;
;;++BS-3(021) SUBROUTINE TO CLEAR DEVICE ACTIVE BIT
;;++BS-3(021) FOR OUTPUT ABORT COMPLETE ACK
;;++BS-3(021) CALLED BY DTE TASK ONLY


HCLAOA:	

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCXLT(R5), R2	;POINT TO XLATE TASK
	MOV	TCLCB(R2), R2	;POINT TO LCB
	CMP	#TTHASP, LB.DVT(R2) ;HASP LINE ?
	BEQ	23$		;YES, THIS IS A NOP
				;NO, CLEAR THE ACTIVE BIT
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	BIT	#LF.SIM, LB.FGS(R2) ;SIMULATION OR SUPPORT ?
	BEQ	21$		;SUPPORT
	MOV	#3, R1		;SIMULATION, MUST BE CDR
	BR	22$		;SET DEVICE ACTIVE BIT
21$:	MOV	#4, R1		;SUPPORT, MUST BE LPT
22$:	JSR	PC, HSAMPC	;SET THE DEVICE ACTIVE BIT
23$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN
	
;;++BS-3(021) END OF HCLAOA
;
;
;
;
;;++BS-3(021) SUBROUTINE TO CLEAR DEVICE ACTIVE BIT
;;++BS-3(021) FOR INPUT ABORT COMPLETE ACK
;;++BS-3(021) CALLED BY DTE TASK ONLY

HCLAIA:	

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCXLT(R5), R2	;POINT TO XLATE TASK
	MOV	TCLCB(R2), R2	;POINT TO LCB
	CMP	#TTHASP, LB.DVT(R2) ;HASP LINE ?
	BEQ	23$		;YES THIS IS A NOP
				;NO, CLEAR THE ACTIVE BIT
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	BIT	#LF.SIM, LB.FGS(R2) ;SIMULATION OR SUPPORT ?
	BEQ	21$		;SUPPORT
	MOV	#4, R1		;SIMULATION, MUST BE LPT
	BR	22$		;SET DEVICE ACTIVE BIT
21$:	MOV	#3, R1		;SUPPORT, MUST BE CDR
22$:	JSR	PC, HSAMPC	;SET THE DEVICE ACTIVE BIT
23$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN

;;++BS-3(021) END OF HCLAIA


;
;
; SUBROUTINE TO SEND AN EOT TO CLEAR THE LINE AND RETURN
;  THE DEVICE AT THE OTHER END TO CONTROL STATE.  THIS
;  IS USED TO ABORT THE STREAM AND AFTER RECEIVING
;  ACKNOWLEDGMENT OF THE LAST MESSAGE IN AN OUTPUT STREAM.
;
; TO SIMPLIFY THE CODING OF THE ERROR ROUTINES THIS
;  SUBROUTINE MAY BE CALLED REDUNDENTLY.  EXTRA CALLS FOR A
;  PARTICULAR MESSAGE STREAM ARE IGNORED.
;
; ON RETURN:
;
;	C IS SET IF THE MESSAGE FAILED BECAUSE OF ERROR OR
;	  TRANSMITTER TIMEOUT, CLEAR IF THE MESSAGE WAS SENT
;	  OK OR IF NO MESSAGE NEEDED TO BE SENT.
;
;	ALL REGISTERS BUT R5 ARE DESTROYED.
;
DQSEOT:	BIT	#TCEOT,TCST2(R5) ;DO WE NEED AN EOT TO CLEAR THE LINE?
	BNE	11$		;NO, ONE IS ENOUGH.
	BIS	#TCEOT,TCST2(R5) ;YES, ONLY ONE REQUIRED PER STREAM
	MOV	#EOTMSG,R0	;SEND AN EOT
	MOV	#EOTLEN,R1
	BIS	#LS.LWR,@TCLCB(R5) ;LAST MESSAGE OF THE STREAM
	JSR	PC,CTLMSG
	RTS	PC		;RETURN.
;
; HERE IF THERE IS NO NEED TO SEND A MESSAGE
;
11$:	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN.
;
;
; THIS SUBROUTINE CHECK S FOR INPUT AND OUTPUT ABORTS
; AND FLUSHES ALL MESSAGES QUEUED TO THE BSC TASK
;
HSCKAB:
	JSR	PC,HSWALX	;WAKE UP ALL XLATE TASKS
	MOV	TCLCB(R5),R4	;POINT TO LCB
	CLR	TCDTB(R5)	;INITIALIZE DEVICE FOR ABORT
11$:	INC	TCDTB(R5)	;START WITH CONSOLE AND INC
	CMP	TCDTB(R5),LB.NTC(R4) ;DONE WITH ALL DEVICES
	BHI	12$		;YES, EXIT
	MOV	TCDTB(R5),R1	;NEED DEVICE # IN R1
	JSR	PC,HSCKDO	;DO ABORT PROCESSING
	BR	11$		; FOR ALL DEVICES
12$:	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN
;
;
; THE FOLLOWING CODE (FROM HERE TO END OF THIS MODULE) 
; IS USED ONLY IF LINE IS IN HASP-MODE.
;
; HERE IF THE LINE IS FOUND TO BE IN HASP MODE. 
;
HSPLIN:	MOV	#JIFSEC,TCTIM(R5) ;FOR ACKING ONCE IN 2-SECS
	BIT	#TCOPG,TCFG2(R5) ;IS BID COMPLETE?
	BEQ	11$		;NO.
	mov	tclcb(r5),r4	;point to lcb
	bic	#ls.err,(r4)	;clear any previous errors
	BIT	#TCDIDO,TCBSCF(R5) ;WERE WE XMITTING LAST?
	BNE	13$		;YES, PREPARE TO RECEIVE NOW
	BR	19$		;NO, GO XMIT
;
; HERE WHEN BID IS NOT COMPLETE.
;
11$:	
	JSR	PC,HSCKAB	;CHECK FOR ABORTS
	MOV	TCLCB(R5),R4	;R4 POINTS TO LCB
	BIT	#TCOPR,TCFG2(R5) ;SEE IF REQUESTED BID?
	BNE	16$		;YES, TRY BIDDING SOH-ENQ
	JSR	PC,DQREAD	;SEE IF OTHER SIDE IS BIDDING
	CLR 	R4		;NO DATA AS YET
	JSR	PC,MSGGTC	;GET CHARACTER FROM MSG READ
	BCS	15$		;NONE.
12$:	CMPB	#EBCSOH,R1	;RECVD SOH?
	BNE	15$		;NO, UNRECOGNIZED RESPONSE
	JSR	PC,MSGGTC	;YES,GET NEXT CHAR
	BCS	15$		;NONE
	CMPB	#EBCENQ,R1	;ENQ FOLLOWING SOH?
	BNE	15$		;NO, UNRECOGNIZED RESPONSE
	JSR	PC, HSETCE	;;++BS-COMMUNICATIONS ESTABLISHED 3(013)
	JSR	PC,HSINIR	;YES, INITIALIZE MESSAGE HEADERS
	BCS	14$		;TROUBLE TRANSMITTING ACK0
;
; HERE SOH-ENQ SEQUENCE HAS BEEN RECEIVED.
; AND ACK0 HAS BEEN SENT, GET READY TO RECEIVE RESPONSE
;
13$:	JSR	PC,HSRECV	;GO RECEIVE DATA
14$:	JMP	DQBCTL		;WHEN DONE CHECK AGAIN
;
15$:	JSR	PC,MSGGTT	;END MESSAGE AND WAIT THE SECOND
	BR	20$		;WAIT AND WAKE UP ALL XLATE TASKS
;
; HERE WHEN WE HAVE DATA TO SEND , BID FOR THE LINE
;
16$:	MOV	LB.EQN(R4),LB.RTY(R4) ;NO. OF TRIES TO GET THE LINE
18$:	MOV	#BIDMSG,R0	;SEND SOH-ENQ BID SEQUENCE 
	MOV	#BIDLEN,R1	;LENGTH OF THE BID SEQUENCE
	JSR	PC,CTLMSG	;SEND AS CONTROL MSG
	BCS	22$		;ERROR, QUIT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.EQW(R4),TCTIM(R5) ;TIME TO WAIT FOR REPLY
	CLR	R4		;NO DATA YET
	JSR	PC,MSGGTC	;GET CHAR FROM RECVER
	BCS	21$		;NOTHING RECVD
	CMPB	#EBCDLE,R1	;IS IT DLE?
;	BNE	21$		;NO, CHECK FOR SOH-ENQ SEQUENCE
	BNE	12$		;;++BS-NO, CHECK FOR SOH-ENQ SEQUENCE
	JSR	PC,MSGGTC	;GET NEXT CHAR
	BCS	21$		;NONE
	CMPB	#EBCAK0,R1	;IS IT ACK0 AFTER DLE?
	BNE	21$		;NO, UNRECOGNIZED MSG
	jsr	pc,msggte	;clear the receiver
	JSR	PC, HSETCE	;;++BS-COMMUNICATIONS ESTABLISHED 3(013)
	bic	#tcdido,tcbscf(r5) ;operation was receive
;
; HERE WE HAVE RECEIVED ACKNOWLEDGEMENT FOR THE BID 
; THE LINE IS MARKED AS BID COMPLETE AND SET TO SEND MESSAGES
; AFTER AWAKENING ALL THE XLATE DEVICE TASKS
;
	JSR	PC,HSINIT	;INITIALIZE BCB,FCS AND MARK LINE BID
19$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,HSWALX	;AWAKEN ALL TRANSLATE TASKS
	JSR	PC,HPXMIT	;GO TRANSMIT SIGNON BLOCK
20$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,HSWALX	;AWAKEN ALL TRANSLATE TASKS
	MOV	#EBTIME!EBWAIT,(R5) ;WAIT A WHILE
	MOV	#30,TCTIM(R5)	;SO XLATE CAN FINISH
	JSR	PC,WAIT		;ABORTS ETC.
	JMP	DQBCTL
;
;
; HERE WHEN THE RESPONSE TO BID IS UNRECOGNIZABLE
;  FINISH WAITING IF NECESSARY AND BID AGAIN.
;
21$:	JSR	PC,MSGGTT	;EMPTY THE RECEIVER AND WAIT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC8(R4)	;RECORD UNRECOGNIZABLE BID RESPONSE
	BIT	#TCOPR,TCFG2(R5) ;STILL WANT TO BID FOR THE LINE?
	BEQ	20$		;NO.
22$:	DEC	LB.RTY(R4)	;YES, HAVE WE TRIED OFTEN ENOUGH?
	BNE	18$		;NO, TRY AGAIN
	BIC	#TCOPR,TCFG2(R5) ;YES, NO LONGER BIDDING
	BR	20$		;AWAKEN ALL XLATE TASKS
;
; THIS SUBROUTINE INITIALIZES BCB AND FCS BYTES BESIDES 
; CLEARING THE RECEIVER AND MARKING LINE AS BID COMPLETE.
;
hsinit:
	BIC	#TCOPR,TCFG2(R5) ;NO LONGER BIDDING
	BIS	#TCOPG,TCFG2(R5) ;BID COMPLETE
	CLR	TCSDM(R5)	;INITIALIZE DEV PTR
	CLR	TCDPG(R5)	;PERMISSION CELL
	CLR	TCRQPT(R5)	;FOR SENDING REQ TO HASP
	MOV	#200,TCTBCB(R5)	;INITIALIZE TRANSMIT BLOCK COUNT
	MOV	#200,TCXBCB(R5)	;INITIALIZE RECEIVE BLOCK COUNT
	MOV	#104301,TCTFCS(R5) ;INITIALIZE TRANSMIT FCS
	MOV	#104301,TCPFCS(R5) ;AND PREV FCS TOO
	MOV	TCLCB(R5),R4	;POINT TO LCB
	BIC	#LF.SON,LB.FGS(R4) ;NOT YET SIGNED ON
	CLC			;INDICATE SUCCESS
	RTS	PC		;AND RETURN
;
; THIS SUBROUTINE SENDS AN ACK0 AND INITIALIZES
; BCB AND FCS BYTES
;
HSINIR:	JSR	PC,MSGGTE	;CLEAR THE RECEIVER
	MOV	#AK0MSG,R0	;SET UP TO SEND ACK0
	MOV	#AK0LEN,R1	;
	JSR	PC,CTLMSG	;SEND THE CONROL MESSAGE
	BCS	11$		;ERROR IN SENDING
	bis	#tcdido,tcbscf(r5) ;last operation was xmit
	JSR	PC,HSINIT	;INITILIZE BCB AND FCS
11$:	RTS	PC		;AND RETURN
;
;
; subroutine is called when we have to receive .
;
HSRECV:	CMP	CHFREC,#36	;HAVE WE PLENTY OF CHUNKS?
	BGT	12$		;YES.
;
; HERE TO SEND A UNIVERSAL SUSPENSION TO HASP
;
	BIS	#FCSUNV,TCTFCS(R5)	;SET SUSPEND
	BR	HSPXM5		;RECEIVE DATA AND TRANSMIT STATUS
;
; HERE IF THERE ARE ENOUGH CHUNKS TO RECEIVE DATA
;
12$:	BIC	#FCSUNV,TCTFCS(R5) ;UNSUSPEND HASP DATA
	BR	HSPXM5		;SET UP TO RECEIVE
;
;THE FOLLOWING SUBROUTINE CHECKS THE MODEM STATUS
;
HSCMDS:	MOV	TCLCB(R5),R0	;POINT TO LCB
	CLR	R1		;CLEAR FOR STATUS
	JSR	PC,DQMDMS	;GET MODEM STATUS
	BIT	#B2,R1		;DATA SET READY?
	BNE	12$		;YES.
11$:	SEC			;NO, SET CARRY
	RTS	PC		;AND RETURN
12$:	BIT	#B1,R1		;DTR UP?
	BEQ	11$		;NO, SET C
	CLC			;INDICATE SUCCESS, DSR ON
	RTS	PC		;AND RETURN
;
;
; HERE WE HAVE BID COMPLETE. SEND MESSAGES OR AK0 IF IDLE.
;
HPXMIT:
	JSR	PC,HSCMDS	;DATA SET READY?
	BCS	HSPXAI		;NO, ABORT OUTPUT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	BIT	#LS.ENB,(R4)	;LINE DISABLED?
	BEQ	HSPXAI		;YES....GONE
	CLR	TCCMA(R5)	;SO WE DONT SEND IT AGAIN
	MOV	#15.,LB.RTY(R4) ;RETRY COUNT IS 15.
	BIT	#LS.ERR,(R4)	;HAVE WE HAD A DQ11 ERROR?
	BNE	HSPXM3		;YES, TERMINATE.
	JSR	PC,HSGTMS	;GET MESSAGE TO XMIT (IF ANY)
	TST	LB.MSG(R4)	;DID WE GET A MESSAGE
	bne	hspxm1		;yes, start sending
HSPXM4:	mov	#ak0msg,r0	;no, set up to send an ak0
	mov	#ak0len,r1	;length of ack0 msg
	jsr	pc,ctlmsg	;send the ack0
	bcs	hspxm3		;can't output control message
	bis	#tcdido,tcbscf(r5) ;just did output
	br	HSRECV		;start receiving now
;
;
; HERE WITH A MESSAGE TO BE SENT IN LB.MSG
;
HSPXM1:	MOV	TCLCB(R5),R4	;POINT TO LCB FOR RE-ENTRY
	MOV	#EBINTR!EBTIME!EBWAIT,(R5)
				;WE WILL WAIT FOR XMITTER TO FINISH
	MOV	LB.MSG(R4),R0	;POINT TO MESSAGE
	BEQ	HSPXM4		;SEND ACK0 IF NO MESSAGE
	MOV	MSGLEN(R0),TCTIM(R5) ;NO MORE THAN ONE JIFFIE PER CHAR
	ADD	LB.CSD(R4),TCTIM(R5) ;PLUS CLEAR-TO-SEND DELAY
	JSR	PC,DQWRIT	;START SENDING MESSAGE
	BCS	HSPXM3		;ERROR
	BIS	#TCSTMS!TCDIDO,TCBSCF(R5) ;A MESSAGE WAS SENT, EXPECT ACK
	JSR	PC,DQREAD	;SETUP TO READ RESPONSE
	JSR	PC,WAIT		;WAIT FOR MESSAGE TO BE SENT
	BIT	#EBINTR,(R5)	;TIMED OUT?
	BEQ	HSRECV		;NO, GOT AN INTERRUPT.
	MOV	TCLCB(R5),R4	;YES, POINT TO LCB
	JSR	PC,DQKILL	;STOP THE TRANSMITTER [1(637)]
	INC	LB.TTO(R4)	;COUNT TRANSMITTER TIMEOUTS
;
; HERE TO TERMINATE THE MESSAGE STREAM BECAUSE
; THE 10 REQUESTED TERMINATION, BECAUSE OF TRANSMITTER 
;  ERROR OR TIMEOUT OR BECAUSE THE RETRY COUNTER RAN OUT.
;
hspxm3:
.if ne,BSBUG
	stopcd	dbg		;for BSBUGging only
.endc ;.if ne,BSBUG
HSPXAB:
	JSR	PC, HSETHA	;;++BS-SET H/W ABORT 3(015)
	MOV	TCLCB(R5),R4	;POINT TO LCB
	JSR	PC,DQKILL	;KILL ALL DQ/DUP ACTION
	JSR	PC,HSABTO	;FLAG OUTPUT ABORTED.
	JSR	PC,HSRLOM	;RELEASE ALL OUT GOING MESSAGES
	JSR	PC,HSABTI	;INPUTS ALSO
	JSR	PC,HSRMRL	;RELEASE MESSAGES
	RTS	PC		;EXIT FROM HPXMIT
;
;
HSPXAI:
	BR	HSPXAB		;DO ABORTS
;
;
; HERE IF THE TRANSMISSION OF THE DATA MESSAGE WAS SUCCESSFUL.
; HERE TO RECEIVE DATA OR RESPONSE FROM HASP
;
HSPXM5:
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	#<<20.*150.>/512.>+1,LB.RRY(R4) ;20 SEC MAX WAIT
HSPXM2:	JSR	PC,HSCMDS	;DSR ON?
	BCS	HSPXAI		;NO, ABORT INPUT
	MOV	TCLCB(R5),R4	;POINT TO LCB
	BIT	#LS.ENB,(R4)	;LINE DISABLED?
	BEQ	HSPXAI		;YES, ABORT OPERATION
	JSR	PC,HSARSP	;READ AND ANALYZE RESPONSE
	mov	tclcb(r5),r4	;point to lcb
	BIT	#LS.ERR,(R4)	;ANY ERRORS IN LAST OPERATION?
	BNE	20$		;YES, ABORT INPUT
	BIT	#LF.HWA,LB.FGS(R4) ;;++BS- H/W ABORT ? 3(015)
	BNE	20$		;;++BS-YES, ABORT THE STREAMS 3(015)
				;;++BS- NO 3(015)
	asl	r0		;no, for word pointer
11$:	MOV	12$(R0),R2	;GET ADR OF RESPONSE ROUTINE
	JMP	(R2)		;JUMP TO THE ROUTINE
;
; TABLE OF ADDRESSES OF RESPONSE ROUTINES
;
12$:	.WORD	13$		;R0=0, RECEIVED AN ACK0
	.WORD	34$		;R0=1, RECEIVED GOOD DATA
	.WORD	16$		;R0=2, RECEIVED NAK
	.WORD	18$		;R0=3, BCC ERROR IN RECEIVE DATA
	.WORD	17$		;R0=4, UNRECOGNIZED DATA
	.WORD	23$		;R0=5, BCB ERROR IN RECEIVED DATA
	.WORD	21$		;R0=6, BCB ERROR IN XMIT REPORTED BY HASP
;
;
;
; HERE WHEN AN ACK0 IS RECEIVED
;
13$:
	
	MOV	R4, -(SP)	;;++BS-SAVE R4
	MOV	TCLCB(R5), R4	;;++BS-POINT TO LCB
	BIT	#LF.SIM, LB.FGS(R4) ;;++BS-SIMULATION ?
	BEQ	39$		;;++BS-NO, SUPPORT, CONTINUE
	BIC	#TCDSP,TCFG2(R5);;++BS-CLEAR SYSTEM SUSSPEND
39$:	MOV	(SP)+, R4	;;++BS-RESTORE R4
				;;++BS-CONTINUE

	BIT	#TCSTMS,TCBSCF(R5) ;WAS A MESSAGE SENT?
	BEQ	15$		;NO, WE MUST HAVE SENT AN ACK0
	jsr	pc,hsmsak	;yes, release message


;	JMP	HPXMIT		;ATTEMPT TO SEND ANOTHER MESSAGE WITHOUT WAITNG
;
; HERE WHEN LINE IS IDLING, I,E RECVD ACK0 FOR ACK0
; OR WHEN A WAIT TO DO AFTER RECEIVE OF DATA
;
15$:	;mov	#jifSEC,tctim(r5) ;wait for a while
	MOV	#12, TCTIM(R5)	;;++BS-WAIT FOR A WHILE 3(011)
	MOV	#EBINTR!EBTIME!EBQCHK!EBQMSG!EBWAIT,(R5) ;WAIT FOR ANYTHING TO HAPPEN
	jsr	pc,wait
	jmp	hpxmit		;recirculate
;
; HERE WHEN A MESSAGE HAS BEEN RECEIVED CORRECTLY.
;
34$:	BIT	#TCSTMS,TCBSCF(R5) ;WAS AMESSAGE SENT?
	BEQ	35$		;NO.
	JSR	PC,HSMSAK	;RELEASE THE MESSAGE
35$:	BIT	#20,TCRBCB(R5)	;WAS BCB FOR BYPASS?
	BNE	36$		;YES.
	BIT	#40,TCRBCB(R5)	;WAS IT RESET BCB?
	BNE	36$		;YES, NOTE IT WAS SET TO RECEIVE COUNT IN HSARSP
	TST	TCERB(R5)	;ERROR IN RECEIVED BCB?
	BNE	36$		;YES, BYPASS INC OF EXPECTED
	INC	TCXBCB(R5)	;EXPECT THIS BCB FOR NEXT
36$:	BIC	#160,TCXBCB(R5)	;MAKE IT MODULO 16
;	JMP	HPXMIT		;ATTEMPT TO SEND ANOTHER MESSAGE WITHOUT WAITNG
	BR	15$		;WAIT AND LOOK FOR MORE DATA
;
;
; HERE WHEN A NAK IS RECEIVED
;
16$:	INC	LB.OC2(R4)	;COUNT NAKS RECEIVED
26$:	DEC	LB.RTY(R4)	;DECREMENT RETRY COUNT
	BEQ	HSPXM3		;TRIED ENOUGH, ABORT OUTPUT
	JSR	PC,HSWAIT	;WAIT FOR A WHILE
	JMP	HSPXM1		;SEND DATA AGAIN
; HERE WHEN UNRECOGNIZED DATA RECEIVED.
;
17$:	INC	LB.OC4(R4)	;RECORD INVALID REPLY
	BR	19$		;RETRY BEFORE GIVING UP
;
;
; HERE WHEN MESSAGE RECEIVED WITH BAD BCC
;
18$:	JSR	PC,HSRMRL	;RELEASE MESSAGES FORMED
19$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	DEC	LB.RRY(R4)	;TRIED ENOUGH TIMES?
	BEQ	20$		;YES, ABORT INPUT
	JSR	PC,HSWAIT	;WAIT A WHILE
	MOV	#NAKMSG,TCCMA(R5) ;SET UP NAK REPLY
	MOV	#NAKLEN,TCCMC(R5) ;LENGTH OF MESSAGE
	BR	HSPXM2		;TRY READING AGAIN
20$:	
.if ne,BSBUG
	stopcd	dbg		;BSBUG stopcode
.endc; .if ne,BSBUG
	INC	LB.IC6(R4)	;COUNT ABORTS
	JMP	HSPXAB		;FLAG STREAMS ABORTED
;
; HERE WHEN A BCB ERROR HAS BEEN REPORTED BY HASP
;
21$:	INC	LB.OC3(R4)	;COUNT BCB ERRORS ON XMIT
	BR	26$		;TREAT THE BCB ERROR AS NAK
;
23$:
;23$:	INC	LB.IC5(R4)	;COUNT BAD FORMATTED DATA RECEIVED
	BR	18$		;RELEASE MESSAGES AND SEND NAK
;

; SUBROUTINE TO WAIT A WHILE
;
HSWAIT:	MOV	#EBTIME!EBWAIT,(R5) ;WAIT
	MOV	#2,TCTIM(R5)	;A WHILE
	JSR	PC,WAIT
	RTS	PC		;RETURN
;
;
; this subroutine is called to process the acknowledgement
; received for a message sent. it frees the message
; and takes care of signon message acks also.
;
hsmsak:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.MSG(R4),R0	;POINT TO MESSAGE SENT
	MOV	TCIDLE,R1	;POINT TO IDLE TASK
	JSR	PC,QUEMSG	;SEND MESSAGE TO FREE
	CLR	LB.MSG(R4)	;NO LONGER A MESSAGE TO SEND
	INC	LB.OC1(R4)	;COUNT MESSAGES SENT SUCCESSFULLY
	CLR	TCERB(R5)	;CLEAR ANY PREV BCB ERROR INDICATOR
;	BIC	#TCDSP,TCFG2(R5) ;;++BS-REMOVED, CLEAR SYSTEM SUSPEND
	BIC	#TCSTMS!TCDTMS,TCBSCF(R5) ;LAST MESSAGE SENT ACCOUNTED FOR
	MOV	TCTFCS(R5),TCPFCS(R5) ;MAKE TRANSMITTED FCS AS PREVIOUS
	MOV	R4,R1		;KEEP R4 INTACT WITH LCB POINTER
	BIT	#TCSONM,TCBSCF(R5) ;WAS THE MESSAGE A SIGNON?
	BEQ	11$		;NO.
	BIC	#TCSONM,TCBSCF(R5) ;SIGNON ACCOUNTED FOR
	BIS	#LF.SON,LB.FGS(R4) ;INDICATE SIGNED ON
	ADD	#6,R1		;FOR CDR AS SIGNON DEVICE
	MOV	LB.TCD(R1),R1	;POINT TO CARD READER XLATE TCB
	BIC	#TCOTC!TCDMP,TCFG1(R1) ;SIGNON COMPLETE.
	MOV	#223,TCCTP(R1)	;RESTORE ORIGINAL RCB
11$:	RTS	PC		;RETURN
;
; THIS SUBROUTINE GETS TRANSMISSION BLOCK FULL OF DEVICE
; MESSAGES (IF ANY) OR STATUS, GRANT, OR REQUEST MESSAGES.
; IT LOOKS FOR SIGNON BLOCK AND IF FOUND THAT GOES AS A 
; LONE BLOCK IN THE T.B..
HSGTMS:
	BIT	#LF.SON,LB.FGS(R4) ;ALREADY SIGNED ON?
	BNE	10$		;YES, DONT LOOK FOR SIGNON BLOCK
	JSR	PC,HSONB	;CHECK FOR SIGNON BLOCKS
	BCS	11$		;TROUBLE IN MAKING T.B.
	TST	TCSTB(R5)	;DO WE HAVE A SIGNON BLOCK?
	BNE	12$		;YES, SEND IT ALONE AS A RECORD
10$:	JSR	PC,HSRQPT	;CHECK REQUEST PERMISSION TO XMIT
	JSR	PC,HSDPG	;CHECK FOR ANY DEVICE PERMISSION GRANTED
	JSR	PC,HSMTBK	;MAKE TRANSMISSION BLOCK
	BCC	13$		;NO ERRORS IN BUILDING T.B.
11$:	CLR	TCSTB(R5)	;OUT OF CHUNKS, CAN'T SEND MESSAGE
	BR	13$		;SET UP LB.MSG ALSO
12$:	BIS	#TCSONM,TCBSCF(R5) ;INDICATE SIGNON BEING SENT
13$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	TCSTB(R5),LB.MSG(R4) ;SET UP T.B. ADR
	CLC			;INDICATE SUCCESS
	RTS	PC		;AND RETURN
;
;
; THIS SUBROUTINE CHECKS FOR ANY REQUESTS FOR TRANSMISSION 
; TO BE SENT TO HASP. A REQUEST IS NEVER SENT TWICE AND 
; FOR THAT A FLAG TCOWR (OUTPUT WAS REQUESTED) IS SET 
; ONCE THE REQUEST IS SENT TO HASP. THIS ENSURES ALL 
; OUTSTANDING REQUESTS TO GO THRU.
;
HSRQPT:	MOV	TCLCB(R5),R4	;POINT TO LCB
	TST	TCRQPT(R5)	;REQUEST ALREADY SITTING THERE?
	BNE	13$		;YES, EXIT
	MOV	#1,R1		;START WITH CONSOLE OUTPUT
11$:	MOV	TCLCB(R5),R2	;POINT TO LCB
	ASL	R1		;DEV NO * 2
	ADD	R1,R2		;ADD OFFSET FOR THE DEVICE
	ASR	R1		;RESTORE DEV NO 
	MOV	LB.TCD(R2),R2	;POINT TO DEVICE'S XLATE TCB
	BEQ	12$		;JUST IN CASE TCB POINTER IS WIPED
	BIT	#TCOPR,TCFG2(R2) ;REQUEST OUTSTANDING?
	BNE	14$		;YES, CHECK IF REQUEST WAS SENT
12$:	INC	R1		;ADVANCE TO NEXT DEVICE
	CMP	R1,LB.NTC(R4)	;DONE WITH ALL DEVICES?
	BLOS	11$		;NO, LOOP FOR NEXT DEVICE
	CLR	TCRQPT(R5)	;NO REQUEST TO SEND
13$:	RTS	PC		;AND RETURN
;
14$:	BIT #LF.SIM,LB.FGS(R4) ;SIM MODE?
	BEQ	24$		;NO.
	CMPB	#222,TCCTP(R2)	;CONSOLE OUT MSG?
	BNE	24$		;NO.
25$:	BIS	#TCOPG!TCORN,TCFG2(R2) ;SET GRANT, PERMIT RUN
	BIC	#TCOPR,TCFG2(R2) ;CLEAR REQUEST BIT
	BR	12$		;CHECK FOR OTHER DEVICES
24$:	CMPB	#221, TCCTP(R2)	;;++BS-OUTPUT PERMISSION UNNECCESSARY IF
	BEQ	25$		;;++BS-OPERATOR DISPLAY REQUEST (CONSOLE OUTPUT)
	CMPB	#RCBCTL,TCCTP(R2) ;CHECK FOR SIGNON
	BNE	15$		;ITS NOT
	BIS	#TCORN!TCOPG,TCFG2(R2) ;GIVE IT RUN AND GRANT
	BIC	#TCOPR,TCFG2(R2) ;CLEAR THE REQUEST
	RTS	PC		;DONT SET FOR SIGNON
15$:
	BIT	#TCOWR,TCFG2(R2) ;WAS REQUEST SENT BEFORE?
	BNE	12$		;YES, TRY NEXT DEVICE
	BIS	#TCOWR,TCFG2(R2) ;REQUEST GONE IN THE T.B.
	MOV	TCCTP(R2),TCRQPT(R5) ;SAVE RCB FOR MESSAGE BUILDING
	INC	TCCRQT(R2)	;COUNT REQUESTS SENT
	RTS	PC		;RETURN
;
;
; THIS SUBROUTINE CHECKS FOR ANY PERMISSIONS GRANTS TO BE 
; SENT TO HASP. RCB FOR THE DEVICE IS SET IN TCDPG 
; OFFSET IN BSC TCB.
;
HSDPG:
	TST	TCDPG(R5)	;PENDING PERMISSION?
	BNE	13$		;YES, EXIT
	MOV	#1,R1		;START WITH CONSOLE INPUT
11$:	MOV	TCLCB(R5),R2	;POINT TO LCB
	asl	r1		;device no * 2
	ADD	R1,R2		;GET DEVICE'S
	asr	r1		;restore dev no
	MOV	LB.TCD(R2),R2	;TRANSLATE TCB ADR
	BEQ	12$		;JUST IN CASE TCB POINTER IS WIPED
	BIT	#TCIPG!TCIRN,TCFG2(R2) ;INPUT PERMISSION GRANTED?
	BNE	14$		;YES, CHECK IF REQUEST IS ON
12$:	INC	R1		;MOVE TO NEXT DEVICE
	CMP	R1,LB.NTC(R4)	;DONE WITH ALL THE DEVICES
	BLOS	11$		;NO, LOOP FOR THE NEXT ONE
	CLR	TCDPG(R5)	;NO PERMISSSIONS TO SEND
13$:	RTS	PC		;RETURN
;
14$:;	JSR	PC,HSUNSP	;UNSUSPEND DEVICE
	BIT	#TCIPH,TCFG1(R2) ;PERMISSION ALREADY SENT?
	BEQ	12$		;YES, CHECK NEXT DEVICE
	JSR	PC, HSUNSP	;;++BS-UNSUSPEND THE DEVICE
	MOV	TCCTP(R2),TCDPG(R5) ;SET RCB FOR THE DEVICE
	BIC	#TCIPH,TCFG1(R2) ;INPUT PERMISSION SENT TO HASP
	RTS	PC		;RETURN
;
;
; HERE TO BUILD A SIGNON BLOCK TO BE SENT TO HOST
;
HSONB:	MOV	LB.LNU(R4),R1	;GET THE LINE #
	SWAB 	R1		;PUT IN LEFT BYTE
	ADD	#RCBCTL,R1	;MAKE IT SIGNON I.D.
	JSR	PC,DEQMID	;LOOK FOR SIGNON BLOCK
	BCC	11$		;FOUND IT
	CLR	TCSTB(R5)	;NO SIGNON TO SEND YET
	CLC			;WAIT FOR SIGNON TO ARRIVE
	RTS	PC		;RETURN
;
11$:	MOV	R0,-(SP)	;;++BS-SAVE MESSAGE POINTER FOR LATER 3(023)
	MOV	R0,-(SP)	;SAVE MESSAGE POINTER
	JSR	PC,MSGSUP	;SET UP TRANSMISSION BLOCK
;3(023)	BCS	15$		;OUT OF CHUNKS
	BCS	16$		;;++BS-OUT OF CHUNKS, FATAL ERROR 3(023)
	MOV	R0,TCSTB(R5)	;SAVE POINTER TO T.B.
	JSR	PC,MSGHDR	;SET UP BCB,FCS ETC IN T.B. HEADER
	BCS	16$		;RAN OUT OF CHUNKS IN MSGHDR
	MOV	(SP)+,R4	;MESSAGE PTR IN R4
12$:	MOV	CHNXT(R4),R3	;POINT TO DATA CHUNK
	BEQ	14$		;END OF MESSAGE
	MOV	R3,R4		;SAVE CHUNK PTR FOR REF LATER
	MOV	CHLEN(R3),R2	;LENGTH OF DATA IN CHUNK
	BEQ	12$		;EMPTY CHUNK
	ADD	#CHDAT,R3	;POINT TO START OF DATA
13$:	MOVB	(R3)+,R1	;GET WITH ACTUAL SIGNON MESSAGE FROM CHUNK
	KGACUM	R1		;ACCUMULATE BCC
	JSR	PC,MSGAPC	;APPEND CHAR TO MESSAGE
	BCS	16$		;OUT OF CHUNKS
	SOB	R2,13$		;LOOP TILL DONE WITH CHUNK
	BR	12$		;GET NEXT CHUNK
;
14$:	CLR	R1		;PUT A ZERO RCB TO INDICATE EOB
	KGACUM	R1		;ACCUMULATE RCB(0) IN BCC
	JSR	PC,MSGAPC	;APPEND THE RCB (00)
	BCS	16$		;OUT OF CHUNKS
	JSR	PC,HSTRL	;SET TRAILER TO MESSAGE
	BCS	16$		;OUT OF CHUNKS
	MOV	TCLCB(R5),R4	;POINT TO LCB
	DEC	LB.MSC(R4)	;ONE LESS MESSAGE TO XMIT

	MOV	(SP)+, R0	;;++BS-GET MESSAGE POINTER 3(023)
	MOV	TCIDLE, R1	;;++BS-POINT TO IDLE TASK 3(023)
	JSR	PC, QUEMSG	;;++BS-FREE THE MESSAGE 3(023)

	CLC			;INDICATE SUCCESS
15$:	RTS	PC		;RETURN
;
; OUT OF CHUNKS
16$:	STOPCD	HSA		;TROUBLE BUILDING T.B.
;
;
; THIS SUBROUTINE CHECKS FOR DUMP OR EOF ON OUTPUT
; AND WHEN ALL MESSAGES ARE SENT, INDICATES SO TO XLATE
;
HSCDEF:

	BIT	#TCDSP, TCFG2(R4) ;;++BS-IS DEVICE SUSPENDED ?
	BNE	11$		;;++BS-YES, RETURN WITH NO MESSAGES

	JSR	PC,DEQMID	;GET MESSAGE FOR DEVICE, I.D IN R1
				;REMEMBER I.D. IS IN R1
	BCC	12$		;GOT A MESSAGE
	BIT	#TCOTC,TCFG1(R4) ;LAST OUTPUT ON DEVICE?
	BEQ	11$		;NO
	BIC	#TCOTC,TCFG1(R4) ;YES, ITS DONE (THERE ARE NO MESSAGES)
11$:	SEC			;INDICATE NO MESSAGES FOR DEVICE
	RTS	PC		;RETURN
;
12$:
	DEC	TCMSC(R4)	;COUNT DOWN MESSAGES TO GO FOR DEVICE

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

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	MOV	TCCTP(R4), R1	;GET DEVICE NUMBER
	BIC	#177400, R1	;CLEAR JUNK
	TST	TCCHK1(R4)	;ANY CHUNKS QUEUED TO XLATE TASK ?
	BEQ	21$		;NO, CHECK QUEUED MESSAGES
25$:	JSR	PC, HSAMPC	;YES, CLEAR DEVICE ACTIVE BIT
	BR	22$		;RESTORE REGISTERS AND CONTINUE
21$:	CMP	TCMSC(R4), #MSGXML ;IS THE MAX # OF MESSAGES QUEUED TO THIS TASK
	BGT	25$		;YES, CLEAR DEVICE ACTIVE BIT
	JSR	PC, HSACMP	;NO, SET THE DEVICE ACTIVE BIT
22$:	JSR	PC, HSRESR	;RESTORE THE REGISTERS
;;++BS-END OF CODE TO SET OR CLEAR THE DEVICE ACTIVE BIT

	MOV	R0,TCSDM(R5)	;PTR TO DEVICE MESSAGE SAVED
	MOV	R0,R4		;FOR USE LATER
	MOV	TCSTB(R5),R0	;R0 MUST POINT TO T.B. BUILT
	CLC			;INDICATE MESSAGE FOUND
	RTS	PC		;RETURN
;
;
;
; THIS SUBROUTINE MAKES A TRANSMISSION BLOCK FROM DIFFERENT 
; OR SAME DEVICE RECORDS. THE BLOCK  MAY ALSO CONTAIN 
; REQUEST FOR DEVICE OUTPUT PERMISSION AS LAST RECORD ONLY 
; OR MAY HAVE THE LAST RECORD AS DEVICE PERMISSION GRANTED
; FOR A REQUEST PREVIOUSLY MADE. THE DEVICES ARE POLLED 
; FOR DATA IN THE FOLLOWING PRIORITIES:
; CONSOLE OUTPUT, CARD READER, LINE PRINTER AND LASTLY 
; CARD PUNCH OUTPUT (IF ANY)
;
HSMTBK:	JSR	PC,HSCDOT	;CHECK FOR OUTPUT DATA & MAKE MESSAGE
	BCS	19$		;OUT OF CHUNKS
	MOV	TCSTB(R5),R0	;POINT TO MESSAGE T.B. IF OUTPUT TO GO
	BNE	11$		;YES, GO SET UP HEADER
	CLC			;NO, EXIT
19$:	RTS	PC		;RETURN
;
11$:	JSR	PC,MSGHDR	;SET UP BCB, FCS ETC.
	BCS	29$		;OUT OF CHUNKS
	MOV	#368.,TCSLFT(R5) ;INITIAL SPACE LEFT FOR T.B.
	TST	TCERB(R5)	;ANY BCB ERRORS IN LAST RECEIVE?
	BNE	23$		;YES, MAKE A COMPLAINT AND SEND
	TST	TCDPG(R5)	;ANY DEV GRANTS TO GO
	BNE	24$		;SEND ALONE
	TST	TCRQPT(R5)	;ANY PERMISSIONS TO ASK
	BNE	24$		;YES, SEND ALONE
	CLR	TCDTB(R5)	;NO CURRENT DEVICE IN T.B.
	BIT	#TCDSP,TCFG2(R5) ;OUTPUT SUSPENDED?
	BNE	23$		;SEND REQUESTS ONLY
24$:	MOV	TCSDM(R5),R4	;ANY MESSAGE LEFT
	BEQ	12$		;NONE
	MOV	TCSTB(R5),R0	;T.B. MUST BE SET UP
	BR	14$		;PUT MESSAGE IN T.B.
12$:	CLC			;CLEAR CARRY TO START
	INC	TCDTB(R5)	;START FROM CONSOLE OUTPUT
20$:	MOV	TCDTB(R5),R1	;ANY MESSAGES FOR THIS DEVICE?
	MOV	TCLCB(R5),R4	;POINT TO LCB
	CMP	R1,LB.NTC(R4)	;DONE WITH ALL DEVICES?
	BHI	23$		;YES, CHECK FOR REQUESTS
13$:
	JSR	PC,HSCKDO	;CHECK DEVICE FOR OUTPUT
	BCS	12$		;SUSPENDED OR PERMISSION NOT GRANTED
	JSR	PC,HSCDEF	;CHECK FOR DEVICE MESSAGE
	BCS	12$		;NONE THERE
	CMP	MSGLEN(R4),TCSLFT(R5) ;DOES THIS MESSAGE FIT IN T.B.
	BLOS	14$		;YES, PUT IT IN T.B.
23$:	JSR	PC,HSCKRQ	;CHECK FOR REQUESTS
	BCS	29$		;OUT OF CHUNKS
	RTS	PC		;RETURN
;
14$:	MOV	CHNXT(R4),R3	;POINT TO DATA CHUNK
	BEQ	17$		;END OF CURRENT DEVICE MESSAGE
	MOV	R3,R4		;SAVE CHUNK PTR FOR LOOPING OVER MESSAGE
	MOV	CHLEN(R3),R2	;LENGTH OF DATA IN THIS CHUNK
	BEQ	14$		;EMPTY CHUNK
	ADD	#CHDAT,R3	;POINT TO START OF DATA IN CHUNK
;
;
;THE FOLLOWING LOOP COPIES DEVICE MESSAGE CHUNKS INTO T.B.
;
15$:	MOVB	(R3)+,R1	;GET CHAR FROM CHUNK
	KGACUM	R1		;ACCUMULATE BCC
	JSR	PC,HSCKTP	;CHECK FOR TRANSPARENT OUTPUT
	BCS	29$		;OUT OF CHUNKS
16$:	JSR	PC,MSGAPC	;APPEND CHAR TO MESSAGE
	BCS	29$		;OUT OF CHUNKS
	SOB	R2,15$		;LOOP TILL DONE WITH THE CHUNK
	BR	14$		;START WITH NEXT CHUNK
;
; HERE ON END-OF-DEVICE MESSAGE OR END OF RECORD ALSO
;
17$:	MOV	TCLCB(R5),R4	;POINT TO LCB
	DEC	LB.MSC(R4)	;ONE LESS MESSAGE TO SEND
	BIS	#TCDTMS,TCBSCF(R5) ;ITS A DATA MESSAGE
	MOV	TCSDM(R5),R4	;POINT TO MESSAGE JUST PUT IN TB
	SUB	MSGLEN(R4),TCSLFT(R5) ;THIS MUCH SPACE LEFT
	SUB	MSGLEN(R4),MSGSNL(R0) ;DEPLETE SYN COUNT
	MOV	R4,R0		;DEVICE MESSAGE POINTER IN R0
	MOV	TCIDLE,R1	;POINT TO IDLE TASK
	JSR	PC,QUEMSG	;FREE IT
	CLR	TCSDM(R5)	;CLEAR MESSAGE POINTER
	MOV	TCSTB(R5),R0	;POINT BACK TO MESSAGE BEING FORMED
	TST	MSGSNL(R0)	;DO WE NEED TO APPEND A SYN
	BGT	20$		;NOT YET, ANY MORE DATA FOR THE DEVICE
	BIT	#TCTSP,TCFG1(R5) ;OUTPUT TRANSPARENT?
	BEQ	18$		;NO, INSERT SYN ONLY
	MOV	#EBCDLE,R1	;INSERT DLE-SYN IN TRANSPARENCY
	JSR	PC,MSGAPC	;APPEND TO THE MESSAGE
	BCS	29$		;OUT OF CHUNKS
	DEC	TCSLFT(R5)	;ONE BYTE LESS SPACE LEFT
	
18$:	MOV	#EBCSYN,R1	; SYN ALONE FOR NON-TRANSPARENT
	JSR	PC,MSGAPC	;APPEND TO MESSAGE
	BCS	29$		;OUT OF CHUNKS
	DEC	TCSLFT(R5)	;ONE BYTE LESS
	MOV	#SYNLEN,MSGSNL(R0) ;RESET SYN LENGTH COUNTER
	BR	20$		;CHECK FOR MORE DATA
;
; HERE IF TROUBLE BUILDING MESSAGE
;
29$:	STOPCD	HSA		;TROUBLE BUILDING MESSAGE
;
;
; THIS SUBROUTINE CHECKS FOR TRANSPARENT MODE ON OUTPUT 
; AND INSERTS DLE BEFORE A DATA DLE OR SYN FOR TRANPARENCY.
;
HSCKTP:	MOV	R1,-(SP)	;SAVE R1, IT HAS THE ORIGINAL CHARACTER
	BIT	#TCTSP,TCFG1(R5) ;OUTPUT TRANSPARENT?
	BEQ	11$		;NO.
	CMPB	#EBCDLE,R1	;A DLE?
	BNE	12$		;NO, CHECK FOR SYN
	JSR	PC,MSGAPC	;APPEND A DLE BEFORE DLE
	BCS	13$		;FAILURE RETURN
11$:	MOV	(SP)+,R1	;RESTORE R1, ORIGNAL CHAR
	CLC			;INDICATE SUCCESS
	RTS	PC		;AND RETURN

12$:	CMPB	#EBCSYN,R1	;IS IT A SYN?
	BNE	11$		;NO, EXIT
	MOV	#EBCDLE,R1	;APPEND A DLE
	JSR	PC,MSGAPC	;BEFORE THE SYN
	BCC	11$		;FOR CLEAN EXIT
13$:	MOV	(SP)+,R1	;RESTORE ORIGINAL CHAR
	SEC			;INDICATE FAILURE
	RTS	PC		;RETURN
;
; THIS SUBROUTINE CHECKS IF THERE IS DATA TO XMIT
;
HSCDOT:
	TST	TCERB(R5)	;ANY BCB ERRORS IN LAST RECEIVE?
	BNE	14$		;YES.
	TST	TCRQPT(R5)	;ANY REQUEST TO GO?
	BNE	14$		;YES, SETUP MESSAGE
	TST	TCDPG(R5)	;ANY PERMISSION GRANTS?
	BNE	14$		;YES, SETUP MSG
	BIT	#FCSUNV,TCTFCS(R5) ;IS SUSPEND SET, SHORTAGE OF CHUNKS
	BNE	14$		;YES.
	BIT	#TCDSP,TCFG2(R5) ;SYSTEM SUSPENDED?
	BNE	16$		;YES. DON'T SEND ANY OUTPUT
	CLR	TCDTB(R5)	;INITIALISE DEVICE FOR T.B.
	TST	TCSDM(R5)	;ANY MESSAGE LEFT FROM LAST TIME
	BNE	14$		;LETS GET THAT OUT FIRST
11$:	CLC			;TO AVOID TROUBLE
	INC	TCDTB(R5)	;START WITH CONSOLE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	CMPB	TCDTB(R5),LB.NTC(R4) ;DEVICE # IN LIMITS
	BLOS	12$		;YES, CHECK DEVICE FOR MESSAGES


;;++BS-CODE TO SEND A NULL MESSAGE IF STATUS CHANGED


	MOV	R4, -(SP)	;;++BS-SAVE R4
	MOV	TCLCB(R5), R4	;;++BS-POINT TO LCB
	BIT	#LF.SIM, LB.FGS(R4) ;;++BS- SIMULATION MODE ?
	BEQ	19$		;;++BS-NO,SUPPORT, SEND MESSAGE
				;;++BS-YES, CHECK FOR SIGNON
	BIT	#LF.SON, LB.FGS(R4) ;;++BS-IS THE LINE SIGNED ON ?
	BEQ	18$		;;++BS-NO, DON'T SEND NULL MESSAGE
19$:	MOV	(SP)+, R4	;;++BS-YES, RESTORE R4 AND SEND NULL MESSAGE

	JSR	PC, HSTSUS	;;++BS-CHECK IF STATUS OF DEVICE CHANGED
	BCS	14$		;;++BS-STATUS OF A DEVICE CHANGED, SEND FCS
				;;++BS-NO CHANGE IN STATUS OF DEVICE, CONTINUE

	BR	16$		;;++BS-CONTINUE
18$:	MOV	(SP)+, R4	;;++BS-RESTORE R4 AND CONTINUE


;;++BS-END OF CODE TO SEND A NULL MESSAGE


16$:	CLR	TCSTB(R5)	;NOTHING TO SEND
13$:	CLC			;SUCCESS
	RTS	PC		;RETURN
;
12$:	MOV	TCDTB(R5),R1	;DEVICE FOR T.B.
	JSR	PC,HSCKDO	;ALLOWED TO OUTPUT?
	BCS	11$		;NO, CHECK NEXT DEVICE
14$:	JSR	PC,MSGSUP	;SETUP MESSAGE
	BCS	15$		;FAILED
	MOV	R0,TCSTB(R5)	;POINT TO T.B.
	BR	13$		;RETURN
15$:	SEC			;SIGNAL FAILURE
	RTS	PC		;AND RETURN
;


;++BS-HERE TO TEST CHANGE IN STATUS OF DEVICE SUSPENDED OR UNSUSPENDED
;++BS-TCGHST IS SET IN THE HSUSPD AND HSUNSP


HSTSUS:
	BIT	#TCHGST, TCST2(R5) ;;++BS-HAS DEVICE STATUS CHANGED ?
	BNE	1$		;;++BS-YES, SEND THE NULL MESSAGE AND FCS
	CLC			;;++BS-NO, DON'T SEND A NULL MESSAGE
	RTS	PC		;;++BS-RETURN
1$:	BIC	#TCHGST, TCST2(R5) ;;++BS-STATUS CHANGED NOTICED
	SEC			;;++BS-INDICATE NULL MESSAGE AND FCS TO BE SENT
	RTS	PC		;;++BS-RETURN
;
; SUBROUTINE TO CHECK REQUESTS TO BE SENT 
; OR ANY PERMISSION GRANTED TO BE SENT TO HASP
;
hsckrq:	mov	tcstb(r5),r0	;point to t.b. formed
	TST	TCERB(R5)	;ANY BCB ERROR TO COMPLAIN TO REMOTE?
	BNE	21$		;YES.
	TST	TCRQPT(R5)	;ANY REQUEST PERMISSION TO GO?
	BEQ	15$		;NO, CHECK FOR PERMISSION GRANTED
	MOVB	#RCBRQP,R1	;GET RCB FOR REQUEST BLOCK
	KGACUM	R1		;ACCUMULATE IN BCC
	JSR	PC,MSGAPC	;APPEND TO THE MESSAGE
	BCS	14$		;OUT OF CHUNKS
	MOVB	TCRQPT(R5),R1	;DEVICE RCB GOES INTO SRCB PLACE
	CLR	TCRQPT(R5)	;REQUEST TAKEN CARE OF
11$:	MOV	#3,R2		;FOR SCB AND ZERO RCB
12$:	KGACUM	R1		;ACCUMULATE SRCB IN BCC
	JSR	PC,MSGAPC	;APPEND CHAR TO MESSAGE
	BCS	14$		;OUT OF CHUNKS
13$:	CLR	R1		;ZERO BYTE FOR SCB(EOR) AND RCB
	SOB	R2,12$		;APPEND THEM TO END MESSAGE
17$:	JSR	PC,HSTRL	;SET TRAILER FOR THE MESSAGE
	bcs	14$		;out of storage
	clc			;success
	rts	pc		;return
;
14$:	sec			;signal failure
	RTS	PC		;RETURN
;
;
; HERE FOR ANY PERMISSION GRANTS TO BE SENT
;
15$:	TST	TCDPG(R5)	;ANY GRANTS TO GO
	BNE	16$		;YES, SET UP RCB AND SRCB IN MESSAGE
	CLR	R1		;CLEAR FOR ZERO RCB
	MOV	#1,R2		;PUT RCB(00) AT END OF DATA
	BR	12$		;TO INDICATE END-OF-BLOCK
;
16$:	MOV	#RCBPRG,R1	;GET RCB FOR PERMISSION GRANT
	KGACUM	R1		;INCLUDE IN BCC
	JSR	PC,MSGAPC	;APPEND THE RCB TO MESSAGE
	BCS	14$		;OUT OF CHUNKS
	MOV	TCDPG(R5),R1	;SET UP SRCB AS THE DEVICE'S RCB
	CLR	TCDPG(R5)	;PERMISSION GRANT SENT
	BR	11$		;SET UP THE TRAILER ALSO
;
; HERE FOR BCB ERROR REPORTING TO REMOTE
;
21$:
	MOV	#RCBCBE,R1	;GET RCB FOR BCB ERROR
	KGACUM	R1		;ACCUMULATE IN BCC
	JSR	PC,MSGAPC	;APPEND TO MESSAGE
	BCS	14$		;OUT OF CHUNKS
	MOV	TCERB(R5),R1	;SET SRCB TO EXPECTED BCB COUNT
	BR	11$		;PUT SRCB AND RCB(00)
;
;
; THIS SUBROUTINE CHECKS IF THE DEVICE IS PERMITTED TO 
; DO OUTPUT TO HASP. IF C SET -- CANNOT OUTPUT
;
HSCKDO:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	R4,R0		;FOR REF LATER
	asl	r1		;dev no * 2
	ADD	R1,R4		;GET DEVICE'S TCB ADR
	asr	r1		;restore dev no
	MOV	LB.TCD(R4),R4	;USING DEVICE # IN R1 AS INDEX
	BEQ	12$		;FOR NON-EXISTANT XLATE TCB
	BIT	#TCOAB!TCIAB,TCFG2(R4) ;DEVICE OUTPUT OR INPUT ABORTED?
	beq	11$		;no
	JSR	PC,HSDOAB	;PROCESS DEVICE ABORT
	br	12$		;dont allow to output
11$:	BIT	#TCorn,TCFG2(R4) ;OUTPUT PERMISSION GRANTED?
	BEQ	12$		;NO, CAN'T DO OUTPUT

	BIT	#TCDSP, TCFG2(R4) ;;++BS-DEVICE SUSPENDED ?
	BNE	12$		;;++BS-YES, CANNOT DO OUTPUT
				;;++BS-NO, SET UP FOR MESSAGE

	MOV	LB.LNU(R0),R1	;GET LINE NUMBER
	SWAB	R1		;PUT LINE # IN LEFT BYTE
	ADD	TCCTP(R4),R1	;MAKE I.D. FOR THE DEVICE MSG
	CLC			;YES, ALL O.K FOR OUTPUT
	RTS	PC		;RETURN
12$:	SEC			;INDICATE CANNOT DO OUTPUT
	RTS	PC		;AND RETURN
;
HSDOAB:	MOV	R4,-(SP)	;SAVE R4
	MOV	LB.LNU(R0),R1	;GET LINE NUMBER
	SWAB	R1		;IN LEFT BYTE
	ADD	TCCTP(R4),R1	;MAKE I.D. FOR THE DEVICE MESSAGE
	mov	r1,-(sp)	;save i.d.
12$:	JSR	PC,DEQMID	;IS THERE A MESSAGE FOR DEVICE?
	BCS	13$		;NO MESSAGE
14$:	MOV	TCIDLE,R1	;QUE IT TO IDLE TASK
	JSR	PC,QUEMSG	;FOR FREEING MESSAGE
	mov	(sp),r1		;get the i.d.
	BR	12$		;CHECK FOR MORE MESSAGES
13$:	MOV	#EBTIME!EBWAIT,(R5) ;WAIT A SHORT WHILE
	MOV	#3,TCTIM(R5)	;JUST THREE JIFFIES
	JSR	PC,WAIT		;
	MOV	(SP),R1	;GET THE I.D.
	JSR	PC,DEQMID	;ANY MESSAGES FOR DEVICE
	BCC	14$		;YES, FREE THEM
16$:	MOV	(SP)+,R1	;CLEAN STACK
	MOV	(SP)+,R4	;RESTORE R4
	clc			;success
	rts	pc		;return
;
;
; HERE TO SET TRAILER DLE-ETB AND CRC AND THE PADS AT THE
; END OF THE T.B.
;
HSTRL:	MOV	R4,-(SP)	;SAVE R4
	MOV	TCLCB(R5),R4	;POINT TO LCB 4(026)
	BIT	#LF.TSP,LB.FGS(R4) ;OUTPUT TRANSPARENT? 4(026)
	BEQ	11$		;NO, USE ETB 4(026)
	MOV	#EBCDLE,R1	;YES, INSERT DLE-ETB 4(026)
	JSR	PC,MSGAPC	;APPEND THE CHAR TO MESSAGE 4(026)
	BCS	13$		;OUT OF CHUNKS 4(026)
11$:	MOV	#EBCETB,R1	;NOW THE ETB
	KGACUM	R1		;MUST BE INCLUDED IN BCC
	JSR	PC,MSGAPC	;APPEND CHAR TO MESSAGE
	BCS	13$		;OUT OF CHUNKS
	JSR	PC,STOBCC	;APPEND BCC
	BCS	13$		;OUT OF CHUNKS
	JSR	PC,XLPADS	;APPEND PADS AT THE END
	BCS	13$		;OUT OF CHUNKS
	jsr	pc,msgape	;return unused chunks
	MOV	TCSTB(R5),LB.MSG(R4) ;POINT TO MESSAGE TO BE SENT
	CLC			;SIGNAL SUCCESS
12$:	MOV	(SP)+,R4	;RESTORE R4
	RTS	PC		;AND RETURN
;
13$:	CLR	LB.MSG(R4)	;SIGNAL FAILURE
	SEC			;INDICATE FAILURE
	BR	12$		;AND EXIT
;
; THIS SUBROUTINE BUILDS A TRANSMISSION BLOCK HEADER
; TO SET UP BCB, FCS ETC.
;
MSGHDR:	BIT	#TCTSP,TCFG1(R5) ;OUTPUT TRANSPARENT?
	BNE	15$		;YES, THEN DONT INCLUDE STX
	MOV	#EBCSTX,R1	;HASP NEEDS STX IN BCC
	KGACUM	R1		;COUNT IN BCC
15$:	TST	TCERB(R5)	;BCB ERROR TO REPORT?
	BNE	13$		;YES, SET UP DIFFERENT TBCB
	MOV	TCTBCB(R5),R1	;GET CURRENT BCB
	KGACUM	R1		;INCLUDE IN BCC
	JSR	PC,MSGAPC	;APPEND BCB TO MESSAGE
	BCS	11$		;OUT OF CHUNKS
	CMPB	TCTBCB(R5),#BCBINI ;RESET BCB?
	BEQ	12$		;YES, DON'T INCREMENT FOR NEXT
	INC	TCTBCB(R5)	;BLOCK COUNT FOR TRANSMIT
12$:	BIC	#160,TCTBCB(R5)	;MAKE BCB MODULO 16
14$:	MOVB	TCTFCS+1(R5),R1	;GET FIRST FCS BYTE
	KGACUM	R1	;INCLUDE FCS BYTE IN BCC
	JSR	PC,MSGAPC	;APPEND IT TO MESSAGE
	BCS	11$		;OUT OF CHUNKS
	MOVB	TCTFCS(R5),R1	;GET SECOND FCS BYTE TO TRANSMIT
	KGACUM	R1		;INCLUDE IN BCC
	JSR	PC,MSGAPC	;APPEND TO MESSAGE
	BCS	11$		;OUT OF CHUNKS
	CLC			;INDICATE SUCCESS
11$:	RTS	PC		;RETURN
;
13$:				;HERE FOR HEADER TO REPORT BCB ERROR
	MOV	TCRBCB(R5),R1	;GET RECVD BCB
	BIC	#177760,R1	;MAKE COUNT
	ADD	#220,R1		;MAKE BCB FOR BYPASS
	MOV	R1,TCPBCB(R5)	;KEEP TRACK OF THIS BCB SENT
	KGACUM	R1		;INCLUDE IN BCC
	JSR	PC,MSGAPC	;AND MESSAGE TO GO
	BCS	11$		;EXIT WITH C SET FOR ERROR
	BR	14$		;JOIN THE MAIN PATH
;
;
; THIS MODULE PROCESSES DATA RECEIVED FROM HASP
; ON RETURN R0 = 0,1,2,3 OR 4 DEPENDING ON WHETHER 
; WE RECEIVED ACK0,DATA,NAK,STATUS OR UNRECOGNIZED 
; MESSAGE BLOCK. 
;
HSARSP:
	MOV	TCLCB(R5),R4	;NO, POINT TO LCB
	MOV	TCCMA(R5),R0	;ANY CONTROL MESSAGE TO SEND?
	BEQ	11$		;NO, JUST ISSUE A READ
	MOV	TCCMC(R5),R1	;YES, GET ADDRESS AND COUNT
	ADD	R1,TCTIM(R5)	;INCREASE TIME TO ALLOW FOR TRANSMISSION
	ADD	LB.CSD(R4),TCTIM(R5) ;PLUS CLEAR-TO-SEND DELAY
	JSR	PC,CTLMSG	;SEND CONTROL MESSAGE
	BCS	13$		;FATAL ERROR SENDING
	CLR	TCCMA(R5)	;DONT SEND MESSAGE TWICE
	BIS	#TCDIDO,TCBSCF(R5) ;LAST OPER WAS XMIT
;
	MOV	TCLCB(R5),R4	;POINT TO LCB
11$:	MOV	#EBQCHK!EBTIME!EBWAIT,(R5) ;WAIT CONDITIONS
	MOV	#500.,TCTIM(R5)	;MAX MSG TIME FOR WAIT
				;MAX SIZE MSG AT SLOWEST SPEED
				; (THIS EXPRESSION ALSO USED AT MSGGT2)
				;REMEMBER DQREAD ISSUED EARLIER
				; (WILL GET TIMEOUT IF CANNOT READ)
	CLR	R4		;NO DATA YET
	BIC	#TCDIDO,TCBSCF(R5) ;LAST OPERATION WAS READ
	JSR	PC,MSGGTC	;GET INPUT CHARACTER
	BCS	12$		;TIMEOUT
	CMPB	#EBCSTX,R1	;START OF TEXT?
	BEQ	22$		;YES.
	CMPB	#EBCDLE,R1	;NO, DATA LINK ESCAPE?
	BEQ	14$		;YES,ACK0 OR STX NEXT
	CMPB	#EBCSOH,R1	;SOH?
	BEQ	18$		;POSSIBLY NON-TRANSPARENT DATA
	CMPB	#EBCNAK,R1	;NAK?
	BEQ	17$		;YES,PROCESS NAK
;
;
; HERE WHEN RECEIVED DATA IS UNRECOGNIZABLE.
;
12$:
.IF NE,BSBUG
	STOPCD	DBG		;FOR UNRECOG MESSAGES
.ENDC
	JMP	HSRXPT		;RELESAE MESSAGES AND RETURN
;
; HERE WHEN OUTPUT STREAM IS ABORTED
;
13$:
;3(015)	JMP	HSPXAB		;ABORT STREAMS
	JSR	PC, HSETHA	;;++BS-INDICATE H/W ABORT 3(015)
	RTS	PC		;;++BS-RETURN 3(015)

;
; HERE WHEN DLE IS RECVD
;
14$:	JSR	PC,MSGGTC	;GET NEXT CHAR
	BCS	12$		;TIMEOUT
	CMPB	#EBCAK0,R1	;ACK0?
	BEQ	16$		;YES,PROCESS ACK0
	CMPB	#EBCSTX,R1	;IS IT TRANSPARENT DATA?
	BNE	12$		;NO, UNRECOGNIZED DATA
	BIS	#TCITSP,TCBSCF(R5) ;YES, SET TRANSPARENCY FLAG
	BR	23$		;RECEIVE MEASSGE
;
; HERE TO PROCESS RECEIPT OF AN ACK0
;
16$:	JSR	PC,MSGGTE	;CLEAR THE RECEIVER
	CLR	R0		;INDICATE RECEIVED ACK0
	RTS 	PC		;RETURN
;
;HERE WHEN A NAK IS RECEIVED.
;
17$:	JSR	PC,MSGGTE	;END MESSAGE
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.OC2(R4)	;COUNT NAKS RECEIVED
	MOV	#2,R0		;INDICATE NAK RECEIVED
	RTS	PC		;RETURN
;
; HERE WHEN SOH IS RECEIVED IN NON-TRANSPARENT MODE
;
18$:	KGLOAD	#0		;INITIALIZE KG11-A
19$:	JSR	PC,MSGGTC	;GET NEXT CHAR
	BCS	12$		;TIMEOUT
	KGACUM	R1		;ACCUMULATE IN BCC
	CMPB	#EBCSTX,R1	;STX AFTER SOH?
	BNE	12$		;UNRECOGNIZED SEQ 4(026)
;4(026)	BNE	19$		;UNRECOGNIZED SEQ
	BIC	#TCITSP,TCBSCF(R5) ;NON-TRANSPARENT MODE
21$:	JSR	PC,HSRXPM	;GET THE RECEIVED MESSAGE
	RTS	PC		;RETURN
;
22$:	BIC	#TCITSP,TCBSCF(R5) ;INDICATE NON-TRANSPARENT MODE
23$:	KGLOAD	#0		;INITIALIZE KG11-A
	BR	21$		;AND RECEIVE MESSAGE
;
; HERE FOR PROCESSING RECEIVED DATA ( DEVICE REQUEST, PERMISSION 
; GRANT, OR DATA BLOCK )
;
HSRXPM:	CLR	TCRMSG(R5)	;INITIALIZE PTR TO START OF CURRENT MESSAGES
	CLR	TCCRCB(R5)	;& CURRENT RECEIVED RCB
	CLR	TCSRCB(R5)	;  AND SRCB
	CLR	TCST2(R5)	; FOR ETB STATUS
	CLR	TCERB(R5)	;CLEAR ANY PREV BCB ERROR FLAG
;
; CHECK THE BCB RECEIVED AGAINST EXPECTED
;
	JSR	PC,HMSGTC	;GET CHAR FROM BLOCK
	BCS	15$		;TIMEOUT
	MOVB	R1,TCRBCB(R5)	;SAVE RECEIVED BCB
.IF NE,BSBUG
	MOV	TCXBCB(R5),R2	;PUT EXPECTED BCB
	SWAB	R2		;IN LEFT SIDE
	BISB	R1,R2		;AND RECEIVED IN RIGHT BYE
	TRACE	TRCBCB,R2	;TRACE BCB EXPECTED,RECEIVED
.ENDC ;.IF NE BSBUG
	CMPB	TCXBCB(R5),R1	;BCB MATCH?
	BEQ	14$		;YES.
	TSTB	R1		;PROPER BCB (HIGH ORDER BIT MUST
				; BE SET)
	BPL	13$		;NO, ERROR
	BIT	#20,R1		;IGNORE (BYPASS BCB CHECK) BCB?
	BNE	14$		;YES, BYPASS CHECKING
	BIT	#40,R1		;RESET BCB?
	BNE	11$		;YES.,PUT RECEIVE BCB IN EXPECTED
	MOV	TCRBCB(R5),TCERB(R5) ;MARK BCB ERROR AND SAVE BCB
	INC	TCBCBE(R5)	;COUNT BCB ERRORS RECEIVED
	BR	14$		;PROCEED AS NORMAL BCB
13$:
.IF NE,BSBUG
	STOPCD	DBG		;BSBUGGING ONLY
.ENDC ;.IF NE,BSBUG
	JSR	PC,MSGGTT	;CLEAR RECEIVER AFTER 2-SEC WAIT

	MOV	R4, -(SP)	;;++BS-SAVE R4
	MOV	TCLCB(R5), R4	;;++BS-POINT TO LCB
	INC	LB.IC7(R4)	;;++BS-COUNT MESSAGES IGNORED
	MOV	(SP)+, R4	;;++RESTORE R4

	MOV	#5,R0		;BCB ERROR IN RECVD DATA
	RTS	PC		;RETURN
;
11$:	MOVB	TCRBCB(R5),TCXBCB(R5) ;RESET EXPECTED BCB
;
; NOW SET UP FCS (FUNCTION CONTROL SEQ RECD) FROM HASP
;
14$:	JSR	PC,HSTFCB	;SET FCS BYTE
15$:	BCS	HSRXET		;TIMEOUT
HSRXP1:	JSR	PC,HSTRCB	;SET RCB AND SRCB BYTES
	BCS	HSRXET		;TIMEOUT
	BIT	#TCETB,TCST2(R5) ;RECEIVED EOB?
	BEQ	11$		;NO.
	JMP	HSEOB		;RECEIVED E-O-B.
;
; CONTINUED TO NEXT PAGE
;
; 
; CHECK RCB FOR ERROR, REQUEST OR PERMISSION FOR DEVICE
;
11$:	CMPB	#220,TCCRCB(R5)	;REQUEST FOR DEVICE?
	BNE	12$		;NO
	BR	HSRQMS		;YES, PROCESS REQUEST MESSAGE
12$:
	CMPB	#240,TCCRCB(R5)	;PERMISSION GRANT MESSAGE?
	BNE	13$		;NO
	BR	HSRQMS		;YES, PERMISSION MESSAGE
13$:
	CMPB	#340,TCCRCB(R5) ;BCB ERROR REPORTED BY HASP?
	BNE	14$		;NO
	JMP	HSETBC		;YES, ERROR IN LAST XMIT
14$:
	MOV	TCRMSG(R5),R0	;ANY MESSAGES FORMED YET?
	BEQ	16$		;NO, START A NEW ONE
15$:	CMPB	TCCRCB(R5),MSGID(R0) ;MESSAGE FOR CURRENT DEVICE?
	BEQ	20$		;YES
	MOV	MSGNXT(R0),R0	;NO, CHECK NEXT MESSAGE IN CHAIN
	BNE	15$		;FOR MATCH WITH DEVICE
16$:	MOV	CHLST,R0	;GET A CHUNK
	JSR	PC,GETCHK	;FROM END OF LIST
	BCC	19$		;GOT ONE
17$:	TRAP	105
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC7(R4)	;COUNT MESSAGES IGNORED
	MOV	#4,R0		;INDICATE CHUNK DEPLETION
18$:	RTS	PC		;RETURN
;
;
19$:	MOV	R0,MSGLCH(R0)	;SET UP MESSAGE HEADER BLOCK
	MOV	TCRCID(R5),MSGID(R0) ;PUT RECEIVED I.D IN MESSAGE
	MOV	TCRMSG(R5),MSGNXT(R0) ;LINK MESSAGE IN CHAIN
	MOV	R0,TCRMSG(R5)	;UPDATE CURRENT MESSAGE PTR
	BIT	#TCITSP,TCBSCF(R5) ;INPUT TRANSPARENCY?
	BEQ	20$		;NO, NORMAL MODE
	BIS	#MSGTSP,MSGFGS(R0) ;FLAG MESSAGE AS TRANSPARENT
20$:	MOV	TCCRCB(R5),R1	;SET UP RECORD HEADER
	JSR	PC,MSGAPC	;RCB AT BEGINNING OF RECORD
	BCS	HSRXET		;OUT OF CHUNKS
	MOV	TCSRCB(R5),R1	;SRCB ALSO
	JSR	PC,MSGAPC	;IN MESSAGE TO XLATE
	BCS	HSRXET		;OUT OF CHUNKS
	CMPB	#RCBCTL,TCCRCB(R5) ;IS IT A SIGNON RECORD?
	BEQ	HSRSON		;YES, RECEIVED A SIGNON
21$:	JSR	PC,HMSGTC	;GET FIRST SCB OF THE RECORD
	BCS	HSRXET		;TIMEOUT
	JSR	PC,MSGAPC	;PUT CHAR IN MESSAGE
	BCS	HSRXET		;OUT OF CHUNKS
	TSTB	R1		;END-OF-FILE (DATALESS RECORD)
	BNE	22$		;GET NEXT CHAR
	BR	HSRXP1		;EOF RECEIVED
;
;
;

22$:				;;++4(032)
	CMPB	#100, R1	;IS THIS A TRANSMISSION ABORT SCB ? ;;++4(032)
	BEQ	21$		;YES, GET END OF RECORD (SCB=0) ;;++4(032)
	TSTB	R1		;NO, CHECK FOR LEGAL SCB ;;++4(032)

	BMI	23$		;LEGAL SCB?
25$:	JSR	PC, MSGGTT	;;++BS-TERMINATE READING
	JMP	HSEOB1		;;++BS-GIVE ERROR RETURN
;25$:	JMP	HSEOB1		;GIVE ERROR RETURN
23$:	BIT	#100,R1		;DUP STRING?
	BEQ	30$		;YES, GET DUP CHAR
	MOV	R1,R2		;GET THE SCB CHAR
	BIC	#177700,R2	;GET COUNT OF NON-DUP CHARS
	BEQ	25$		;ZERO COUNT ILLEGAL
24$:	JSR	PC,HMSGTC	;GET CHAR
	BCS	HSRXET		;TIMEOUT
	JSR	PC,MSGAPC	;PUT CHAR IN MESAGE TO XLATE
	SOB	R2,24$		;LOOP FOR ALL CHAR OF STRING
	BR	21$		;GET NEXT SCB
30$:	BIT	#40,R1		;DUP CHAR BLANK?
	BEQ	21$		;YES, LOOK FOR NEXT SCB
	MOV	#1,R2		;GET THE NON-BLANK CHAR
	BR	24$		;PUT IT IN MESSAGE BEING BUILT
;
;
;
; HERE FOR ERROR RETURN
HSRXET:	JMP	HSRXPT		;RECEIVE TIMEOUT OR OUT OF CHUNKS
;
; HERE WHEN HASP REQUESTED PERMISSION FOR (INPUT) A DEVICE
;
HSRQMS:	MOV	TCSRCB(R5),R1	;SRCB HAS THE RCB OF THE REQUESTED DEVICE
	BIC	#177770,R1	;GET THE DEVICE # FROM RCB
	mov	r4,-(sp)	;save r4
	MOV	TCLCB(R5),R4	;POINT TO THE LCB
	asl	r1		;dev no * 2
	MOV	R1,R2		;PRESERVE DEV NO * 2 IN R1
	ADD	R4,R2		;POINT TO THE DEVICE'S
	MOV	LB.TCD(R2),R2	;TRANSLATE TCB
	CMPB	#240,TCCRCB(R5)	;IS IT PERMISSION GRANTED MSG?
	BEQ	11$		;YES
	BIT	#TCIRN,TCFG2(R2);;++KR- is input already running 3(024)
	BEQ	5$		;;++KR- no, just continue 3(024)
	BIS	#TCIRH,TCFG1(R2);;++KR- yes, set bit to remember it 3(024)
	BR	HSRQM1		;;++KR- and exit 3(024)
5$:				;;++KR- NEW LABEL 3(024)
	BIS	#TCIPH,TCFG1(R2) ;SEND REPLY WHEN PERMISSION GRANTED.
	JSR	PC,HSDRIP	;REQUEST INPUT PERMISSION
	BR	HSRQM1		;CHECK NEXT CHARACTER FOR RCB
11$:	ASR	R1		;GET BACK THE DEVICE NUMBER
	CMPB	R1,LB.NTC(R4)	;IF OUT OF LIMIT, CHECK FOR RCB
	BHI	20$		;YES, ITS OUT OF LIMITS
	CMPB	TCSRCB(R5),TCCTP(R2) ;DOES IT MATCH THE RCB?
	BEQ	21$		;YES.
20$:	CLR	R1		;INITIALIZE DEVICE # FOR HUNT
22$:	INC	R1		;FOR MATCH THRU ALL DEVICES
	CMPB	R1,LB.NTC(R4)	;WITHIN LIMITS
	BLOS	23$		;ITS IN LIMITS
	STOPCD	HDO		;DEVICE OUT OF LIMITS
23$:	MOV	R1,R2		;R1 HAS TO BE PRESERVED
	ASL	R2		;DEVICE # * 2
	ADD	R4,R2		;POINT TO DEVICE'S XLATE TCB
	MOV	LB.TCD(R2),R2	;
	CMPB	TCSRCB(R5),TCCTP(R2) ;MATCH?
	BNE	22$		;NO, LOOP TILL MATCH FOUND
21$:	BIS	#TCOPG!TCORN,TCFG2(R2) ;SET OUTPUT PERMISSION GRANTED?
	bic	#tcopr!tcowr!TCDSP,tcfg2(r2) ;no pending requests
	BIT	#EBINTR,(R2)	;WAITING FOR US
	BEQ	12$		;NO.
	BIC	#EBWAIT!EBINTR,(R2) ;MAYBE, UNWAIT IT
12$:	INC	TCCDPG(R2)	;COUNT PERMISSIONS RECVD
HSRQM1:	MOV	(SP)+,R4	;RESTORE R4
HSRQM2:	JSR	PC,HMSGTC	;GET THE SCB(00) FOR EOR
	BCS	HSRXET		;TIMEOUT
	TSTB	R1		;IT MUST BE ZERO SCB
	BNE	13$		;ITS NOT, FORMAT ERROR
	JMP	HSRXP1		;YES, LOOK AT NEXT RCB
;
13$:
.IF NE,BSBUG
	STOPCD	HFR		;RECEIVED DATA IN FORMAT ERROR
.ENDC
	JSR	PC,MSGGTT	;CLEAR RECEIVER
	JSR	PC,HSRMRL	;RELEASE RECEIVED MESSAGES
	MOV	#5,R0		;WRONG DATA FORMAT RECEIVED
	RTS	PC		;RETURN
;
;
; HERE WHEN RECEIVED RCB INDICATES A SIGNON RECORD
;
HSRSON:	JSR	PC,HMSGTC	;GET NEXT CHARACTER
	BCS	11$		;TIMEOUT
	BIT	#TCETB,TCST2(R5) ;DID WE RECEIVE ETB?
	BNE	HSEOB		;YES.
	JSR	PC,MSGAPC	;APPEND CHAR TO MESSAGE
	BCS	11$		;OUT OF CHUNKS
	BR	HSRSON		;LOOP FOR NEXT CHARACTER
11$:	JMP	HSRXPT		;ERROR RETURN FOR TIMEOUT OR OUT
				;OF CHUNKS
;
; HERE WHEN HASP REPORTED A BCB ERROR IN XMIT
;
HSETBC:
.IF NE,BSBUG
	STOPCD	DBG
.ENDC ;.IF NE,BSBUG
	MOV	#240,TCTBCB(R5) ;SEND A RESET BCB
	BR	HSRQM2		;RECEIVE THE REST OF THE MESSAGE
;
;
; SUBROUTINE TO RELEASE MESSAGES FORMED FROM CURRENT BLOCK
;
HSRMRL:	MOV	TCRMSG(R5),R0	;ANY MESSAGES FORMED?
	BEQ	12$		;NONE
11$:	MOV	TCIDLE,R1	;POINT TO IDLE TASK
	JSR	PC,QUEMSG	;QUE MESSAGE FOR FREEING
	MOV	MSGNXT(R0),R0	;GET NEXT MESSAGE IN CHAIN
	BNE	11$		;GO RELEASE IT
	CLR	TCRMSG(R5)	;CLEAR SO WE DONT RELEASE AGAIN
12$:	RTS	PC		;ALL DONE, RETURN
;
; THIS SUBROUTINE RELEASES ALL OUTGOING MESSAGES IF ANY
;
HSRLOM:	
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.MSG(R4),R0	;MESSAGE TO BE RELEASED?
	BEQ	11$		;NO, CHECK FOR ANY DEVICE MSG STUCK
	MOV	TCIDLE,R1	;YES, POINT TO IDLE TASK
	JSR	PC,QUEMSG	;QUEUE TO FREE
	CLR	LB.MSG(R4)	;CLEAR MESSAGE PTR
11$:	MOV	TCSDM(R5),R0	;ANY DEV MSG STUCK IN BSC
	BEQ	12$		;NO, EXIT
	MOV	TCIDLE,R1	;YES, RELEASE IT
	JSR	PC,QUEMSG	;BY QUING TI IDLE TASK
	CLR	TCSDM(R5)	;CLEAR DEV MESSAGE PTR
12$:	RTS	PC		;RETURN
;
; END OF BLOCK PROCESSING
;
HSEOB:
	JSR	PC,DQRBCC	;ACCUMULATE NEXT TWO CHARACTERS
	BCS	HSRXPT		;TIMEOUT
	JSR	PC,MSGGTE	;TERMINATE READING
	KGTEST			;IS BCC CORRECT?
	BNE	14$		;NO. GOT BCC ERROR
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC1(R4)	;COUNT BLOCKS RECVD SUCCESSFULLY
	MOV	TCRMSG(R5),R0	;YES, QUE MESSAGES FORMED (IF ANY)
	BEQ	13$		;DATA-LESS MESSAGE, MUST BE STATUS BLOCK
12$:	MOV	MSGID(R0),R1	;GET MESSAGE I.D.
	CMPB	#RCBCTL,R1	;SIGNON RECORD?
	BNE	18$		;NO
	MOV	#3,R1		;YES, QUE IT UP FOR CARD READER
18$:	BIC	#177770,R1	;GET DEVICE # FROM I.D.
.IF NE BSBUG
	BNE	19$		;HALT ONLY FOR ZERO DEV
	STOPCD	DBG		;ERROR FROM IBM
19$:
.ENDC ;.IF NE BSBUG
	asl	r1		;dev no * 2
	MOV	R1,R2		;PRESERVE R1
	ADD	R4,R2		;POINT TO DEVICE'S
	MOV	LB.TCD(R2),R2	;XLATE TCB
	JSR	PC,HSDRIP	;INDICATE INPUT COMING
	MOV	R2,R1		;R1 POINTS TO XLATE

	INC	TCIMC(R1)	;;++BS-ONE MORE MESSAGE QUEUED TO XLATE

	CMP	CHFREC, #45	;;++BS-MORE THAN 60 FREE CHUNKS IN THE FE ?
	BGE	31$		;;++BS-YES, CHECK MAX NUMBER OF MESSAGES
	BR	32$		;;++BS-NO, SUSPEND DEVICE NOW

31$:	CMP	TCIMC(R1), #2	;;++BS-MAX NUMBER OF MESSAGES ?
	BLT	33$		;;++BS-NO
32$:	MOV	R1, -(SP)	;;++BS-YES, SAVE R1
	MOV	TCCTP(R1), R1	;;++BS-GET DEVICE TYPE
	BIC	#177770, R1	;;++BS-GET DEVICE NUMBER
	JSR	PC, HSUSPD	;;++BS-SUSPEND THE DEVICE
	MOV	(SP)+, R1	;;++BS-RESTORE R1
33$:				;;++BS-CONTINUE

	BIT	#TCIAB,TCFG2(R1) ;INPUT ABORT?
	BEQ	17$		;NO
	CLR	TCIMC(R1)	;;++BS-CLEAR MESSAGE COUNT
	MOV	TCIDLE,R1	;YES, FREE THE MESSAGE (PUNT IT OUT)
17$:	JSR	PC,QUEMSG	;QUE MESSAGE FOR THE DEVICES TRANSLATE TASK
	MOV	MSGNXT(R0),R0	;ANY MORE MESSAGES IN CHAIN
	BNE	12$		;YES, QUE IT
	CLR	TCRMSG(R5)	;CLEAR MESSAGE PTR
13$:	JSR	PC,HSCHST	;CHECK FOR STATUS CHANGE
	CLC			;INDICATE SUCCESS
	MOV	#1,R0		;INDICATE REAL DATA RECEIVED
	RTS	PC		;RETURN
;
;
; HERE FOR BCC ERROR
;
14$:
HSEOB1:
.if ne,BSBUG
	stopcd	dbg		;BSBUG stopcode
.endc ;.if ne,BSBUG
	MOV	TCRMSG(R5),R0	;ANY MESSAGES TO RELEASE
	BEQ	HSEOB2		;NONE LEFT
15$:	MOV	TCIDLE,R1	;POINT TO THE IDLE TASK
	JSR	PC,QUEMSG	;QUE TO FREE MESSAGE BLOCKS
	MOV	MSGNXT(R0),R0	;ANY MORE MESSAGES TO FREE
	BNE	15$		;YES, LOOP TILL DONE
HSEOB2:	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC2(R4)	;COUNT BAD BCC BLOCKS
	CLR	TCERB(R5)	;CLEAR BAD BCB INDICATOR
.IF NE,BSBUG
	TRAP 	104		;WE COME HERE FOR TRAPPING BCC
				;SO MESSAGES CAN BE SEEN BEFORE REL
.ENDC
	CLR	TCRMSG(R5)	;CLEAR RECEIVED MESSAGE PTR
	MOV	#5,R0		;INDICATE INVALID DATA
	RTS	PC		;RETURN
;

; HERE FOR ERROR RETURN ON CHUNK DEPLETION OR TIMEOUT
;
HSRXPT:
HSRXPE:
.IF NE,BSBUG
	STOPCD	DBG		;TRAP TIMEOUT ERRORS
.ENDC	
	JSR	PC,MSGGTT	;CLEAR RECEIVER
	JSR	PC,HSRMRL	;RELEASE MESSAGES FORMED
	MOV	TCLCB(R5),R4	;POINT TO LCB
	INC	LB.IC7(R4)	;COUNT MESSAGES IGNORED
	MOV	#4,R0		;UNRECOG MESSAGES
	RTS	PC		;RETURN
;
;
; THIS SUBROUTINE GETS A CHARACTER FROM
; INPUT AND CHECKS FOR DLE OR SYN AND EXCLUDES THEM FROM BCC
;
HMSGTC:	JSR	PC,MSGGTC	;GET CHARACTER
	BCS	13$		;TIMEOUT
	BIT	#TCITSP,TCBSCF(R5) ;INPUT TRANSPARENT?
	BEQ	11$		;NO, NORMAL
	CMPB	#EBCDLE,R1	;YES, CHECK FOR DLE
	BNE	12$		;ITS NOT A DLE
	JSR	PC,MSGGTC	;LOOK AT CHAR AFTER DLE
	BCS	13$		;TIMEOUT
11$:	CMPB	#EBCSYN,R1	;IS IT A SYN
	BEQ	HMSGTC		;LOOK FOR CHAR AFTER DLE-SYN
12$:	KGACUM	R1		;INCLUDE IN BCC
	CMPB	#EBCETB,R1	;RECEIVED ETB?
	BNE	14$		;NO
	BIS	#TCETB,TCST2(R5) ;MARK ETB RECVD
14$:	CLC			;INDICATE SUCCESS
13$:	RTS	PC		;RETURN
;
;
; THIS SUBROUTINE SETS THE FCS FROM HASP
;
HSTFCB:	JSR	PC,HMSGTC	;GET FCS CHAR
	BCS	11$		;TIMEOUT
	MOVB	R1,TCRFCS+1(R5)	;SAVE FCS BYTE RECD
	JSR	PC,HMSGTC	;GET NEXT FCS BYTE
	BCS	11$		;NONE THERE
	MOVB	R1,TCRFCS(R5)	;SAVE SECOND BYTE OF FCS
11$:	RTS	PC		;RETURN
;
;
; THIS SUBROUTINE SETS UP THE RCB AND SRCB
;
HSTRCB:	CLR	TCCRCB(R5)	;INITIALIZE RECVD RCB
	CLR	TCSRCB(R5)	;INITIALIZE RECVD SRCB
	JSR	PC,HMSGTC	;GET RCB BYTE
	BCS	12$		;TIMEOUT
	BIT	#TCETB,TCST2(R5) ;ETB RECEIVED?
	BNE	12$		;YES.
	MOVB	R1,TCCRCB(R5)	;SAVE RECEIVED RCB
	BEQ	14$		;EOB RECEIVED

;;++4(031)- ROUTE CONTROL MESSAGE TO CONSOLE IN EMULATION

	MOV	R4, -(SP)	;SAVE R4 ;;++4(031)
	MOV	TCLCB(R5), R4	;POINT TO LCB ;;++4(031)
	BIC	#177400, R1	;CLEAR JUNK ;;++4(031)
	CMPB	R1, #RCBCTL	;IS IT A SIGNON ? ;;++4(031)
	BNE	20$		;NO, TREAT NORMALLY ;;++4(031)
	BIT	#LF.SIM, LB.FGS(R4) ;YES, IS IT SIMULATION MODE ? ;;++4(031)
	BEQ	20$		;NO, TREAT NORMALLY ;;++4(031)
	MOVB	#221, TCCRCB(R5) ;YES,SAVE CONSOLE IN AS CURRENT RCB ;;++4(031)
	MOVB	#221, R1	;SEND MESSAGE TO CONSOLE IN ;;++4(031)
20$:	MOV	(SP)+, R4	;RESTORE R4 ;;++4(031)

;;++4(031)- END OF CODE TO ROUTE CONTROL MESSAGE TO CONSOLE IN EMULATION


11$:	BIC	#177770,R1	;FIND DEVICE TYPE
	MOV	R1,TCRDVT(R5)	;SAVE CURRENT DEVICE TYPE
	MOV	R4,-(SP)	;SAVE R4, IT HAS PTR TO REC CHUNKK
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.LNU(R4),R1	;GET LINE NO. IN LEFT BYTE
	SWAB	R1		;
	ADD	TCCRCB(R5),R1	;PUT RCB IN RIGHT BYTE
	MOV	R1,TCRCID(R5)	;SAVE CURRENT I.D. RECEIVED
	MOV	(SP)+,R4	;RESTORE R4
	JSR	PC,HMSGTC	;GET SRCB BYTE
	BCS	12$		;TIMEOUT
	MOVB	R1,TCSRCB(R5)	;SAVE SRCB RECEIVED
12$:	RTS	PC		;RETURN
;
;
;
14$:	JSR	PC,HMSGTC	;GET THE NEXT CHAR
	BCS	12$		;TIMEOUT
	BIT	#TCETB,TCST2(R5)  ;RECEIVED ETB YET?
	BNE	12$		;YES.


	CMPB	#128., R1	;;++4(025) IS IT A BCB ?
	BNE	1$		;;++4(025) NO, ERROR
	JSR	PC,HMSGTC	;;++4(025) YES, READ FCS BYTE #1
	BCS	1$		;;++4(025) TIMEOUT, ERROR
	JSR	PC,HMSGTC	;;++4(025) READ FCS BYTE #2
	BCS	1$		;;++4(025) TIMEOUT, ERROR
	JSR	PC,HMSGTC	;;++4(025) LOOK FOR ETB
	BCS	1$		;;++4(025) TIMEOUT, ERROR
	BIT	#TCETB,TCST2(R5)  ;;++4(025) RECEIVED ETB YET?
	BNE	12$		;;++4(025) YES.	
1$:				;;++4(025) 

	SEC			;;++BS-INDICATE ERROR
	RTS	PC		;;++BS-RETURN

	TRAP	107		;ILLEGAL STRING
				;ETB DID NOT FOLLOW ZERO RCB
; HERE FOR STATUS BLOCK PROCESSING
;
HSCHST:		
	MOV	TCRFCS(R5),R1
	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	R4,R2		;SAVE FOR REF
	BIT	#FCSUNV,R1	;SUSPEND ALL?
	BEQ	11$		;NO, CHECK FOR CARD READER
	BIS	#TCDSP,TCFG2(R5) ;SET UNIVERSAL SUSPEND BIT
	BR	12$		;START CHECKING DEVICES
11$:	BIC	#TCDSP,TCFG2(R5) ;UNSUSPEND SYSTEM
12$:				;HERE TO CHECK CARD READER OR LPT
	ADD	#6,R2		;FIND DEVICE'S
	BIT	#LF.SIM,LB.FGS(R4) ;SIMULATE MODE?
	BNE	13$		;YES, TREAT DEVICE AS CDR
	ADD	#2,R2		;LPT FOR SUPPORT MODE
13$:	MOV	LB.TCD(R2),R2	;POINT TO DEVICE'S XLATE TCB
	BIT	#FCSRD1,R1	;DEVICE SUSPENDED?
	BNE	14$		;NO.
	BIS	#TCDSP,TCFG2(R2) ;SUSPEND THE DEVICE
	BR	15$		;CHECK NEXT DEVICE
14$:	BIC	#TCDSP,TCFG2(R2) ;UNSUSPEND DEVICE
15$:	MOV	R4,R2		;GET PTR TO LCB
	ADD	#2,R2		;POINT TO DEVICE'S
	MOV	LB.TCD(R2),R2	;XLATE TCB
	BIT	#FCSCSL,R1	;CONSOLE SUSPENDED?
	BNE	16$		;NO
	BIS	#TCDSP,TCFG2(R2) ;SUSPEND CONSOLE OUTPUT
	BR	17$		;CHECK NEXT DEVICE
16$:	BIC	#TCDSP,TCFG2(R2) ;UNSUSPEND CONSOLE
17$:	MOV	R4,R2		;GET PTR TO LCB
	ADD	#12,R2		;POINT TO PUNCH 4(027)
;4(027)	ADD	#10,R2		;POINT TO PUNCH
	MOV	LB.TCD(R2),R2	;XLATE TCB
	BEQ	19$		;;++BS-JUMP IF NO PUNCH
	BIT	#FCSPU1,R1	;PUNCH SUSPENDED?
	BNE	18$		;NO
	BIS	#TCDSP,TCFG2(R2) ;SUSPEND PUNCH DEVICE
	BR	19$		;ALL DONE
18$:	BIC	#TCDSP,TCFG2(R2) ;UNSUSPEND THE DEVICE
19$:	RTS	PC		;RETURN
;
;
; SUBROUTINE TO REQUEST INPUT PERMISSION.
; ON ENTRY R1= DEVICE NUMBER OF THE REQUESTED DEVICE * 2
;          R2= DEVICE'S XLATE TCB PTR
; THIS SUBROUTINE IS CALLED BY HSRXPM WHILE PROCESSING 
; THE RECEIVED RECORD FOR DEVICE PERMISSION
;
; ON RETURN:
;
HSDRIP:	BIS	#TCIPR!TCIWR,TCFG2(R2) ;REQUEST INPUT PERMISSION

;;++BS-CODE TO SET THE DEVICE ACTIVE BIT WHEN INPUT PERMISSION WAS REQUESTED

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	CLC			;CLEAR FOR ROTATE
	ASR	R1		;GET BACK DEVICE NUMBER
	BIC	#177400, R1	;CLEAR JUNK
	MOV	TCLCB(R5),R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	JSR	PC, HSACMP	;SET THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

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

	ASR	R1		;GET DEV # BACK
	MOV	R4,-(SP)	;SAVE R4
	BIT	#TCIOM,TCFG1(R2) ;DEVICEIN INPUT MODE?
	BNE	14$		;YES.
	STOPCD	HSE		;ASKING INPUT PERMISSION FROM OUTPUT DEVICE
14$:
	BIT	#TCIPG!TCIRN,TCFG2(R2) ;PERMISSION GRANTED?
	BNE	12$		;YES
				; AND NOTE IT WAS REQ. [2(770)]
	JSR	PC,HSUSPD	;SUSPEND DEVICE IF NOT RUNNING
	JSR	PC,HSAWXL	;WAKE UP XLATE TASK
	BR	13$		;RETURN
;
; HERE IF PERMISSION HAS BEEN GRANTED.
;
12$:

;;++BS-CODE TO CLEAR THE DEVICE ACTIVE BIT WHEN INPUT PERMISSION WAS GRANTED

	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	BIC	#177400, R1	;CLEAR JUNK
	MOV	TCLCB(R5),R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	JSR	PC, HSAMPC	;CLEAR THE DEVICE ACTIVE BIT
	JSR	PC, HSRESR	;RESTORE THE REGISTERS

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

	JSR	PC,HSUNSP	;UNSUSPEND DEVICE
	JSR	PC,HSAWXL	;AWKEN THE XLATE TASK
13$:	MOV	(SP)+,R4	;RESTORE R4
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO AWAKEN THE TRANSLATE TASK
;
; R1 = HAS THE DEVICE # WHOSE XLATE TASK NEEDS TO BE AWAKENED.
; R4 POINTS TO THE LCB
;
HSAWXL:	
.IF NE,BSBUG
	CMP	R4,TCLCB(R5) 	;DOES R4 POINT TO LCB? [1(730)]
	BEQ	11$		;YES. [1(730)]
	STOPCD	DBG		;NO, CODING ERROR IN BSC TASK [1(730)]
11$:
.ENDC ;.IF NE,BSBUG
	asl	r1		;dev no * 2
	ADD	R1,R4		;POINT TO SPECIFIC DEVICE'S
	asr	r1		;restore dev no
	MOV	LB.TCD(R4),R4	;GET ADR OF XLATE TCB
	BEQ	12$		;FOR MISSIING OR RELEASED TCB'S
	BIT	#EBINTR,(R4)	;IS XLATE TASK WAITING FOR US?
	BEQ	12$		;NO.
	BIC	#EBINTR!EBWAIT,(R4) ;MAYBE, UNWAIT IT.
12$:	RTS	PC		;RETURN
;
; THIS SUBROUTINE WAKES UP ALL DEVICE'S XLATE TASKS
;
HSWALX:
	mov	lb.ntc(r4),r1	;max dev number
	BEQ	11$		;EXIT IF ZERO TCBS
12$:	mov	tclcb(r5),r4	;point to lcb
	jsr	pc,hsawxl	;awake the xlate task
	SOB	R1,12$		;LOOP FOR ALL DEVICES
11$:	RTS	PC		;RETURN
;
; SUBROUTINE TO SUSPEND A DEVICE WHEN INPUT PERMISSION REFUSED
;
HSUSPD:	MOV	R2,-(SP)	;SAVE R2
	MOV	R3,-(SP)	;;++BS-SAVE R3
	MOV	R5, R3		;;++BS-POINT R3 TO CALLING TCB
	MOV	TCLCB(R3), R3	;;++BS-POINT TO LCB
	MOV	LB.TC1(R3), R3	;;++BS-POINT TO BSC TCB
	asl	r1		;dev no * 2
	MOV	SUSTBL(R1),R2	;R1 HAS DEVICE # ON ENTRY
;	BIC	R2,TCTFCS(R5)	;SUSPEND THE DEVICE
	BIC	R2,TCTFCS(R3)	;;++BS-SUSPEND THE DEVICE
;	BIS	#TCHGST,TCST2(R5) ;INDICATE STATUS CHANGED
	BIS	#TCHGST,TCST2(R3) ;;++BS-INDICATE STATUS CHANGED
	asr	r1		;restore dev no
	MOV	(SP)+,R3	;;++BS-RESTORE R3
	MOV	(SP)+,R2	;RESTORE R2
	RTS	PC		;RETURN
;
SUSTBL:	.WORD	0		;START OF SUSPEND TABLE
	.WORD	FCSCSL		;SUSPEND CONSOLE OUTPUT
	.WORD	FCSCSL		;SUSPEND CONSOLE INPUT
	.WORD	FCSRD1		;SUSPEND CARD READER
	.WORD	FCSPR1		;SUSPEND LINE PRINTER
	.WORD	FCSPU1		;SUSPEND CARD PUNCH
;
;
; THIS SUBROUTINE UNSUSPENDS A DEVICE WHEN INPUT PERMISSION 
; IS GRANTED FOR THAT DEVICE
; R1=DEVICE #
;
HSUNSP:	MOV	R2,-(SP)	;SAVE R2
	MOV	R3,-(SP)	;;++BS-SAVE R3
	MOV	R5, R3		;;++BS-POINT R3 TO CALLING TCB
	MOV	TCLCB(R3), R3	;;++BS-POINT TO LCB
	MOV	LB.TC1(R3), R3	;;++BS-POINT TO BSC TCB
	ASL	R1		;DEV NO * 2
	MOV	SUSTBL(R1),R2	;GET THE UNSUSPEND WORD FOR DEVICE
;	BIS	R2,TCTFCS(R5)	;UNSUSPEND THE DEVICE
	BIS	R2,TCTFCS(R3)	;;++BS-UNSUSPEND THE DEVICE
;	BIS	#TCHGST,TCST2(R5) ;INDICATE STATUS CHANGED
	BIS	#TCHGST,TCST2(R3) ;;++BS-INDICATE STATUS CHANGED
	ASR	R1		;RESTORE DEV NUMBER
	MOV	(SP)+,R3	;;++BS-RESTORE R3
	MOV	(SP)+,R2	;RESTORE R2
	RTS	PC		;AND RETURN
;
;
; THIS SUBROUTINE SETS ABORT FLAG FOR A DEVICE STREAM.
;
hsabro:	trace	trcabo,(sp)	;trace abort
.if ne,BSBUG
	bit	#trcabo,trchlt	;want to halt at abort
	beq	11$		;no
	stopcd	dbg		;yes
11$:
.endc ;
	ASL	R1		;R1 HAS DEV NO
	MOV	TCLCB(R5),R4	;POINT TO LCB
	ADD	R1,R4		;DEVICE'S XLATE TCB
	ASR	R1		;RESTORE DEV NO
	MOV	LB.TCD(R4),R4	;GET POINTER TO 
	BEQ	12$		;FOR MISSING TCB
	BIT	#TCIOM,TCFG1(R4) ;OUTPUT DEV?
	BNE	12$		;NO.
	BIS	#TCOAB,TCFG2(R4) ;SET ABORT FLAG
12$:	RTS	PC		;RETURN
;
; THIS SUBROUTINE SETS INPUT ABORT FLAG FOR A DEVICE.
;
hsabri:	trace	trcabo,(sp)	;trace input abort
.if ne,BSBUG
	bit	#trcabo,trchlt  ;want to stop at abort
	beq	11$		;no
	stopcd	dbg		;yes
11$:
.endc ;
	ASL	R1		;ON ENTRY R1 HAS DEV NO
	MOV	TCLCB(R5),R4	;POINT TO LCB
	ADD	R1,R4		;GET DEVICE'S 
	ASR	R1		;GET DEV # BACK
	MOV	LB.TCD(R4),R4	;POINT TO XLATE TCB
	BEQ	12$		;FOR MISSING TCB??
	BIT	#TCIOM,TCFG1(R4) ;INPUT DEVICE?
	BEQ	12$		;NO, EXIT
	BIS	#TCIAB,TCFG2(R4) ;SET ABORT FLAG
12$:	RTS	PC		;RETURN
;
; THIS SUBROUTINE SETS ABORT FOR ALL OUTPUT DEVICES
;
HSABTO:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.NTC(R4),R1	;GET MAX DEVICE #
11$:	JSR	PC,HSABRO	;ABORT THE DEVICE
	SOB	R1,11$		;ALL DONE
	BIS	#TCOAB,TCFG2(R5) ;SET OUTPUT ABORT STARTED BY BSC
	MOV	TCLCB(R5),R4	;POINT TO LCB
	RTS	PC		;YES, EXIT
;
; THIS SUBROUTINE SETS ABORT FOR ALL INPUT DEVICES.
;
HSABTI:	MOV	TCLCB(R5),R4	;POINT TO LCB
	MOV	LB.NTC(R4),R1	;GET MAX DEVICE #
11$:	JSR	PC,HSABRI	;ABORT THE DEVICE
	SOB	R1,11$		;LOOP TILL ALL DONE
	BIS	#TCIAB,TCFG2(R5) ;SET INPUT ABORT STARTED BY BSC
	MOV	TCLCB(R5),R4	;POINT TO LCB
	RTS	PC		;THEN RETURN
;
;THE FOLLOWING ROUTINES SET OR CLEAR THE DEVICE AND ANY DEVICE 
;ACTIVE BITS.

;TO CLEAR A DEVICE ACTIVE BIT, THE ENTRY IS: JSR PC, HSAMPC
;TO SET A DEVICE ACTIVE BIT, THE ENTRY IS: JSR PC, HSACMP

;IF NO DEVICES ARE ACTIVE, THE ANY DEVICE ACTIVE BIT IS CLEARED

;ON ENTRY:	R0 = THE LINE NUMBER
;		R1 = THE DEVICE NUMBER


;THIS IS THE ENTRY POINT TO CLEAR A DEVICE ACTIVE


HSAMPC:	MOV #1,HSCLDA			;CLEAR ACTIVE STATUS

;THIS IS THE ENTRY POINT TO SET A DEVICE ACTIVE


HSACMP:	MOV	R0, -(SP)		;SAVE THE REGISTERS
	MOV	R1, -(SP)		;
	MOV	R2, -(SP)		;
	MOV	R3, -(SP)		;

;CONVERT LINE NUMBER TO OFFSET INTO STATUS TABLE


	CLC				;CLEAR FOR ROTATE
	ASL	R0			;MAKE LINE NUMBER EVEN
	ASL	R0			;POINT TO FIRST WORD OF
					;TWO WORD STATUS

	MOV	R1, R2			;GET DEVICE NUMBER

	BIC	#177400, R2		;CLEAR JUNK
	CMP	#360, R2		;IS THIS A SIGNON ?
	BNE	20$			;NO, CONTINUE 3(014)
	MOV	#223, R2		;YES, CONVERT TO CDR 3(014)
	MOV	#223, R1		;CONVERT TO CDR 3(014)

20$:
	BIC	#177770,R2		;GET OFFSET INTO DEVICE TABLE
	CLC				;CLEAR FOR ROTATE
	ASL	R2			;MAKE EVEN

	TST	R2			;IS DEVICE NUMBER ZERO ?
	BEQ	21$			;YES, ERROR
	CMP	R2, #12			;IS THE DEVICE UNKNOWN ?
	BLE	22$			;NO, CONTINUE
21$:	STOPCD	RNG			;OUT OF RANGE
22$:

	JSR	PC, @HSASER-2(R2)	;SET OR CLEAR THE UNIT BIT

;;SEE IF THE ANY DEVICE ACTIVE BIT MUST BE SET OR CLEARED
;	BIT	#177700, D60ACT(R0)	;ANY ACTIVE TTYS OR CDRS?
;	BNE	1$			;YES, SET ANY DEVICE ACTIVE BIT
;	BIT	#177777, D60ACT+2(R0)	;ANY ACTIVE LPTS OR CDPS?
;	BNE	1$			;YES, SET ANY DEVICE ACTIVE BIT
;	BIC	#B1, D60ACT(R0)		;NO, CLEAR ANY DEVICE ACTIVE BIT
;	BR	2$			;BEGIN EXIT PROCEDURE
;1$:	BIS	#B1, D60ACT(R0)		;SET ANY DEVICE ACTIVE BIT

2$:	CLR	HSCLDA			;CLEAR BIT THAT SAYS CLEAR ACTIVE BIT

	MOV	(SP)+, R3		;RESTORE REGISTERS
	MOV	(SP)+, R2		;
	MOV	(SP)+, R1		;
	MOV	(SP)+, R0		;

	RTS	PC			;RETURN TO CALLER




;THESE ARE THE HANDLERS FOR THE SETTING OR CLEARING OF A
;DEVICE ACTIVE BIT


;CONSOLE OUT HANDLER


HSCTYO:	TST	HSCLDA			;CLEAR THE ACTIVE BIT ?
	BEQ	1$			;NO
	BIC	#B7, D60ACT(R0)		;CLEAR THE BIT
	BR	2$			;BEGIN RETURN
1$:	BIS	#B7, D60ACT(R0)		;SET THE ACTIVE BIT
2$:	RTS	PC			;RETURN TO CALLER

;CONSOLE IN HANDLER


HSCTYI:	TST	HSCLDA			;CLEAR THE ACTIVE BIT ?
	BEQ	1$			;NO
	BIC	#B6,D60ACT(R0)		;CLEAR THE BIT
	BR	2$			;BEGIN THE RETURN
1$:	BIS	#B6, D60ACT(R0)		;SET THE ACTIVE BIT
2$:	RTS	PC			;RETURN TO CALLER


;CARD READER HANDLER



HSDCDR:	MOV	#B8, R3			;UNIT # 1 = BIT # 0
1$:	CMP	R1, #223		;UNIT #0 OR NOT HASP ?
	BLE	2$			;YES, NOW SET OR CLEAR ACTIVE BIT
	SUB	#20, R1			;NO, REDUCE THE DEVICE #
	CLC				;CLEAR FOR ROTATE
	ASL	R3			;SHIFT UNIT #
	BR	1$			;SEE IF WE FOUND UNIT
2$:	TST	HSCLDA			;CLEAR THE ACTIVE BIT ?
	BEQ	3$			;NO, SET IT
	BIC	R3, D60ACT(R0)		;CLEAR THE ACTIVE BIT
	BR	4$			;BEGIN RETURN
3$:	BIS	R3, D60ACT(R0)		;SET THE ACTIVE BIT
4$:	RTS	PC			;RETURN TO CALLER


;LINE PRINTER HANDLER


HSDLPT:	MOV	#B0, R3			;UNIT # 1 = BIT # 0
1$:	CMP	R1, #224		;UNIT #0 OR NOT HASP ?
	BLE	2$			;YES, NOW SET OR CLEAR ACTIVE BIT
	SUB	#20, R1			;NO, REDUCE THE DEVICE #
	CLC				;CLEAR FOR ROTATE
	ASL	R3			;SHIFT UNIT #
	BR	1$			;SEE IF WE FOUND UNIT
2$:	TST	HSCLDA			;CLEAR THE ACTIVE BIT ?
	BEQ	3$			;NO, SET IT
	BIC	R3, D60ACT+2(R0)	;CLEAR THE ACTIVE BIT
	BR	4$			;BEGIN RETURN
3$:	BIS	R3, D60ACT+2(R0)	;SET THE ACTIVE BIT
4$:	RTS	PC			;RETURN TO CALLER


;CARD PUNCH HANDLER


HSDCDP:	MOV	#B8, R3			;UNIT # 1 = BIT # 8
1$:	CMP	R1, #225		;UNIT #0 OR NOT HASP ?
	BLE	2$			;YES, NOW SET OR CLEAR ACTIVE BIT
	SUB	#20, R1			;NO, REDUCE THE DEVICE #
	CLC				;CLEAR FOR ROTATE
	ASL	R3			;SHIFT UNIT #
	BR	1$			;SEE IF WE FOUND UNIT
2$:	TST	HSCLDA			;CLEAR THE ACTIVE BIT ?
	BEQ	3$			;NO, SET IT
	BIC	R3, D60ACT+2(R0)	;CLEAR THE ACTIVE BIT
	BR	4$			;BEGIN RETURN
3$:	BIS	R3, D60ACT+2(R0)	;SET THE ACTIVE BIT
4$:	RTS	PC			;RETURN TO CALLER



;DISPATCH TABLE TO DEVICE HANDLERS FOR SETTING AND 
;CLEARING ACTIVE BIT


HSASER:	.WORD	HSCTYO			;CONSOLE OUT
	.WORD	HSCTYI			;CONSOLE IN
	.WORD	HSDCDR			;CARD READER
	.WORD	HSDLPT			;LINE PRINTER
	.WORD	HSDCDP			;CARD PUNCH


;BIT TO INDICATE WE WANT ACTIVE BIT CLEARED
;HSCLDA = 1 IMPLIES CLEAR ACTIVE BIT
;HSCLDA = 0 IMPLIES SET ACTIVE BIT


HSCLDA:	.WORD	0			;INITIALIZE TO 0






;SUBROUTINE TO SAVE ALL THE REGISTERS


HSSAVR:	MOV	R0, -(SP)		;save R0
	MOV	2(SP), R0		;get return PC
	MOV	(SP), 2(SP)		;store R0 where it was
	MOV 	R1, (SP)		;save R1 in cell where R0 was
	MOV	R2, -(SP)		;save R2
	MOV	R3, -(SP)		;..R3
	MOV	R4, -(SP)		;..R4
	MOV	R5, -(SP)		;..R5
	MOV	R0,-(SP)		;save PC on stack
	MOV	14(SP),R0		;restore R0 value
	RTS	PC


;SUBROUTINE TO RESTORE THE REGISTERS


HSRESR:	MOV	(SP)+, R0		;get return PC
	MOV	(SP)+, R5		;restore the registers from the stack
	MOV	(SP)+, R4
	MOV	(SP)+, R3
	MOV	(SP)+, R2
	MOV	(SP)+, R1
	MOV	R0, -(SP)		;push return PC
	MOV	2(SP), R0		;restore R0
	MOV	(SP), 2(SP)		;copy PC
	TST	(SP)+			;pop first copy
	RTS	PC			;return using second PC
;
;
;SUBROUTINE TO CHECK IF THERE IS A DISABLE IN PROGESS
;
;R5 = POINTER TO CALLING TASK
;
;


HTDIPF:	MOV	R0, -(SP)	;SAVE R0
	MOV	TCLCB(R5), R0	;POINT TO LCB
	BIT	#LF.DIP, LB.FGS(R0) ;DISABLE IN PROGRESS ?
	BNE	1$		;YES
	MOV	(SP)+, R0	;NO, RESTORE R0
	CLC			;INDICATE NO DISABLE IN PROGRESS
	RTS	PC		;RETURN
1$:	MOV	(SP)+, R0	;YES, RESTORE R0
	SEC			;INDICATE DISABLE IN PROGRESS
	RTS	PC		;RETURN


;
;
;
;
;;++BS-3(013) SUBROUTINE TO INDICATE COMMUNICATIONS ESTABLISHED


HSETCE:	MOV	R4, -(SP)	;SAVE R4
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIS	#LF.CME, LB.FGS(R4) ;INDICATE COMMUNICATION ESTABLISHED
	MOV	(SP)+, R4	;RESTORE R4
	RTS	PC		;RETURN

;;++BS-3(013) END OF HSETCE
;




;
;;++BS-3(013) SUBROUTINE TO SET H/W ABORT 


HSETHA:	MOV	R4, -(SP)	;SAVE R4
	MOV	TCLCB(R5), R4	;POINT TO LCB
	BIS	#LF.HWA, LB.FGS(R4) ;INDICATE A H/W  ABORT
	JSR	PC, HSTBTS	;;++BS-SET ALL THE ACTIVE BITS 3(017)
	MOV	(SP)+, R4	;RESTORE R4
	RTS	PC		;EXIT

;;++BS-3(013) END OF HSETHA
;
;
;
;
;
;;++BS-3(017) SUBROUTINE TO SET ALL THE DEVICE ACTIVE BITS 
;;++BS-3(017) WHEN A HARDWARE ABORT OCCURS.

HSTBTS:	JSR	PC, HSSAVR	;SAVE THE REGISTERS
	MOV	TCLCB(R5), R2	;POINT TO LCB
	MOV	LB.LNU(R2), R0	;GET LINE NUMBER
	BIC	#177770, R0	;CLEAR JUNK
	CLC			;CLEAR FOR ROTATE
	ASL	R0		;MAKE EVEN
	ASL	R0		;POINT TO FIRST WORD OF 2 WORD STATUS
	MOV	#-1, D60ACT(R0)	;CLEAR ACTIVE STATUS BITS
	MOV	#-1, D60ACT+2(R0) ;CLEAR ACTIVE STATUS BITS
	JSR	PC, HSRESR	;RESTORE THE REGISTERS
	RTS	PC		;RETURN





;;++BS-3(017) END OF HSTBTS
;
;
;
;