Google
 

Trailing-Edge - PDP-10 Archives - tops10_703_distr_bb-x140b-sb - 10,7/703anf/dndz11.p11
There are 3 other files named dndz11.p11 in the archive. Click here to see a list.
.SBTTL	DNDZ11	--  DZ11 DRIVER  18 DEC 84

;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,1981,1982,1983,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.

VRDZ11=047			;FILE EDIT NUMBER


.IF NE FTDZ11		;ONLY IF WE HAVE A DZ11 (COVERS ALL OF DNDZ11)

;NOTE:	THE DZ11 MODEM-CONTROL AND DDCMP ROUTINES HAVE BEEN MOVED TO THE
;	END OF THE DNDZ11 MODULE.
	.SBTTL		SET DZ LINE SPEED

;CALL	JSR PC,DZSPD
; R0/	POINTER TO DZ11
; R1/    SPEED (UNIVERSAL VERSION)
; R2/	LINE NUMBER

DZSPD:	PIOFF				;DONT BOTHER ME
	MOV	R1,-(P)			;SAVE SPEED
	SWAB	R1			;BELIEVE ONLY TERMINAL TRANSMIT SPEED
	MOVB	R1,(P)			;POSITION FOR RETURN SPEED
	CMP	#B.134,R1		;IS THIS A 2741??
	BEQ	96$			;IF SO, THEN SPECIAL BITS
	BIC	#^C377,R1		;CLEAR EXTRA BITS
	BEQ	95$			;ZERO BAUD == SPECIAL CODE
	MOVB	DZSPDT(R1),R1		;GET DZ VERSION
	BMI	99$			;BAD SPEED, PACK IT IN
	BIS	#DZ.CL8!DZ.2SB!DZ.RON,R2; 2 STOP BITS, 8 DATA BITS
.IF EQ FT2BIT
	CMP	R1,#2			;FASTER THAN 110?
	BLOS	.+6
	BIC	#DZ.2SB,R2		;CLEAR STOP BIT
.ENDC
97$:	BIC	#^C17,R1		;CLEAR EXTRA BITS
	SWAB	R1			;POSITION BITS
	ADD	R2,R1
	MOV	R1,DZ.RBF(R0)		;SET LINE SPEED
98$:	MOV	(P)+,R1			;RETURN ACTUAL SPEED VALUE
	PION				;RESTORE PI LEVEL
	CLC				;CLEAR ERROR FLAG
	RTS	PC


96$:					;HERE IF IT'S A 2741
	BIS	#DZ..OP!DZ.PEN!DZ.CL6!DZ.RON,R2
					; 6 BIT CHARS, AND ENABLE THE RECIEVER
	BIC	#^C377,R1		;CLEAR EXTRA BITS
	MOVB	DZSPDT(R1),R1		;LOAD THE SPEED,
	BR	97$			;AND BACK TO MAIN-LINE CODE


99$:	TST	(P)+			;PITCH BOGUS SPEED VALUE
	PION				;RESTORE PI LEVEL
	SEC				;SET ERROR FLAG
	RTS	PC			;RETURN CARRY SET. I.E. ERROR

95$:	MOV	R2,DZ.RBF(R0)		;SELECT LINE, BUT NO RECIEVE ACTIVE
	BR	98$			;RETURN
DZSPDT:	.BYTE	-1			; 0 BAUD
	.BYTE	0			; 50 BAUD
	.BYTE	1			; 75 BAUD
	.BYTE	2			; 110 BAUD
	.BYTE	3			; 134.5 BAUD
	.BYTE	4			; 150 BAUD
	.BYTE	-1			; 200 BAUD
	.BYTE	5			; 300 BAUD
	.BYTE	6			; 600 BAUD
	.BYTE	7			; 1200 BAUD
	.BYTE	10			; 1800 BAUD
	.BYTE	11			; 2000 BAUD
	.BYTE	12			; 2400 BAUD
	.BYTE	13			; 3600 BAUD
	.BYTE	14			; 4800 BAUD
	.BYTE	15			; 7200 BAUD
	.BYTE	16			; 9600 BAUD
	.BYTE	17			; 19200 BAUD
	.BYTE	-1			;EXT 1.
	.BYTE	-1			;EXT 2.
.SBTTL		DZ-11 BREAK CONTROL CODE

DZBKON:	SAVE	<R0,R3>			;HERE DO SET XMIT-BREAK
	MOV	DB.DHB(J),R3		;GET THE DZ?BLK ADDRESS
	MOVB	DB..LN(J),R0		;GET THE LINE NUMBER.
	ASL	R0			;  TURN IT INTO A WORD INDEX
	BISB	BITS(R0),DZB.BR(R3)	;SET BREAK FOR THE LINE
	BR	DZBKXX			;NOW LET COMMON CODE FINISH THE WORK

DZBKOF:	SAVE	<R0,R3>			;HERE TO CLEAR SMIT-BREAK
	MOV	DB.DHB(J),R3		;GET THE DZ?BLK ADDRESS
	MOVB	DB..LN(J),R0		;GET THE LINE NUMBER,
	ASL	R0			;  AND TURN IT INTO A WORK INDEX
	BICB	BITS(R0),DZB.BR(R3)	;CLEAR THE SOFTWARE BREAK BIT.
DZBKXX:	MOV	@R3,R0			;GET THE REAL DZ HARDWARE ADDRESS
	MOVB	DZB.BR(R3),DZ.TDR+1(R0)	;  AND SET THE BREAK BITS
	RESTORE	<R3,R0>			;RESTORE THE REGS,
	RTS	PC			;AND WE'RE DONE

	.SBTTL		DZ INITILAZTION

DZ.INI:	;R3=	DZnBLK

	SAVE	<R4>
	MOV	(R3),R4			;GET ADDR OF DEVICE
	BIT	#DZ.TIE!DZ.RIE,(R4)	;INTERUPTS ON ?
	BNE	10$
	CLRB	DZ.TCR(R4)		;DISABLE ALL THE LINES
	BIS	#DZ.MSE!DZ.TIE!DZ.RIE,(R4); ARM DZ11
