Google
 

Trailing-Edge - PDP-10 Archives - tops10_703_distr_bb-x140b-sb - 10,7/703anf/dnrde.p11
There are 3 other files named dnrde.p11 in the archive. Click here to see a list.
.SBTTL	RDE PSEUDO DEVCE ROUTINES  11 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,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD MASS.

VRRDE=004			;FILE EDIT NUMBER

.IF NE FT.RDM!FT.RDP		;POINT-TO-POINT AND MULTI-POINT SERVICE
;OFFSETS FOR THE DEVICE DEPENDENT PORTION OF DEVICE BLOCK
.IF NE FT.RDM			;MULTI-POINT SERVICE
	DB.SSC=DB.SIZ		;STATION STATUS RECORD
	ZZL=DB.SIZ+M$MAX+M$MAX
.IF EQ FTSLCT-3
	DB.POL=ZZL		;STORAGE FOR THE POLLING LIST IF USED
	ZZL=ZZL+POLLSZ
	DB..PX=ZZL		;POLLING INDEX
	DB.PLE=ZZL		;END OF THE POLLING LIST
	ZZL=ZZL+2
.ENDC
	DB.PLE=ZZL		;END OF THE POLLING LIST
	DB.DSM=ZZL		;LINK TO THE DDCMP STATUS MSG
	ZZL=ZZL+2		;UNDER CONSTRUCTION
	DB.RSZ=ZZL		;SIZE OF RDE DDB
.ENDC ;.IF NE FT.RDM



;DEVICE DEPENDENT PORTION OF DEVICE BLOCK
.MACRO	DDXGEN	DEV,DV,DRQ,XBITS,XZZ
;				;DB.SSC
.IF NE FT.RDM
	.REPT	M$MAX
		.WORD	0
	.ENDR
	.IF EQ	FTSLCT-3
;					;DB.POL
	.REPT	POLLSZ
		.BYTE	0
	.ENDR
	.WORD	.-POLLSZ		;DB..PX  (DB.PLE)
	.ENDC
	.WORD	0			;DB.DSM
.ENDC ;.IF NE FT.RDM
.ENDM	DDXGEN
;FIRST BUILD THE SIMPLE POINT-TO-POINT "RDP" DDBS

DRESET=0			;START FRESH WITH RDP LINES
ASYDEV=ASY.DH			;DO DH11 LINES FIRST
NXTDH=-1			;START WITH FIRST ONE

	DDBGEN	RDP,P,RDPDHN,RDEDRQ,<DS.OUT>

DRESET=1			;CONTINUE WHERE LEFT OFF WITH "P" DDBS
ASYDEV=ASY.DZ			;DO DZ11 LINES NEXT
NXTDZ=-1			;START WITH FIRST ONE

	DDBGEN	RDP,P,RDPDZN,RDEDRQ,<DS.OUT>


;NOW BUILD THE MULTI-POINT "RDM" DDBS

DRESET=0			;START FRESH WITH RDM LINES
ASYDEV=ASY.DH			;DO DH11 LINES FIRST
NXTDH=-1			;START WITH FIRST ONE

	DDBGEN	RDM,R,NDHMPT,RDEDRQ,<DS.OUT>

DRESET=1			;CONTINUE WHERE LEFT OFF WITH "R" DDBS
ASYDEV=ASY.DZ			;DO DZ11 LINES NEXT
NXTDZ=-1			;START WITH FIRST ONE

	DDBGEN	RDM,R,NDZMPT,RDEDRQ,<DS.OUT>



;UNDEFINE DDXGEN
.MACRO	DDXGEN	DEV,DV,DRQ,XBITS,XZZ
.ENDM	DDXGEN
;HERE ON TIME OUT

RDMTIM:
RDPTIM:	RTS	PC



RDEMAP:			;MAPPING FROM DH LINE # TO RDE DEV
Z=0
ZZ=0
.MACRO X Q,QQ
	.IF EQ DHL'Q-3
		.WORD	R'QQ'DDB
		ZZ=ZZ+1
	.IFF
		.WORD	0
	.ENDC
.ENDM
.REPT	NDH11*20
	X	\Z,\ZZ
	Z=Z+1
.ENDR


;HERE TO SET J TO RDE DDB 

RDEGTB:	MOVB	LB.LNU(J),J	;GET THE LINE #
	BIC	#^C377,J
	CMP	#NDH11*20,J	;IF NOT IN RANGE
	BHI	5$
	CLR	J		;ERROR HERE
	RTS	PC
