Google
 

Trailing-Edge - PDP-10 Archives - bb-k345a-sb - dncdds.p11
There are 10 other files named dncdds.p11 in the archive. Click here to see a list.
.SBTTL	DNCDDS - DS11 SYNCHRONOUS LINE INTERFACE  28 MAR 79

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

VRCDDS=006			;FILE EDIT NUMBER

.IF NE DSN	;.IF SYNCHRONOUS LINES PRESENT, AND THEY HAVE DS11S
.IF NE FTDS11

;NOTES ON THE TRANSMIT AND RECEIVE INTERRUPT SERVICE ROUTINES

;DATA INTERRUPTS REALLY CONSIST OF 2 PHASES, SUPPLYING THE NEXT
;CHARACTER AND SETTING UP THE NEXT BUFFER. SINCE THE LATTER MAY TAKE
;SO MUCH TIME THAT DATA INTERRUPTS ARE LOCKED OUT, BOTH THESE ISR'S
;EMPLOY A TECHNIQUE TO GET AROUND THESE PROBLEMS. ONLY THE TRANSMITTER
;IS DESCRIBED HERE AS THE RECEIVER IS ESSETIALLY IDENTICAL.

;THE FIRST THING THE TRANSMIT INTERRUPT ROUTINE DOES IS TO SUPPLY
;THE HARDWARE WITH THE NEXT CHARACTER TO OUTPUT. IF THERE ARE MORE
;CHARACTERS WAITING IN THE STRING THE INTERRUPT IS DISMISSED.
;HOWEVER, IF THE STRING IS EXHAUSTED, THE DDCMP TRANSMIT COROUTINE
;MUST BE CALLED VIA @LB.XDN(J) TO GET THE NEXT STRING. SINCE THIS
;MAY TAKE A LONG TIME (THE RECEIVER CHECKS THE BCC), THE PRIORITY
;LEVEL IN THE PS IS DECREMENTED TO ALLOW DATA INTERRUPTS FROM THE
;RECEIVER OR OTHER LINES TO BE PROCESSED. ONCE THE COROUTINE IS DONE,
;WE INCREMENT THE PS, STORE THE POINTER TO THE NEXT STRING, AND
;FINALLY DISMISS THE INTERRUPT.

;THERE ARE A COUPLE OF RACE CONDITIONS TO KEEP IN MIND. FIRST, IF A
;DATA INTERRUPT FOR A DIFFERENT LINE OCCURS WHILE IN THE COROUTINE
;AND IT DECIDES IT HAS TO CALL ITS COROUTINE, IT WILL DO SO, GET AN
;ANSWER AND EXIT BEFORE THE FIRST INTERRUPT FINISHES BEING PROCESSED!
;THEREFORE, WHILE THIS SCHEME SHORTENS RESPONSE TIME TO DATA INTERRUPTS,
;IT MAY DOUBLE (OR TRIPLE...) RESPONSE TO REQUESTS FOR A NEW STRING.
;IT DOESN'T HAPPEN OFTEN, BUT IT DOES HAPPEN.

;SECOND, THERE ARE TIMES WHEN RESPONSE IS SO SLOW THAT A DATA INTERRUPT
;WILL OCCUR FOR A LINE ALREADY IN ITS COROUTINE. IF ITS PRESENT
;STRING STILL HAS DATA, THE LINE WILL GET ITS CHARACTER AND EVERYTHING
;KEEPS PLODDING ALONG. HOWEVER, IT CAN OCCUR THAT THE CURRENT
;STRING IS EXHAUSTED. IN THIS CASE LB.SXR+6 WILL BE 0, A FLAG
;THAT SAYS WE ARE STILL INSIDE THE COROUTINE. IN THIS CASE (AND IT
;DOES HAPPEN!) ABOUT THE ONLY THING WE CAN DO IS CALL DSXABT TO
;STOP THE TRANSMITTER AND LET THE DDCMP LOOP LEVEL CODE FIGURE
;OUT WHAT HAPPENED AND RESTART THE TRANSMITTER.

;DSDINI IS CALLED TO INITIALIZE A DS11 LINE
DSDINI:	MOV	#DS.IVA,DS.AUX		;SET VECTORS AGAIN
	MOV	#DS.DTR,DS.RST(DQ)	;SET ONLY DATA TERM. READY
	MOV	#DS.DTR,DS.XST(DQ)	;IN BOTH STATUS REGISTERS
	RTS	PC
;DSXBEG IS USED TO START UP AN IDLE DS11 LINE