10$:	MOV	4(P),R4			;GET LCB ADDR
	MOV	LC.SPD(R4),R1		;GET THE SPEED
	BIT	#LCB.AB,(R4)		;IS IT AUTOBAUD ?
	BEQ	20$			;NO
	BIC	#LCB.LS,LC.CAR(R4)	;CLEAR LOW SPEED BIT
	MOV	#B.HSPD,R1		;YES, ASSUME AUTO BAUD
20$:
.IF NE TTYDZN
	CMP	6(P),#TTDZIN		;TTY LINE ?
	BNE	25$
	MOV	R1,-(P)			;SAVE SPEED
	JSR	PC,SETSPD
	MOV	(P)+,R1
	BR	30$
25$:
.ENDC
	MOV	(R3),R0			;GET DZ ADDR
	JSR	PC,DZSPD		;SET THE SPEED
30$:	MOV	J,LC.BLK(R4)		;SET DDB ADDR
	MOV	6(P),LC.INS(R4)		;SET INPUT HANDLE
	MOV	10(P),LC.OUS(R4)	;SET OUTPUT HANDLE
	CLR	LC.CNT(R4)		;CLEAR COUNT
	CLR	LC.BUF(R4)		;CLEAR BUFFER
	RESTORE <R4>
	RTS	PC			;ALL DONE
	.SBTTL		DZ11 DATABASE

	DZADDR=0	;ADDRESS OF DZ HARDWARE
	DZB.BN=2	;FIRST LINE # IN GROUP
	DZB.VC=4	;VECTOR ADDR OF DZ
	DZB.BR=6	;BREAK BITS
	DZB.LC=10	;START OF LCB'S
	DZB.SZ=DZB.LC+<LC..SZ*10>; LENGTH OF DZ BLOCK

.MACRO	XX
	.MACRO	XXX	NNN
		.IF NDF DZS'NNN
			.IIF EQ DZL'NNN, DZS'NNN=0
			.IIF EQ DZL'NNN-1, DZS'NNN=B.HSPD ;HIGH AUTO BAUD
			.IIF EQ DZL'NNN-2, DZS'NNN=AL.SPD ; 300 BAUD
			.IIF EQ DZL'NNN-3, DZS'NNN=MP.SPD ; 300 BAUD
			.IIF EQ DZL'NNN-4, DZS'NNN=MP.SPD ; 300 BAUD
			.IIF EQ DZL'NNN-5, DZS'NNN=RP.SPD ; 300 BAUD
			.IIF EQ DZL'NNN-6, DZS'NNN=RA.SPD ; 300 BAUD
			.IIF EQ DZL'NNN-7, DZS'NNN=B.LSPD ;LOW AUTO BAUD
		.ENDC
		.IF NDF DZC'NNN
			.IF EQ DZL'NNN-1
				DZC'NNN=LCB.AB
			.IFF
				DZC'NNN=0
			.ENDC
		.ENDC
		.IF NE <DZS'NNN&377>-<DZS'NNN/400>
			.ERROR 201	;ILLEGAL SPLIT SPEED FOR DZ11
		.ENDC
		.MACRO	LCBLAB	XXX
		LCB'XXX:
		.ENDM
		LCBLAB	\NNN+<NDH11*20>
		.WORD	DZC'NNN		;LC.CAR
		.IIF NDF DZZ'NNN,DZZ'NNN=0
		.BYTE	DZZ'NNN		;LC.STA
		.BYTE	0		;LC.MOD
		.WORD	DZS'NNN		;LC.SPD
		.WORD	DZS'NNN		;LC.PSP
		.WORD	0		;LC.BLK
		.WORD	0		;LC.INS
		.WORD	0		;LC.OUS
		.WORD	0		;LC.CNT
		.WORD	0		;LC.BUF
	.ENDM
	.MACRO	X	A
		.IIF LT DZ.MAX-NDZ11,.ERROR 200; TOO MANY DZ11'S
	DZ'A'BLK:
		0
		<A*10>+<NDH11*20>
		0
		0
		Q=<A*10>
		.REPT	10
			XXX	\Q
			Q=Q+1
		.ENDR
	.ENDM	X
	Z=0
	.REPT	NDZ11
		X	\Z
		Z=Z+1
	.ENDR
.ENDM	XX
	XX
DZBLIM:
	.SBTTL	DZ11 RECEIVE INTERUPT TTY SERVICE

.MACRO	X	A
DZI'A'IN:
	MOV	R0,-(P)
	MOV	#DZ'A'BLK,R0
.ENDM

Z=DZ.MAX-1
	.REPT	DZ.MAX
	X	\Z
.IIF NE Z,BR	DZIINT
	Z=Z-1
	.ENDR


DZIINT:	SAVE	<R1,R2,R3,R4,J>
	MOV	(R0),-(P)		;SET DZ11 HARDWARE ADDRESS FOR LOOP
	ADD	#DZB.LC,R0		;BASE ADDRESS OF LCB'S
	MOV	R0,-(P)			;SET FOR PER-CHAR LOOP

;LOOP FOR EACH CHARACTER STORED IN THE SILO

10$:	MOV	2(P),R3			;GET HARDWARE ADDR BACK
	MOV	DZ.RBF(R3),R1		;GET BOTTOM OF SILO
	BPL	90$			;QUIT WHEN NO MORE CHARACTERS
	MOV	R1,J			;COPY OF BYTE
	SWAB	J			;SWAP HALVES
	BIC	#^C7,J			;LINE NUMBER NOW IN J
	ASL	J			;WORD INDEX
	MOV	LCBIDX(J),J		;GET INDEX
	ADD	(P),J			;RELOCATE TO LCB ADDRESS
	MOV	LC.INS(J),R2		;SERVICE ROUTINE
	BEQ	10$			;NONE = DONE
	MOV	LC.BLK(J),J		;GET DDB
	BEQ	10$			;STILL, NONE= DONE
	JSR	PC,(R2)			;PROCESS CHAR.
	BR	10$			;GET NEXT ONE

