Google
 

Trailing-Edge - PDP-10 Archives - BB-4170G-SM - sources/impanx.mac
There are 16 other files named impanx.mac in the archive. Click here to see a list.
;<3-MONITOR>IMPANX.MAC.10,  7-Nov-77 13:02:21, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-MONITOR>IMPANX.MAC.9,  2-Nov-77 23:04:39, EDIT BY CROSSLAND
;ADD IMPOFL BUGINF
;<3-MONITOR>IMPANX.MAC.8, 12-Oct-77 13:50:05, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>IMPANX.MAC.7,  4-Oct-77 11:01:57, EDIT BY MILLER
;CHANGE EXPRESSIONS WITH MSEC1 IN THEM
;<3-MONITOR>IMPANX.MAC.6, 29-Sep-77 02:22:14, EDIT BY CROSSLAND
;GET STAUS ON INPUT ERROR BEFORE TURNING OFF INPUT
;<3-MONITOR>IMPANX.MAC.5, 23-Jul-77 22:53:24, EDIT BY CROSSLAND
;MOVE BUFFERS TO ANBSEC SECTION
;<3-MONITOR>IMPANX.MAC.4, 17-Jun-77 05:38:12, EDIT BY CROSSLAND
;CONVERT TO EXTENDED ADDRESSING
;CHANGE TO IMPCHK,ININX0,IMIERR TO RECOVER FROM NO RFNIB NET HANG
;<3-MONITOR>IMPANX.MAC.3, 19-May-77 04:56:41, EDIT BY CROSSLAND
;FIX WRONG HOST BUGCHK
;<3-MONITOR>IMPANX.MAC.2, 10-May-77 19:08:56, EDIT BY HURLEY
;<101B-MONITOR>IMPANX.MAC.3, 29-Mar-77 10:08:33, EDIT BY CROSSLAND
;TCO 1763 - FIX MESSAGE SIZE.
;<A-MONITOR>IMPANX.MAC.2, 25-Jan-77 15:24:03, EDIT BY OPERATOR
; FIX TYPO IN IMPEI5 SITE ADDRESS CHECK
;<A-MONITOR>IMPANX.MAC.1, 21-Jan-77 18:00:21, EDIT BY CLEMENTS
;RECODE FOR AN10 INTERFACE. RENAME FILE TO BE IMPANX.MAC
;<CLEMENTS>IMPPHY.MAC.1, 19-Jul-76 16:18:47, EDIT BY CLEMENTS
;SEPARATED PHYSICAL IMP DRIVER FROM IMPDV.MAC

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976, 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

SEARCH PROLOG
SEARCH MACSYM,MONSYM

	TTITLE (IMPPHY,IMPANX,< -  IMP DRIVER FOR AN10 - R CLEMENTS>)



;HARDWARE DEFINITIONS FOR AN10 DEVICE INTERFACE

ANI=520				;I/O DEVICE NUMBER FOR INPUT SIDE
ANO=524				;I/O DEVICE NUMBER FOR OUTPUT SIDE

;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 BEING ASSEMBLED INTO 36 BIT
				;  WORDS IF 1, 32 BIT WORDS IF 0.
ANIWCO==1B24			;WD COUNT OVERFLOW. MESSAGE PORTION IS DONE.
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==IMPCHS			;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 WORDS.
				; ELSE, JUST SEND LEFT-HAND 32 BITS.
ANOWCO==1B24			;WORD COUNT OVERFLOW. THIS MSG
				; PORTION COMPLETED.
ANODON==1B23			;ALL BITS INCLUDING "LAST" HAVE BEEN SENT.
ANOIID==1B19			;IMP IS DOWN, SAME AS IN ANI
ANOIWD==1B18			;IMP WAS DOWN, SAME AS IN ANI

;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
ANXDR==0B29			;DATA REGISTER.

;BITS IN INPUT DEVICE VECTOR ADDRESS REGISTER

ANIHRL==1B10			;HOST READY LINE. DATAO A 1 TO BECOME READY.


;MISCELLANEOUS VARIABLES

PIMSTK:	IOWD NIMSTK,IMSTK	;IMP INTERRUPT STACK POINTER

DEFSTR IMWDCT,,12,12		;WORD COUNT FOR WORD COUNT/ADDRESS REG.
DEFSTR IMBFAD,,35,23		;ADDRESS FOR WORD COUNT/ADDRESS REG.