5$:	ASL	J
	MOV	RDEMAP(J),J	;GET THE DDB
	RTS	PC
;HERE WHEN DDCMP XMITTED A MESSAGE

RDEODN:	SAVE	<J>		;SAVE THE LINE BLOCK ADDRESS
	JSR	PC,RDEGTB	;LOCATE THE RDE DEVICE
	BEQ	RDODN3		;IF THERE IS ONE,
	JSR	PC,RDODN2	;SEND DATA REQUESTS
RDODN3:	JSR	PC,FRECKS	;AND THROW THE MESSAGE AWAY
	RESTORE	<J>		;RESTORE LINE BLOCK/DDB ADR
	RTS	PC



;HERE TO SEND DATA REQUESTS

RDODN2:	SAVE	<R4,R3,R2,R1,R0>	;SAVE REGS
	JSR	PC,DVXDRQ	;SEND DATA REQUESTS TO HOST AS REQUIRED
	RESTORE	<R0,R1,R2,R3,R4>	;RESTORE REGS
	RTS	PC
;HERE TO SERVICE PSEUDO DEV RDE

RDMSER:
RDPSER:	CMP	#RDEMML,DB.MML(J)	;IF MSG SIZE TO LARGE
	BHIS	10$
	MOV	#RDEMML,DB.MML(J)	;USE DEFAULT SIZE
10$:	MOVB	#B0,DB.DCM(J)		;IMAGE MODE
RDES.1:	JSR	PC,DVCCFM		;CONNECT CONFIRM IF REQUIRED
	BIT	#DS.CON,(J)		;IF NOT CONNECTED
	BNE	20$
	RTS	PC			;EXIT

.IIF NDF RDXDCS,RDXDCS=.-2		;IF HOST IGNORES, DEVICE STATUS
					; USE NULL PROC FOR DEVICE STATUS XMISSION
					;OTHERWISE, SET RDXDCS=DVXDCS
20$:	MOVB	#-5,DB.TIM(J)		;AS LONG AS THINGS ARE FLYING
					;DON'T LET THE TIMER RUN OUT
	JSR	PC,RDXDCS		;SEND CONTROL STATUS TO 10 IF NECESARY
	JSR	PC,RDTODD		;IF OUTPUT FROM 10,PASS IT ON
	TSTB	DB.IDR(J)		;HAS 10 ASKED FOR DATA
	BEQ	35$
30$:	MOV	DB.IBF(J),R0		;YES,SO GET THE BUFFER
	BEQ	35$
	SAVE	<J,R0>
	CLR	-(P)			;SAFE STORAGE FOR MSG ADR
	JSR	PC,RDEBMS		;START THE MSG
	  BR	RDES.2			;CAN'T START IT
	MOV	2(P),R0			;GET THE MESSAGE LENGTH
	MOV	CN.LEN(R0),-(P)
	MOV	CN.MLK(R0),DB.IBF(J)	;UNLINK IT
	TSTB	CN.NCT-1(R0)		;MOVE MSB OF STATION ADR TO CARRY BIT
	BPL	.+4
	SEC
	MOV	(P),R0
	ADC	R0
	INC	R0			;COUNT IN STATION ADR (EXTENSIBLE FIELD)
	INC	R0			;COUNT THE TYPE FIELD
	JSR	PC,PUTEXN		;AND PUT IT IN THE MSG
	MOV	#2,R0			;PUT MSG TYPE (DATA EOR) IN MSG
	JSR	PC,PUTBYT
	MOV	4(P),R0			;GET THE STATION'S ADR
	MOVB	CN.NCT-1(R0),R0
	BIC	#^C377,R0		;MUST SUPPRESS SIGN EXTENSION
	JSR	PC,PUTEXN		;AND INSERT IT IN THE MESSAGE
	ADD	(P),R2			;GET FINAL MSG LENGTH
	MOV	2(P),R0			;GET STARTING CHUNK
	MOV	4(P),(R0)		;APPEND THE ORIGINAL MSG
	MOV	R2,CN.LEN(R0)		;AND SET THE FINAL LENGTH
	MOV	(R0),R0			;GET THE ORIGINAL MESSAGE
	ADD	#CN.NCT,R0
