Google
 

Trailing-Edge - PDP-10 Archives - de-10-omona-v-mc9 - 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  - V020
SUBTTL	DMCC/KR  05 APR 77
	SEARCH F,S
	$RELOC
	$HIGH

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1975,1976,1977,1978 BY DIGITAL EQUIPMEMT  CORP., MAYNARD, MASS.
XP	VD85INT,020	;VERSION NUMBER

ENTRY	D85INT
D85INT:
;HERE ONCE A SECOND FROM NETSER

D85SEC==:CPOPJ##
D85ONC==:CPOPJ##
D85RDD::			;handle a read request from NETSER
	PUSHJ	P,SAVE4##	;save P1-P4
	PUSH	P,U		;SAVE U
	MOVE	U,FEKIAD##(J)	;point to PCB
	MOVEI	P4,D85IN	;point to proper routine
	JRST	D85CON		;continue
D85WRT::			;write request from NETSER
	PUSHJ	P,SAVE4##	;save P1-P4
	PUSH	P,U		;SAVE U
	MOVE	U,FEKOAD##(J)	;pick up PCB
	MOVEI	P4,D85OUT	;point to proper routine
D85CON:				;common code for read and write
	PUSH	P,W		;SAVE REGISTER FOR WINDOW
	MOVE	W,@FEKUNI##(J)	;POINT TO WINDOW
	PUSH	P,F		;SAVE PCB REGISTER
	MOVE	F,U		;POINT TO PCB
IFN FTKL10,<
	PUSHJ	P,CSDMP##	;MAKE SURE THE DATA IS IN CORE
>
	PUSHJ	P,(P4)		;BUILD WINDOW ENTRY
	POP	P,F		;RESTORE F
	POP	P,W		;RESTORE W
	MOVE	P1,FEKUNI##(J)	;dLBAS table
	XCT	DLXI11##(P1)	;interrupt PDP-11
	PJRST	UPOPJ##

D85IN:				;input request
	SETZM	DLXIC1##(W)
	SETZM	DLXIC2##(W)
	HRRZ	P1,PCBICT##(F)	;byte count from PCB
	MOVE	P2,PCBIAD##(F)	;GET BYTE POINTER
	PUSHJ	P,BP		;CONVERT TO DL10 BYTE POINTER
	MOVEM	P3,DLXID1##(W)	;STORE POINTER
	MOVEM	P4,DLXIC1##(W)	;STORE COUNT
	MOVEI	P3,1		;TO TELL -11 IT MAY SEND
	MOVSI	T1,400000	;TO REMIND US WE'RE EXPECTING INPUT
	CONO	PI,PIOFF##	;AVOID RACE
	MOVEM	P3,DLXIFL##(W)	;LET -11 SEND MESSAGE
	IORM	T1,FEKUNI##(J)	;LET INTERRUPT GIVE IT TO FEKINT
	PJRST	ONPOPJ##	;DONE
D85OUT:
	SETZM	DLXOC1##(W)
	SETZM	DLXOC2##(W)
	SETZM	DLXOC3##(W)
	HRRZ	P1,PCBOCT##(F)
	MOVE	P2,PCBOAD##(F)
	PUSHJ	P,BP
	MOVEM	P3,DLXOD1##(W)
	MOVEM	P4,DLXOC1##(W)
	HRRZ	P1,PCBOC2##(F)
	MOVE	P2,PCBOA2##(F)		;GET ADDRESS FOR USER POINTER
	SKIPN	P1
	  JRST	RETURN			;NO USER PORTION FOR MESSAGE
	PUSHJ	P,BP
	LDB	T1,[POINT 9,P3,35]	;GET ADR ON PAGE OF DATA
	LDB	T2,[POINT 8,P3,13]	;GET WORD COUNT FROM POINTER
	SUBI	T1,400(T2)		;MAKES # OF WORDS ON OTHER PAGE
	JUMPLE	T1,D85OU7		;IF NONE WE ARE DONE
	ADD	T2,T1			;MAKES NUMBER OF WORDS IN FIRST POINTER
	DPB	T2,[POINT 8,P3,13]	;PUT INTO DL10 POINTER
	MOVNI	T2,-400(T2)		;MAKE POSITIVE WORD COUNT
	LDB	T3,[POINT 3,P3,5]	;GET S FROM DL10 POINTER
	IMULI	T2,(T3)			;MAKES NUMBER OF BYTES IN 1ST POINTER
	SUBI	P4,(T2)			;MAKES NUMBER OF BYTES IN 2ND POINTER
	EXCH	T2,P4			;PUT IN RIGHT LOCATION
	MOVNS	T1			;MAKE WORD COUNT RIGHT FORMAT
	DPB	T1,[POINT 8,P1,13]	;PUT COUNT INTO DL10 POINTER
	MOVEM	P1,DLXOD3##(W)
	MOVEM	T2,DLXOC3##(W)