;INTERRUPT LOCATION

ANOVIL:	XPCW ANOVI1		;OUTPUT INTERRUPT LOCATION

ANIVIL:	XPCW ANIVI1		;INPUT INTERRUPT LOCATION

;CLOCK LEVEL CHECK ROUTINE

IMPCHK::MOVEI T2,^D1000
	MOVEM T2,IMPTM2		;CALL THIS EVERY SECOND
	SKIPN IMPRDY		;NET ON?
	RET			;NO.
	CONSO ANI,ANIIWD	;IF IMP WAS DOWN CALL IMIERR AND RESET
	CALL IMPRLQ		;IS IMP DOWN NOW OR RECENTLY?
	 SKIPL IMPRDT		;AND NOT ALREADY NOTICED?
	RET			;NO. NO NEED TO SET ERROR FLAGS
	CALL IMIERR		;BE SURE IT'S NOTICED
	AOS IMPFLG		;CAUSE RUNNING OF NCP FORK
	RET
;START INPUT
;CALLED FROM PROCESS LEVEL WHEN BUFFERS MADE AVAILABLE AND INPUT IS OFF
;AND FROM ENDIN PROCESSOR IF MORE BUFFERS ARE AVAILABLE

IMISRT::CALL IMPRLQ		;IS DEVICE UP AND IMP READY?
	 RET			;NO, DO NOTHING
	SOSL IMPNFI		;SUB 1 FROM COUNT OF FREE INPUT BUFFERS
	SKIPN T1,IMPFRI		;GET POINTER TO FREE INPUT BUFFER
	BUG(HLT,IMPNII,<NO IMP INPUT BUFFERS>)
	HLRZ T2,0(T1)		;GET NEXT FREE
	HRLI T2,ANBSEC		;SET SECTION NUMBER
	MOVEM T2,IMPFRI		;UPDATE POINTER TO FIRST FREE BUFFER
	HRRZS 0(T1)		;CLEAR LINK OF CURRENT BUFFER
	MOVEM T1,IMIB		;SAVE ADDRESS OF BUFFER
	AOS T1			;FIRST WORD TO READ INTO
	TLO T1,(2B12)		;A WORD COUNT FIELD OF 2
	MOVEM T1,IMPINP		;THIS IS THE FIRST DATAO TO ANXWAR
	MOVE T1,[MSEC1,,IMIN0]	;SET STATE TO "WAITING FOR IMP TO GO"
	MOVEM T1,IMIDSP
	SETZM IMPIOV		;AND CLEAR "INPUT OVERFLOW" FLAG
	CONSZ ANI,ANIIWD	;HAS IMP BEEN DOWN?
	CALL IMIERR		;YES, BE SURE IT GETS NOTICED
	CONO ANI,ANICLE+ANXWAR+ANXCHS ;TELL IMP WE ARE READY TO GO.
	RET			;IT WILL INTERRUPT ON FIRST BIT TO US
;PI SERVICE FOR INPUT
;DISPATCHED AT IMPSV TO ONE OF THE FOLLOWING:
;IMIN0: FIRST BIT FLOWED, NEED TO SET WD CT AND ADDRESS.
;IMIN1: FIRST TWO WORDS OF MSG
;IMIN2: SECOND WORD OF MSG - NOT USED - IMIN1 READS TWO WORDS
;IMIN3: BODY OF MESSAGE HAS COME IN
;IF ANIDON IS ON, THEY GO TO IMPEIN FOR END OF INPUT HANDLING.


;IMIN0
;HERE WHEN INPUT HAS BEEN IDLE AND IMP STARTS TO SEND BITS. THIS
;FIRST INTERRUPT REQUIRES US TO SEND OVER WD COUNT AND ADDRESS.
;THE FIRST WORD COUNT WILL BE TWO, TO READ JUST THE IMP-TO-HOST
;LEADER PLUS SECOND 36 BITS.


IMIN0:	CONSO ANI,ANIMRQ	;MESSAGE REQUEST IS ONLY VALID BIT
	JRST IMIN0X		;IT WASN'T THAT. SOMETHING WIERD.
	MOVEM T1,IMIDSP		;SAVE AC T1, PREPARE TO SET DISPATCH.
	MOVE T1,[MSEC1,,IMIN2]	;NEXT INTERRUPT WANTED IS THIS
	EXCH T1,IMIDSP		;SET DISPATCH FOR READING I-H LEADER.
	DATAO ANI,IMPINP	;TELL IT BUFFER ADDRESS AND COUNT OF 2.
	CONO ANI,ANIM36+ANIBSY+ANXCHS ;SET TO READ 36 BITS, THEN PI.
	XJEN ANIVI1		;DISMISS INPUT INTERRUPT.

