Google
 

Trailing-Edge - PDP-10 Archives - bb-x130a-sb - d85int.mac
There are 7 other files named d85int.mac in the archive. Click here to see a list.
TITLE D85INT - INTERRUPT SERVICE ROUTINE FOR THE DAS85  - V042
SUBTTL	DMCC/KR/JBS  18 APR 83
	SEARCH	F,S,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<
COPYRIGHT (C) 1975,1976,1977,1978,1979,1980,1982,1984 BY DIGITAL EQUIPMEMT  CORP., MAYNARD, MASS.
>
;
; DATE		LOAD	EDIT #
; ----		----	------
;
;28-OCT-80	70124	040
;12-APR-83	70135	041
;10698
;18-APR-83	70136	042
;10703
;
;
XP	VD85INT,042	;VERSION NUMBER

ENTRY	D85INT
D85INT::
                           Comment @

THE FORMAT OF A DL-10 BYTE POINTER IS:

	BYTE	3(P), 3(S), 8(C), 22(A)

WHERE
	P := THE POSITION OF THE BYTE IN THE WORD
	S := THE SIZE OF THE BYTE (SEE TABLE)
	C := THE WORD COUNT (PDP-10 WORDS) OF THE BLOCK OF BYTES THAT
	     IS BEING TRANSFERRED.  (IN NEGATIVE FORM.  OVERFLOW OCCURS
	     WHEN YOU TRY TO IMCREMENT "377")
	A := THE 22 BIT PHYSICAL ADDRESS OF THE WORD CONTAINING THE
	     NEXT BYTE.

TABLE OF LEGAL VALUES FOR THE "S" FIELD

  S	MODE	    BITS/BYTE	FUNCTION

  0	IMMEDIATE	16	THE BYTE IS IN THE RIGHT MOST 16 BITS
				OF THE "A" FIELD OF THE BYTE POINTER ITSELF.
  1	NOT IMM		16	THE BYTE IS IN THE LOCATION SPECIFIED BY
				"A" AT POSITION "P"
  2	NOT IMM, INCR	16	ANALOGOUS TO THE ILDB INSTRUCTION.
  3	NOT IMM, INCR	12		SAME
  4	NOT IMM, INCR	 8		SAME
  5	NOT IMM, INCR	 7		SAME
  6	NOT IMM, INCR	 6		SAME
  7	IMMEDIATE	16	SAME AS "S" = 0.

THE "P" FIELD IS THE POSITION OF THE BYTE IN THE PDP-10 WORD.  SINCE THE
DL-10 PERFORMS THE "ILDB" FUNCTION A "P" FIELD OF ZERO WILL GIVE THE SECOND
BYTE OF THE WORD WHEN USED IN AN INCREMENTING BYTE POINTER.  IN ORDER TO GET
THE FIRST BYTE OF THE WORD ONE SHOULD SPECIFY A "P" FIELD OF "7".  THIS
FIELD WHEN INCREMENTED DOES NOT ADVANCE THE WORD-COUNT OR THE ADDRESS.

                        End of Comment @



;BYTE POINTERS TO THE FIELDS OF A DL-10 BYTE POINTER

	DEFINE	%DLBPP (AC),<POINT 3,AC,2>	;POINT TO THE "P" FIELD
	DEFINE	%DLBPS (AC),<POINT 3,AC,5>	;POINT TO THE "S" FIELD
	DEFINE	%DLBPC (AC),<POINT 8,AC,13>	;POINT TO THE "C" FIELD
	DEFINE	%DLBPA (AC),<POINT 22,AC,35>	;POINT TO THE "A" FIELD

;D85DSP	ROUTINE CALLED BY NETSER THAT DISPATCHES TO THE PROPER FEK FUNCTION
;CALL	T1 := FUNCTION CODE
;	J := FEK ADDRESS
;RETURN	CPOPJ