D85OU7:	MOVEM	P3,DLXOD2##(W)
	HRRZM	P4,DLXOC2##(W)
RETURN:	LDB	T1,PCBPCV##	;GET CONVERSION CODE
	ADDI	T1,1(T1)	;SHIFT OVER 1 AND TURN ON MESSAGE AVAILABLE FLAG
	MOVSI	T2,200000	;GET OUTPUT WAIT BIT
	CONO	PI,PIOFF##
	MOVEM	T1,DLXOFL##(W)	;SET FLAGS SO 11 WILL READ OUTPUT
	IORM	T2,FEKUNI##(J)	;SET EXPECTING OUTPUT INTERRUPT BIT
	PJRST	ONPOPJ##
BP:
;	P1=BYTE COUNT REMAINING
;	P2=BYTE POINTER
;	P3=DL10 BYTE POINTER RETURNED
;	P4=DL10 BYTE COUNT
;	
;	ALL REGISTERS ARE MODIFIED, SO THAT SUCCESSIVE
; CALLS WILL RETURN SUCCESSIVE DL10 BYTE POINTERS TO
; TRANSFER THE WHOLE MESSAGE (CALLER KNOWS THAT HE
; IS THROUGH WHEN BYTE COUNT IS 0).
;
;	USES T1-T4 WITHOUT RESTORATION, AND EXPECTS P
; TO POINT TO THE STACK.
	PUSH	P,W
	PUSH	P,F
	LDB	T1,[POINT 6,P2,11]	;GET BYTE SIZE
	MOVEI	T2,^D36			;WORD SIZE
	IDIV	T2,T1			;BYTES/WORD
	MOVE	T3,P1			;BYTE COUNT
	ADDI	T3,-1(T2)		;ADD ANOTHER WORDs WORTH
	IDIV	T3,T2			;WORD COUNT
	CAILE	T3,^D256		;IS IT BIGGER THAN DL10 WILL HANDLE?
	  STOPCD	.,STOP,KR3,	;MESSAGE TOO LARGE
	MOVE	W,T3			;WORD COUNT
	MOVEI	T3,^D36			;BYTE POSITION 0
	LDB	T4,[POINT 6,P2,5]	;POSITION OF OUR BYTE
	SUB	T3,T4			;DISTANCE INTO WORD
	IDIV	T3,T1			;INDEX OF STARTING BYTE
	MOVE	F,T3			;SAVE
	MOVE	T4,T2			;BYTES/WORD
	SUB	T4,T3			;BYTES IN 1ST WORD
	SUB	P1,T4			;DECREMENT BYTE COUNT
	MOVE	P4,T4			;SAVE BYTES IN 1ST WORD
	MOVEI	T3,-1(W)		;GET WORD COUNT
	PUSH	P,P2			;SAVE OLD BYTE POINTER
	ADD	P2,W			;ADD WORD COUNT TO ADDRESS
	IMUL	T3,T2			;CONVERT WORD COUNT INTO BYTE COUNT
	SUB	P1,T3			;DECREMENT BYTE COUNT FURTHER
	ADD	P4,T3			;END OF OUR BYTE COUNT
	CAIGE	P1,0			;SEE IF WE OVERSHOT
	JRST	ADJ			;YES, ADJUST
DLBLD:
	HRLI	P2,440000		;INITIALIZE PDP-10 BYTE POINTER
	DPB	T1,[POINT 6,P2,11]	;CORRECTLY
	HLRZI	P3,0			;CLEAR DL10 BYTE POINTER
IFN FTKL10!FTKI10,<
	MOVSI	T3,(MAP T4,0)		;MAP INSTRUCTION
	HRR	T3,(P)			;OLD BYTE POINTER ADDRESS
	XCT	T3			;GET REAL ADDRESS
IFN FTKL10,<
	LSH	T4,-11
>	;END FTKL10
>	;END FTKL10!TFKI10

IFN FTKA10,<
	HRRZ	T3,(P)
	MOVEI	T4,(T3)
	LSH	T4,-11
>	;END FTKA10
	DPB	T4,[POINT 13,P3,26]	;PUT INTO DL10 POINTER
	DPB	T3,[POINT 9,P3,35]	;AND OFFSET
	ADDI	T3,1000			;FIND NEXT PAGE IN CASE WE NEED IT
IFN FTKI10!FTKL10,<
	XCT	T3
IFN FTKL10,<
	LSH	T4,-11
>	;END FTKL10
>	;END FTKI10!FTKL10
IFN FTKA10,<
	MOVEI	T4,(T3)
	LSH	T4,-11