;IMIN0X - INNERRUPT ERROR ROUTINE.
;IF THE INPUT SIDE OF THE ANX HAS BEEN IDLE, ANY INTERRUPT OTHER THAN
;MESSAGE REQUES IS INVALID.

IMIN0X:	MOVEM T1,IMIDSP		;HERE IF NO MSG REQ. SAVE T1
	CONI ANI,T1		;GET STATUS
	CONO ANI,0		;TURN OFF INPUT.
	BUG(INF,IMINX1,<UNUSUAL ANI INTERRUPT, CONI ANI IS>,<T1>)
	MOVE T1,[MSEC1,,IMIN0X]	;SET DISPATCH ADDRESS
	EXCH T1,IMIDSP		;RESTORE T1
	CONO ANI,ANIRST		;RESET ANI, LEAVE ANIIWD ON, INPUT OFF
	XJEN ANIVI1		;AND LET CLOCK/NCPFRK FIX IT.
REPEAT 0,<
;REMOVED THIS CODE, BUT IT MAY BE NEEDED AGAIN SOME DAY

;HERE ON FIRST DATA INTERRUPT. FOR NOW, JUST GO READ ANOTHER WORD.
;IF SNDIM GETS RE-SPECED, MAY CHANGE TO 32 BIT MODE HERE.

IMIN1:	CONSZ ANI,ANIDON	;DID IMP LAST BIT HAPPEN?
	JRST IMPEIN		;YES. GO HANDLE 1 WORD MSG
	AOS IMPINP		;NO, ONE MORE 1WD BLOCK AT NEXT LOC
	MOVEM T1,IMIDSP		;AND UPDATE DISPATCH ADDR TO HANDLE IT.
	MOVE T1,[MSEC1,,IMIN2]
	EXCH T1,IMIDSP		; ..
	DATAO ANI,IMPINP	;TELL IT THIS NEW BLOCK
	CONO ANI,ANIM36+ANIBSY+ANXCHS ;TURN IT ON FOR 36 MORE BITS.
	XJEN ANIVI1		;DISMISS THE INTERRUPT
> ;END REPEAT 0
;HERE AT PI LEVEL AFTER SECOND WORD OF BUFFER HAS BEEN READ.
;IF NOT END OF MESSAGE, USE THIS MUCH INFO TO DECIDE WHETHER TO
;READ THE REST OF THE MSG IN 36 OR 32 BIT MODES.

IMIN2:	CONSZ ANI,ANIDON	;END OF MESSAGE YET?
	JRST IMPEIN		;YES. GO PROCESS 2 WD OR LESS MSG
	MOVEM T1,IMIDSP		;NO. NEED AN AC. STORE IT.
	MOVEI T1,MAXWPM		;WHAT IS BIGGEST MSG WE CAN HANDLE?
	SUBI T1,3		;LESS LINK AND 2 WDS READ ALREADY
	STOR T1,IMWDCT,IMPINP	;SET THE WORD COUNT
	MOVE T1,IMIB		;WHERE THE BUFFER STARTS
	ADDI T1,3		;BUT SKIP LINK AND 2 WDS ALREADY IN
	STOR T1,IMBFAD,IMPINP	;STORE THE STARTING ADDRESS
	DATAO ANI,IMPINP	;THIS IS THE AN10 WC/ADDR WORD
	MOVE T1,IMIB		;NOW GO BACK AND DECIDE ON WORD SIZE
	MOVE T1,1(T1)		;GET IMP-HOST LEADER
	ANDX T1,<LD%FIM!LD%MST!LD%LNK> ;GET TYPE AND LINK FIELDS
				; *** - THIS IS SHORT LEADER FORMAT
	CAMLE T1,[MAXNCP]	;IS IT A REGULAR MSG ON NCP LINK?
	JRST IMIN2A		;NO. SO READ IT IN 36 BIT MODE.
	MOVE T1,IMIB		;YES. IT HAS A CONNECTION SIZE FIELD
	MOVE T1,2(T1)		;IN THIS WORD.
	TXNE T1,7B11		;CONN SIZE DIVISIBLE BY 8?
	JRST IMIN2A		;NO. READ IN 36 BIT MODE
	CONO ANI,ANIBSY+ANXCHS	;YES. READ IN 32 BIT MODE.
	SKIPA			; ..
