Google
 

Trailing-Edge - PDP-10 Archives - BB-X140B-BB_1986 - 10,7/703mon/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 - V030
SUBTTL	ERIC WERME/EJW/JBS/EGF  10 SEP 85
	SEARCH	F,S,DTEPRM,NETPRM
	$RELOC
	$HIGH


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


;
;

XP	VD8SINT,030		;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	NTFSEC##	;USE NETSER'S DEFAULT SECOND CODE
	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.


;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
	CPOPJ##			;(-1) LOST TO -10 IN DIRECT MESSAGE
NCLDSP::EATMSG##		;(0)
	EATMSG##		;
	EATMSG##		;
	D8SSTR			;(3) HERE IS STRING DATA
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;(10)
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;(20)
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;
	EATMSG##		;(26)
	EATMSG##		;(27)
	EATMSG##		;(30)
	EATMSG##		;(31)
	EATMSG##		;(32)
;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
	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

	XLIST
	$LIT
	LIST
	END