31$:	MOVB	(R0)+,R2		;GET THE NEXT BYTE OF THE MSG
	ADVCNK	R0			;MOVE TO NEXT CHUNK IF NECESSARY
	ADVCNK	R3			;MOVE TO NEXT CHUNK IF NO MORE
					;SPACE IN THE CURRENT ONE
33$:	MOVB	R2,(R3)+		;SAVE THE DATA BYTE
	DEC	(P)			;COUNT IT
	BGT	31$			;AND LOOP IF NOT DONE
	TST	(P)+			;POP THE EXHAUSTED COUNT
	DEC	R3			;LOCATE THE START OF THE LAST
	BIC	#CNKSIZ-1,R3		;CHUNK STUFFED WITH DATA
	MOV	(R3),R0			;GET THE EXTRA CHUNKS IF ANY
	BEQ	34$			;IF THERE IS ONE FREE IT
	CLR	(R3)			;CLEAR THE LINK
	JSR	PC,FRECKS
34$:	MOV	(P)+,R0			;RESTORE THE NEW MSG ADR
	TST	(P)+
.IIF NE FT.SNK,	MOV	(P),J		;RESTORE DDB ADR FOR SINK
	JSR	PC,NCLIN1		;AND SEND IT ON ITS WAY
	RESTORE	<J>
	DECB	DB.IDR(J)		;DECREMENT THE 10'S REQUESTS
	BNE	30$
35$:	JSR	PC,RDEXCM		;SEND CONTROL MSGS IF REQUIRED
	RTS	PC

RDES.2:	RESTORE	<R0,R0,J>		;RESTORE REGS
	RTS	PC			;AND EXIT
;HERE TO PROCESS MSGS FROM THE 10

RDTODD:	TST	DB.OCN(J)		;IF COUDN'T UNLOAD MSG LAST TIME
	BGT	72$			;DO IT NOW
78$:	JSR	PC,DVGBYT		;GET THE NEXT BYTE FROM THE 10
	BR	78$			;MUST NOT BE DATA
	BR	70$			;ITS A MSG TYPE
79$:					;THERE IS NO MORE SO EXIT OR DISCONNECT
	BIT	#DS.DIE!DS.DSC,(J)	;IF DISCONECTED,
	BNE	RDES.1			;SEND DISCONNECT
	RTS	PC			;ELSE EXIT
70$:	DEC	R0			;CHECK THE TYPE
	BEQ	72$			;DATA
	DEC	R0
	BEQ	72$			;DATA EOR
	DEC	R0
	BEQ	100$			;STATUS
	DEC	R0
	BEQ	110$			;CONTROL
.IF EQ DGUTS
	TRAP				;ILLEGAL MSG TYPE
.IFF
	BR	60$
.ENDC ;.IF EQ DGUTS
72$:	JSR	PC,DVGEXF		;GET THE STATION ADR (EXTENSIBLE FIELD)
	MOV	R0,R1			;AND REMEMBER IT
	MOV	DB.OCN(J),R0		;GET THE DATA LENGTH
	BLE	60$			;IGNORE NULL MSGS
	INC	R0			;COUNT THE STATION ADR
	MOV	R1,-(P)			;SAVE STATION ADR
	MOV	R0,-(P)			;AND THE LENGTH
	JSR	PC,GTMSG1		;GET STORAGE FOR THE WHOLE MSG
	BNE	71$
.IF EQ DGUTS
	TRAP				;IF NO STORAGE,ZAP HIM
.IFF
	CMP	(P)+,(P)+
	BR	60$			;MUST CHUCK THE MSG, IF NO STORAGE
					;SINCE IT MAY BE IMPOSSIBLE TO BACK
					;UP MSG POINTERS.
.ENDC ;.IF EQ DGUTS
71$:	MOV	(P),CN.LEN(R0)		;SET THE MSG LENGTH
	MOV	R0,(P)			;SAVE THE MSG ADR
	MOV	R0,-(P)			;SAVE THE ADR OF THE NEXT DATA BYTE
	ADD	#CN.NCT,(P)
73$:	JSR	PC,RDEGDT		;GET THE NEXT BYTE
	BR	75$			;BRANCH IF NOT DATA
74$:	MOVB	R0,@(P)			;STORE THE DATA BYTE
	INC	(P)			;AND ADVANCE THE POINTER
	BIT	#CNKSIZ-1,(P)		;IF NEXT BYTE NOT IN THIS CHUNK
	BNE	73$
	SUB	#CNKSIZ,(P)		;REGENERATE THE POINTER
	MOV	@(P),(P)
	ADD	#2,(P)			;AND MOVE ON TO THE NEXT CHUNK
	BR	73$			;LOOP FOR MORE DATA
