Google
 

Trailing-Edge - PDP-10 Archives - BB-EV84A-SM_1985 - monitor-sources/impanx.mac
There are 16 other files named impanx.mac in the archive. Click here to see a list.
; UPD ID= 2082, SNARK:<6.1.MONITOR>IMPANX.MAC.8,   3-Jun-85 14:41:47 by MCCOLLUM
;TCO 6.1.1406  - Update copyright notice.
; UPD ID= 1945, SNARK:<6.1.MONITOR>IMPANX.MAC.7,   9-May-85 17:07:57 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1607, SNARK:<6.1.MONITOR>IMPANX.MAC.6,   8-Mar-85 11:53:46 by PAETZOLD
;Document BUGxxx's
; UPD ID= 1571, SNARK:<6.1.MONITOR>IMPANX.MAC.5,  26-Feb-85 17:17:41 by PAETZOLD
;Document BUGxxx's
; UPD ID= 1032, SNARK:<6.1.MONITOR>IMPANX.MAC.4,  12-Nov-84 15:23:41 by PAETZOLD
;TCO 6.1041 - Move ARPANET to XCDSEC
; UPD ID= 283, SNARK:<TCPIP.5.4.MONITOR>IMPANX.MAC.3,  24-Sep-84 13:53:37 by PURRETTA
;Update copyright notice.
; UPD ID= 171, SNARK:<TCPIP.5.4.MONITOR>IMPANX.MAC.2,   9-Jun-84 11:29:39 by PAETZOLD
;No more LLINK.
; UPD ID= 3898, SNARK:<6.MONITOR>IMPANX.MAC.8,  11-Mar-84 10:37:54 by PAETZOLD
;More TCO 6.1733 - Guard against higher priority PIs (like the KLNI) in INETIN.
; UPD ID= 3830, SNARK:<6.MONITOR>IMPANX.MAC.7,  29-Feb-84 18:18:13 by PAETZOLD
;More TCO 6.1733 - ANBSEC and MNTSEC removal.  Bug Fixes.  Cleanup.
;<TCPIP.5.3.MONITOR>IMPANX.MAC.5,  6-Dec-83 23:50:34, Edit by PAETZOLD
;No more NTPRIO stuff.  No more 36 bit packing mode.  Move BADIFL and IMPIBF
;to IMPANX from IMPDV.
;TCO 6.1866 - Rewrite the IOPGF detection code
;More TCO 6.1733 - NCPFRK has gone away
;<TCPIP.5.1.MONITOR>IMPANX.MAC.8,  5-Jul-83 08:24:56, Edit by PAETZOLD
;Changes for 5.1.  Remove NCP support.

;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, 1985.
;ALL RIGHTS RESERVED.


SEARCH PROLOG,ANAUNV
TTITLE (IMPANX,IMPANX,<- AN20 Device Driver>)

IFNDEF REL6,<REL6==1>

ANI==:520
ANO==:524

		;BITS IN CONI FOR ANI
ANIMRQ==1B27	;MSG REQUEST. IMP STARTING TO SEND TO HOST.
ANIBSY==1B26	;BUSY. HOST IS ACCEPTING A MESSAGE
ANIM36==1B25	;MESSAGE ASSEMBLED INTO 36 BIT WDS IF 1, 32 BIT WORDS IF 0.
ANIDON==1B23	;DONE. IMP SENT LAST BIT.
ANIIID==1B19	;IMP IS DOWN. (READY LINE OFF)
ANIIWD==1B18	;IMP WAS DOWN. (READY LINE HAS BEEN OFF)

		;BITS IN CONO FOR ANI
ANIRST==1B19	;RESET THE WHOLE AN10 (EXCEPT HOST READY LINE)
ANICLE==1B18	;CLEAR ERROR FLAGS IN LH OF CONI, CLR IMP WAS DOWN.
ANXCHS==<IMPCHN>B32+<IMPCHN>B35;TWO ADJACENT PI CHANNELS IN B30-35

		;BITS IN CONI FOR ANO
ANOEND==1B27	;END OF MSG. SEND "LAST" WHEN WD CNT RUNS OUT.
ANOBSY==1B26	;BUSY. SEND WORDS TO THE IMP.
ANOM36==1B25	;MODE 36. SEND ALL 36 BITS OF DATA WORDS. ELSE, JUST SEND LEFT-HAND 32 BITS.
ANODON==1B23	;ALL BITS INCLUDING "LAST" HAVE BEEN SENT.

		;BITS IN CONO FOR ANO
ANOCLE==1B18	;CLEAR ERROR BITS, IMP WAS DOWN BIT.

;register  select field, in both ANO and ANI CONO's note these aren't
;used much because hardware switches to the "right" register most  of
;the time by itself.

ANXVAR==2B29	;VECTOR INTERRUPT ADDRESS REGISTER
ANXWAR==1B29	;WORD COUNT AND ADDRESS REGISTER

		;BITS IN INPUT DEVICE VECTOR ADDRESS REGISTER
ANIHRL==1B10	;HOST READY LINE. DATAO A 1 TO BECOME READY.

       			;MISCELLANEOUS VARIABLES
DEFSTR IMWDCT,,12,12   	;WORD COUNT FOR WC/ADR REGISTER

			;Device-dependent data for leaders
STY%NP==5		;Number of Padding words, for H2I NOP
	SUBTTL Start Input

IFE REL6,<RESCD>		; THIS CODE IS RESIDENT
IFN REL6,<XRESCD>		; THIS CODE IS RESIDENT

;Called  from  process level when buffers made available and input is
;off and from endin processor  if  more  buffers  are  available.  P1
;contains pointer to NCT.