D85DSP::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 APPRIOATE ROUTINE
	JRST	NTFONC##		;ONCE ONLY CODE
	JRST	NTFSEC##	;ONCE/SECOND CODE -- USE NETSER'S DEFAULT
	JRST	D85RDD		;SET UP A READ REQUEST
	JRST	D85WRT		;SET UP A WRITE REQUEST
	JRST	D85CRS		;CRASH THE FEK (CPU WENT DOWN?)
	JRST	CPOPJ##		;NOT USED FOR D85'S
	JRST	CPOPJ##		;NOT USED EITHER
	JRST	CPOPJ##		;WE DON'T HANDLE STATION CONTROL
	JRST	D85CPS		;GET READY TO GO TO SLEEP
	JRST	D85CPW		;CPU JUST WOKE UP.


;D85RDD	THIS ROUTINE IS CALLED TO START A READ FROM THE DL-10.
D85RDD:
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 INTERRLOCK (WE GET HERE FROM
				;  BOTH UUO AND INTERRUPT LEVEL)
	POPJ	P,		;IF ALREADY DOING INPUT, EXIT

	JSP	T3,SETUP	;SET UP W, S
	HRRZ	U,FEKIAD(J)	;GET A POINTER TO THE PCB TO FILL
IFN FTKL10,<			;ONLY WORRY ABOUT CACHE ON A KL-10
	PUSHJ	P,PCBCHK##	;MAKE SURE DATA IS ACCESSABLE. SWEEP CACHE
				;  IF NECESSARY
>
	MOVE	T1,PCBIAD(U)	;GET THE PDP-10 BYTE POINTER
	HRRZ	T2,PCBICT(U)	;GET THE PDP-10 BYTE COUNT
	PUSHJ	P,DLBP		;GO BUILD A DL-10 BYTE POINTER
	MOVEM	T1,DLXID1##(W)	;STORE THE DL-10 BYTE POINTER
	HRRZM	T2,DLXIC1##(W)	;STORE THE DL-10 BYTE COUNT
	SETZM	DLXIC2##(W)	;INDICATE THAT ONLY ONE BYTE POINTER.
	MOVEI	T1,1		;GET THE FLAG AND
	MOVEM	T1,DLXIFL##(W)	;TELL THE -11 TO START.
	MOVSI	T1,FK.IAC	;GET THE "INPUT ACTIVE" BIT
IFN PARANOID&P$FEK,<
	TDNE	T1,FEKBLK(J)	;MAKE SURE WE AREN'T ALREADY READING
	PUSHJ	P,NTDSTP##	;++ ERROR: READ ALREADY IN PROGRESS
>
	IORM	T1,FEKBLK(J)	;SET INPUT ACTIVE FOR D85KII TO SEE
	JRST	EXIT		;GO TO COMMON EXIT TO CLEAR THE STACK
				;  AND INTERRUPT THE -11


;D85WRT	HERE TO START AN OUTPUT TRANSFER

D85WRT:
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
	SKIPG	FEKOCT(J)	;MAKE SURE WE HAVE SOMETHING TO OUTPUT
	JRST	[SETOM FEKBSO(J);IF NO OUTPUT MSGS, SET OUTPUT IDLE
		 POPJ P,]	;  AND RETURN

	JSP	T3,SETUP	;SET UP W & S

	HRRZ	U,FEKOAD(J)	;GET A POINTER TO THE PCB TO SEND
IFN FTKL10,<
	PUSHJ	P,PCBCHK##	;MAKE SURE IT'S OUT OF CACHE. SWEEP IF NOT