75$:	MOV	J,(P)			;SAVE DDB ADR
.IF NE FT.RDM				;MULTI-POINT
	MOV	4(P),R0			;GET STATION ADDRESS FOR MSG
	BEQ	52$
					;IF ADDRESSED HERE
					;DON'T KNOW WHAT TO DO SO CHUCK IT
	MOV	DB.HDW(J),J		;GET SEARCH LIST
.IF NE FTRDCM&2
	JSR	PC,GETMPA		;AND FIND THE STATION
.IFF
	JSR	PC,LOCMPA		;AND FIND THE STATION
.ENDC ;.IF NE FTRDCM&2
					;IF NO SUCH STATION
	BNE	55$
52$:	MOV	(P)+,J			;RESTORE DDB ADR
	JSR	R0,RD1SST		;REPORT THE ERROR
	.BYTE	0,300
51$:	MOV	(P)+,R0			;RESTORE MSG
	TST	(P)+			;AND POP THE STATION ADR
	JSR	PC,FRECKS		;FREE THE MSG
		;			;CAUSE CAN'T THINK OF SOMETHING BETTER
.ENDC ;.IF NE FT.RDM

60$:	JSR	PC,RDODN2		;SEND DATA REQUESTS IF REQUIRED
.IF NE DGUTS
	CTYMSG	NCL			;REPORT THE ERROR
.ENDC ; .IF NE DGUTS
	BR	78$			;AND TRY FOR ANOTHER MSG

.IF NE FT.RDM
55$:
.IF NE FTRDCM&2
	BITB	#MP.OFF!MP.SOL,LB.MPS(J);IF STATION IS OFF LINE
	BEQ	53$
	JSR	R0,RDESST		;MUST REPORT THE PROBLEM
	.BYTE	0,205
	MOV	(P)+,J			;RESTORE THE DDB ADR
	BR	51$			;AND DUMP THE MESSAGE
.IFF
	BITB	#MP.OFF,LB.MPS(J)	;IF STATION IS OFF LINE
	BEQ	53$
					;MUST SET IT ON LINE
	JSR	PC,SLCT.1		;RESTART THE LINE IF THIS IS FIRST
	JSR	R0,RDESST		;MUST REPORT THE PROBLEM
	.BYTE	1,200
					;STATION TO COME ON LINE
.ENDC ;.IF NE FTRDCM&2
.ENDC ;.IF NE FT.RDM

.IIF NE FT.RDP,MOV DB.LCB(J),J		;ADDRESS OF LCB

53$:	MOV	2(P),R0			;RESTORE THE MSG
	MOV	#SOH,R2			;NUMBERED DATA MSG

.IF DF FTPUMP
.IF NE FTPUMP
	PUMP	GOTMSG
.ENDC
.ENDC

	JSR	PC,DDQ.00		;QUEUE THE MSG FOR XMISSION
	MOV	(P)+,J			;RESTORE DDB ADR
	CMP	(P)+,(P)+		;POP MSG AND STATION ADRS
	BR	78$			;TRY FOR ANOTHER MSG


;STATUS FROM THE -10

100$:	JSR	PC,DVRSTS		;RESET THE STATUS BITS
	BR	78$			;TRY FOR ANOTHER MSG


;CONTROL MESSAGE FROM THE -10

110$:	JSR	PC,RDERCM		;PROCESS IT
	JSR	PC,DVXDRQ		;SEND DATA REQUESTS IF REQUIRED
	BR	78$			;TRY FOR ANOTHER MSG
;HERE WHEN DATA IS TO BE PASSED TO THE 10

RDEINP:	MOV	J,-(P)			;SAVE  LINE BLOCK ADDRESS
	JSR	PC,RDEGTB		;GET THE RDEDDB
	BNE	80$
.IF NE DGUTS
	TWIDDLE
					;IF NONE WE ARE IN TROUBLE
	BR	85$
.IFF
	TRAP
.ENDC	;.IF NE DGUTS
80$:	BIT	#DS.CON,(J)		;IF DEAD, OR DISCONNECTED DDB
	BNE	87$
85$:	JSR	PC,FRECKS		;CHUCK MSG
	MOV	(P)+,J
	JSR	PC,L.DOWN		;AND SHUT HIM UP
.IF NE DGUTS
	CTYMSG	NDV			;REPORT ERROR