ANISRT::CALL ANXSCK		;IS THE IMP UP?
 	 RET			;NO, SO CAN'T USE IT
	PIOFF
	SKIPE NTIB(P1)		;ALREADY DOING INPUT?
	 SOSA IMPNFI		;YES, SO DON'T DO ANOTHER
	SOSGE IMPNFI		;NO.  IS THERE A BUFFER TO READ INTO?
	 JRST ANISR2		;NO BUFFER
	MOVE T2,IMPFRI		;THERE ARE SOME, IT SAYS. GRAB ONE.
	LOAD T1,NBQUE,(T2)	;GET NEXT FREE BUFFER
	SKIPE T1		;IF THERE'S A SUCCESSOR,
	 SETSEC T1,INTSEC	;SET SECTION NUMBER
	MOVEM T1,IMPFRI
	SETZRO NBQUE,(T2)	;DEQUEUE IT FROM ANY OTHERS
	MOVEM T2,NTIB(P1)	;SAVE AS INPUT BUFFER
	HRRZS NTBFFL(P1)	;REMEMBER NTIB IS AN NCP BUFFER
	XMOVEI T1,.NBLD0(T2)	;FIRST WORD TO READ INTO
	TXO T1,<<.NBLD2+1>B12>	;READ THRU LEADER AND SOME PADDING
	MOVEM T1,NTINP(P1)	;THIS IS THE FIRST DATAO TO ANXWAR
	XMOVEI T1,IMIN0		;SET STATE TO "WAITING FOR IMP TO GO"
	MOVEM T1,NTIDSP(P1)	;IN INPUT DISPATCH WORD
	PION
	MOVEI T1,ANICLE+ANXWAR+ANXCHS ;TELL IMP WE ARE READY TO GO.
	MNTXCT NTCONO		;DO I/O INSTRUCTION
	RET			;IT WILL INTERRUPT ON FIRST BIT TO US
ANISR2:				;HERE WHEN NO INPUT BUFFERS
	AOSN IMPNFI		;IF NOT, CORRECT COUNT AND GIVE UP.
	SETOM NOIBFS		;FLAG THAT FAILED IF NO BUFFERS
	PION
	RET
	SUBTTL PI Service for Input - First Level

;All ACs have been saved by startup routine, we are dispatched to via
;the  NTIDSP  word  of  the  proper  NCT. If ANIDON is on, they go to
;IMPEI0 for end of input handling. For subsequent interrupts, a field
;will steer the packing and counts. Values are named .IIxxx  for  Imp
;Interrupt  dispatch. Store in NTITYP(NCT) for input and similarly in
;NTOTYP for output.

;The following AC usage conventions are adhered to
;T1    		Temp - used to hold I/O instruction arguments
;T2  	 	Points to Buffer if we're working on one
;T3,T4,CX  	Temp
;P -		Hold stack pointer

.IINC2==0		;This is a 32 bit 1822 message
.IISPQ==1		;Special queue
.IIINT==2		;Internet packing
.IISQ2==3		;False start on Internet -- Handle as spec. Q.

;Here  when input has been idle and IMP starts to send bits. This first
;interrupt requires us to send over word count and address.  The  first
;count  will  read  the IMP-to-host leader and a word of padding, in 36
;bit mode.

IMIN0:	MOVEI T1,ANIMRQ		;MESSAGE REQUEST IS ONLY VALID BIT
	MNTXCT NTCNSO		;CHECK IF ON
	 JRST IMIN0X		;IT WASN'T THAT. SOMETHING WIERD.
	XMOVEI T1,IMIN1		;NEXT INTERRUPT WANTED IS THIS
	MOVEM T1,NTIDSP(P1)	;SET DISPATCH FOR READING I-H LEADER.
	MOVE T1,NTINP(P1)	;GET POINTER
	MNTXCT NTDATO		;TELL THE IMP
	MOVEI T1,ANIM36+ANIBSY+ANXCHS ;SET TO READ 36 BITS, THEN PI.
	MNTXCT NTCONO		;..
	RET			;AND RETURN TO CALLER

;IMIN0X  -  Input interrupt error routine. 
;If the input side of the ANX has been idle, any interrupt other than
;MSG REQUEST is an error.

IMIN0X:	MNTXCT NTCONI		;GET STATUS FOR BUGINF
	BUG.(INF,IMINX1,IMPANX,HARD,<Unusual ANI interrupt, CONI ANI is>,<<T1,D>>,<

Cause:	The monitor received an interrupt from the input side of the AN20
	when it was supposed to be idle.  This may indicate a hardware
	problem with the AN20.

>)
	MOVEI T1,0
	MNTXCT NTCONO		;TURN OFF INPUT
	MOVEI T1,ANIRST		;AND GET BITS TO
	MNTXCT NTCONO		;RESET ANI, LEAVE ANIIWD ON, INPUT OFF
	RET			;BACK TO RESTORE
	SUBTTL PI Service for Input - Second Level

;Here  at  PI  level  after  IMP leader and a word of padding have been
;read. ANIDON on means it wasn't that long.  

IMIN1:	MOVEI T1,ANIDON		;END OF MESSAGE?
	MNTXCT NTCNSZ		;?
	 JRST IMPEI0		;YES, GO PROCESS SHORT (IRREG) MSG
	MOVE T2,NTIB(P1)	;POINT TO THE INPUT BUFFER
	LOAD T1,IHLNK,(T2)	;GET THE LINK AND HOST NUMBERS
	LOAD T3,IHHST,(T2)	;GET FULL HOST
	CAIN T1,INTLNK		;INTERNET LINK?
	 SKIPA T4,[.IIINT]     	;YES.
          MOVX T4,.IISPQ       	;SPECIAL QUEUES
	XMOVEI T1,.NBLD2+2(T2)	;WHERE NEXT WORD IN GOES.
	IOR T1,II1WCT(T4)	;WORD COUNT
	MOVEM T1,NTINP(P1)	;COMMAND FOR DEVICE
	MNTXCT NTDATO		;DO DATAO T1
	MOVEI T1,@II1CNO(T4)	;GET PROPER BITS
	MNTXCT NTCONO		;AND MAKE IT GO
	XMOVEI T3,IMIN2		;ADDRESS FOR NEXT INTERRUPT
	MOVEM T3,NTIDSP(P1)	;SAVE FOR NEXT INTERRUPT
	MOVEM T4,NTITYP(P1)	;SAVE DISPATCH CODE
	RET			;AND DONE WITH THIS INTERRUPT

