Google
 

Trailing-Edge - PDP-10 Archives - tops10_704_monitoranf_bb-x140c-sb - 10,7/mon/d8sint.mac
There are 6 other files named d8sint.mac in the archive. Click here to see a list.
TITLE	D8SINT - INTERRUPT SERVICE ROUTINE FOR DN87S - V036
SUBTTL	ERIC WERME/EJW/JBS/EGF  09-FEB-88
	SEARCH	F,S,DTEPRM,NETPRM
	$RELOC
	$HIGH


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1976,1988>


XP	VD8SINT,036		;VERSION NUMBER

ENTRY	D8SINT			;REFERENCED IN COMNET TO FORCE LOADING
D8SINT::

                           Comment @

This module is meant to be a carbon copy of D85INT, the
DL10/NETSER interface. Since D85INT is oriented around single
message transfers, so is D8SINT even though DTESER is willing to
queue any number of messages.

                        End of Comment @


LN.MOR==1B17			;LINE NUMBER BIT SAYING ANOTHER
				;  FRAGMENT IS COMING
SUBTTL	FEKDSP -- D8SINT ENTRY VECTOR

D8SDSP::CAIL	T1,FF.ONC	;RANGE CHECK THE FUNCTION
	CAILE	T1,FF.CPW	;  CODE AND STOP IF BAD
	PUSHJ	P,NTDSTP##	;++ ERROR: BAD FUNCTION CODE TO FEK
	JRST	@.+1(T1)	;DISPATCH TO APPROPRIATE ROUTINE
	IFIW	NTFONC##	;USE NETSER'S DEFAULT ONCE-ONLY CODE
	IFIW	D8SSEC		;CHECK FOR DOWN FE
	IFIW	D8SRDD		;SET UP A READ REQUEST
	IFIW	D8SWRT		;SET UP A WRITE REQUEST
	IFIW	D8SCRS		;CRASH THE FEK (CPU WENT DOWN -- 11 HUNG)
	IFIW	D8SDWN		;CALLED WHEN LEAVE PRIMARY PROTOCOL
	IFIW	D8SUP		;CALLED WHEN ENTER PRIMARY PROTOCOL
	IFIW	CPOPJ##		;CALLED WITH STATION CONTROL (WE DON'T WANT IT)
	IFIW	D8SCPS		;OUR CPU IS GOING TO SLEEP
	IFIW	D8SCPW		;OUR CPU IS WAKING UP.