>	;END FTKA10
	SETZ	P1,
	DPB	T4,[POINT 13,P1,26]
	MOVE	T3,STAB(T1)		;PICK UP CODE
	DPB	T3,[POINT 3,P3,5]	;PUT S INTO DL10 POINTER
	DPB	T3,[POINT 3,P1,5]	;AND INTO OTHER ALSO
	MOVN	W,W			;NEGATE WORD COUNT
	DPB	W,[POINT 8,P3,13]	;STORE WORD COUNT
BKIT:
	JUMPE	F,BKUP			;IF POSITION 0, BACK UP
	SOJ	F,			;DECREMENT
BKE:
	DPB	F,[POINT 3,P1,2]
	DPB	F,[POINT 3,P3,2]	;STORE POSITION
	POP	P,(P)			;CLEAN STACK
	POP	P,F			;RESTORE F
	PJRST	WPOPJ##
BKUP:
	MOVEI	F,7
	JRST	BKE
ADJ:
	ADD	P4,P1		;TAKE DOWN OUR BYTE COUNT
	HLRZI	P1,0		;CLEAR REMAINING BYTE COUNT
	JRST	DLBLD
STAB:				;TABLE OF CODES
	0
	0
	0
	0
	0
	0
	6
	5
	4
	0
	0
	0
	3
	0
	0
	0
	2
	
;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
	MOVE	T1,@DLXFEK##(W)	;GET FIRST WORD OF FEK
	TLO	T1,FK.ONL##	;SET ON-LINE BIT
	HLLM	T1,@DLXFEK##(W)	;PUT BACK FLAGS HALF
	MOVE	T1,DLXFEK##(W)	;GET FEK ADDRESS
	HRRM	W,FEKUNI##(T1)	;STORE ADDRESS OF BASE TABLE
	MOVE	T2,DLXWIN##(W)	;WINDOW ADDRESS
	MOVE	T2,DLXREC##(T2)	;GET MAX RECORD LENGTH
	HRRM	T2,FEKMXL##(T1)	;STORE IN PROPER PLACE
	POPJ	P,		;DONE WITH INITIALIZATION



;HERE WHEN DL10 INTERRUPTS
D75KII::			;INTERRUPT ROUTINE
	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	HRRZ	J,DLXFEK##(W)	;GET FEK ADDRESS
	MOVE	P1,DLXWIN##(W)	;WINDOW ADDRESS
	MOVE	P2,DLXIFL##(P1)	;TO ONLY CHECK INPUT ARRIVING BEFORE OUTPUT DONE
	MOVSI	T1,200000	;BIT FOR EXPECTING OUTPUT DONE INTERRUPT
	TDNE	T1,FEKUNI(J)	;EXPECTING OUTPUT DONE INTERRUPT ?
	SKIPE	DLXOFL##(P1)	;MAKE SURE COUNT IS 0
	JRST	CHKIN		;NOT EXPECTED OR NOT REAL
	ANDCAB	T1,FEKUNI##(J)	;CLEAR WAITING OUTPUT BIT
	HRLI	J,FI.OUD##	;OUTPUT PLUS IOD
	PUSHJ	P,FEKINT##
CHKIN:	JUMPN	P2,ENDINT	;DONE IF NO INPUT YET
	MOVSI	T1,400000	;BIT FOR INPUT INTERRUPT
	TDNN	T1,FEKUNI##(J)	;WERE WE EXPECTING INPUT DONE ?
	JRST	ENDINT		;NOT EXPECTED OR NOT REALLY THIS TYPE
	ANDCAB	T1,FEKUNI##(J)	;CLEAR WAITING INPUT BIT
	HRLI	J,FI.IND##	;INPUT AND IOD
	MOVE	T2,FEKIAD##(J)	;PCB ADDRESS
	HRL	T2,DLXIC1##(P1)	;COUNT OF INPUT BYTES
	HLRM	T2,PCBICT##(T2)	;STORE IN PCBICT
IFN FTKL10,<
	PUSHJ	P,CSDMP##	;INVALIDATE THE CACHE
>
	PUSHJ	P,FEKINT##
ENDINT:
	POPJ	P,		;RETURN FROM INTERRUPT
;HERE WHEN A DC75 GOES DOWN
REMPRG::
	PUSH	P,J
	HRRZ	J,DLXFEK##(P2)
	TLO	J,FI.DWN##
	PUSHJ	P,FEKINT##
	HRRZM	P2,FEKUNI##(J)
	POP	P,J
	POPJ	P,
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
	POP	P,J
	POPJ	P,
;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
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,.C0JOB##	;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.
	$LIT
D85END::END