II1WCT:	EXP 2B12		;TYPE NCP32
	EXP 1B12		;TYPE SPECIAL Q
	EXP 4B12		;TYPE INTERNET
	EXP 2B12		;SHOULD NOT BE REFERENCED HERE

II1CNO:	EXP ANIM36+ANIBSY+ANXCHS	;TYPE NCP32
	EXP ANIBSY+ANXCHS		;TYPE SPECIAL Q
	EXP ANIBSY+ANXCHS		;TYPE INTERNET
	EXP ANIM36+ANIBSY+ANXCHS	;SHOULD NOT BE REFERENCED HERE
	SUBTTL PI Service for Input - Third Level

IMIN2:	MOVEI T1,ANIDON		;END OF MESSAGE YET?
	MNTXCT NTCNSZ		;?
	 JRST IMPEI0		;YES. GO PROCESS SHORT MESSAGE
	MOVE T2,NTIB(P1)	;POINT TO THE INPUT BUFFER

;Padding  removal  isn't  needed  if haven't read that much, but it's
;cheaper to always remove it than to test for needing to.

	DMOVE T3,.NBLD2+2(T2)	;CRUNCH OUT THE PADDING ON INPUT
	STOR T3,IHPD1,(T2)	;MOVE THIS PARTIAL WORD
	MOVEM T4,.NBHHL(T2)	; ..
	MOVE T4,NTITYP(P1)	;GET TYPE CODE FOR THIS MESSAGE
	CAIE T4,.IIINT		;INPUTTING POSSIBLE INTERNET MSG?
	 JRST IMIN2B		;NO
	MOVE T1,T2		;PLACE BUFFER IN REG FOR ROUTINE
	CALL INETIN		;CHECK FURTHER. MAY CHANGE T4,T1.
	MOVE T2,T1		;RESTORE
IMIN2B:	LOAD T1,NBBSZ,(T2)	;GET ITS SIZE
	MOVE T3,II2LDT(T4)	;AMOUNT WE HAVE USED SO FAR
	SUBI T1,(T3)		;..
	ASH T1,^D23		;POSITION FOR AN10 WORD COUNTER
	IOR T1,T2		;ADDRESS OF THE BUFFER
	ADDI T1,(T3)		;NEXT WORD TO WRITE
	MOVEM T1,NTINP(P1)	;FEED THIS TO THE HARDWARE
	MNTXCT NTDATO		;TELL IT
	MOVEI T1,@II2CNO(T4)	;MAKE IT GO
	MNTXCT NTCONO		;..
	XMOVEI T1,IMIN3		;SET DISPATCH FOR NEXT INTERRUPT
	MOVEM T1,NTIDSP(P1)	;..
	RET			;RESTORE ACS AND DISMISS

;Table of CONO values to read data portion of message, by msg type

II2CNO:	EXP ANIBSY+ANXCHS		;TYPE NCP32
	EXP ANIBSY+ANXCHS		;TYPE SPECIAL Q
	EXP ANIBSY+ANXCHS		;TYPE INTERNET
	EXP ANIBSY+ANXCHS		;TYPE SPECIAL Q - FALSE INTERNET

;Table of next word to read into at IMIN2 time, by message type

II2LDT:	EXP .NBDW0		;TYPE NCP32
	EXP .NBHHL		;TYPE SPECIAL QUEUES
	EXP .NBHHL+3		;TYPE INTERNET
	EXP .NBHHL+3		;TYPE SPECIAL Q - FALSE INTERNET
	SUBTTL Internet Input Service

;Called  from IMIN2 when possible Internet message is coming in. This
;routine does the following:
;
;	1.	Move the 2 remaining H-H words to the right place
;	2.	Check for right message type and subtype
;	3.	Check for right Internet message type
;	4.	Check for a Internet-supplied buffer being available
;
;If  any  of  those  conditions  is  lacking,  input is resumed and the
;message is handled as a normal special queue message.  Correction:  To
;avoid  waking  the NCP it is flushed If the message is really destined
;for  the  gateway  (TCP,  XNET,  ...),   it   gets   copied   into   a
;Internet-supplied  buffer and input resumes. IMPEIN will then queue it
;for the gateway.
;
; T1/	Pointer to current NCP-supplied buffer
; T4/	.IIINT
;	CALL INETIN
; Ret+1:	Always. T4 still .IIINT if I.N. msg to be completed, or .IISQ2
;		if it will be given to a special Q. NTITYP adjusted.