90$:	ADD	#4,P			;POP JUNK OFF STACK
	RESTORE	<J,R4,R3,R2,R1,R0>
	RTI				;BACK TO WHERE WE WERE
	.SBTTL	DZ11 TTY OUTPUT INTERUPT SERVICE

.MACRO	X	A
DZO'A'IN:	MOV	R0,-(P)
	MOV	#DZ'A'BLK,R0
.ENDM

Z=DZ.MAX-1
.REPT	DZ.MAX
	X	\Z
.IIF NE Z,BR	DZOINT
	Z=Z-1
.ENDR

DZOINT:	SAVE	<R0,R1,R2,R3,R4,J>
3$:	MOV	@R0,R1			;GET DZ HARDWARE ADDR
	MOV	@R1,J			;GET STATUS WORD
	BMI	10$			;LOOKS OK TO ME
.IF EQ DGUTS
	TRAP
.IFF
	TWIDDLE
.ENDC
10$:	SWAB	J
	BIC	#^C7,J			;GET LINE NUMBER
	ASL	J
	MOV	J,-(P)			;SAVE LINE NUMBER*2 FOR LATER (MAYBE)
	MOV	LCBIDX(J),J		;GET INDEX
	ADD	R0,J			;ADD IN BASE POINTER
	ADD	#DZB.LC,J		;AND LENGTH OF HEADER
	MOV	LC.OUS(J),R3		;SERVICE ROUTINE ?
	BEQ	97$			;NO, STUFF BYTE, DROP ENABLE
	TST	LC.BLK(J)		;DDB?
	BEQ	97$			;NO, ANOTHER LOSER
	TST	LC.CNT(J)		;SEE IF WE HAVE STUFF TO TYPE
	BNE	98$			;YES, OUTPUT IT
	MOV	(P)+,R0			;GET LINE NUMBER * 2
.IF NE NDZMPT!NADZLN!NDZTRB!RDPDZN
	CMP	#DDDZOU,R3
	BEQ	20$
.ENDC
	BICB	BITS(R0),DZ.TCR(R1)	;SAY WE ARE DONE ON LINE
20$:	MOV	LC.BLK(J),J		;SET UP DDB POINTER FOR ROUTINE
	JSR	PC,(R3)			;SERVICE IT
	MOV	12(P),R0		;RESTORE POINTER TO DZ'N'BLK
	MOV	@R0,R1			;AND POINT TO DEVICE AGAIN
96$:	TST	(R1)			;MORE TO DO ?
	BMI	5$			;YES, LOOP FOR MORE
99$:	RESTORE	<J,R4,R3,R2,R1,R0,R0>
	RTI

5$:	MOV	12(P),R0		;GET OLD R0 BACK AGAIN
	BR	3$			;REENTER LOOP

98$:	INC	LC.CNT(J)
	MOVB	@LC.BUF(J),R2		;GET BYTE
	INC	LC.BUF(J)		;BUMP POINTER
	MOV	LC.BLK(J),J		;POINT TO DDB
	MOVB	#-2,DB.TIM(J)		;IRMA FOR A SECOND OR TWO
	JSR	PC,DZBKOF		;MAKE SURE WE AREN'T SENDING BREAKS
	MOVB	R2,DZ.TDR(R1)		;OUT YOU GO TROUBLESOME CHARACTER.
	TST	(P)+			;POP OFF THE LINE NUMBER*2
	BR	96$			;SEE IF MORE IS THERE

97$:	MOV	(P)+,J			;GET LINE *2
	BIC	BITS(J),DZ.TCR(R1)	;CLEAR ENABLE TO SHUT HIM UP
	BR	96$			;RETURN FOR NEXT CHR
	.SBTTL	DZTYPE	TYPE ON THE DZ 11

DZTYPE:	;CALL	R0=CHAR
	; 	JSR	PC,DZTYPE
	MOVB	R0,DB.BUF(J)
	MOV	#-1,R0
	MOV	J,R1
	ADD	#DB.BUF,R1		;POINT TO CHR

DZIMTY:	;HERE TO TYPE STRING WITH
	; 	R1=ADDR OF STRING
	; 	R0=-COUNT



	MOV	DB.DHB(J),R2		;POINT TO HARDWARE BLOCK
	MOV	@R2,R3			;POINT TO HARDWARE ITSELF
	MOV	DB.LCB(J),R2
	MOV	R0,LC.CNT(R2)		;SAVE COUNT
	ASR	R0
	ASR	R0
	DEC	R0
	MOVB	R0,DB.TIM(J)		;SAVE IT AWAY
	MOV	R1,LC.BUF(R2)		;SAVE BUFFER
	JSR	PC,DZBKOF		;MAKE SURE WE AREN'T SENDING BREAKS
	MOVB	DB..LN(J),R0		;LINE NUMBER
	ASL	R0			;MAKE IT AN INDEX
	BIS	BITS(R0),DZ.TCR(R3)	;ENABLE LINE FOR LATER
	RTS	PC
	.SBTTL		DZ11 MODEM CONTROL ROUTINES

;DZ11 MODEM CONTROL CODE

DZSCN:	;HERE EVERY 12 TICKS OF THE CLOCK TO CHECK HOW EACH LINE IS DOING

	MOV	#DZ0BLK,-(P)		;SAVE ADDR OF FIRST BLOCK
DZS.00:	CMP	#DZBLIM,(P)		;ARE WE ALL DONE?
	BHI	10$			;NO DO NEXT DZ
	MOV	(P)+,R0			;CLEAR STACK
	RTS	PC