>
	MOVE	T1,PCBOAD(U)	;GET THE PDP-10 BYTE POINTER
	HRRZ	T2,PCBOCT(U)	;GET THE PDP-10 BYTE COUNT
	PUSHJ	P,DLBP		;BUILD THE DL-10 BYTE POINTER
	MOVEM	T1,DLXOD1##(W)	;SAVE THE CONTROL DL-10 BYTE POINTER
	HRRZM	T2,DLXOC1##(W)	; SAVE THE HEADER BYTE COUNT

	MOVE	T1,PCBOA1(U)	;GET THE FIRST USER BYTE POINTER
	HRRZ	T2,PCBOC1(U)	;GET THE BYTE COUNT OF THE FIRST SEGMENT
	SKIPE	T2		;DON'T MAKE A BYTE POINTER IF CNT IS ZERO
	PUSHJ	P,DLBP		;MAKE A DATA BYTE POINTER FOR THE DL-10
	MOVEM	T1,DLXOD2##(W)	;STORE THE OUTPUT BYTE POINTER
	HRRZM	T2,DLXOC2##(W)	;STORE THE OUTPUT BYTE COUNT

	SETZM	DLXOC3##(W)	;WE NEVER USE THE THIRD BYTE POINTER.

	LDB	T1,PCBPCV##	;GET THE CONVERSION CODE
	ADDI	T1,1(T1)	;SHIFT OVER AND TURN ON MSG AVAILABLE FLAG
	MOVEM	T1,DLXOFL##(W)	;TELL THE -11 THAT HE CAN START READING.
	MOVSI	T1,FK.OAC	;GET THE "OUTPUT ACTIVE" BIT
IFN PARANOID&P$FEK,<
	TDNE	T1,FEKBLK(J)	;MAKE SURE IT ISN'T SET
	PUSHJ	P,NTDSTP##	;++ ERROR: OUTPUT IN PROGRESS
>
	IORM	T1,FEKBLK(J)	;TELL D85KII THAT INTERRUPT MAY BE OUTPUT DONE
	JRST	EXIT		;CLEAN UP THE STACK AND INTERRUPT THE -11



;SETSTO & SETSTI -- ROUTINES TO SET THE REQUEST BITS SO NETSER WILL
;  CALL US ON THE PROPER CPU

SETSTO:	MOVSI	T1,FK.STO	;GET THE START OUTPUT BIT
	CAIA
SETSTI:	MOVSI	T1,FK.STI	;GET THE START INPUT BIT
	IORM	T1,FEKBLK(J)	;SET THE BIT
	POPJ	P,		;  AND WAIT FOR NETSER TO CALL
;DLBP	MAKE A DL-10 BYTE POINTER FOR DATA.
;CALL	MOVE	T1,EXEC VIRTUAL ADDRESS OF DATA
;	MOVE	T2,NUMBER OF BYTES
;	PUSHJ	P,DLBP
;RETURN	CPOPJ			;ALWAYS
;	T1 CONTAINS A DL-10 BYTE POINTER
;	T2 CONTAINS THE NUMBER OF BYTES.

DLBP:	LDB	T3,[POINT 6,T1,11] ;GET THE SIZE FROM THE PDP-10 POINTER
	CAIN	T3,^D16		;IS IT A 16 BIT BYTE?
	JRST	[MOVEI T4,2	;THEN 2 BYTES/WORD
		 JRST DLBP1]	; AND GO PROCESS IT
	CAIN	T3,^D12		;IS IT A 12 BIT BYTE?
	JRST	[MOVEI T4,3	;THEN 3 BYTES/WORD
		 JRST DLBP1]	; AND GO PROCESS IT
	MOVEI	T4,^D12		;THEN ASSUME IT IS OF SIZE 8, 7, OR 6.
	SUBI	T4,(T3)		;TRANSLATE IT INTO A DL-10 BYTE SIZE.
	CAIL	T4,4		; AND IF THE RESULT IS NOT LEAGAL. (IE
	CAILE	T4,6		; NOT 4, 5, OR 6) GO GIVE AN ERROR
	STOPCD	.,STOP,BBS,	;++ BAD BYTE SIZE
DLBP1:
	MAP	T3,(T1)		;CONVERT THE BYTE-POINTER ADDR TO PHYSICAL ADDR