INETIN:	STKVAR <INTFR>
	DMOVE T2,.NBDW0+2(T1)	;PICK UP THE INTERNET HEADER
	DMOVEM T2,.NBDW0(T1)	;STASH IN PROPER PLACE
	LOAD T2,IHFTY,(T1)	;ARPANET MESSAGE FORMAT
	LOAD T3,IHMTY,(T1)	;ARPANET MESSAGE TYPE
	CAIN T3,.IHREG		;REGULAR MSG?
	CAIE T2,ITY%LL		;LONG LEADER?
	 JRST INETIC		;NO. LET NORMAL CODE HANDLE IT.
	LOAD T2,IHSTY,(T1)	;ARPANET SUBTYPE
	LOAD T3,INPVR,(T1)	;INET PACKET VERSION FLAG (PART OF 2.5 NET)
	CAIE T2,STY%FC		;NORMAL, FLOW-CONTROLLED?
	CAIN T2,STY%UC		;OR UNCONTROLLED?
	CAIE T3,.INTVR		;AND RIGHT INTERNET VERSION?
	 JRST INETIC		;NO.  LET NORMAL CODE HANDLE THIS.
	PIOFF			;GUARD AGAINST HIGHER PRIORITY PI'S
	SOSL INTNFI		;IS THERE AN INTERNET BUFFER AROUND?
	IFSKP.
	  AOS INTNFI		;NO, COUNT IT BACK
	  PION			;HIGHER PRIORITY PI'S OKAY NOW
	  JRST INETIC		;LET NORMAL SPECIAL QUEUE HAVE IT
	ENDIF.
	SKIPN T3,INTFRI		;GET POINTER TO BUFFER TO USE
	BUG.(HLT,IMPIBF,IMPANX,SOFT,<Internet buffers fouled>,<<CX,D>>,<

Cause:	The monitor was trying to obtain an internet buffer and none were
	available.  This is a problem because the available buffer count
	was non-zero.

>)
	LOAD T2,NBQUE,(T3)	;GET NEXT INTERNET FREE BUFFER IF ANY
	IFN. T2			;WAS THERE SOMETHING THERE?
	  SETZRO NBQUE,(T3)	;YES, CLEAR LIST POINTER
	  SETSEC T2,INTSEC	;YES SO SET THE SECTION NUMBER
	ENDIF.
	MOVEM T2,INTFRI		;BECOMES HEAD OF LIST
	PION			;ALLOW INTERRUPTS AGAIN
	MOVEM T3,INTFR		;SAVE THE BUFFER ADDRESS
	XMOVEI T2,.NBLD0(T1)	;"FROM" POINTER FOR BLT
	XMOVEI T3,.NBLD0(T3)	;"TO" -- INTO INTERNET
	LOAD T1,IMWDCT,II1WCT(T4);GET SIZE OF SECOND TRANSFER
	ADDI T1,.NBHHL-2	;COMPUTE COUNT (-2 FOR FILL CRUNCH)
	CALL XBLTA		;COPY ARPANET AND INTERNET HEADERS
	MOVE T1,INTFR		;GET BACK THE BUFFER ADDRESS
	EXCH T1,NTIB(P1)	;OLD HEAD IS NOW CURRENT INPUT BFR
	EXCH T1,IMPFRI		;OLD INPUT BFR GOES TO NCP FREE LIST
	MOVE T2,IMPFRI		;GET COPY FOR INDEXING
	STOR T1,NBQUE,(T2)	;OLD LIST IS OFF OF NEW HEAD
	AOS IMPNFI		;THERE IS NOW ANOTHER FREE INPUT BFR
	HRROS NTBFFL(P1)	;THE CURRENT ONE IS OWNED BY INTERNET
	MOVE T1,NTIB(P1)	;NOW THINK IN TERMS OF INTERNET BUFFER
	RET

;Here when current input is to be continued.  Fix to be spec. q. input.

INETIC:	SETOM NTFLS(P1)		;MARK TO FLUSH MESSAGE WHEN COMPLETE
	MOVEI T2,.IISPQ		;MARK FOR SPECIAL QUEUE DISPATCH
	MOVEM T2,NTITYP(P1)	;ON NEXT INTERRUPT
	MOVEI T4,.IISQ2		;RETURN THIS TO CALLER
	RET
	SUBTTL PI Service for Input - Fourth Level

;Here on interrupt level for body of message from imp.

IMIN3:	MOVEI T1,ANIDON		;I HOPE IT FIT IN A BUFFER
	MNTXCT NTCNSZ		;..?
	 JRST IMPEI0		;GOOD. IT DID.
	SETOM NTFLS(P1)		;FLAG TO FLUSH MESSAGE
	MOVE T1,[1B12+IMSTK+NIMSTK-1] ;USE STACK AS BIT BUCKET
	MNTXCT NTDATO		;...
	MOVEI T1,ANIBSY+ANXCHS	;GET BITS
	MNTXCT NTCONO		;KEEP READING UNTIL END COMES ALONG
	RET			;AND RETURN

;Here when end msg recd from imp

IMPEI0:	MOVEI T1,ANXWAR		;SELECT WC/ADDR REG, CLEAR PIA
	MNTXCT NTCONO		;..
	MNTXCT NTDATI		;GET DATA
	MOVEM T1,NTINP(P1)	;SAVE IT
	MNTJRST NTIDUN		;DO INPUT DONE ROUTINE
	SUBTTL PI Service for Output - Startup and First Level

;Routine  to  start  msg  going  out. called at pi level, and at Main
;level if no output in progress

ANOSRT::PIOFF			;START OUTPUT
	SKIPN NTOB(P1)		;ANY OUTPUT IN PROGRESS?
	 JRST IMPXO1		;NO
	PION			;YES, TURN PI BACK ON
	RET			;AND RETURN

IMPXO1:	SETOM NTOB(P1)		;MARK OUTPUT IN PROGRESS
	PION			;NOW IT'S OK TO TURN PI BACK ON
	SKIPLE NTNOP(P1)	;ANY NOP'S TO SEND?
	 JRST IOUNOP		;YES, GO SEND THEM
	HLLZS NTBFFL(P1)	;ASSUME THIS WILL BE NCP'S OUTPUT BUFFER
	PIOFF			;OWN MACHINE FOR Q HACKING
	SKIPN T1,NTHOBO(P1)	;HI PRIORITY MSG WAITING?
	 JRST IMPIOT		;NO, CHECK LO PRIORITY
				;HERE TO SEND A HIGH PRIORITY MESSAGE
	LOAD T2,NBQUE,(T1)	;DOES IT HAVE A SUCCESSOR
	JUMPN T2,IMPIO1		;JUMP IF SO
	SETZM NTHOBI(P1)	;IF NOT, CLEAR TAIL OF Q
	SKIPA			;AND DON'T ADD NETWORK SECTION