IMIN2A:	CONO ANI,ANIM36+ANIBSY+ANXCHS ;READ IN 36 BIT MODE.
	MOVE T1,[MSEC1,,IMIN3]	;SET DISPATCH FOR NEXT INTERRUPT
	EXCH T1,IMIDSP		;AND RESTORE THE SCRATCH AC
	XJEN ANIVI1		;DISMISS THIS INTERRUPT.



;HERE ON INTERRUPT LEVEL FOR BODY OF MESSAGE FROM IMP.

IMIN3:	CONSZ ANI,ANIDON	;I HOPE IT FIT IN THE BUFFER.
	JRST IMPEIN		;GOOD. IT DID.
	AOS IMPIOV		;IT DIDN'T. FLAG THAT IT'S TOO LONG.
	DATAO ANI,IMPINP	;GIVE IT SAME BUFFER AREA TO RUN OVER
	CONO ANI,ANIBSY+ANXCHS	;KEEP READING UNTIL END COMES ALONG.
	XJEN ANIVI1		;WAIT FOR NEXT INTERRUPT. END, PLEASE?
;HERE WHEN END MSG RECD FROM IMP

IMPEIN:	MOVEM T4,IMPIAC+4	;SAVE T4
	MOVEI T4,IMPIAC		;SET UP BLT POINTER
	BLT T4,IMPIAC+3		;SAVE AC'S
	MOVEM P,IMINP		;SAVE P
	MOVE P,PIMSTK		;SETUP LOCAL STACK
	PUSH P,CX		;SAVE CX
	CONSZ ANI,ANIIWD!ANIIID	;IMP IS OR WAS DOWN?
	CALL IMIERR		;TAKE CARE OF IT
	CONO ANI,ANXWAR		;SELECT WC/ADDR REGISTER, CLEAR PIA
	DATAI ANI,IMPINP	;READ CURRENT ADDRESS
	SKIPG T1,IMIB		;BFR ADDRESS
	JRST IMPEI2		;WASN'T ONE
	AOSG IMPFLS		;FLUSHING MSGS?
	JRST IMPEI3		;YES, RETURN BUFFER TO FREE LIST
	SKIPE IMPIOV		;GOT AN OVERFLOW?
	JRST IMPEI6		;YES, REPORT IT AND RETURN TO FREE LIST
	MOVE T2,1(T1)		;GET HEADER
	LOAD T3,LD%MST,T2	;AND MESSAGE TYPE
	ANDX T2,<LD%FIM!LD%LNK>	;GET FROM IMP BIT AND LINK NUMBER
	CAIN T3,6		;DEAD HOST STATUS
	JRST IMPEI4		;YES. HAS NO MESSAGE ID
	CAIN T3,17		;LONG FORMAT MESSAGE?
	JRST IMPEI5		;YES.
	CAIE T3,2		;GOING DOWN?
	CAMG T2,[MAXNCP]	;ABOVE HOST TO HOST LINKS
	JUMPN T3,IMPEI4		;IRREGULAR MSG NOT SPECIAL LINK
	HRRZS 0(T1)		;CLEAR FORWARD POINTER, LEAVING LENGTH
	MOVE T3,IMPIBI		;GET ADDRESS OF LAST BUFFER ON IN QUEUE
	JUMPN T3,IMPEI1		;BUFFERS ON QUEUE?
	MOVEM T1,IMPIBO		;NO.  MUST UPDATE REMOVAL POINTER TOO
	SKIPA			;AND SKIP PUTTING BUFFER ON THE CHAIN
IMPEI1:	HRLM T1,0(T3)		;ADD BFR TO IN QUEUE
	MOVEM T1,IMPIBI		;WHENCE NCPFRK WILL DISTRIBUTE IT
	HRRZ T3,0(T1)		;GET SIZE FIELD
	CAILE T3,MAXWPM		;MAKE SURE NOT RELEASED
	BUG (HLT,IMPAUF,<IMPEIN: BUFFER ON FREELIST USED FOR INPUT>)