IFN FTKI10,<			;THE MAP INSTRUCTION IS SCREWEY ON THE KI, SO
	LSH	T3,11		; WE MUST FIXUP THE LOW 9 BITS OF THE ADDRESS
	DPB	T1,[POINT 9,T3,35] ; FROM THE ORIGIONAL ADDRESS
>
	DPB	T3,[%DLBPA T1]	;STORE BACK THE PHYSICAL ADDRESS.
	DPB	T4,[%DLBPS T1]	;STORE THE SIZE
	MOVEI	T3,(T2)		;COPY THE BYTE COUNT.
	IDIVI	T3,(T4)		;DIVIDE TO GET THE NUMBER OF WORDS
	SKIPE	T4		;IF IT WASN'T AN EVEN MULTIPLE, THEN
	AOS	T3		; ALLOW FOR THE EXTRA WORD.
	MOVNS	T3		;MAKE THE WORD COUNT NEGATIVE FOR THE DL-10
	DPB	T3,[%DLBPC T1]	;STORE THE WORD COUNT
	SETO	T3,		;GET A 7 FOR THE POSITION FIELD
	DPB	T3,[%DLBPP T1]	;STORE THE POSITION FIELD
	POPJ	P,		;T1 := DL-10 BYTE POINTER; T2 := BYTE COUNT.
;D85CRS	ROUTINE TO CLEAR THE DL-10 PORT ENABLE.
;	CALLED BY NETSER WHEN IT BELIEVES THE -11 IS SICK
;CALL	J := FEK ADDRESS
;RETURN	CPOPJ

D85CRS:	PUSHJ	P,SAVE3##	;WE SET UP THE P'S FOR REMPRG
	HRRZ	P2,FEKUNI(J)	;GET THE DL-10 BASE TABLE ADDRESS
	JUMPE	P2,CPOPJ##	;RETURN IF WE DON'T HAVE A WINDOW
	HRRZ	P3,DLXWIN##(P2)	;GET THE WINDOW ADDRESS
	SETZM	DLXDWN##(P3)	;TELL THE -11 WE THINK HE'S CRASHED
	XCT	DLXCLR##(P2)	;CLEAR PORT ENABLE
	XCT	DLXPRG##(P2)	;CALL REMPRG TO CALL NETSER...
	MOVSI	T1,(JFCL)	;GET A JFCL INSTRUCTION
	MOVEM	T1,DLXINI##(P2)	;  AND PUT IT IN AS THE INTERRUPT INSTR
	MOVEM	T1,DLXPRG##(P2)	;  AND THE "CRASH" INSTRUCTION
	POPJ	P,		;THE -11 CAN NO LONGER POKE -10 MEMORY.


;D85CPS	ROUTINE CALLED WHEN THIS CPU IS ABOUT TO GO TO SLEEP
;	SHUTS DOWN THE FEK AND LETS NETSER KNOW IT'S DOWN
;CALL	J := POINTER T O THE FEK
;RETURN	CPOPJ

D85CPS:	JRST	D85CRS		;JUST "CRASHING" THE FEK SHOULD BE ENOUGH


;D85CPW	ROUTINE CALLED WHEN THIS CPU IS WAKING UP AFTER A SLEEP
;	I DON'T THINK IT NEEDS TO DO ANYTHING...
;CALL	J := POINTER T O THE FEK
;RETURN	CPOPJ

D85CPW:	POPJ	P,
;UTILITY ROUTINES FOR D85RDD AND D85WRT

;SETUP	ROUTINE TO SAVE AND SETUP REGISTERS U, S, & W
;CALL	JSP	T3,SETUP

SETUP:	PUSH	P,S		;SAVE THE FLAGS
	PUSH	P,U		;PRESERVE U
	PUSH	P,W		;PRESERVE W
	HLLZ	S,FEKBLK(J)	;SET UP THE FLAGS
	HRRZ	W,FEKUNI(J)	;GET ADDRESS OF DL-10 BASE TABLE
	SKIPN	W		;MAKE SURE THAT THE WINDOW IS SET UP
	STOPCD	CPOPJ##,DEBUG,WNS, ;++ WINDOW WAS NOT SETUP?
	HRRZ	W,DLXWIN(W)	;  AND FROM THAT, GET ADDRESS OF WINDOW
	JRST	(T3)		;RETURN TO CALLER