IMPIO1:	 SETSEC T2,INTSEC	;SECTION BUFFERS ARE IN
	MOVEM T2,NTHOBO(P1)	;FOR NEXT REMOVAL
	JRST IMPIOC		;SEND BUFFER IN T1

;Select  either  an  Internet  buffer  or  low  priority NCP buffer for
;output. 

IMPIOT:				;HERE TO CHECK NON HPQs
	PIOFF			;PROTECT THE QUEUES
	CALL IMPIOL		;CHECK FOR NON IP OUTPUT TRAFFIC
	 JRST IMPIOC		;FOUND SOME SO SEND IT
	CALL IMPIOO		;CHECK FOR IP OUTPUT TRAFFIC
	 JRST IMPIOC		;FOUND SOME SO SEND IT
	PION			;QUEUES OK NOW
	SETZ T1,		;GET A ZERO
	SKIPLE T2,HSTGDM(P1)    ;NEED TO SEND HOST-GOING-DOWN MESSAGE?
	 JRST IOUHGD		;YES SO SEND THE HOST GOING DOWN MSG
	MNTXCT NTOCNO		;CONO A 0 AND SHUTDOWN THE OUTPUT SIDE
	XMOVEI T1,IMODN2	;DISPATCH WHEN IT IS TURNED ON
	MOVEM T1,NTODSP(P1)	;..
	SETZM NTOB(P1)
	RET

;Check for an IP message.  If one is present dequeue it and use it

IMPIOO:				;HERE TO CHECK FOR AN IP BUFFER
	SKIPN T1,NTIOBO(P1)	;IP OUTPUT MESSAGE?
	 RETSKP			;NO
	HLLOS NTBFFL(P1)	;REMEMBER OUT BUF IS INTERNET OWNED
	LOAD T2,NBQUE,(T1)	;GET ITS SUCCESSOR
	JUMPN T2,IMPIOP		;JUMP IF NOT LAST ONE
	SETZM NTIOBI(P1)	;YES.  MAKE QUEUE NULL
	SKIPA
IMPIOP:	 SETSEC T2,INTSEC	;PLACE IN PROPER SECTION
	MOVEM T2,NTIOBO(P1)	;UPDATE OUTPUT POINTER
	RET			;WE FOUND A BUFFER

;Check for a non IP message.  If one is present dequeue it and use it.

IMPIOL:				;HERE TO CHECK FOR AN NCP MSG
	SKIPN T1,NTLOBO(P1)	;MSG WAITING TO GO OUT?
         RETSKP			;NO
	LOAD T2,NBQUE,(T1)	;GET BFR
	JUMPN T2,IMPIO2
	SETZM NTLOBI(P1)	;CLEAR TAIL
	SKIPA			;AND LEAVE OFF SECTION NUMBER
IMPIO2:	 SETSEC T2,INTSEC	;SET BUFFER'S SECTION
	MOVEM T2,NTLOBO(P1)	;SET NEW HEAD
	RET			;AND GO OUTPUT THE BUFFER

IMPIOC:				;HERE WHEN WE HAVE DECIDED WHICH MESSAGE 
	PION			;PI'S ON NOW THAT Q'S ARE SAFE
	MOVEM T1,NTOB(P1)	;...
	MOVMS HSTGDM(P1)	;ENABLE ANOTHER GOING-DOWN IF ONE EXISTS
	SETZRO NBQUE,(T1)	;DEQUEUE BUFFER FROM ITS OLD CHAIN

; Now decide on packing via message type

	MOVEI T3,.IIINT		;ASSUME INTERNET FORMAT
	HRRE T4,NTBFFL(P1)	;INTERNET OWN THE BUFFER?
	JUMPL T4,IMPIOD		;YES
	LOAD T2,IHHST,(T1)	;GET HOST 
	LOAD T1,IHLNK,(T1)	;GET LINK
	CAIGE T2,FKHOST		;FAKE HOST?
	 CAILE T1,INTLNK	;OR LINK OUT OF RANGE?
	  SKIPA T3,[.IISPQ]	;YES, SPECIAL QUEUE FORMATTING.
	   MOVEI T3,.IINC2     	;SELECT 32 BIT MODE
IMPIOD:
	XMOVEI T2,IMOLDR	;WHERE TO GO ON NEXT INTERRUPT
	MOVEM T2,NTODSP(P1)
	MOVEM T3,NTOTYP(P1)	;REMEMBER PACKING TYPE DECISION
	MOVEI T1,ANXWAR		;SELECT WC/ADDR REG
	MNTXCT NTOCNO		;DO AN OUTPUT CONO
	MOVE T1,NTOB(P1)	;GET BUFFER BACK
	XMOVEI T1,.NBLD0(T1)	;FIRST WORD TO SEND OUT
	TXO T1,<<.NBLD2+1>B12>	;SEND 1ST 3 WORDS AND SOME FILLS
	MNTXCT NTODTO		;DO A DATAO
	MOVEI T1,ANOM36+ANOBSY+ANOCLE+ANXCHS ;SEND IT IN 36-BIT MODE
	MNTXCT NTOCNO		;AND DO OUTPUT CONO
	RET			;DONE WITH START-UP-OUTPUT ROUTINE
	SUBTTL PI Service for Output - More Fill and 1822 Leader