REPEAT 0,<			;THIS CODE SHOUD BE REPLACED IF BUFFER
				;SIZE CHANGES
	ADD T1,0(T1)		;COMPUTE TAIL OF BFR
	SOS T1			;POINT TO LAST WORD IN BUFFER
	CALL MULKMP		;UNLOCK IT
> ;END OF REPEAT 0

	LOAD T3,IMBFAD,IMPINP	;GET LAST LOC WITH DATA +1
	MOVE T4,IMIB		;START ADDRESS OF BUFFER
	SUB T3,T4		;T3=END+1-(START)=ACTUAL COUNT
	HRRM T3,0(T4)		;RECORD ACTUAL COUNT IN BUFFER HEADER
	AOS IMPFLG		;REQUEST JOB 0 SERVICE
IMPEI2:	SETZM IMIB
	SKIPLE IMPNFI		;MORE BUFFERS AVAILABLE?
	 CALL IMISRT		;YES, START NEW INPUT
	POP P,CX		;RESTORE CX
	MOVE P,IMINP		;RESTORE P
	MOVSI T4,IMPIAC		;RESTORE AC'S
	BLT T4,T4
	XJEN ANIVI1		;AND DISMISS INPUT INTERRUPT
IMPEI4:	MOVE T2,1(T1)		;GET HEADER
	CALL IMP8XQ		;PUT ON IRREG MSG Q
	AOS IMPFLG		;REQUEST JOB 0 SERVICE
IMPEI3:	MOVE T2,T1		;SAVE CURRENT BUFFER ADDRESS
	EXCH T1,IMPFRI		;EXCHANGE IT WITH TOP OF FREE LIST
	HRLM T1,0(T2)		;MAKE IT POINT TO OLD TOP OF LIST
	AOS IMPNFI		;ICREMENT COUNT OF FREE BUFFERS
	JRST IMPEI2



;HERE ON LONG FORMAT MESSAGE. BETTER BE A NEW NOP. CHECK SITE
;ADDRESS TO MAKE SURE NLHOST IS CORRECT.

IMPEI5:	LDB T3,[POINT 8,1(T1),31] ;MESSAGE TYPE
	CAIE T3,4		;NO-OP?
	JRST IMPEI3		;NO, DISCARD THE MSG
	MOVE T2,2(T1)		;YES. GET THE IMP'S IDEA OF MY ADDRESS
	LSH T2,-10		;(THE IMP OUGHTA KNOW)
	XOR T2,NLHOST		;CHECK THE IMP NUMBER
	MOVE T3,2(T1)		;AGAIN, FOR HOST ON IMP
	LSH T3,-22		;LINE UP THE HOST FIELD
	XOR T3,NLHOST		;COMPARE THEM
	TRNN T2,77		;IS THE IMP NUMBER RIGHT?
	TRNE T3,37700		;AND THE HOST NUMBER RIGHT?
	BUG(CHK,IMPHNW,<LHOSTN DISAGREES WITH THE IMP>)
	JRST IMPEI3		;THROUGH WITH THIS MSG.



;HERE TO REPORT AN OVERFLOW ON INPUT AND FREE UP THE BUFFER

IMPEI6:	PUSH P,T1		;SAVE BUFFER ADDRESS
	MOVE T3,IMPIOV		;GET OVERFLOW COUNT
	MOVE T4,IMPINP		;GET RESIDUAL COUNT
	MOVE T2,2(T1)		;GET SECOND WORD OF MESSAGE
	MOVE T1,1(T1)		;GET FIRST WORD OF MESSAGE
	BUG(INF,IMPOFL,<MESSAGE BUFFER OVERFLOW>,<T1,T2,T3,T4>)
	POP P,T1		;RESTORE BUFFER POINTER
	JRST IMPEI3		;GO RELEASE BUFFER
;IMIERR - IMP INPUT ERROR ROUTINE
;THIS ROUTINE IS CALLED IF THE IMP IS DOWN OR HAS BEEN DOWN.
;IT CLEARS THE IMP WAS DOWN FLAG AND SETS THINGS UP FOR JOB 0
;TO RESTART THE IMP