DSXBEG:	MOV	LB.SLA(J),DQ		;BE CONSISTENT
	TRACE	DS			;SO YOU CAN SEE WHAT GOES ON
	BIS	#LS..XG,(J)		;SET RUN BIT SO NO 2ND CALL
	MOV	#SYNCHS,LB.SXR(J)	;START WITH SYNCS
	MOV	#-FTNSYN,LB.SXR+2(J)
	JSR	PC,@LB.XDN(J)		;GET MORE
	MOV	R0,LB.SXR+4(J)		;SET SECONDARY BUFFER
	MOV	R1,LB.SXR+6(J)		;AND COUNT
	MOV	#DS.XGO,DS.XST(DQ)	;BEFORE STARTING DS11
	MOVB	#SYN,DS.XDR(DQ)		;PRIME IT WITH A SYNCH
	RTS	PC
.MACRO	X	Q
DSVC'Q:
DSC.'Q:	SAVE	<J>
	MOV	#FLBDS+<LB.SIZ*'Q>,J
.ENDM	X
	Z=DSN-1
.REPT	DSN
	X	\Z
.IIF NE Z, BR	DSXINT			;NOW TO GENERAL XMINT ROUTINE
	Z=Z-1
.ENDR

;DSXINT COME HERE FOR A DATA TRANSMIT INTERRUPT

DSXINT:	SAVE	<DQ>			;SAVE REGISTERS AS NECESSARY
	MOV	LB.SLA(J),DQ		;GET ADDRESS OF DEVICE REGISTERS
	MOVB	@LB.SXR(J),DS.XDR(DQ)	;SEND NEXT CHARACTER
	INC	LB.SXR(J)		;AND UPDATE THE ADDRESS
	INC	LB.SXR+2(J)		;COUNT THE BYTE
	BNE	DSXDIS			;THAT'S ALL
	MOV	LB.SXR+6(J),LB.SXR+2(J)	;COPY COUNT
	BEQ	DSXABT			;ABORT IF WE OVERRAN LOW LEVEL
	CLR	LB.SXR+6(J)		;MARK THIS STRING INVALID
	MOV	LB.SXR+4(J),LB.SXR(J)	;COPY ADDRESS
	SUB	#40,PS			;ENTER LOW LEVEL
	SAVE	<R0,R1,R2>
	JSR	PC,@LB.XDN(J)		;MORE TO DO?
	MOV	R0,LB.SXR+4(J)		;STORE THE ADDRESS
	ADD	#40,PS			;BACK TO HIGH LEVEL
	MOV	R1,LB.SXR+6(J)		;AND THE DATA COUNT
	BNE	40$
	MOV	#DS.DTR,DS.XST(DQ)	;MAKE IT IDLE
	BIC	#LS..XG,(J)		;NO MORE BUSY
	QUEPUT	QO 39$
40$:	RESTORE	<R2,R1,R0>
DSXDIS:	RESTORE	<DQ,J>
	RTI
.MACRO	X	Q
DSVD'Q:
DSD.'Q:	SAVE	<J>
	MOV	#FLBDS+<LB.SIZ*'Q>,J
.ENDM	X
	Z=DSN-1
.REPT	DSN
	X	\Z
.IIF NE Z, BR	DSXSIN			;NOW TO GENERAL XMT STATUS ROUTINE
	Z=Z-1
.ENDR

;DSXSIN IS CALLED FOR XMIT STATUS INTERRUPTS

DSXSIN:	SAVE	<DQ>
	MOV	LB.SLA(J),DQ		;GET HARDWARE ADR
DSXABT:					;HERE IF DATA OVERRUNS XMIT COROUTINE
.IIF EQ FT.SLB,	INC	LB.SLE(J)	;COUNT ERROR INTERRUPTS
.IIF EQ FT.SLB,	MOV	DS.XST(DQ),LB.SLE+2(J) ;SAVE ERROR STATUS
	MOV	#DS.ZAP+DS.DTR,DS.XST(DQ) ;CLEAR THE LINE
	BIT	#LS..XG!LS.XDT!LS.XCT,@J ;ARE WE ACCOUNTED AS BUSY
	BEQ	DSXDIS			;IF NOT ACTIVE DONE
	QUEPUT	QO 19$			;SOLVE THE RIDDLE
	BIC	#LS.XDT!LS.XCT!LS..XG,@J ;TRANSMITTER IS NO LONGER RUNNING
	BR	DSXDIS			;DISMISS INTERRUPT
;DSRBEG IS CALLED TO START LISTENING TO A LINE

DSRBEG:	BIS	#LS..RG,(J)		;RECEIVER GOING AND STRIPPING
	MOV	LB.SLA(J),DQ		;GET HDW VALUE
	MOV	#SYN,DS.RDR(DQ)		;TELL DS11 WHAT SYNCH IS
	TRACE	DS			;AND TRACE IT
	MOV	LB.IPT(J),R0		;GET INPUT BUFFER
	ADD	J,R0			;ADDRESS
	MOV	R0,LB.SRR(J)		;STORE THE ADDRESS
	MOV	#-4,LB.SRR+2(J)		;ZAP THE COUNT
	ADD	#4,R0			;NEXT SEGMENT
	MOV	R0,LB.SRR+4(J)		;ADDRESS GOES HERE
	MOV	#-4,LB.SRR+6(J)		;THIS IS THE COUNT
	MOV	#DDRJNK,LB.RDN(J)	;HERE FOR A RECEIVE
	MOV	#DS.RGO,DS.RST(DQ)	;LET THE LINE RUN
	BIC	#LS.SSY,(J)		;RESET REQUEST STRIP SYNCH FLAG
	RTS	PC			;AND WAIT