;Here at PI level when leader and first fill word have been sent. Now
;re-send some more fill, and send H-H leader.

IMOLDR:	XMOVEI T1,IMOLD3	;WHERE TO COME ON NEXT INTERRUPT
	MOVEM T1,NTODSP(P1)	;..
	MOVE T2,NTOB(P1)	;BUFFER WE ARE WORKING ON
	MOVE T4,NTOTYP(P1)	;GET THE PACKING CONTROL
	XMOVEI T1,.NBHHL-1(T2)	;RESEND ANOTHER WORD AS PADS, THEN H-H LEADER
	IOR T1,II1WCT(T4)	;SET UP RIGHT COUNT
	MNTXCT NTODTO		;DO OUTPUT DATAO
	MOVE T1,T2		;PUT ADDRESS IN T1
	LOAD T3,NBBSZ,(T1)	;THAT MIGHT BE ALL. CHECK SIZE OF BUFFER
	CAILE T3,.NBHHL		;JUST THAT MUCH?
	 TDZA T1,T1		;THERE'S MORE THAN THAT.
	MOVEI T1,ANOEND		;THAT'S ALL. INCLUDE END OF MSG BIT
	IOR T1,IO1CNO(T4)	;PLUS THE RIGHT WORD SIZE, ETC.
	MNTXCT NTOCNO		;TELL INTERFACE
	RET			;DONE WITH INTERRUPT

IO1CNO:	ANOM36+ANOBSY+ANXCHS	;NCP 32 BIT MODE
	ANOBSY+ANXCHS		;SPECIAL QUEUES
	ANOBSY+ANXCHS		;INTERNET MODE
	ANOM36+ANOBSY+ANXCHS	;NOT REFERENCED HERE

IO2CNO:	ANOEND+ANOBSY+ANXCHS		;NCP 32 BIT MODE
	ANOEND+ANOBSY+ANXCHS		;SPECIAL QUEUES
	ANOEND+ANOBSY+ANXCHS		;INTERNET MODE
	ANOEND+ANOBSY+ANXCHS		;NOT REFERENCED HERE
	SUBTTL PI Service for Output - Send Remaining Data

;Here after completing the above, again on PI level. If more words to
;send, set them up.

IMOLD3:	MOVEI T1,ANODON		;DONE BIT...
	MNTXCT NTOCSZ		;CONSZ, WAS IT A SHORT MESSAGE?
	 JRST IMODN0		;YES, GO WRAP UP. RELEASE BUFFER, ETC.
	MOVE T2,NTOB(P1)	;BUFFER WE HAVE BEEN SENDING
	MOVE T4,NTOTYP(P1)	;GET THE PACKING CONTROL
	LOAD T1,NBBSZ,(T2)	;HOW MANY WORDS IN IT?
	MOVE T3,II2LDT(T4)	;HOW FAR WE HAVE DONE SO FAR
	SUBI T1,(T3)		;LESS THOSE SENT ABOVE
	ASH T1,^D23		;POSITION FOR AN10 WORD COUNT
	IOR T1,T2		;NEXT WORD TO GO OUT.
	ADDI T1,(T3)		;ADJ COUNT
	MOVEM T1,NTOUP(P1)	;SAVE
	MNTXCT NTODTO		;DO A DATAO
	MOVEI T1,@IO2CNO(T4)	;GET BITS FOR CONO
	MNTXCT NTOCNO		;AND DO IT
	XMOVEI T3,IMODN0	;WHEN DONE, WE WILL RELEASE THE BUFFER
	MOVEM T3,NTODSP(P1)	;..
	RET			;DONE, DISMISS INTERRUPT
	SUBTTL Build Host to IMP Going Down Message

;Here to make a Host Going Down message Get here when nothing to output
;and  HSTGDM(P1)  is .gt. 0. T2 has contents of HSTGDM(P1). HSTGDM is 0
;if not going down, +N if one needs to be sent, and -N if it  has  been
;sent.  Host going down must be the last thing we tell the IMP. Sending
;after saying HGD means another HGD is needed.

IOUHGD:	MOVNS HSTGDM(P1)	;DISABLE SUBSEQUENT HGDS
	MOVEI T3,0		;BUILD THE MESSAGE IN 2 AND 3
	LSHC T2,-^D8		;FROM DOWN-TIME AND REASON
	DMOVEM T2,IIMBUF+1	;AND USE THE SPECIAL IRREG MSG BUFFER
	MOVE T2,H2IHGD		;PROTO HOST-GOING-DOWN MSG
	MOVEM T2,IIMBUF		;TO THE SCRATCH BUFFER
	XMOVEI T2,IIMBUF	;POINT TO THIS MSG
	JRST IOUIRG		;GO SEND IT

				;Here to make a nop message
IOUNOP:	SOS NTNOP(P1)		;DECREMENT COUNT OF NOP'S TO SEND
	MOVMS HSTGDM(P1)	;MAY NOW NEED ANOTHER GOING DOWN MSG
	XMOVEI T2,H2INOP	;PROTOTYPE OF A NOP/PADDING REQUEST
IOUIRG:	TXO T2,<<.NBLD2>B12>	;LENGTH OF THE MSG, DATA IN MON. SEC.
	MOVEI T1,ANXWAR		;SET FOR WD CT/ADDR REGISTER
	MNTXCT NTOCNO		;DO A CONO (T1) SETTING WC/ADDR REG
	MOVE T1,T2		;GET MESSAGE POINTER
	MNTXCT NTODTO		;DO A DATAO ANO,T1
	MOVEI T1,ANOM36+ANOBSY+ANOEND+ANXCHS ;START IT 36 BIT MODE
	MNTXCT NTOCNO		;...
	MOVE T1,TODCLK		;GET TIME NOW
	ADDI T1,^D60*^D1000	;TIMEOUT IN ONE MINUTE
	MOVEM T1,NTTOUT(P1)	;SET INTERFACE HUNG TIMEOUT
	XMOVEI T1,IMODN2	;WHEN DONE, NO BUFFER TO RELEASE
	MOVEM T1,NTODSP(P1)	;SET DISPATCH ADDRESS
	RET