.ENDC
	RTS	PC
87$:
	MOV	J,-(P)			;SAVE THE DDB ADR
					;AND GENERATE A DUMMY MSG LINK
	ADD	#DB.IBF-CN.MLK,J
	PIOFF
81$:	TST	CN.MLK(J)		;IF THERE IS A MSG
	BEQ	82$
	MOV	CN.MLK(J),J		;STEP TO THE NEXT
	BR	81$
82$:	MOV	R0,CN.MLK(J)		;QUEUE LAST MSG (FIFO)
	PION
	MOV	(P)+,J			;RESTORE THE DDB ADR
	JSR	PC,QUEDEV		;BE SURE THE DEV IS QUEUED
	MOV	(P)+,J			;RESTORE THE THE LINE BLOCK ADR
	RTS	PC
GTMSG1:	ADD	#CN.NCT-2,R0		;CORRECT FOR OVERHEAD STUFF
GTMSG:	CLR	-(P)
	CLR	-(P)
	MOV	R0,-(P)			;SAVE THE STORAGE LENGTH
91$:	JSR	PC,GETCNK		;ALLOCATE A CHUNK
	BEQ	92$			;IF NONE TAKE FAILURE EXIT
	TST	2(P)			;IF NO PREVIOUS CHUNK ALLOCATED
	BNE	93$
	MOV	R0,4(P)			;SAVE THE FIRST LINK
	BR	94$
93$:	MOV	R0,@2(P)		;ELSE LINK IN THE NEW BLOCK
94$:	MOV	R0,2(P)			;SAVE THE LAST LINK
	SUB	#CNKSIZ-2,(P)		;IF MORE THAN A CHUNK LEFT
	BHI	91$
	CMP	(P)+,(P)+		;POP LOCAL VARIABLES
	MOV	(P)+,R0			;GET ADR OF FIRST CHUNK
	RTS PC
92$:	CMP	(P)+,(P)+		;POP LOCAL VARIABLES
	MOV	(P)+,R0			;GET ADR OF FIRST CHUNK
	BEQ	95$
	JSR	PC,FRECKS		;IF THERE IS ONE,FREE IT
95$:	CLR	R0			;RETURN ZERO AND Z BIT SET
	RTS	PC



RDEGDT:	TST	DB.OCN(J)		;IF MORE DATA
	BEQ	05$
	JSR	PC,DVGBYT		;GET THE NEXT BYTE
	BR	04$
	TRAP				;CAN'T BE MSG TYPE
	BR	05$			;ZAPPED IF END OF 10'S MSG
04$:	ADD	#2,(P)			;MUST SKIP ON SUCCESS
05$:	RTS	PC


.IF NE 0			;NOT USED ANYMORE
RDEADR:				;GET MULTIPOINT ADDRESS FROM MSG
	ADD	#CN.NCT,R0
	SAVE	<R1>
	MOV	R0,R1
	MOVB	(R1)+,R0		;GET FIRST BYTE OF MSG
	BPL	96$			;IF EXTENDED FIELD
	MOVB	(R1),R1			;GET THE SECOND BYTE
	SWAB	R1
	COM	R1
	ROR	R1
	BIC	#140177,R1
	BIC	R1,R0			;AND PACK THEM TOGETHER
96$:	RESTORE	<R1>
	RTS	PC
.ENDC ;.IF NE 0
RDEBMS:	MOV	DB.SCB(J),SB		;GET SCB FOR DEV
	MOV	SB,DNA			;SET DESTINATION
	MOV	#OURSCB,SNA		;SET SOURCE
	CLR	R1			;NCL NCT
	JSR	PC,NCLBMS		;START THE NCL MESSAGE
	BNE	.+4
	RTS	PC			;COULDN'T SO EXIT
	MOV	(P),4(P)		;SAVE THE MSG ADR IN PROPER LOC
	TST	(P)+			;EXTRA INSTRUCTION FOR MACHINE COMPATIBILITY
	ADD	#2,(P)			;SUCCESS RETURN
	MOV	DB.RLA(J),R0		;PUT DLA IN MESSAGE
	JMP	PUTEXN
.IF NE FTRDCM&2

;START CONTROL MSGS DESTINED FOR 10