EXIT:	HRRZ	W,FEKUNI(J)	;GET THE ADDRESS OF THE DL-10 BASE TABLE
	XCT	DLXI11##(W)	;  IT CONTAINS INSTRUCTION TO INTERRUPT THE 11
	POP	P,W		;RESTORE W
	POP	P,U		;RESTORE U
	POP	P,S		;RESTORE THE FLAGS
	POPJ	P,
;DC75 WINDOW OFFSETS.  THESE ARE COPIED FROM THE DC75 CODE.
;  THE FIRST FEW WORDS CORRESPOND TO THE DC76 WINDOW.

D75WIN:	PHASE	0
	BLOCK	3		;INTERRUPT INSTR AND TWO UNUSED WDS
	BLOCK	1		;POINTER TO NAME "DC75"
	BLOCK	1		;PDP-11 PORT NUMBER
	BLOCK	1		;11-ALIVE.  INC BY 10 ONCE A SEC.
	BLOCK	1		;STOP CODE VALUE
	BLOCK	1		;"DOWN" INDICATOR
	BLOCK	1		;UP TIME

;THE FOLLOWING ITEMS ARE SPECIFIC TO THE DC75

DLSWRD:!BLOCK	1		;GLOBAL STATUS WORD
	DLS.DP==1		;DEPOSIT 11 CORE
	DLS.EX==2		;EXAMINE 11 CORE
	DLS.ER==4		;ILLEGAL ADDRESS
DLADR:! BLOCK	1		;ADDRESS TO EXAMINE 11 CORE
DLDTA:! BLOCK	1		;CONTENTS OF DLADR
DLREC:!	BLOCK	1		;MAXIMUM RECORD LENGTH
DLMOD:!	BLOCK	1		;VERSION OF 85 SOFTWARE
DL10A:! BLOCK	1		;10-ALIVE INDICATOR
DL10S:! BLOCK	1		;INITIALIZATION STATUS OF 10
DL11S:! BLOCK	1		;INITIALIZATION STATUS OF 11
DLIFL:!	BLOCK	1		;INPUT FLAGS
DLIC1:!	BLOCK	1		;INPUT COUNT 1
DLID1:!	BLOCK	1		;INPUT POINTER 1
DLIC2:!	BLOCK	1		;INPUT COUNT 2
DLID2:!	BLOCK	1		;INPUT POINTER 2
DLOFL:!	BLOCK	1		;OUTPUT FLAGS
DLOC1:!	BLOCK	1		;OUTPUT COUNT 1 (HEADER)
DLOD1:!	BLOCK	1		;OUTPUT POINTER 1 (HEADER)
DLOC2:!	BLOCK	1		;OUTPUT COUNT 2 (DATA 1)
DLOD2:!	BLOCK	1		;OUTPUT POINTER 2 (DATA 1)
DLOC3:!	BLOCK	1		;OUTPUT COUNT 3 (DATA 2)
DLOD3:!	BLOCK	1		;OUTPUT POINTER 3 (DATA 2)
	BLOCK	200-.		;THE UNUSED PART OF THE WINDOW

	DEPHASE
	RELOC	D75WIN		;SAVE SPACE
SUBTTL	PDP-11 INTERFACE
;COME HERE WHEN A PDP11 IS FIRST RECOGNIZED AS BEING A DC75 PDP11