;Prototypes of the two H2I irreg messages we ever send.
;Prototype Host-to-Imp NOP msg, with padding control.

H2INOP:	BYTE (4)0,ITY%LL (16)0 (8).IHNOP (4)0
	EXP 0
	BYTE (4)0,STY%NP	;DESIRED PADDING AMOUNT

;Prototype Host-to-IMP Host-going-down message.

H2IHGD:	BYTE (4)0,ITY%LL (16)0 (8).IHHGD (4)0
;	BYTE (4)0 (24)0 (3)DAYOFWEEK (5)HOUR
;	BYTE (4)5MINPERIOD, REASON
	SUBTTL PI Service for Output - Output Done Interrupt

;Here after "out done" interrupt for a real buffer

IMODN0:	MNTCALL NTODUN		;DO OUTPUT DONE STUFF

;Here after "out done" interrupt when no buffer to release.

IMODN2:	SETZM NTTOUT(P1)	;CLEAR OUTPUT HUNG TIMEOUT
	SETZM NTOB(P1)		;MARK NO OUTPUT IN PROGRESS
	SKIPGE HSTGDM(P1)	;FINISHED HOST-GOING-DOWN?
	  JRST ANXKI2		;YES, GO FINISH TAKING INTERFACE DOWN
	CALLRET ANOSRT		;START NEXT MSG IF ANY
				;AND DONE
	SUBTTL ANXSCK - Check State of Interface 

;ANXSCK	Check state of interface (NCT pointed by P1)
;Returns+1	Interface off
;Returns+2	Interface on

ANXSCK::SAVEAC <T1>		;SAVE AN AC
	MNTXCT NTCONI		;GET CURRENT STATUS
	TXNN T1,<1B4+1B5>	;IS IT POWERED UP, WITH A CABLE IN IT?
	 SOSA INTFLG		;NO, SO DON'T REQUEST RUN INTERNET FORK
	TXNE T1,<ANIIID+ANIIWD>	;YES. IS READY LINE ALSO OK?
	 SETOM NTERRF(P1)	;NO, FLAG AN ERROR
	SKIPL NTERRF(P1)	;ERROR SEEN NOW OR BEFORE?
	 RETSKP
	MOVNI T1,2		;FLUSH 2 MESSAGES
	MOVEM T1,NTFLS(P1)
	MOVEI T1,10		;AND SEND SOME NOPS
	MOVEM T1,NTNOP(P1)
	MNTXCT NTCONI		;SEE IF PIAS ARE ON
	ANDI T1,77
	MOVEI T1,ANICLE(T1)	;CLEAR THE ERROR FLOP
	MNTXCT NTCONO		;...
	AOS INTFLG		;RUN INTERNET FORK UNLESS POWER OFF
	RET
	SUBTTL ANXKIL - Shut Down an AN20

;Here  from down-sequence processing in NCPFRK to completely shut off
;the hardware device.

;	T1/	Why going down, a la 1822  or  -1 to abort
;	T2/	When back up

ANXKIL::
	JUMPL T1,ANXKI2		;FORGET TELLING IMP, SHUT IT OFF
	SKIPL HSTGDM(P1)	;TOLD IMP WERE GOING AWAY?
         CALLRET IMPHLT		;NO, DO IT NOW, THEN ...
				;Back here after going down message sent
ANXKI2:	MOVEI T1,0		;TURN OFF OUTPUT SIDE
	MNTXCT NTOCNO		;...
	MOVEI T1,ANIRST		;CLEAR DEVICE
	MNTXCT NTCONO
	MOVEI T1,ANXVAR		;HAVE TO POINT TO WHERE HOST READY IS
	MNTXCT NTCONO
	MOVEI T1,NTIINT(P1)	;CLEAR READY, LEAVE INTERRUPT ADDRESS ALONE
	HRLI T1,MSEC1		;MAKE SURE INTERRUPT INST XCTS IN SECTION ONE
	MNTXCT NTDATO		;...
	MOVE T1,NTRDY(P1)	;RECORD IF ANYTHING CHANGED
	IOR T1,NETON(P1)
	IOR T1,NTORDY(P1)
	SETZM NTTOUT(P1)	;CLEAR OUTPUT HUNG TIMEOUT
	JUMPE T1,ANXKIX		;NOTHING CHANGED SO EXIT QUIETLY
	SETZM NTRDY(P1)		;IMP OFF
	SETZM NTORDY(P1)	;OUTPUT OFF
	AOS NTSTCH(P1)		;JUST CHANGED STATE
	AOS JB0FLG		;GET IT PRINTED
ANXKIX:	RET
	SUBTTL PI Service Initialization 

;Call  here  from MNTINI when initializing the networks, not on every
;cycle of the ready line.

ANXINI::XMOVEI T1,IMIN0X	;RESET DISPATCHES
	MOVEM T1,NTIDSP(P1)	;INPUT PI DISPATCH TO SHUT OFF DEVICE
	XMOVEI T1,IMODN2	;OUTPUT PI DISPATCH TO START NEW MSG
	MOVEM T1,NTODSP(P1)
	SETZM HSTGDM(P1)	;CANCEL GOING DOWN MESSAGES
	RET
	SUBTTL ANXRSS - Set AN20 Online If IMP Online

;Call here from NCPFRK, process level, when IMP is wanted up but net is
;currently down.

