1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-01 17:26:38 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

335 lines
13 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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