IMIERR:	PUSH P,T1		;SAVE T1
	SETOM IMPRDL		;BE SURE THIS FLAP GETS NOTICED
	SETZM IMPRDY		;INDICATE IMP NOT UP TO GET IT RESTARTED
	MOVNI T1,2
	MOVEM T1,IMPFLS		;FLUSH 2 MESSAGES
	MOVNM T1,NOPCNT		;SEND SOME NOPS
	CONI ANI,T1		;SEE IF PIA'S ARE NOW ON
	BUG(INF,IMINX2,<IMIERR CALLED, CONI ANI IS>,<T1>)
	ANDI T1,77		;SAVE THE PI CHANNELS
	CONO ANI,ANICLE(T1)	;CLEAR THE ERROR FLOP
	JRST PA1		;RESTORE T1, RETURN.
;PI SERVICE FOR OUTPUT

;HERE AFTER "OUT DONE" INTERRUPT FOR A REAL BUFFER

IMODN0:	MOVEM T4,IMPIAC+4	;SAVE T4
	MOVEI T4,IMPIAC		;SET UP FOR BLT
	BLT T4,IMPIAC+3		;SAVE AC'S
IMODN1:	MOVEM P,IMINP		;SAVE P
	MOVE P,PIMSTK		;SET UP STACK
	PUSH P,CX		;CALLING ROUTINE OUSIDE THIS MODULE SAVE CX
	CALL IMODUN		;POST COMPLETION, FREE THE BUFFER
	MOVE T1,IMPOB		;GET ADDRESS OF OUTPUT BUFFER
	CALL IMULKB		;UNLOCK BFR
	JSP T4,IMPIOU		;SELECT ANOTHER MSG TO SEND, IF ANY.
	POP P,CX		;RESTORE CX
	MOVE P,IMINP		;RESTORE AC P
IMPUBO:	MOVSI T4,IMPIAC		;RESTORE TEMP AC'S
	BLT T4,T4
	XJEN ANOVI1		;AND DISMISS INTERRUPT



;HERE AFTER "OUT DONE" INTERRUPT WHEN NO BUFFER TO RELEASE.

IMODN2:	MOVEM T4,IMPIAC+4	;SAVE T4
	MOVEI T4,IMPIAC		;SET UP FOR BLT
	BLT T4,IMPIAC+3		;SAVE AC'S
	JSP T4,IMPIOU		;START NEXT MSG IF ANY
	JRST IMPUBO
;ROUTINE TO START MSG GOING OUT. CALLED AT PI LEVEL, AND AT
;MAIN LEVEL IF NO OUTPUT IN PROGRESS

IMPXOU::PIOFF
	SKIPN IMPOB		;ANY OUTPUT IN PROGRESS?
	JRST IMPXO1		;NO
	PION			;YES, TURN PI BACK ON
	JRST (T4)		;AND RETURN

IMPXO1:	SETOM IMPOB		;MARK OUTPUT IN PROGRESS
	PION			;NO IT'S OK TO TURN PI BACK ON
IMPIOU:	SKIPLE NOPCNT		;ANY NOP'S TO SEND?
	JRST IOUNOP		;YES, GO SEND THEM
	MOVE T1,IMPHBO		;HI PRIORITY MSG WAITING?
	JUMPE T1,IMPIOL		;NO, CHECK LO PRIORITY
	HLRZ T2,0(T1)		;GET NEXT BUFFER
	JUMPN T2,IMPOU1		;IS THERE A ONE?
	SETZM IMPHBI		;NO. ZERO BUFFER POINTER FOR ADDING
	SKIPA			;AND SKIP ADDING SEC. NO. SO PTR = 0
IMPOU1:	HRLI T2,ANBSEC		;SET SECTION NUMBER
	MOVEM T2,IMPHBO		;SET HIGH PRI OUT POINTER
	JRST IMPIOC		;GO FINISH UP BUFFER POINTER TO BY T1

IMPIOL:	MOVE T1,IMPOBO		;MSG WAITING TO GO OUT?
	JUMPE T1,[SKIPE T2,HSTGDM ;IS HOST GOING DOWN
		 JRST IOUIRG	;YES.  SEND THE HOST GOING DOWN MSG
		CONO ANO,0	;NONE TO SEND. TURN OFF OUTPUT.
		MOVE T1,[MSEC1,,IMODN2] ;DISPATCH WHEN IT IS TURNED ON
		MOVEM T1,IMODSP
		SETZM IMPOB	;ZERO BUFFER POINTER
		JRST 0(T4)]	;RETURN
	HLRZ T2,0(T1)		;GET NEXT BFR POINTER
	JUMPN T2,IMPOU2		;IS THERE A ONE?
	SETZM IMPOBI		;NO. ZERO BUFFER POINTER FOR ADDING
	SKIPA			;AND SKIP ADDING SEC. NO. SO PTR = 0