RDESCM:	CLR	-(P)			;SAFE STORAGE FOR MSG ADR
	JSR	PC,RDEBMS		;START THE MESSAGE
	BR	18$			;CAN'T SEND IT NOW
	MOV	R3,R4			;SAVE ADR OF NEXT BYTE
	JSR	PC,PUTBYT		;RESERVE COUNT FIELD
	MOV	#4,R0			;INSERT CONTROL TYPE
	JSR	PC,PUTBYT
	JMP	@2(P)			;RETURN
18$:	CMP	(P)+,(P)+		;POP THE SAFE STORE AND THE RETURN
	TWIDDLE				;COUNT THE ERRORS
	RTS	PC			;THEN RETURN TO THE CALLER'S CALLER



;SEND CONTROL MSG TO 10 IF REQUIRED

RDEXCM:	JSR	PC,RDESCM		;START THE MESSAGE
	MOV	R2,2(P)			;SAVE THE OLD COUNT
	CLR	R2			;CLEAR LENGTH
	MOV	R4,-(P)			;SAVE THE COUNT ADDRESS
	MOV	#1,R0			;INSERT TYPE 1 CONTROL
	JSR	PC,PUTBYT
	ADD	#DB.SCB,J		;LOCATE THE CONTROL STATUS TABLE
	MOV	#M$MAX,R4		;GET ITS LENGTH
10$:	TSTB	1(J)			;AND SCAN IT
	BMI	11$
	TST	(J)+			;SKIP VACANT ENTRY
	BR	12$
11$:	MOVB	(J)+,R0			;MOVE THE ENTRY TO THE MSG
	JSR	PC,PUTBYT
	MOVB	(J),R0
	CLRB	(J)+			;AND VACATE IT
	JSR	PC,PUTBYT
12$:	SOB	R4,10$
	SUB	#DB.SSC+<2*M$MAX>,J	;RESTORE THE DDB ADR
	CMP	#1,R2
	BNE	RDESMO
	TST	(P)+			;FREE IT
	MOV	(P)+,R0
	TST	(P)+
	JMP	FRECKS
RDESMO:	MOVB	R2,@(P)+		;FILL THE EMPTY SLOT IN THE MSG
	MOV	(P)+,R0			;RESTORE THE MSG ADR
	ADD	(P)+,R2			;GET THE TOTAL COUNT
	MOV	R2,CN.LEN(R0)		;AND SAVE IT IN THE MSG HEADER
	SAVE	<J>
	JSR	PC,NCLIN1		;THEN SEND MSG ON
	RESTORE	<J>
	RTS	PC
;SEND CONTROL MSGS (TYPE 2) TO 10 IF REQUIRED

RDE2CM:	JSR	PC,RDESCM		;START THE MESSAGE
	MOV	R2,2(P)			;SAVE THE OLD COUNT
	CLR	R2			;CLEAR LENGTH
	MOV	R4,-(P)			;SAVE THE COUNT ADDRESS
	MOV	#2,R0			;INSERT TYPE 2 CONTROL
	JSR	PC,PUTBYT
	MOV	J,-(P)			;SAVE THE DDB ADR
	MOV	12(J),J			;GET THE LINE BLOCK ADR
	MOVB	LB.MPA(J),R0		;PUT THE STATION ADR IN THE MSG
	JSR	PC,PUTBYT
	CLR	R0			;PUT THE ONLINE/OFFLINE FLAG IN MSG
	BITB	#MP.OFF!MP.SOL,LB.MPS(J)
	BEQ	10$
	INC	R0
10$:	JSR	PC,PUTBYT
	ADD	#LB.OCN,J		;NOW PUT THE DDCMP COUNTERS IN THE MSG
	MOV	#20,R4
11$:	MOVB	(J),R0
	CLRB	(J)+
	JSR	PC,PUTBYT
	SOB	R4,11$
	BR	RDESMO
.IFF
RDEXCM:
RDE2CM:	RTS	PC	;DUMB TEN DOESN'T KNOW CONTROL MSGS
.ENDC
;RECORD THE CHANGE OF STATE FOR A STATION TO
;REPORT TO THE TEN (TYPE 1 CONTROL MSG).

RDESST:
.IF NE FT.RDM
	BIT	#LS.MPT,(J)		;IF MULTIPOINT LINE
	BEQ	RD7SST
	TST	LB.MPL(J)		;AND IF NOT A TRIBUTARY
	BEQ	RD7SST
	SAVE	<J,R1>
	CLR	-(P)			;SAFE STORAGE FOR TABLE ENTRY ADR
	CLR	-(P)
	MOVB	LB.MPA(J),(P)		;SAVE STATION'S ADR
	JSR	PC,RDEGTB		;LOCATE RDEDDB
	BEQ	RD6SST			;EXIT IF NONE
