Google
 

Trailing-Edge - PDP-10 Archives - bb-bt99g-bb - rdxser.c11
There is 1 other file named rdxser.c11 in the archive. Click here to see a list.
 REP 11/4	;11C1
		  JRST	R.DERR		;NOT THERE?? RETURN IODERR
		LDB	T2,PIOMOD##	;GET THE DEVICE MODE
 WIT
		  JRST	R.HUNG		;NOT THERE?? RETURN IODERR
		TLNN	S,IOBEG		;FIRST TIME THROUGH?
		JRST	ROLOO0		;NO, ALREADY BEEN HERE.
		MOVSI	S,IOBEG!IOSREL	;GET TAWDRY BITS
		ANDCAB	S,DEVIOS(F)	;AND CLEAN THEM OUT
	ROLOO0:	LDB	T2,PIOMOD##	;GET THE DEVICE MODE
 REP 18/5	;11C2

		PUSH	P,T1		;SAVE THE DROP NUMBER
		JFFO	T1,.+2		;GET 36-LOG(T1)
		MOVEI	T2,^D35		;ASSUME "0" IS ONE BIT LONG
		SUBI	T2,^D36+6	;THESE TWO INSTRUCTIONS FIND THE NUMBER OF
		MOVN	T2,T2		; SIGNIFICANT BITS IN THE DROP NUMBER (ROUND UP)
		IDIVI	T2,7		;NOW GET NUMBER OF "EXTENSIBLE" BYTES
		PUSH	P,T2		;SAVE THE DROP NUMBER'S LENGTH

		MOVEI	T1,^D32		;GET A 32 WORD LONG PCB
		PUSHJ	P,NTDHDR##	; AND FILL IN THE HEADER UP TO THE "DLA"
		  JRST	[SUB P,[2,,2]	;CAN'T GET THE CORE.  CLEAN UP THE STACK
			POPJ P,]	; AND RETURN TO UUOCON.
		MOVE	T2,PCBOCT(U)	;GET XWD PCB'S SIZE,BYTES ALREADY WRITTEN
		HLRZ	T4,T2		;GET THE SIZE OF THE PCB (WORDS)
		LSH	T4,2		;GET THE SIZE OF THE PCB (BYTES)
		SUBI	T4,(T2)		;ACCOUNT FOR THE BYTES IN THE HEADER
		POP	P,T2		;GET THE LENGTH OF THE DROP NUMBER
		SUBI	T4,3(T2)	;ACCOUNT FOR "CNT" AND "TYP" GET BYTES LEFT
		MOVEI	T3,DC.DAR	;ASSUME DATA WITH EOR
		CAML	T4,DEVAXO+1(F)	;SEE IF THE DATA WILL FIT IN THE PCB
		SKIPA	T4,DEVAXO+1(F)	;YES. ADJUST THE "CNT" TO BE BYTES LEFT
		MOVEI	T3,DC.DAT	;NO. THIS WILL BE DATA W/O E-O-R
	;CNT
		MOVEI	T1,1(T4)	;ALLOW FOR THE "TYP" BYTE
		XMT	T1		;SEND THE "COUNT" FIELD
	;TYP
		XMT	T3		;SEND THE "TYP"
	;DROP
		POP	P,T1		;GET THE DROP NUMBER
		XMT	T1		;AND SEND THAT
	;DATA
	R.MXM2:	SOSGE	DEVAXO+1(F)	;COUNT OFF THE NEXT BYTE
		PUSHJ	P,NTDSTP##	;++ MY ARITHMETIC SUCKS
		EXCTUX	<ILDB T1,DEVAXO(F)> ;GET ANOTHER BYTE FROM THE USER'S BUFFER
		XMT1	T1		;SEND THE BYTE
		SOJG	T4,R.MXM2	;LOOP UNTIL WE'VE SENT IT ALL
 WIT
		TRNE	T1,740000	;ABSURD DROP NUMBER?
		JRST	R.IMPM		;YEAH, FLAG IO.IMP ERROR
		PUSH	P,T1		;SAVE THE DROP NUMBER

	;START UP AN NCL MESSAGE (CAN'T USE NTDXMT DUE TO MULTIPOINT'S UNIQUE
	;"DROP" NUMBER SANDWICHED BETWEEN "TYP" AND "DATA" FIELDS . . .)

		MOVE	T1,DEVAXO+1(F)	;COUNT OF ACTUAL DATA BYTES TO BE SENT
		LDB	T2,NETMML##	;GET RDM'S MAX MESSAGE LENGTH
		CAMLE	T1,T2		;WILL USER'S BUFFER FIT IN ONE MESSAGE?
		JRST	R.OBTL		;NO, BLOCK-TOO-LARGE ERROR
		ADDI	T1,20+3		;ALLOW FOR NCL OVERHEAD, ROUND UP
		LSH	T1,-2		;AND CONVERT TO WORD SIZE
		CAILE	T1,MSGMAW##	;CAN WE GET A PCB THAT LARGE?
		JRST	R.MXME		;NO, BLOCK-TOO-LARGE ERROR
		PUSHJ	P,NTDHDR##	; AND FILL IN THE HEADER UP TO THE "DLA"
		  JRST	[POP	P,T1		;NO PCB MEMORY, BACK OUT OF TRANSMIT
			MOVNI	T1,5		;NUMBER OF BYTES IN "DROP"
			ADJBP	T1,DEVAXO(F)	;ADJUST BUFFER POINTER BACKWARDS
			MOVEM	T1,DEVAXO(F)	;TO START OF DROP FOR NEXT ROLOOP CYCLE
			MOVEI	T1,5		;NUMBER OF BYTES IN "DROP"
			ADDM	T1,DEVAXO+1(F)	;ADJUST BUFFER COUNTER TOO
			MOVEI	T1,DEPAIO	;THE "NON-BLOCKING-I/O" BIT
			TDNE	T1,DEVAIO(F)	;IS JOB DOING ASYNC I/O?
			POPJ	P,		;YES, "NON-BLOCKING" RETURN TO UUOCON
			PUSHJ	P,NETSLP##	;NO, WAIT A BIT FOR SOME FREE CORE
			JRST	ROLOOP]		;AND TRY AGAIN

	;CONTINUED ON NEXT PAGE
	;CONTINUED FROM PREVIOUS PAGE

		POP	P,T4		;RETRIEVE THE DROP NUMBER
		MOVEI	T1,2		;COUNT "TYP" BYTE, ASSUME ONE BYTE FOR DROP
		TRNE	T4,777600	;SMALL OR LARGE DROP NUMBER?
		ADDI	T1,1		;TWO BYTE'S WORTH OF DROP NUMBER
		ADD	T1,DEVAXO+1(F)	;ADD COUNT OF DATA BYTES LEFT
	;CNT
		XMT	T1		;SEND THE "COUNT" FIELD
	;TYP
		XMTI	DC.DAR		;SEND THE "TYP" = DATA WITH EOR
	;DROP
		XMT	T4		;AND SEND THE DROP NUMBER
	;DATA
		SETZ	T4,		;COUNT OF BYTES THAT WILL BE LEFT OVER
		EXCH	T4,DEVAXO+1(F)	;GET COUNT OF USER DATA BYTES IN BUFFER
		JRST	R.MXM3		;ENTER OUTPUT LOOP

	R.MXM2:	EXCTUX	<ILDB T1,DEVAXO(F)> ;GET ANOTHER BYTE FROM THE USER'S BUFFER
		XMT1	T1		;SEND THE BYTE
	R.MXM3:	SOJGE	T4,R.MXM2	;LOOP UNTIL WE'VE SENT IT ALL
 INS 61/5	;11C3


	;HERE ON OUTPUT BLOCK TOO LARGE (RETURN IO.BKT ERROR)

	R.MXME:	POP	P,T1		;PITCH DROP NUMBER
		JRST	R.OBTL		;GO SET IO.BKT ERROR FOR USER
 REP 18/6	;11C4
		  JRST	R.DERR		;IF NOT, THEN SET IODERR AND RETURN
 WIT
		  JRST	R.HUNG		;IF NOT, THEN SET IODERR AND RETURN
 REP 10/9	;11C5
	;R.DERR, R,IMPM ROUTINES TO SET IODERR AND IOIMPM
	;
	R.DERR:	MOVE	S,[XWD IOSERR,IODERR] ;TWO ERROR BITS TO SET
		CAIA
	R.IMPM:	MOVEI	S,IOIMPM	;ERROR BIT TO SET
		IORB	S,DEVIOS(F)	;SET THE BIT
		POPJ	P,		;AND RETURN
 WIT

	;R.OBTL	ROUTINE TO SET IOBKTL IF THE USER GAVE US AN OUTPUT BUFFER THAT
	; WAS TOO LARGE.  IT ALSO SETS THE OUTPUT BUFFER AS "DONE" SO THAT THE
	; NEXT "OUT" CALL WILL AUTOMATICALLY ADVANCE PAST THE OFFENDING BUFFER.

	R.OBTL:	SETZM	DEVAXO+1	;MARK THE OUTPUT BUFFER AS "DONE" (EMPTY)
		MOVEI	S,IOBKTL	;GET THE ERROR BIT
		JRST	R.ERRS		;SET ERROR BIT, TAKE NON-SKIP RETURN
 INS 20/9	;11C6
	;R.HUNG	RDA IS "OFFLINE" (NTDONL), CHECK IT OUT

	R.HUNG:	TLNN	S,IOSCON	;STILL CONNECTED?
		JRST	NTDGON##	;NO, DEVICE WENT AWAY
					;YES, FALL INTO R.DERR



	;R.DERR, R,IMPM ROUTINES TO SET IODERR AND IOIMPM
	;
	R.DERR:	MOVE	S,[XWD IOSERR,IODERR] ;TWO ERROR BITS TO SET
		CAIA
	R.IMPM:	MOVEI	S,IOIMPM	;ERROR BIT TO SET
	R.ERRS:	IORB	S,DEVIOS(F)	;SET THE BIT
		POPJ	P,		;AND RETURN



 SUM 90300