IMPOU2:	HRLI T2,ANBSEC		;SET SECTION NUMBER
	MOVEM T2,IMPOBO		;SET OUT PUT POINTER
IMPIOC:	MOVEM T1,IMPOB		;INDICATE CURRENT OUTPUT BUFFER
	HRRZ T3,0(T1)		;GET COUNT OF WORDS IN MSG
	SOS T3			;SUBTRACT ONE FOR LINK,,COUNT WORD
	MOVE T2,1(T1)		;GET HEADER
	ANDX T2,<LD%FIM!LD%LNK>	;GET FROM IMP BIT AND LINK NUMBER
	CAMLE T2,[MAXNCP]	;SPECIAL MESSAGE?
	SKIPA T2,[<^D36>B11]	;YES, ASSUME 36-BIT MODE
	MOVE T2,2(T1)		;WORD WITH BYTE SIZE IN IT
	AOS T1			;T1 = ADDRESS OF FIRST WORD TO GO OUT
	TXNE T2,<7B11>		;SIZE DIVISIBLE BY 8?
	JRST IMO36		;NO.  GO DO 36 BIT TRANSFERS
	SUBI T3,2		;NUMBER WORDS LEFT AFTER HEADER
	STOR T3,IMWDCT,IMPOUP	;PUT COUNT IN RIGHT FIELD
	MOVE T2,T1		;GET BUFFER ADDRESS
	ADDI T2,2		;FIRST WORD TO SEND AFTER HEADER
	STOR T2,IMBFAD,IMPOUP	;SAVE TO SET AFTER FIRST INTERRUPT
	MOVE T2,[MSEC1,,IMO32]	;TRANSMIT IN 32-BIT DISPATCH
	TLO T1,(2B12)		;WORD COUNT FIELD FOR LEADER
	SKIPLE T3		;ANY WORDS BEYOND HEADER?
	TDZA T3,T3		;YES.
IMPIO3:	MOVEI T3,ANOEND		;NO. SET END BIT IN THIS POINTER.
	MOVEM T2,IMODSP		;SETUP DISPATCH
	CONO ANO,ANXWAR		;SELECT WD CT/ADDRESS REGISTER
	DATAO ANO,T1		;SET WORD COUNT / ADDRESS
	CONO ANO,ANOM36+ANOBSY+ANOCLE+ANXCHS(T3) ;SEND MESSAGE
	JRST 0(T4)


;HERE TO SET UP TO SEND ENTIRE MESSAGE IN 36 BIT MODE.

IMO36:	STOR T3,IMWDCT,T1	;PUT COUNT IN RIGHT FIELD
	MOVEM T1,IMPOUP		;SAVE OUTPUT WD CT/ ADDRESS WORD
	MOVE T2,[MSEC1,,IMODN0]	;36 BIT DISPATCH
	JRST IMPIO3		;GO START TRANSFER
;IOUNOP - SEND NOP'S

IOUNOP:	SOS NOPCNT
	MOVE T2,[BYTE (8)4,0,0,0]
IOUIRG:	SETOM IMPOB		;MARK OUTPUT IN PROGRESS
	MOVEM T2,IMOIRD		;IRREG MSG DATA TEMP
	CONO ANO,ANXWAR		;SET FOR WD CT / ADDR REGISTER
	DATAO ANO,[1B12+MSEC1B+IMOIRD] ;TELL IT TO GET THIS DATA WORD
	CONO ANO,ANOBSY+ANOEND+ANXCHS ;SEND A 32 BIT MSG
	MOVE T1,[MSEC1,,IMODN2]
	MOVEM T1,IMODSP
	JRST (T4)


;HERE ON INTERRUPT AFTER SENDING 72 BITS AND WHEN WANT TO
;SWITCH TO 32 BIT WORDS OF OUTPUT.

IMO32:	CONSZ ANO,ANODON	;WAS IT SHORT?
	JRST IMODN0		;YES.
	DATAO ANO,IMPOUP	;NO. SEND REMAINING COUNT AND ADDRESS
	CONO ANO,ANOBSY+ANOEND+ANXCHS ;THIS WILL BE THE END OF IT.