RD0SST:	MOV	#M$MAX,R1		;GET TABLE SIZE
	BEQ	RD6SST			;BETTER NOT BE NULL
	ADD	#DB.SSC,J		;AND TABLE
RD2SST:	CMPB	(J)+,(P)		;AND SEARCH FOR THE STATION
	BEQ	RD4SST			;BRANCH IF FOUND
	TSTB	(J)+			;SKIP THE OTHER HALF OF THE ENTRY
	BMI	RD3SST
	MOV	J,2(P)			;SAVE TABLE LOC IF REUSABLE
RD3SST:	SOB	R1,RD2SST
	MOV	2(P),J			;DIDN'T FIND STATION,SO CHECK FOR VACANT ENTRY
	BEQ	RD6SST
	CLR	-(J)			;CLEAR THE VACANT ENTRY
	MOVB	(P),(J)+		;SAVE THE STATION ADDRESS
RD4SST:	BICB	(R0)+,(J)		;CLEAR THE FLAGS AS REQUESTED
	BISB	(R0)+,(J)		;SET THE  FLAGS AS REQUESTED
RD5SST:	CMP	(P)+,(P)+		;CLEAN STACK
	RESTORE	<R1,J>
	RTS	R0
RD6SST:	TWIDDLE				;COUNT THE FAILURES
	TST	(R0)+			;SKIP THE ARG
	BR	RD5SST			;AND EXIT
.ENDC ;.IF NE FT.RDM

RD7SST:	TST	(R0)+			;SKIP THE ARG
	RTS	R0			;AND RETURN


.IF NE FT.RDM
;RECORD STATE CHANGE WHEN J=DDB, AND R0=STATION

RD1SST:	SAVE	<J,R1>
	CLR	-(P)			;SAFE STORAGE FOR TABLE ENTRY ADR
	CLR	-(P)			;EXTRA OP FOR 11 CPU COMPATABILITY
	MOV	10(P),(P)		;MOVE STATION ADR TO TOP OF STACK
	BR	RD0SST			;AND CONTINUE AS IN RDESST
.ENDC ;.IF NE FT.RDM
.IF NE FTRDCM

;PROCESS AN INCOMING CONTROL MSG

RDERCM:	JSR	PC,RDEGDT		;GET THE FIRST DATA BYTE
	RTS	PC			;EXIT IF NONE
	CMP	#1,R0			;IS IT A TYPE 1 MSG
	BNE	20$
.IF NE FTRDCM&2
11$:	JSR	PC,RDEGDT		;GET THE STATION ADR
	RTS	PC			;RETURN IF NONE
	MOV	R0,-(P)			;AND SAVE IT
	JSR	PC,RDEGDT		;GET THE REQUEST
	BR	19$			;POP THE STACK AND EXIT IF NONE
	MOVB	R0,1(P)			;SAVE THE REQUEST
	MOVB	(P),R0			;RESTORE THE STATION'S ADR
	MOV	J,-(P)			;SAVE THE DDB ADR
	JSR	PC,GT1MPA		;LOCATE THE STATION'S LINE BLOCK
	BNE	13$
	TWIDDLE				;IF NOT THERE, COUNT THE ERRORS
	MOV	(P)+,J			;RESTORE THE DDB ADR
	TST	(P)+			;POP THE LOCAL STORAGE
	BR	11$			;AND TRY THE NEXT ONE
13$:	BITB	#2,3(P)			;IF HE WANTS DDCMP COUNTERS
	BEQ	14$
	MOV	J,-(P)			;RESTORE THE DDB
	MOV	2(P),J
	JSR	PC,RDE2CM		;AND SEND THE REQUESTED MSG
	MOV	(P)+,J			;RESTORE THE LINE BLOCK
14$:	BITB	#1,3(P)			;IF HE WANTS THE STATION ONLINE
	BNE	15$
	BICB	#MP.SOL,LB.MPS(J)	;CLEAR THE REQUEST TO SET OFFLINE IF SET
	BITB	#MP.OFF,LB.MPS(J)	;IF OFF LINE
	BEQ	16$
	JSR	PC,SLCT.1		;SET ONLINE STARTING UP THE LINE IF REQUIRED
	JSR	R0,RDESST		;REPORT THE CHANGE OF STATE
	.BYTE	1,200