.MACRO	X	Q
DSVA'Q:
DSA.'Q:	SAVE	<J>
	MOV	#FLBDS+<LB.SIZ*'Q>,J
.ENDM	X
	Z=DSN-1
.REPT	DSN
	X	\Z
.IIF NE Z, BR	DSRINT			;NOW TO GENERAL RECEIVE ROUTINE
	Z=Z-1
.ENDR

;DSRINT RECEIVE INTERRUPTS FOR THE DS 11 COME HERE
;WHEN THE LINE IS SKIPPING BLANKS LB.SRR IS ZERO

DSRINT:	SAVE	<DQ>			;SAVE REGISTERS
	MOV	LB.SLA(J),DQ		;GET ADR OF LINE REGISTERS
	MOVB	DS.RDR(DQ),@LB.SRR(J)	;GET DATA BYTE
	INC	LB.SRR(J)		;ADVANCE POINTER
	INC	LB.SRR+2(J)		;COUNT THE BYTE
	BNE	DSRDIS			;AND THAT'S ALL NEARLY
	BIT	#LS.SSY,@J		;WANT TO START STRIPPING SYNC ?
	BEQ	20$
	BIC	#LS.SSY,@J
	MOV	#SYN,DS.RDR(DQ)		;TELL DS WHAT TO LOOK FOR
	MOV	#DS.RGO,DS.RST(DQ)	;RESTART RECEIVER IN SYNC SEARCH
20$:	SAVE	<R0,R1,R2>
	MOV	LB.SRR+6(J),LB.SRR+2(J)	;SECONDARY IS FIRST NOW
	BEQ	50$			;STOP LINE IF WE OVERRUN LOW LEVEL
	CLR	LB.SRR+6(J)		;MARK FRAGMENT AS INVALID
	MOV	LB.SRR+4(J),LB.SRR(J)	;NEXT ONE
	SUB	#40,PS			; IN CASE WE TAKE A VERY LONG TIME
	JSR	PC,@LB.RDN(J)		;RECEIVE WSA DONE
	MOV	R0,LB.SRR+4(J)		;STORE NEXT ADDRESS AND COUNT
	ADD	#40,PS			;LOCKOUT INTERRUPTS AGAIN
	MOV	R1,LB.SRR+6(J)		;IF ANY
	BNE	60$			;TRY TO GET ANOTHER BUFFER

;HERE TO STOP THE RECEIVER
50$:	MOV	#DS.ZAP+DS.DTR,DS.RST(DQ);SILENCE THE LINE
	BIC	#LS..RG,@J		;CLEAR RECEIVER RUNS FLAG
	QUEPUT	QI 49$
	JSR	PC,DDCIGO		;NOW RESTART IT SO WE DON'T LOSE
					;SOMETHING VALUABLE
60$:	RESTORE	<R2,R1,R0>		;RESTORE REGISTERS
DSRDIS:	RESTORE	<DQ,J>
	RTI				;DISMISS INTERRUPT
;HERE FOR A RECEIVER STATUS INTERRUPT
.MACRO	X	Q
DSVB'Q:
DSB.'Q:	SAVE	<J>
	MOV	#FLBDS+<LB.SIZ*'Q>,J
.ENDM	X
	Z=DSN-1
.REPT	DSN
	X	\Z
.IIF NE Z, BR	DSRSIN			;NOW TO GENERAL RECEIVE ROUTINE
	Z=Z-1
.ENDR

DSRSIN:	SAVE	<DQ>
	MOV	LB.SLA(J),DQ		;GET HDW ADR FOR DS11 LINE
	BIT	#170000,@DQ		;WAS THIS A SYNC TYPE INT
	BEQ	DSRDIS
.IIF EQ FT.SLB,	INC	LB.SLE(J)	;COUNT ERROR INTERRUPTS
.IIF EQ FT.SLB,	MOV	@DQ,LB.SLE+2(J)	;SAVE STATUS
	MOV	#DS.ZAP+DS.DTR,@DQ	;IDLE THE RECEIVER
	BIT	#LS..RG,(J)		;BUSY ACCORDING TO THE BOOKS
	BEQ	DSRDIS			;IF NOT GOING IGNORE
	BIC	#LS..RG,(J)		;CLEAR THE FLAG
	QUEPUT	QI 89$			;PUT IT IN Q
	BR	DSRDIS			;DISMISS INTERRUPT

.ENDC;.IF NE FTDS11
.ENDC ; .IF NE DSN