IMO3X:	MOVEM T1,IMODSP		;NOW SET DISPATCH FOR FINAL INTRPT
	MOVE T1,[MSEC1,,IMODN0]	;TO GO HERE.
	EXCH T1,IMODSP
	XJEN ANOVI1		;DISMISS VECTORED INTERRUPT.
;IMPRLQ - CHECK IMP STATUS
;RETURNS +1 IF IMP IS NOT READY
;RETURN +2 IF IMP IS READY

IMPRLQ::PUSH P,T1		;SAVE AN AC
	CONI ANI,T1		;GET CURRENT STATUS
	TLNE T1,(1B4+1B5)	;IS IT POWERED UP, WITH A CABLE IN IT?
	TRNE T1,ANIIID		;YES. IS READY LINE ALSO OK?
	SKIPA			;NO, IT ISN'T READY.
	AOS -1(P)		;ALL IS WELL. SKIP RETURN.
	JRST PA1		;RESTORE AC1 AND RETURN



;HERE FROM DOWN-SEQUENCE PROCESSING IN NCPFRK TO COMPLETELY
;SHUT OFF THE HARDWARE DEVICE

IDVKIL::CONO ANO,0		;TURN OFF OUTPUT SIDE
	CONO ANI,ANIRST		;CLEAR DEVICE
	CONO ANI,ANXVAR		;SELECT VECTOR INTERRUPT ADDRESS REG.
	DATAO ANI,[<0*ANIHRL>+MSEC1B+ANIVIL] ;CLEAR READY,
				; LEAVE VECTOR INTERRUPT ADDRESS ALONE.
	RET



;CALL HERE FROM IMPINI (ONLY FROM NCPFRK) AT INITIALIZATION OF
;BACKGROUND FORK - NOT ON EVERY RECYCLE OF READY LINE.

IMPRSD::MOVE T1,[MSEC1,,IMIN0X]	;RESET DISPATCHES
	MOVEM T1,IMIDSP		;INPUT PI DISPATCH TO DISCARD DATA
	MOVE T1,[MSEC1,,IMODN2]	;OUTPUT PI DISPATCH TO START NEW MSG
	MOVEM T1,IMODSP
	RET
;CALL HERE FROM NCPFRK, PROCESS LEVEL, WHEN IMP IS WANTED UP
;BUT NET IS CURRENTLY DOWN.

IMPRSS::CALL IMPRLQ		;IS IMP ON AND READY?
	 RET			;NO, STOP HERE
	CALL IMPRSN		;RESET VARIABLES
	SETZM IMPRDL		;AND NOTICES OF IMP ERROR
	CONO ANI,ANIRST		;CLEAR THE DEVICE
	CONO ANI,ANXVAR+ANICLE	;SET VECTOR ADDRESS WORDS
	DATAO ANI,[ANIHRL+MSEC1B+ANIVIL] ;SET THE HOST READY LINE
	CONO ANO,ANOCLE+ANXVAR	;SAME FOR OUTPUT
	DATAO ANO,[MSEC1,,ANOVIL] ;VECTOR INT LOCATION FOR OUTPUT
	SETZM IMPDRQ		;FORGET ANY INTERVENING DOWN REQUESTS
	MOVNI T1,2
	MOVEM T1,IMPFLS		;INITIAL FLUSH COUNT
	MOVEI T1,3
	MOVEM T1,NOPCNT		;SEND 3 NOP'S
	MOVEI T1,^D1000
	DISMS			;ALLOW TIME FOR READY LINE TO SETTLE
	AOS NETTCH		;CAUSE CHANGE IN STATE TO BE NOTED
	AOS JB0FLG		;REQUEST JOB 0 TO RUN
	GTAD			;GET TIME
	MOVEM T1,NCPUPT		;SAVE TIME WHEN IT CAME UP
	JSP T4,IOUNOP		;TELL OUTPUT SIDE TO GO AND SEND A NOP
	SKIPLE IMPNFI		;IF INPUT BFRS AVAILABLE,
	 CALL IMISRT		;START INPUT
	SETOM IMPRDY		;SAY IMP IS UP
	SETOM IMPORD		;ALLOW OUTPUT
	MOVE T1,NLHOST		;LOCAL HOST
	CALL IMPRRP		;SEND OURSELVES AN RRP
	RET

	TNXEND
	END ; OF IMPPHY