16$:	MOV	(P)+,J			;RESTORE THE DDB ADR
	TST	(P)+			;CLEAN THE STACK
	BR	11$			;AND LOOP ON NEXT REQUEST
15$:	BISB	#MP.SOL,LB.MPS(J)	;FLAG IT TO BE SET OFFLINE
	BITB	#MP.SEL,LB.MPS(J)	;IF NOT SELECTED
	BNE	16$
	JSR	PC,L.DOWN		;REALLY SET IT OFFLINE
	BR	16$
19$:	TST	(P)+			;CLEAN THE STACK
	RTS	PC			;AND EXIT
.IFF
.IF NE DGUTS
	CTYMSG	NCL			;REPORT ERROR
.ENDC ;.IF NE DGUTS
18$:	JSR	PC,RDEGDT		;EAT MSG
	  RTS	PC
	BR	18$
.ENDC
20$:	TST	R0			;CHECK IF TYPE 0 CONTROL
	BNE	30$
.IF EQ	FTSLCT-1
21$:	JSR	PC,RDEGDT		;GET THE NEXT DATA BYTE
	RTS	PC			;EXIT IF NONE
	MOV	R0,-(P)			;SAVE THE STATION'S ADR
	JSR	PC,RDEGDT		;GET THE NEXT DATA BYTE
	BR	29$			;POP THE STACK AND EXIT IF NONE
	MOVB	R0,1(P)			;SAVE THE WEIGHT
	MOVB	(P),R0			;GET THE STATION'S ADR BACK
	MOV	J,-(P)			;SAVE THE DDB ADR
	JSR	PC,GETMPA		;GET THE LINE BLOCK FOR THE STATION
	BEQ	22$			;SKIP THE ACTION IF NONE
MXWGHT=20	;MAX ALLOWED VALUE FOR WEIGHT
	MOVB	1(P),R0			;GET THE WEIGHT BACK
	CMPB	R0,#MXWGHT		;IF GREATER THAN MAX
	BLOS	.+6
	MOV	#MXWGHT,R0		;SET IT TO THE LIMIT
	MOVB	R0,LB.MPN+1(J)		;SET THE WEIGHT
22$:	MOV	(P)+,J			;RESTORE THE DDB ADR
	TST	(P)+			;POP THE LOCAL STORE
	BR	21$			;AND TRY FOR ANOTHER WEIGHT
29$:	TST	(P)+			;POP THE LOCAL STORE
	RTS	PC			;AND EXIT
.IFF
.IF EQ FTSLCT-3
21$:	SAVE	<R3,R4>			;SAVE R3,R4
	MOV	J,R4			;GET THE POLLING LIST
	ADD	#DB.POL,R4
	MOV	R4,-(P)			;AND SAVE ITS ADR
	MOV	#POLLSZ,R3		;GET LIST SIZE
22$:	CLRB	(R4)+			;AND CLEAR IT
	SOB	R3,22$
23$:	MOV	(P),R4			;GET THE LIST'S ADR BACK
	MOV	#POLLSZ,R3		;AND ITS LENGTH
24$:	JSR	PC,RDEGDT		;GET THE NEXT ENTRY
	BR	29$			;IF NONE,FIX STACK UP AND EXIT
	MOVB	R0,(R4)+		;PUT THE ENTRY IN THE LIST
	SOB	R3,24$
	TST	DB.OCN(J)		;IF STILL MORE ENTRIES
	BNE	23$			;WRAP AROUND
29$:	MOV	(P)+,DB..PL(J)		;RESET THE LIST INDEX
	RESTORE	<R4,R3>
	RTS	PC			;AND EXIT
.IFF
	TWIDDLE
21$:	JSR	PC,RDEGDT		;SO COUNT ERROR AND CHUCK MSG
	RTS	PC
	BR	21$
.ENDC
.ENDC
30$:	TWIDDLE				;ILLEGAL MSG
31$:	JSR	PC,RDEGDT		;SO COUNT ERROR AND CHUCK MSG
	RTS	PC
	BR	31$
.IFF
RDERCM:	TWIDDLE			;DUMB TEN DOES'T KNOW CONTROL MSGS
21$:	JSR	PC,RDEGDT		;SO COUNT ERROR AND CHUCK MSG
	RTS	PC
	BR	21$
.ENDC ;.IF NE FTRDCM

.ENDC ;.IF NE FT.RDM!FT.RDP