D75III::MOVE	J,DLXWIN##(W)	;POINT TO WINDOW
	MOVE	T1,DLMOD(J)	;PICK UP MOD NUMBER
	CAIE	T1,1		;RIGHT?
	STOPCD	CPOPJ##,DEBUG,5WE,	;++DC75 WRONG PDP11 CODE
	SETOM	DL10A(J)	;MARK 10 AS ALIVE
	SETZM	DLADR(J)	;CLEAR EXAMINE ADDRESS
	SETZM	DLDTA(J)	;AND EXAMINE DATA
	SETZM	DLIFL(J)
	HRLI	T1,DLIFL(J)
	HRRI	T1,DLIFL+1(J)
	BLT	T1,DLOD3(J)
	MOVE	T1,[PUSHJ P,D75KII]
	MOVEM	T1,DLXINI##(W)	;INTERRUPT INSTRUCTION
	MOVE	T1,[XWD MC11FN,C11FTB]
	MOVEM	T1,DLXCAL##(W)	;CAL11. POINTER
	MOVE	T1,[PUSHJ P,REMPRG]
	MOVEM	T1,DLXPRG##(W)	;PURGE INSTRUCTION
	SETOM	DL10S(J)	;MARK 10 AS RUNNING
	HRRZ	J,DLXFEK##(W)	;GET THE ADDRESS OF THE FEK
	SETOM	FEKBSO(J)	;CLEAR OUTPUT ACTIVE
	SETOM	FEKBSI(J)	;  AS WELL AS INPUT ACTIVE
	MOVSI	T1,FK.ONL	;GET THE ONLINE BIT
	IORM	T1,FEKBLK(J)	;  AND SET IT  (CLOCK LEVEL WILL NOTICE)
	HRRM	W,FEKUNI(J)	;STORE ADDRESS OF DL-10 BASE TABLE
	POPJ	P,		;DONE WITH INITIALIZATION
;HERE WHEN DL10 INTERRUPTS
D75KII::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	HRRZ	J,DLXFEK##(W)	;GET FEK ADDRESS
	MOVE	P1,DLXWIN##(W)	;WINDOW ADDRESS
	MOVE	P2,DLXOFL##(P1)	;ONLY TO CHECK OUTPUT ARRIVING
				;  BEFORE INPUT DONE
	MOVE	T1,FEKBLK(J)	;GET THE FEK'S "FLAGS"
	TLNE	T1,FK.IAC	;  AND SEE IF EXPECTING INPUT DONE
	SKIPE	DLXIFL##(P1)	;MAKE SURE FLAG SAY'S -11'S DONE
	JRST	CHKOUT		;NOT EXPECTED OR NOT REAL
	HRRZ	U,FEKIAD(J)	;PCB ADDRESS
	MOVE	T1,DLXIC1##(P1)	;COUNT OF INPUT BYTES
	HRRM	T1,PCBICT(U)	;STORE IN PCBICT
IFN PARANOID&P$FEK,<
	SKIPGE	FEKBSI(J)	;MAKE SURE WE "AOSED" THE LOCK TO GET HERE
	PUSHJ	P,NTDSTP##	;++ ERROR: INPUT MYSTERIOUSLY BUSY
>
	MOVSI	T1,FK.IAC	;GET INPUT ACTIVE AND
	ANDCAM	T1,FEKBLK(J)	;  CLEAR IT SO WE DON'T CALL NETSER AGAIN
	SETOM	FEKBSI(J)	;CLEAR BUSY  (RACE FREE. WERE AT PI LEVEL)
IFN FTKL10,<
	PUSHJ	P,CSDMP##	;CLEAR ANY "VALID" BITS SET BY SOMEONE
>				;  "PEEKING" AT THE BUFFER BEING FILLED
	MOVEI	T1,FI.RDD	;GET INPUT DONE FUNCTION CODE
	PUSHJ	P,FEKINT##

