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