;D8SSEC ROUTINE TO CHECK FOR A DOWN FE
;CALL:		J := FEK
;RETURN	CPOPJ (THROUGH NETSER'S NTFSEC ROUTINE)
D8SSEC:	SKIPN	DTRJOB##	;AUTO RELOAD JOB (DTELDR)?
	SKIPL	FEKBLK(J)	;FEK ALREADY DOWN?
	PJRST	NTFSEC##	;DO NETSER ONCE-A-SECOND CODE
	PUSH	P,F		;SAVE F
	MOVE	F,FEKUNI(J)	;GET CPU,,DTE
	TRNN	F,-1		;WERE WE EVER UP AND RUNNING?
	JRST	D8SSE1		;NO
	PUSHJ	P,GTETDS##	;FETCH ETD
	MOVSI	T1,(ED.RLD)	;BIT TO TEST
	TDNN	T1,ETDSTS(F)	;NEED TO RELOAD?
	JRST	D8SSE1		;NO
	MOVEI	T1,FI.DWN	;FUNCTION CODE FOR NETSER
	PUSHJ	P,FEKINT##	;DECLARE FEK DEAD
D8SSE1:	POP	P,F		;RESTORE F
	PJRST	NTFSEC##	;ENTER COMMON FEK CODE


;D8SRDD	ROUTINE TO BY NETSER TO POST A READ REQUEST (INPUT BUFFER)
;CALL	        J := FEK
;	FEKIAD(J) := INPUT BUFFER TO FILL
;RETURN	CPOPJ

D8SRDD:
IFN FTMP,<
	HLRZ	T1,FEKUNI(J)	;GET OUR CPU NUMBER, AND IF THIS IS
	CAME	T1,.CPCPN##	;  NOT "OUR" CPU, THEN SET "FK.STI"
	PJRST	SETSTI		;  SO THAT CLOCK LEVEL WILL RE-START US
>
	AOSE	FEKBSI(J)	;GET THE INPUT INTERLOCK (WE GET HERE FROM
				;  BOTH UUO AND INTERRUPT LEVEL)
	POPJ	P,		;IF ALREADY DOING INPUT, EXIT
	SKIPN	FEKIAD(J)	;MAKE SURE WE HAVE A BUFFER TO FILL
	JRST	[SETOM FEKBSI(J);IF NO BUFFERS, SET THIS FEK IDLE (INPUT)
		 POPJ P,]	;  AND EXIT.

	HRRZ	U,FEKIAD(J)	;GET ADDRESS OF INPUT BUFFER
	MOVE	T1,PCBPTR(U)	;GET BYTE POINTER TO BUFFER TO FILL
	MOVEM	T1,FEKIBP(J)	;SAVE BYTE POINTER IF FEK (FOR STRING DATA)
	SETZM	PCBCTR(U)	;CLEAR THE COUNT IN THE PCB (NO DATA YET)
	AOS	FEKAKC(J)	;COUNT ONE MORE QPR-ACK TO BE SENT
	PJRST	D8SWRT		;  AND CALL D8SWRT TO SEND IT

SETSTI:	MOVSI	T1,FK.STI	;GET THE "KICK ME FOR INPUT" BIT
	IORM	T1,FEKBLK(J)	;  AND SET IT IN THE STATUS BLOCK OF THE FEK
	POPJ	P,		;  NEXT JIFFY NETSER WILL CALL AGAIN
;D8SWRT	ROUTINE TO POST AN OUTPUT BUFFER TO D8SINT
;CALL	        J := FEK POINTER
;	FEKOAD(J) := OUTPUT MESSAGE
;RETURN	CPOPJ
D8SWRT:
IFN FTMP,<
	HLRZ	T1,FEKUNI(J)	;GET THIS FEK'S CPU NUMBER, AND IF IT'S
	CAME	T1,.CPCPN##	;  NOT THE SAME AS THE CPU WE'RE ON, THEN
	JRST	SETSTO		;  SET "FK.STO" SO CLOCK LEVEL WILL KICK US
>
	AOSE	FEKBSO(J)	;GET THE "OUTPUT BUSY" INTERLOCK
	POPJ	P,		;  IF ALREADY DOING OUTPUT, EXIT NOW
	PUSHJ	P,SAVE4##	;SAVE THE P'S (DTESER USES THEM ALL)
	PUSH	P,S		;SAVE S (UUO LEVEL CALLS HERE)
	PUSHJ	P,SNDACK	;SEND QPR-ACK'S IF NECESSARY
	SKIPG	FEKOCT(J)	;MAKE SURE WE HAVE SOMETHING TO OUTPUT
	JRST	[SETOM FEKBSO(J);  IF NOTHING, CLEAR OUTPUT BUSY
		 JRST SPOPJ]	;  AND RETURN

	HRRZ	U,FEKOAD(J)	;GET ADDRESS OF THE PCB TO SEND
	MOVSI	S,T11DON	;POST ADDRESS FOR WHEN MESSAGE IS DONE
	MOVE	P1,FEKUNI(J)	;GET "XWD CPU,DTE"
	MOVE	P2,[XWD .EMNCL,EM.IND!.EMSTR] ;SEND INDIRECT STRING DATA
	MOVE	P3,PCBCTR(U)	;GET THE COUNT OF THE NCL HEADER PORTION
	MOVE	P4,PCBPTR(U)	;GET THE B.P. TO THE NCL HEADER PORTION
	SKIPE	PCBCT2(U)	;GET THE LENGTH OF THE SECOND FRAGMENT
	JRST	[MOVSI S,CPOPJ##	;IF THERE IS MORE, ZAP THE POST ADDR
		HRLI P3,(LN.MOR)	;  AND SET THE "THERE IS MORE" FLAG
		JRST .+1]		;BACK TO MAIN CODE
	S0PSHJ	DTEQUE##	;GIVE THE FIRST FRAGMENT TO DTESER.
	  JRST	[PUSHJ P,SETSTO		;IF NO CORE.  SET THE "KICK ME" BIT
		SETOM FEKBSO(J)	;  CLEAR OUTPUT IN PROGRESS FLAG
		JRST SPOPJ]		;  AND EXIT.  WILL TRY AGAIN LATER
	SKIPN	P3,PCBCT2(U)	;GET THE LENGTH OF THE SECONDARY OUTPUT BUFFER	
	JRST	SPOPJ		;EXIT NOW UNLESS SECOND FRAGMENT TO BE SENT
	MOVSI	S,T11DON	;GET THE POST ADDRESS
	MOVE	P4,PCBPT2(U)	;GET THE ADDRESS OF THE FRAGMENT (EVA)
	LDB	T1,PCBPCV##	;GET THE COMPRESSION CODE.
	CAIN	T1,PCV.BN	;IF IT IS BINARY, THEN WE MUST
	JRST	[IORI P2,EM.16B	;  REQUEST WORD MODE TRANSFERR.
		 LSH P3,1	;  AND DOUBLE COUNT (MAKE IT # OF -11 BYTES)
		 JRST .+1]	;BACK TO MAIN FLOW
	DPB	T1,[POINT 2,P3,16] ;  PUT THE COMPRESSION CODE IN THE LINE 
				   ;  NUMBER FIELD
	S0PSHJ	DTEQUE##	;SEND THE MESSAGE
	  JRST	[POP P,S	;IF WE FAIL ON THE SECOND PART, FIX UP STACK
		 JRST D8SCRS]	;  AND CRASH THE FEK (WE CAN'T RESTART PART
				;  WAY THROUGH...)
SPOPJ:	POP	P,S		;
	POPJ	P,		;ALL DONE

SETSTO:	MOVSI	T1,FK.STO	;GET THE "CLOCK LEVEL PLEASE KICK ME" FLAG
	IORM	T1,FEKBLK(J)	;  AND SET IT SO WE GET TO TRY OUTPUT AGAIN
	POPJ	P,		;ALL DONE FOR NOW.  CLOCK LEVEL WILL CALL
				;  IN A JIFFY OR SO...
;HERE AFTER DTESER HAS SUCCESSFULLY TRANSMITTED THE MESSAGE

T11DON:	HLRZ	T1,P1		;ISOLATE CPU #
	MOVE	J,@DTEFEK##(T1)	;GET FEK ADDRESS

	SKIPGE	FEKBLK(J)	;IF WE THINK THE FEK IS DOWN,
	TLNE	P3,(LN.MOR)	;  OR IF THIS IS JUST THE HEADER OF A
	POPJ	P,		;  2 PART MESSAGE, DON'T CALL NETSER

IFN PARANOID&P$FEK,<
	SKIPGE	FEKBSO(J)	;MAKE SURE THAT WE ARE OUTPUT ACTIVE
	PUSHJ	P,NTDSTP##	;++ ERROR: OUTPUT DONE INTERRUPT BUT NOT ACTIVE
>
	HRRZ	U,FEKOAD(J)	;GET THE OUTPUT BUFFER
	NETOFF			;DON'T LET OTHER CPU HACK QUEUES
	HRRZM	U,FEKODN(J)	;GIVE THE "SENT" MESSAGE TO NETSER
	HRRZ	U,PCBBLK(U)	;GET THE "NEXT" OUTPUT BUFFER
	HRRZM	U,FEKOAD(J)	;MAKE THE NEXT THE NEW "FIRST"
	SOS	FEKOCT(J)	;COUNT DOWN ONE LESS BUFFER
	NETON			;QUEUE IS CONSISTANT
	SETOM	FEKBSO(J)	;CLEAR THE "OUTPUT BUSY" FLAG
	MOVEI	T1,FI.ODN	;GET THE "OUTPUT DONE" CODE
	PUSHJ	P,FEKINT##	;  AND TELL NETSER THAT BUFFER IS OUT
	PJRST	D8SWRT		;TRY TO SET UP ANOTHER WRITE REQUEST AND EXIT
;Here when D8SWRT has queued all the fragments of the ncl message it can so
;  it is now safe to see if the interrupt code (D8SRDD) wanted to send
;  an ack to request another message. It cannot do so between the time we
;  send the first and last fragments because the ack will look like a
;  message termination and the next data fragment will look like the start
;  of an NCL message.

SNDACK:	SKIPN	FEKAKC(J)	;SEE IF WE NEED TO SEND ANY ACK'S
	POPJ	P,		;  IF NO QPR-ACK'S TO SEND, RETURN
	SOS	FEKAKC(J)	;DECREMENT NUMBER OF QPR-ACK'S TO SEND
	MOVSI	S,CPOPJ##	;DON'T NEED TO KNOW IT'S SENT
	MOVE	P1,FEKUNI(J)	;GET "XWD CPU,DTE" TO SEND MESSAGE THROUGH
	DMOVE	P2,[XWD .EMNCL,.EMACK	;SEND AN ACK
		    EXP 2]		;AND 2 BYTES DATA
	SETZ	P4,		;SNEAKY WAY TO SEND 0 DATA
	S0PSHJ	DTEQUE##	;NO, JUST SEND THIS PIECE
	  PJRST	D8SCRS		;NEED BETTER CODE - CALL IT DEAD FOR NOW
	JRST	SNDACK		;SEE IF WE NEED TO SEND ANY MORE
				;TO DTESTR WHEN THE MESSAGE DOES ARRIVE
;D8SCRS	ROUTINE CALLED WHEN NETSER BELIEVES THAT THE FRONT END -11
;	IS SICK.  THIS ROUTINE PUTS THE -11 IN SECONDARY PROTOCOL.
;CALL	J := FEK POINTER
;RETURN	CPOPJ

D8SCRS:	MOVE	F,FEKUNI(J)	;GET "XWD CPU,DTE"
	TRNN	F,-1		;MAKE SURE WE'RE UP
	POPJ	P,		;IF DTE# NOT SET UP, WE'RE NOT UP
	PUSHJ	P,GTETDS##	;GET F := ETD POINTER
	PUSHJ	P,DTECLR##	;PUT THE DTE IN SECONDARY PROTOCOL
	PJSP	T1,DTERLD##	;NOW SET THE RELOAD BIT FOR DTELDR


;D8SCPS	ROUTINE CALLED WHEN THIS CPU IS GOING TO SLEEP.
;	CURRENTLY, THIS ROUTINE JUST TERMINATES PROTOCOL.  DOING THIS
;	CAUSES DTESER TO DECLARE THE FEK DOWN. SO WE END UP CALLING NETSER
;CALL	J := POINTER TO THE FEK
;RETURN	CPOPJ

D8SCPS:	MOVE	F,FEKUNI(J)	;GET "XWD CPU,DTE"
	TRNN	F,-1		;MAKE SURE WE'RE UP
	POPJ	P,		;IF DTE# NOT SET UP, WE'RE NOT UP
	PUSHJ	P,GTETDS##	;GET F := ETD POINTER
	PJRST	DTECLR##	;PUT THE DTE IN SECONDARY PROTOCOL

;D8SCPW	ROUTINE CALLED WHEN OUR CPU WAKES UP FROM SYSTEM SLEEP
;	CURRENTLY A NO-OP
;CALL	J := POINTER TO THE FEK
;RETURN	CPOPJ

D8SCPW:	POPJ	P,		;CURRENTLY SPRINI DOES ALL THE WORK
;ROUTINE CALLED WHEN DTESER DISCOVERS ANOTHER -11 IS UP. IF THAT
;  -11 HAS A FEK BLOCK, THEN IT IS A DN87S AND NETSER WILL
;  BE TOLD ABOUT IT.

D8SUP:	HLRZ	T1,P1		;ISOLATE CPU #
	SKIPN	J,@DTEFEK##(T1)	;DOES THIS -11 HAVE A FEK?
	POPJ	P,		;NOPE, DON'T WORRY ABOUT IT
	HRRM	P1,FEKUNI(J)	;REMEMBER WHICH DTE IS ASSOCIATED WITH FEK
	SETOM	FEKBSO(J)	;NO LONGER EXPECTING OUTPUT
	SETOM	FEKBSI(J)	;NO LONGER EXPECTING INPUT
	SETZM	FEKAKC(J)	;CLEAR THE "ACK INTERLOCK"
	MOVSI	T1,FK.ONL	;SET ONLINE FLAG FOR NETSER'S ONCE PER
	IORM	T1,FEKBLK(J)	;  SECOND CODE WHICH WILL START THINGS UP
	POPJ	P,		;RETURN TO DTESER


;ROUTINE CALLED FROM DTESER WHEN THE -11 ENTERS SECONDARY PROTOCOL
;  WHICH ONLY HAPPENS WHEN IT IS BEING RELOADED.


D8SDWN:	HLRZ	T1,P1		;ISOLATE CPU #
	SKIPN	J,@DTEFEK##(T1)	;DOES THIS -11 HAVE A FEK?
	POPJ	P,		;NOPE, NETSER WON'T BE INTERESTED
	PUSH	P,F		;SAVE ETD ADDRESS FROM DTESER
	MOVEI	T1,FI.DWN	;GET THE "FRONT END DIED" FUNCTION CODE
	PUSHJ	P,FEKINT##	;  AND TELL NETSER THE NEWS.
	PJRST	FPOPJ##		;RESTORE F BEFORE RETURNING TO DTESER
;TO-10 DISPATCH TABLE
	IFIW	CPOPJ##		;(-1) LOST TO-10 INDIRECT MESSAGE
NCLDSP::DTEFNC			;(??) GENERATE DUMMY TABLE ENTRIES
	DTEFNC	(STR,D8SSTR)	;(03) HERE IS STRING DATA
;ROUTINE TO HANDLE INCOMING STRING DATA MESSAGE. HERE WHEN HEADER
;  HAS ARRIVED.

D8SSTR:	HLRZ	T1,P1		;ISOLATE CPU #
	SKIPN	J,@DTEFEK##(T1)	;GET FEK ADDRESS FOR THIS DTE
	PJRST	EATMSG##	;IGNORE IF WE DON'T THINK IT IS A DN87S
	SKIPL	FEKBLK(J)	;DID I KNOW I WAS UP?
	PUSHJ	P,D8SFST	;FIRST MESSAGE, DO SETUP
	HRRZ	U,FEKIAD(J)	;GET THE PCB WE'RE SUPPOSED TO BE FILLING
	SKIPGE	FEKBSI(J)	;MAKE SURE WE'RE EXPECTING (BUSY INPUT)
	PJRST	EATMSG##	;NOT EXPECTING IT, DISCARD IT
	MOVE	P4,FEKIBP(J)	;TELL DTESER WHERE TO PUT MESSAGE
	HRRZ	T1,P3		;LENGTH OF NEXT SEGMENT
	ADDB	T1,PCBCTR(U)	;ACCUMULATE PROPOSED TOTAL LENGTH OF MESSAGE
	ADDI	T1,3		;ROUND UP BYTE COUNT AND
	LSH	T1,-2		;TRUNCATE TO TOTAL WORD LENGTH OF MESSAGE
	CAMLE	T1,PCBALN(U)	;WILL DTE'S MESSAGE STILL FIT?
	PJRST	D8SCRS		;NO, KROAK OFF THE -11
	HRRZ	T1,P3		;GET SIZE OF NEXT SEGMENT AGAIN
	ADJBP	T1,FEKIBP(J)	;READY POINTER FOR NEXT MESSAGE
	MOVEM	T1,FEKIBP(J)	;AND REMEMBER IT
	MOVSI	S,T10DON	;POST ADDRESS FOR WHEN DATA COMES IN
	POPJ	P,		;RETURN TO HAVE DTESER XFER INDIRECT PORTION
				;CONTINUE AFTER HERE WHEN DATA IS IN

T10DON:	HLRZ	T1,P1		;ISOLATE CPU #
	SKIPN	J,@DTEFEK##(T1)	;GET FEK ADDRESS AGAIN
	POPJ	P,		;I MET A MAN WHO WASN'T THERE...
	SKIPGE	FEKBLK(J)	;IF THIS FEK ISN'T UP, OR
	TLNE	P3,(LN.MOR)	;  THERE IS MORE TO COME,
	POPJ	P,		;  DON'T CALL NETSER

IFN PARANOID&P$FEK,<		;IF WE FEAR DTESER IS SCREWING US,
	SKIPGE	FEKBSI(J)	;MAKE SURE THAT WE EXPECT A MESSAGE
	STOPCD	.+1,DEBUG,UID,	;++ UNEXPECTED INPUT DONE
>
	SETOM	FEKBSI(J)	;CLEAR "INPUT BUSY"

	MOVEI	T1,FI.RDD	;FLAG FOR INPUT DONE
	PJRST	FEKINT##	;AND TELL NETSER WE HAVE A MESSAGE
;HERE TO INITIALIZE A D8S FEK WHEN RECEIVING A NODE-ID

D8SFST:	PUSHJ	P,SAVE4##	;PRESERVE SOME ACS
	PUSHJ	P,SAVT##	;AND SOME MORE
	MOVE	T1,[PUSHJ P,D8SDSP] ;PROPER FEKDSP INSTRUCTION
	CAMN	T1,FEKDSP(J)	;ARE WE REALLY OFF-LINE?
	POPJ	P,		;OOPS.  GET OUT BEFORE WE DO DAMAGE
	PUSH	P,F		;PRESERVE DTESER'S FAVORITE AC
	MOVEI	T2,DD.ANF	;LINE-USER TYPE FOR ANF10
	PUSHJ	P,DFKSET##	;CALL D8SUSR WITH ACS SETUP
	MOVEI	T1,FF.UP	;WE'RE UP NOW
	XCT	FEKDSP(J)	;DO THIS ONE, TOO
	POPJ	P,		;RETURN AFTER INITIALIZING
;HERE TO INITIALIZE A D8S FEK ON DTE. SET-LINE-USER
D8SUSR::MOVE	T4,DFKNAM##(T2)	;GET NAME OF TYPE
	MOVEM	T4,DLXNMT##(T1)	;SET IN BASE BLOCK
	MOVEI	T4,.C1D8S	;MY TYPE
	MOVEM	T4,DLXTYP##(T1)	;SET IN BLOCK
	SETZM	DLXCAL##(T1)	;USE DEFAULT CAL11. DISPATCH IN COMDEV
	PUSHJ	P,SAVE4##	;PRESERVE SOME ACS
	PUSHJ	P,SAVT##	;AND SOME MORE
	MOVE	T2,[PUSHJ P,D8SDSP] ;PROPER FEKDSP INSTRUCTION
	MOVEM	T2,FEKDSP(T3)	;SET IT
	PUSH	P,J		;PRESERVE J
	MOVE	J,T3		;USE PROPER AC FOR FEK ADDRESS
	MOVEI	T1,FF.ONC	;ONCE-ONLY CALL
	XCT	FEKDSP(J)	;DO IT
	JRST	JPOPJ##		;RESTORE AND RETURN TO DTESER


	XLIST
	$LIT
	LIST
	END