CHKOUT:	MOVE	T1,FEKBLK(J)	;GET THE "FLAGS"
	TLNE	T1,FK.OAC	;  AND SEE IF WE'RE WAITING FOR OUTPUT DONE
	SKIPE	P2		;SKIP IF -11 CLEARED "BUSY" FLAG
	POPJ	P,		;NOT EXPECTED OR NO OUTPUT
	MOVE	U,FEKOAD(J)	;PCB ADDRESS
	NETOFF			;CAREFUL WHEN MESSING WITH QUEUES
	HRRZM	U,FEKODN(J)	;POST THIS PCB AS FILLED
	HRRZ	U,PCBBLK(U)	;GET THE "NEXT" ONE TO BE FILLED
	HRRZM	U,FEKOAD(J)	;  AND MAKE IT THE FIRST
	SOS	FEKOCT(J)	;COUNT OFF ONE LESS INPUT PCB
	NETON			;CONSISTANT AGAIN
	MOVEI	T1,FI.ODN	;GET INPUT DONE FUNCTION CODE
	PUSHJ	P,FEKINT##
IFN PARANOID&P$FEK,<
	SKIPGE	FEKBSO(J)	;MAKE SURE WE ENTERED WITH THE "AOSE"
	PUSHJ	P,NTDSTP##	;++ ERROR:  OUTPUT MYSTERIOUSLY ACTIVE
>
	MOVSI	T1,FK.OAC	;GET THE OUTPUT ACTIVE BIT
	ANDCAM	T1,FEKBLK(J)	;  AND CLEAR IT TO SAY WE CAN SEND ANOTHER
	SETOM	FEKBSO(J)	;SAY WE'RE NO LONGER OUTPUT BUSY
	JRST	D85WRT		;SEE IF ANOTHER WRITE REQUEST TO PROCESS
;HERE WHEN A DC75 GOES DOWN
REMPRG::PUSH	P,J
	HRRZ	J,DLXFEK##(P2)
	MOVEI	T1,FI.DWN
	PUSHJ	P,FEKINT##
	HRRM	P2,FEKUNI(J)
	PJRST	JPOPJ##

D85PRE::PUSH	P,J
	MOVE	J,(P2)		;START OF WINDOW
	SETZM	DLXSWD##(J)
	HRLI	T1,DLXSWD##(J)
	HRRI	T1,DLXSWD##+1(J)
	BLT	T1,DLXOD3##(J)
	SETZM	DLXNMT##(P2)	;CLEAR NAME
	PJRST	JPOPJ##
;COME HERE ON CAL11. UUO FROM COMDEV.

;CALLING SEQUENCE IS:
;	MOVE	AC,[XWD LENGTH,BLOCK]
;	CAL11.	AC,
;	  ERROR RETURN
;	OK RETURN

;BLOCK:	EXP	FUNCTION CODE
;	ARGUMENT (1) ...
;

;ENTER FROM COMDEV WITH WINDOW POINTER IN P1,
;  DL10 BASE IN W, LENGTH OF BLOCK IN T3.

;COMDEV DOES THE DISPATCH BASED ON THE FOLLOWING TABLE.  THE
;  HIGH ORDER BIT, IF SET, INDICATES THAT THE USER MUST HAVE
;  THE "POKE" PRIV.


C11FTB:	XWD	400000,DEP11	;(0) DEPOSIT TO -11
	XWD	400000,EXAM11	;(1) EXAMINE THE -11
	XWD	400000,ECOD2##	;(2) ERROR (IN DC76: QUE11)
	XWD	0,NAME11	;(3) RETURN NAME OF PGM IN 11
	XWD	0,DOWN11	;(4) IS PORT UP OR DOWN?
	XWD	400000,SND11	;(5) SEND MESSAGE
	XWD	400000,RCV11	;(6) RECEIVE MESSAGE
	XWD	0,TYP11		;(7) NODE & TYPE
MC11FN==.-C11FTB		;LENGTH OF TABLE

SND11==:CPOPJ##
RCV11==:CPOPJ##
;COME HERE FOR EXAMINE AND DEPOSIT FUNCTIONS