ANXRSS::SETZM NTTOUT(P1)	;CLEAR OUTPUT HUNG TIMEOUT
	MNTXCT NTCONI		;GET STATUS (INTO T1)
	TXNE T1,<1B4+1B5>	;POWER UP?
	 TXNE T1,<ANIIID>	;IMP READY?
	  RET			;NO, STOP HERE
	SETZM NTERRF(P1)	;CLEAR NOTICES OF IMP ERRORS
	HRRES NETON(P1)		;AND ANY DOWN REQUESTS
	MOVEI T1,ANIRST		;CLEAR DEVICE
	MNTXCT NTCONO
	MOVEI T1,ANXVAR+ANICLE	;SET VECTOR ADDRESS WORDS
	MNTXCT NTCONO		;...
	MOVEI T1,NTIINT(P1)	;POINT TO INTERRUPT INSTRUCTION
	HRLI T1,MSEC1		;MAKE SURE INTERRUPT INST XCTS IN SECTION ONE
	TXO T1,ANIHRL		; AND SET READY LINE
	MNTXCT NTDATO		;..
	MOVEI T1,ANOCLE+ANXVAR	;SAME FOR OUTPUT
	MNTXCT NTOCNO		;...
	MOVEI T1,NTOINT(P1)	;SET VECTOR INT LOC FOR OUTPUT
	HRLI T1,MSEC1		;MAKE SURE INTERRUPT INST XCTS IN SECTION ONE
	MNTXCT NTODTO		;DO A DATAO ON OUTPUT DEVICE
	MOVNI T1,2
	MOVEM T1,NTFLS(P1)	;INIT FLUSH COUNT
	MOVEI T1,10
	MOVEM T1,NTNOP(P1)
	MOVEI T1,^D1000
	DISMS			;ALLOW TIME FOR READY LINE TO SETTLE
	AOS NTSTCH(P1)		;CAUSE CHANGE IN STATE TO BE NOTED
	AOS JB0FLG		;BY JOB0
	GTAD
	MOVEM T1,NTXUPP(P1)	;SAVE TIME WHEN IT CAME UP
	MOVEI T1,ANOBSY+ANXCHS	;TELL OUTPUT SIDE TO GO
	SKIPE NTOB(P1)		;IF THERE IS A BUFFER IN TRANSIT
	 MNTXCT NTOCNO		;OUTPUT CONO
	SETOM NTRDY(P1)		;INDICATE FULLY UP
	SETOM NTORDY(P1)	;ALLOW OUTPUT
	CALL INTUP		;INTERFACE IS UP
	CALL ANOSRT		;START OUTPUT IF NEEDED
	CALLRET ANISRT		;START INPUT
	SUBTTL IMPFPF - Handle Possible AN20 Induced IOPGFs

;This  routine  determines if the cause of an IO Page fail was caused
;by the AN20 accessing a bad address. Scan through the  NCTs  looking
;for  an  AN20.  Check the AN20 to see if ANI or ANO was touching the
;page in question. If so shut down the AN20.

IFE REL6,<IMPFPF::>
IFN REL6,<XRENT IMPFPF,G>
				;ROUTINE TO DETERMINE IF AN10/20 CAUSED
				;AN IOPGF....PAGE NUMBER IS IN T1
	SAVEAC <P1>		;DONT TRASH P1
	SKIPA P1,NCTVT		;POINT TO THE NCT VECTOR TABLE
IMPFPL:	LOAD P1,NTLNK,(P1)	;GET LINK TO THE NEXT NCT
	JUMPE P1,R		;YES SO WE DID NOT CAUSE THE PROBLEM
	LOAD T2,NTDEV,(P1)	;GET THE DEVICE TYPE 
	CAIE T2,NT.ANX		;IS IT AN AN20?
	 JRST IMPFPL		;NO SO CHECK THE NEXT NCT
	MOVE T4,T1		;SAVE THE PAGE NUMBER
	MOVEI T1,ANXWAR+ANXCHS	;BITS FOR THE CONO
	MNTXCT NTCONO		;SELECT IWAR
	MNTXCT NTDATI		;GET THE INPUT WORD ADDRESS REGISTER
	MOVE T2,T1		;SAVE THE IWAR
	MOVEI T1,ANXWAR+ANXCHS	;BITS FOR THE CONO
	MNTXCT NTOCNO		;SELECT OWAR
	MNTXCT NTODTI		;GET THE OUTPUT WORD ADDRESS REGISTER
	MOVE T3,T1		;SAVE THE OWAR
	MOVE T1,T4		;PUT THE PAGE NUMBER BACK
	LOAD T2,VPGNO,T2	;GET THE PAGE NUMBER INPUT SIDE WORKING ON
	LOAD T3,VPGNO,T3	;GET THE PAGE NUMBER OUTPUT SIDE WORKING ON
	CAME T1,T2		;INPUT SIDE CAUSE IOPGF?
	 CAMN T1,T3		;OUTPUT SIDE CAUSE IOPGF?
	  SKIPA			;YES WE CAUSED IT
	   JRST IMPFPL		;WE DID NOT CAUSE IT SO CHECK NEXT NCT
				;HERE WHEN WE CAUSED THE IOPGF
	SETO T1,		;DO NOT TELL THE IMP WHY
	MNTCALL NTKILL		;KILL THE AN20
	BUG.(CHK,ANIOPF,IMPANX,HARD,<IO page fail from AN20>,<<P1,NCT>>,<

Cause:	The AN20 was found to be the cause of an IO Page Fail.
	This means that the hardware got a page fault during an interrupt
	instruction.  This may indicate a hardware problem with the AN20.

>)
	RETSKP			;AND SKIP RETURN TO APRSRV

	TNXEND
	END