10$:	MOV	(P),J			;COPY OF DH BLOCK
	ADD	#DZB.SZ,(P)		;UPDATE TO NEXT BLOCK
	MOV	DZADDR(J),R3		;GET ADDRESS OF THE DZ
	BEQ	DZS.00			;IF NO HARDWARE, GO TRY THE NEXT ONE
	ADD	#DZB.LC,J		;POINT J TO FIRST LCB
	CLR	R1
	BR	DZS.11			;JUMP INTO MODEM CODE

DZS.10:	ADD	#LC..SZ,J		;NEXT LCB
	ADD	#2,R1
	CMP	J,(P)			;DONE ALL?
	BHIS	DZS.00			;YES, NEXT DZ
DZS.11:	BIT	#LCB.DS,LC.CAR(J)	;DATA SET LINE?
	BEQ	DZS.13			;IF NOT, THEN SET DTR. (THIS IS
					;NECESSARY TO MAKE 2741'S &CO. HAPPY)
	MOV	DZ.MSR(R3),R0		;GET MODEM BITS
	MOV	LC.BLK(J),R4		;GET DDB ADDR.
	BEQ	DZS.12			;IF NO DDB, RESET LCB
.IF EQ TTYDZN
	BR	DZS.13			;SET DTR
.IFF
	BIT	#DS.TTY,@R4		;IS IT A TTY?
	BEQ	DZS.13			;NO, SET DTR
.ENDC

;AT THE TIME OF DISPATCH THE REGISTERS CONTAIN:
;	R0=MODEM STATUS BITS
;	R1=LINE NUMBER (MUST SAVE)
;	R2=STATE BITS
;	R3=DZ ADDR
;	R4=DDB ADDR
;	J= LCB ADDR

	MOVB	LC.STA(J),R2		;GET STATE
	JMP	@10$(R2)

;DATASET STATE DISPATCH TABLE

10$:	DZSVIR				; (00) VIRGIN
	DZSRNG				; (02) RING
	DZSCDT				; (04) CARRIER
	DZSCDS				; (06) CARRIER DETECT SATISFIED
	DZSABD				; (08) AUTOBAUD
	DZSOKU				; (10) RUNNING BUT NOT CONNECTED TO -10
	DZSOKW				; (12) RUNNING, WAITING ON -10 CONNECT
	DZSOKC				; (14) RUNNING AND CONNECTED TO -10
	DZSLOC				; (16) LOST CARRIER
	DZS.15				; (18) SOMEONE WANTS US TO HANG UP
	DZSHNG				; (20) HANG UP
.IF NE FTDN11
	DZSDIA				; (22) DIALING
	DZSDSU				; (24) DIALOUT SUCCEEDED
	DZSDFA				; (26) DIALOUT FAILED
.ENDC ;FTDN11

.IIF NE .-10$-2-LCS.MX,.ERROR <.-10$-2> ;DISPATCH STATE PHASE ERROR IN DNDZ11
	.SBTTL		DZ11 MODEM ROUTINES OF SOME USE

DZS.12:	MOVB	#LCS.VG,LC.STA(J)	;RESET LCB
	BIC	#LCB.TM,LC.CAR(J)	;CLEAR TIMER
	BICB	BITS(R1),DZ.TCR+1(R3)	;DROP DTR
	TST	R4			;IS THERE A DDB?
	BEQ	DZS.10			;NO, TO THE NEXT LINE
	BR	DZS.16			;CLEAR DDB BITS

DZS.13:	BISB	BITS(R1),DZ.TCR+1(R3)	;SET DTR
	BR	DZS.10			;NEXT LINE

DZS.15:
.IF NE FTDN11
	BITB	#DNDIAL,DB.DNS(R4)	;CONTROLLED BY DN11/801?
	BEQ	30$			;NO

;SINCE THE DATASET LINE IS BEING CONTROLLED BY A DN11/801 (I.E.,
;SOMEONE DIALED OUT ON THE LINE RATHER THAN CALLING IN ON IT) WE
;MUST CLEAR THE DN11/801 TO RELEASE CONTROL OF THE PHONE LINE.

	SAVE	<J,R1>			;YES, SAVE SOME ACS
	MOV	R4,J			;SETUP J WITH DDB ADDRESS
	JSR	PC,DNCLR		;ZAP THE DN11/801
	RESTOR	<R1,J>			;GET BACK OUR ACS
.ENDC ;FTDN11
30$:	BICB	BITS(R1),DZ.TCR+1(R3)	;CLEAR DTR FOR LINE
	MOVB	#LCS.HG,LC.STA(J)	;SET STATE TO HANG UP
	BIC	#LCB.TM,LC.CAR(J)	;FIRST CLEAR OUT THE TIMER,
	BIS	#MDMHDT*6,LC.CAR(J)	;NOW SET THE MODEM HOLD DOWN TIME.
	;BR	DZS.16

DZS.16:	MOV	DB.DCS(R4),R2		;GET DDB CHARACTERISTICS
	BIC	#TS.DTR!TS.CAR,R2	;CLEAR DDB
	;BR	DZS.14

DZS.14:	;CHECK IF STATUS IS SAME AS LAST TIME
	CMP	R2,DB.DCS(R4)		;CHANGED??
	BEQ	DZS.10			;NO, NEXT LINE
	MOV	R2,DB.DCS(R4)		;SET NEW STATE
	SAVE	<J,R1>
	MOV	R4,J
	JSR	PC,QUEXDS		;QUE THE DDB
	RESTORE <R1,J>
	BR	DZS.10			;NEXT LINE, PLEASE

DZS.17:	BISB	BITS(R1),DZ.TCR+1(R3)	;SET DTR
	MOVB	#LCS.RU,LC.STA(J)	;ASSUME THAT WE ARE UNCONNECTED
	BIC	#LCB.TM,LC.CAR(J)	;CLEAR TIMER
DZS.18:	MOV	DB.DCS(R4),R2		;GET DDB STATUS
	BIS	#TS.DTR!TS.CAR,R2
	BR	DZS.14
	.SBTTL		DZ11	MODEM STATE CONTROL

;(00) VIRGIN STATE, WAIT FOR RING

DZSVIR:	MOV	DB.DCS(R4),R2		;COPY OF DDB STATUS
	CLR	R0
	BIT	DZ.MSR(R3),BITS2(R1)	;CARRIER OR RING ?
	BEQ	DZS.16			;NO, CLEAR BITS IN DDB
	BIS	#TS.RNG,R2
	BIC	#TS.DTR,R2		;RING BUT NO DTR
	MOVB	#LCS.RG,LC.STA(J)	;SET TO RINGING
	BR	DZS.14			;TELL -10, DO NEXT LINE

;(02) DATASET PHONE IS RINGING

DZSRNG:	BISB	BITS(R1),DZ.TCR+1(R3)	;SET DTR
	MOVB	#LCS.CD,LC.STA(J)	;SET CARRIER DETECT STATE
	BIS	#30.*6,LC.CAR(J)	;SET TIMER TO RUN FOR 30 SEC
	BR	DZSJ11			;AND CHECK THE LINE AGAIN.

;(04) WE HAVE ANSWERED THE PHONE, NOW WAIT FOR CARRIER TO APPEAR

DZSCDT:	BITB	DZ.MSR+1(R3),BITS(R1)	;DID WE GET CARRIER
	BEQ	10$			;BRANCH IF NOT.
	CLR	DB.STR(R4)		;CLEAR THE STRING POINTER
	CLRB	DB.HLD(R4)		;SO THAT WHEN A PERSON
	CLRB	DB.ASP(R4)		;DIALS IN AGAIN WE DON'T
					;OUTPUT A BOGUS DISCONNECT MESSAGE
	BIT	#LCB.AB,LC.CAR(J)	;IS THIS AN AUTO-BAUD LINE?
	BEQ	30$			;IF NOT THEN LEAVE SPEED ALONE
.IF NE FTDN11
	BITB	#DNDIAL,DB.DNS(R4)	;AUTOBAUD DATASET - BUT IF DIALING OUT
	BNE	20$			;THEN ASSUME USER SPEED'S CORRECT
.ENDC ;FTDN11
	BIC	#LCB.LS,LC.CAR(J)	;CLEAR LOW SPEED BIT
	SAVE	<R1,R3,J,#B.HSPD>	;SAVE LCB POINTER, PUSH SPEED.
15$:	MOV	LC.BLK(J),J		;GET POINTER TO DDB FOR SETSPD.
	JSR	PC,SETSPD		;SET SPEED TO 2400 FOR AUTO-BAUD
	RESTORE	<J,J,R3,R1>		;GET POINTER TO LCB BACK.
20$:	MOVB	#LCS.CS,LC.STA(J)	;NOW GO TO WAIT STATE
	BIC	#LCB.TM,LC.CAR(J)	;AND SET THE TIMER TO RUN FOR
	BIS	#1.*6,LC.CAR(J)		;ANOTHER SECOND
	BR	DZSJ11			;LOOK AT THE LINE AGAIN!

;HERE TO SET SPEED IF DATA SET BUT NOT AUTOBAUD

30$:	SAVE	<R1,R3,J,LC.PSP(J)>	;SAVE POINTERS, PUSH SPEED
	BR	15$			;SET THE SPEED IN COMMON CODE

;HERE TO CHECK FOR TIME OUT DURING CARRIER DETECT

10$:	BIT	#LCB.TM,LC.CAR(J)	;HAS THE TIMER RUN OUT?
	BEQ	DZSJ15			;YES, HANG UP THE PHONE
	DEC	LC.CAR(J)		;OTHER WISE COUNT DOWN TIMER
	BR	DZSJ10			;AND DO THE NEXT LINE
;(06) CARRIER DETECTED, WAIT A MOMENT FOR THINGS TO SETTLE DOWN. THIS IS
; SO WE IGNORE THE RANDOM GARBAGE ON THE LINE CAUSED BY INSERTING THE
; PHONE IN THE ACOUSTIC COUPLER.

DZSCDS:	BIT	#LCB.TM,LC.CAR(J)	;HAS THE TIMER RUN OUT.
	BEQ	10$			;IF SO, CHECK FOR CARRIER STILL UP.
	DEC	LC.CAR(J)		;OTHERWISE COUNT OFF THIS TICK
	BR	DZSJ10			;AND GO DO THE NEXT LINE

10$:	BITB	DZ.MSR+1(R3),BITS(R1)	;IS CARRIER STILL UP?
	BEQ	20$			;IF NOT, TAKE REMEDIAL ACTION
	BIT	#LCB.AB,LC.CAR(J)	;IF THIS IS NOT AN AUTO-BAUD LINE -
	BEQ	DZS.17			;THEN BRING IT ON LINE NOW.
	MOVB	#LCS.AB,LC.STA(J)	;IF IT IS, GO TO AUTO-BAUD STATE,
	BIS	#30.*6,LC.CAR(J)	;AND SET A 30 SEC TIMER.
	BR	DZS.18			;GO MARK TERMINAL UP (SET DTR)

20$:	MOVB	#LCS.CD,LC.STA(J)	;GO BACK TO THE CARRIER DETECT STATE,
	BIS	#28.*6,LC.CAR(J)	;AND RE-SET THE TIMER.
	BR	DZSJ10			;NOW DO NEXT LINE

;(08) WAITING FOR USER TO AUTOBAUD (TYPE <CR>)

DZSABD:
.IF NE FTDN11
	BITB	#DNDIAL,DB.DNS(R4)	;DIALING OUT?
	BNE	DZSJ17			;YES, ALL SET
.ENDC ;FTDN11
	BITB	DZ.MSR+1(R3),BITS(R1)	;IS CARRIER STILL UP?
	BEQ	DZSJ15			;NO, HANG UP ON THIS LINE
	BIT	#LCB.TM,LC.CAR(J)	;OTHERWISE SEE IF HE HAS TIMED OUT.
	BEQ	DZSJ15			;IF HE HAS THEN HANG HIM UP,
	DEC	LC.CAR(J)		;OTHERWISE DECREMENT TIMER, AND
	BR	DZSJ10			;GO DO THE NEXT LINE


;CONVENIENT JUMPS

DZSJ10:	JMP	DZS.10			;CHECK NEXT DATASET LINE
DZSJ11:	JMP	DZS.11			;RECHECK CURRENT DATASET LINE
DZSJ12:	JMP	DZS.12			;RESET THE LINE
DZSJ14:	JMP	DZS.14			;SEND STATUS TO -10 IF CHANGED
DZSJ15:	JMP	DZS.15			;HANG UP THE PHONE
DZSJ17:	JMP	DZS.17			;SET TERMINAL TO RUNNING STATE
;(10) WE ARE RUNNING BUT NOT CONNECTED

DZSOKU:	TST	@R4			;ARE WE STILL UNCONNECTED
	BGE	DZSAOK			;IF SO, JUST CHECK CARRIER
	BIC	#LCB.TM,LC.CAR(J)	;OTHERWISE CLEAR/SET THE
	BIS	#3*6.,LC.CAR(J)		;TIMER TO RUN FOR 3 SEC AND
	MOVB	#LCS.RW,LC.STA(J)	;ENTER CONNECT WAIT STATE
	BR	DZSAOK			; (ALSO MAKE SURE CARRIER IS THERE)

;(12) IN THIS STATE WE ARE WAITING FOR A CONNECT TO THE -10 TO SETTLE
; DOWN. THE REASON THIS STATE IS NECESSARY IS THAT THE -10 SENDS A LOT
; OF STATUS MESSAGES THAT IT DOESN'T REALLY MEAN DURING THE INITIAL STARTUP.
; IF ONE OF THESE STATUS MESSAGES HAPPENS TO CLEAR DTR THE PHONE WILL
; HANG UP... (SIGH)

DZSOKW:	BIT	#LCB.TM,LC.CAR(J)	;HAS THE TIMER RUN OUT
	BEQ	10$			;IF SO, GO INTO THE 'BELIEVE -10' STATE
	DEC	LC.CAR(J)		;OTHERWISE COUNT OFF ONE MORE JIFFY
	BR	DZSAOK			;AND CHECK CARRIER

10$:	MOVB	#LCS.RC,LC.STA(J)	;GO IN TO RUNNING CONNECTED STATE
	BR	DZSAOK			;AND CHECK CARRIER

;(14) WE ARE UP AND RUNNING, CONNECTED TO A -10

DZSOKC:	TST	@R4			;ARE WE STILL CONNECTED?
	BLT	DZSAOK			;YES, CHECK CARRIER
	MOVB	#LCS.RU,LC.STA(J)	;NO, CHANGE STATE
;	BR	DZSAOK			;AND CHECK CARRIER

;MAKE SURE CARRIER IS STILL PRESENT

DZSAOK:	BITB	DZ.MSR+1(R3),BITS(R1)	;IS CARRIER THERE ?
	BNE	DZSJ10			;YES, LINE IS OK, CHECK NEXT ONE
	MOVB	#LCS.LC,LC.STA(J)	;CARRIER LOST STATE
	BIC	#LCB.TM,LC.CAR(J)	;CLEAR AND
	BIS	#5*6,LC.CAR(J)		;SET THE 5 SEC TIMER
	BR	DZSJ10			;AND GO DO THE NEXT LINE
;(16) WE HAVE LOST CARRIER, GIVE IT A FEW SECONDS TO REAPPEAR BEFORE
; HANGING UP IN CASE IT IS JUST A MOMENTARY LINE OUTAGE.

DZSLOC:	BISB	BITS(R1),DZ.TCR+1(R3)	;SET DTR AGAIN
	BITB	BITS(R1),DZ.MSR+0(R3)	;GOT A NEW CALL TRYING TO GET IN?
	BNE	DZSJ15			;YES, THEN HANG UP THE OLD ONE FIRST
					; (SO THE -10 DETACHES OLD JOB, ETC.)
	BITB	BITS(R1),DZ.MSR+1(R3)	;AND CHECK FOR CARRIER
	BNE	DZSJ17			;IF SO, TELL THE -10
	BIT	#LCB.TM,LC.CAR(J)	;HAVE WE TIMED OUT YET?
	BEQ	DZSJ15			;IF SO, THEN HANG IT UP
	DEC	LC.CAR(J)		;OTHERWISE COUNT OFF THE TIME
	BR	DZSJ10			;AND GO DO THE NEXT LINE

;(20) THE LINE IS HUNG UP. WAIT FOR PHONE TO SETTLE DOWN BEFORE RE-ENABLING
; IT FOR ANOTHER INCOMING CALL.

DZSHNG:	BIT	#LCB.TM,LC.CAR(J)	;TIMED OUT?
	BEQ	DZSJ12			;IF SO, THEN RESET LINE
	DEC	LC.CAR(J)		;OTHERWISE COUNT TIME
	BR	DZSJ10			;AND DO THE NEXT LINE

.IF NE FTDN11
;(22) THIS LINE HAS INITIATED A DIALOUT REQUEST. WAIT FOR SUCCESS/FAILURE

DZSDIA:	BISB	BITS(R1),DZ.TCR+1(R3)	;SET DTR
	BR	DZSJ10			;AND CHECK THE NEXT LINE

;(24)	THE DIALOUT SUCCEEDED, TELL THE -10

DZSDSU:	BIT	#DS.XDS,@R4		;ROOM FOR NEW DEVICE CONTROL STATUS?
	BNE	DZSDIA			;NO, WAIT LONGER THEN
	JMP	DZSRNG			;YES, WAIT FOR CARRIER CONFIRM

;(26) THE DIALOUT FAILED, TELL THE -10

DZSDFA:	BIT	#DS.XDS,@R4		;ROOM FOR NEW STATUS YET?
	BNE	DZSDIA			;NO, WAIT LONGER THEN
	BR	DZSJ15			;YES, GO HANG UP THE PHONE
.ENDC ;FTDN11
	.SBTTL		DZ11	DDCMP ROUTINES

Z=NDZMPT!NADZLN!NDZTRB!RDPDZN	;DDCMP DZ LINES
.IF NE Z

DZDINI:					;INITIALIZE THE DZ LINE
	MOVB	LB..LN(J),R2		;GET LINE NUMBER
.IIF NE FT.RDM!FT.RDP,MOV J,-(P)	;SAVE LINE BLK ADDR
	MOV	#DDDZOU,-(P)		;OUTPUT INTERUPT ADDR
	MOV	#DDDZIN,-(P)		;INPUT ADDR
	MOV	LB.LCB(J),-(P)		;LCB ADDR
.IF NE FT.RDM
	BIT	#LS.MPT,(J)		;IF MULTIDROP
	BEQ	11$
	TST	LB.MPL(J)		;AND NOT A TRIB
	BEQ	11$
	CLR	J			;FORGET J 'CAUSE ITS OFFLINE
11$:
.ENDC ;.IF NE FT.RDM
	JSR	PC,DZ.INI		;SET UP LINE CONTROL BLOCK
	ADD	#6,P			;POP ARGS TO DZ.INI
.IIF NE FT.RDM!FT.RDP,MOV (P)+,J	;RESTORE J
	RTS	PC			;AND RETURN


DZRBEG:					;ENABLE RECIEVER
	BIS	#LS..RG,(J)		;RECIEVER RUNNING
	MOV	LB.IPT(J),-(P)		;STASH BUFFER ADDR
	ADD	J,(P)
	MOV	(P),LB.SRR(J)		;SET RECIEVER BUFFER
	MOV	#-1,LB.SRR+2(J)		;AND LENGTH
	INC	(P)			;ALSO FOR NEXT BUFFER
	MOV	(P)+,LB.SRR+4(J)
	MOV	#-1,LB.SRR+6(J)
	MOV	#DZRSYN,LB.RDN(J)	;WHERE TO GO WHEN SEGMENT IS DONE
	RTS	PC			;EXIT
DZRSYN:					;EAT ALL TILL DDCMP HEADER
	MOV	LB.SRR(J),R0		;GET ADDR OF NEXT CHAR
	CMPB	#ENQ,R1
	BEQ	9$
	CMPB	#SOH,R1
	BEQ	9$
	CMP	#DLE,R1
	BNE	11$
9$:
.IF NE FT.MPT
	BITB	#MP.OFF,LB.MPS(J)	;MULTIPOINT OFFLINE ?
	BEQ	10$			;HEADACHE
	TST	LB.MPL(J)		;IF NOT A TRIBUTARY
	BNE	11$
	BIS	#LS..RG,(J)		;RECIEVE GOING
	JSR	PC,SELNXT		;STATION ON LINE
	CLRB	LB.MPT(J)		;CLEAR TIMER TO ONLY PRETEND ONLINE
	BICB	#MP.SEL,LB.MPS(J)	;NOT SELECTED
.ENDC
10$:	ADD	#3,R0
	SUB	#2,LB.SRR+2(J)		;FIX COUNT FOR HEADER
	MOV	#-4,R1			;SET COUNT FOR SECOND HALF
	MOV	#DDRJNK,LB.RDN(J)	;EAT UP THE JUNK
	RTS	PC

11$:	DEC	LB.SRR(J)		;COUNT BYTE IN
	MOV	#-1,R1			;NEW COUNT
	RTS	PC			;OK, READ IT IN
	.SBTTL		DZ11 START TRANSMITTER FOR DZ11 DDCMP

;STILL .IF NE Z=NADZLN!NDZTRB!NDZMPT!RDPDZN

DZXBEG:				;START TRANSMITTER
.IF NE FTTRIB
	BIT	#LS.MPT,(J)		;MULTIPOINT ?
	BNE	DZXBG2			;YES, BAH HUMBUG
.ENDC
DZXBG0:	JSR	PC,@LB.XDN(J)		;GET BUFFER OF DATA
	MOV	R0,LB.SXR(J)
	MOV	R1,LB.SXR+2(J)
	BNE	DZXBG3
	BIC	#LS..XG!LS.XDT!LS.XCT,(J); STOP THE LINE, ALL DONE
	RTS	PC

DZXBG1:	MOV	LB.SXR+4(J),LB.SXR(J)	;SWAP BUFFERS
	MOV	LB.SXR+6(J),LB.SXR+2(J)
	BNE	DZXBG3			;MORE DATA ??
	BR	DZXBG0			;NO

.IF NE FTTRIB
DZXBG2:	BITB	#MP.CMS,LB.MPS+1(J)	;MODEM ALTER ENABLED ?
	BEQ	DZXBG0			;NO
	BITB	#MP.RTS,LB.MPS+1(J)
	BEQ	DZXBG0
	JSR	R0,DZSTAT		;SET NEW STATUS
	.BYTE	0,MP.RTS
	BICB	#MP.RTS,LB.MPS+1(J)	;ITS NOW THERE
	MOV	#DZFILL,LB.SXR(J)	;SEND SYNCS
	MOV	#-FTASYN,LB.SXR+2(J)
.ENDC
DZXBG3:	JSR	PC,@LB.XDN(J)		;FILL SECOND BUFFER
	MOV	R0,LB.SXR+4(J)
	MOV	R1,LB.SXR+6(J)
	BIS	#LS..XG,(J)		;START XMITTING ON LINE
DZSXMT:	PIOFF
	MOV	LB.DHB(J),R3		;ADDR OF DZ11 BLOCK
	MOV	(R3),R3			;ADDR OF DZ11
	MOV	LB..LN(J),R1		;GET LINE NUMBER
	ASL	R1			;MAKE IT AN INDEX
	BIS	BITS(R1),DZ.TCR(R3)	;ENABLE LINE, GET INTERUPT LATER
	PION
	RTS	PC

	.SBTTL		DZ11 DDCMP INTERUPT SERVICE

DDDZIN:
DDZINS:					;INPUT INTERUPT SERVICE
	BIT	#LS..RG,(J)		;BITS COMMING IN ?
	BEQ	80$			;I DONT THINK SO...
	MOVB	R1,@LB.SRR(J)		;STASH CHAR IN BUFFER
	INC	LB.SRR(J)		;BUMP BUFFER POINTER
	INC	LB.SRR+2(J)		;AND COUNT
	BNE	80$			;BRANCH IF NOT DONE WITH STRING.
	MOV	LB.SRR+4(J),LB.SRR(J)	;SWAP BUFFERS AGAIN
	MOV	LB.SRR+6(J),LB.SRR+2(J)	;AND SWAP COUNT
	BIC	#LS.SSY,(J)		;NO SYNC STRIP FOR DZ
	JSR	PC,@LB.RDN(J)		;DONE, TELL DDCMP
	MOV	R0,LB.SRR+4(J)		;NEW SECOND BUFFER
	MOV	R1,LB.SRR+6(J)		;AND COUNT
	TST	LB.SRR+2(J)		;STUFF HERE TO GET ?
	BNE	80$			;YES, KEEP GOING
	BIC	#LS..RG,(J)		;STOP GETTING STUFF
	QUEPUT	QI,79$			;QUEUE FOR SERVICE
80$:	RTS	PC			;BACK TO INTERUPT ROUTINE

DDDZOU:
DDZOUS:					;OUTPUT INTERUPT SERVICE
	TST	LB.SXR+2(J)		;MORE TO THIS BUFFER ?
	BNE	88$			;YES, TYPE IT
	JSR	PC,DZXBG1		;NO, SWAP BUFFERS AND START IO
	TST	LB.SXR+2(J)		;THAT DONE , TOO
	BNE	99$			;NO, ITS RUNNING
.IF NE FT.MPT
	BIT	#LS.MPT,(J)		;MULTIPOINT ?
	BEQ	95$			;NO
	BITB	#MP.SEL,LB.MPS(J)	;SELECTED ??
	BNE	95$			;NO, NOT THAT EITHER
.IF NE FTTRIB
	TST	LB.MPL(J)		;TRIBUTARY
	BNE	90$			;YES, PUNT
	BIS	#LS..XG,(J)		;SAY WE ARE TRANSMITTING
	MOV	#DZFILL,LB.SXR(J)
	MOV	#-FTASYN,LB.SXR+2(J)	;STOP IT NICE, NOW
	MOV	LB.LCB(J),R3		;POINT TO LCB
	MOV	#DDZSTP,LC.OUS(R3)	;SO WE CAN STOP OUTPUT
	MOV	#DZSXMT,-(P)		;
.ENDC
90$:	JSR	PC,DESLCT		;DESELECT THE LINE
.ENDC
95$:	MOV	LB.DHB(J),R3		;ADDR OF DZBLK
	MOV	(R3),R3			;ADDR OF DZ
	MOV	LB..LN(J),R1		;MASK BIT
	ASL	R1			;MAKE INTO INDEX
	BIC	BITS(R1),DZ.TCR(R3)	;TURN OFF LINE ENABLE
	QUEPUT	QO,89$
99$:	RTS	PC

88$:	;HERE TO TYPE NEXT CHR FOR DZ LINE
	MOV	LB.DHB(J),R3		;POINT TO BLOCK
	MOV	(R3),R3			;POINT TO DZ11
	MOVB	@LB.SXR(J),DZ.TDR(R3)	;OUT YOU GO
	INC	LB.SXR(J)
	INC	LB.SXR+2(J)		;BUMP COUNT
	RTS	PC			;RETURN, TO DO MORE LATER
	.SBTTL		DZ11 DDCMP STOP TRANSMITTER

;STILL .IF NE Z=NADZLN!NDZTRB!NDZMPT!RDPDZN
.IF NE FTTRIB

DDZSTP:	JSR	R0,DZSTAT		;SET LINE MODEM  STATUS
	.BYTE	MP.STS,0
	BISB	#MP.RTS,LB.MPS+1(J)	;RTS IS DISABLED
	MOV	LB.LCB(J),R3
	MOV	#DDZOUS,LC.OUS(R3)	;VECTOR TO OUTPUT SERVICE
	BIC	#LS..XG,(J)		;SAY WE STOPED
	CLR	LB.SXR+2(J)		;CLEAR COUNT
	RTS

DZFILL:	.REPT	FTASYN
		.BYTE	-1
	.ENDR
	.EVEN

DZSTAT:					;SET MODEM STATUS
	MOV	LB.DHB(J),R3
	MOV	(R3),R3			;POINT TO DZ11
	BIT	#LS.MPT,(J)		;MULTIPOINT
	BEQ	30$			;NO, LEAVE IT ALONE
	BITB	#MP.CMS,LB.MPS+1(J)	;CHANGE OK TO DO?
	BEQ	30$			;NO, QUICK EXIT
	MOV	LB..LN(J),R1		;GET LINE NUMBER
	ASL	R1
	TSTB	(R0)+			;SEE IF WE ARE TO SET DTR
	BEQ	10$			;NO, OK
	BIC	BITS2(R1),DZ.TCR(R3)	;CLEAR DTR AND ENABLE
10$:	TSTB	(R0)+
	BEQ	12$			;NO BITS TO SET HERE
	BISB	BITS(R1),DZ.TCR+1(R3)
12$:	RTS	R0
30$:	TST	(R0)+
	RTS	R0
.ENDC	; .IF NE FTTRIB
.ENDC	; .IF NE Z=NADZLN!NDZTRB!NDZMPT!RDPDZN

.ENDC	; .IF NE FTDZ11 (FROM BEGINNING OF DNDZ11)