DEP11:	PUSHJ	P,EXDP11	;GET ADDR TO DEPOSIT INTO
	  JRST	ECOD4##
	SOJL	T3,ECOD7##	;GET DATA TO DEPOSIT
	PUSH	P,W		;SAVE DL10 BASE
	PUSHJ	P,GETWD1##	;GET THE DATA
	POP	P,W
	MOVEM	T1,DLDTA(T2)	;SAVE DATA
	MOVEI	T1,DLS.DP	;FLAG TO DEPOSIT WORD
	HRRZM	T1,DLSWRD(T2)
	XCT	DLXI11##(W)	;WAKE THE 11
	MOVEI	T1,^D2000
	MOVE	T3,DLSWRD(T2)	;GET STATUS
	TRNE	T3,DLS.DP	;TEST IF DEPOSIT OFF
	  SOJGE	T1,.-2		;KEEP GOING
	TRNE	T3,DLS.ER	;CHECK BAD ADDRESS
	  JRST	ERRADR		;YES, ERROR CODE 2
	SKIPE	T1,DLSWRD(T2)	;DID 11 RESPOND ?
	  JRST	ECOD5##		;FATAL ERROR
	JRST	STOTC1##	;AND GIVE SUCCESS RETURN.

EXAM11:	PUSHJ	P,EXDP11	;GET ADDR TO EXAMINE/DEPOSIT
	  JRST	ECOD4##
	MOVEI	T1,DLS.EX	;FLAG TO EXAMINE
	HRRZM	T1,DLSWRD(T2)
	XCT	DLXI11##(W)	;WAKE THE 11
	MOVEI	T1,^D2000
	MOVE	T3,DLSWRD(T2)	;GET STATUS
	TRNE	T3,DLS.EX	;TEST FOR EXAMINE BIT OFF
	  SOJGE	T1,.-2		;LOOP TILL DONE OR COUNT GOES
	TRNE	T3,DLS.ER	;BAD ADDRESS?
	  JRST	ERRADR		;YES, ERROR 2
	SKIPE	DLSWRD(T2)	;DID 11 RESPOND ?
	  JRST	ECOD5##		;FATAL ERROR
	MOVE	T1,DLDTA(T2)	;YES, FETCH DATA AT THAT ADDRESS
	JRST	STOTC1##	;AND GIVE SUCCESS RETURN.

ERRADR:	SETZM	DLSWRD(T2)	;CLEAR ERROR BIT
	JRST	ECOD2##		;SET ERROR CODE 2

EXDP11:	MOVE	J,.CPJOB##	;GET JOB NUMBER OF CALLER
	MOVE	T2,DLXWIN##(W)	;POINT TO WINDOW
	SKIPE	DLSWRD(T2)	;IS WINDOW FREE ?
	  POPJ	P,
	SOJL	T3,ECOD7##	;NEED ADDRESS
	PUSH	P,W		;SAVE DL10 BASE
	PUSHJ	P,GETWD1##	;GET THE ADDRESS
	POP	P,W		;RESTORE DL10 BASE
	ANDI	T1,177777	;SIXTEEN BITS ONLY
	MOVEM	T1,DLADR(T2)	;STORE ADDRESS
	JRST	CPOPJ1##
;COME HERE TO RETURN THE NAME OF THE PDP-11 PROGRAM.

NAME11:	MOVE	T1,DLXNMT##(W)	;PICK UP NAME
	JRST	STOTC1##	;SKIP RETURN, GIVING  NAME

;COME HERE TO TELL THE STATUS OF THE PDP-11 PROGRAM.

DOWN11:	SKIPG	T1,DLXDWN##(P1)	;GET STATUS
	TDZA	T1,T1		;PDP-11 IS DOWN
	MOVEI	T1,1		;UP.
	JRST	STOTC1##	;SKIP RETURN.

;HERE TO REPORT NODE & TYPE

TYP11:	MOVE	T1,DLXFEK##(W)	;POINT TOFEK
	HRLZ	T1,FEKNNM(T1)	;GET NODE NUMBER
	HRR	T1,DLXTYP##(W)	;GET TYOE OF FRONT END
	PJRST	STOTC1##	;RETURN
	$LIT
D85END::END