Google
 

Trailing-Edge - PDP-10 Archives - custsupcuspmar86_bb-x130b-sb - d78int.mac
There are 5 other files named d78int.mac in the archive. Click here to see a list.
TITLE	D78INT - INTERRUPT SERVICE ROUTINE FOR THE DAS78  V052
SUBTTL	DMCC+EGF/EGF/DMCC  10 SEP 85
	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.
;
.CPYRT<1974,1986>
;COPYRIGHT (C) 1974,1975,1976,1977,1978,1979,1980,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.


;
XP VD78INT,052		;PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP

	ENTRY	D78INT		;ENTRY POINT SO LINK WILL LOAD D78INT IN LIBRARY SEARCH MODE
D78INT::

IFNDEF	D78TRC,<D78TRC==0>		;DEFINE D78TRC TO BE NON 0
					; IF TRACING FEATURE IS DESIRED
IFN	D78TRC,<
	IFNDEF	TRCNUM,<TRCNUM==^D100>	;TRCBUF WILL CONTAIN 100*STOREN ENTRIES
	IFNDEF	PATD78,<PATD78==^D25>	;WORDS OF PATCH SPACE IN D78PAT
	IF2,<PRINTX TRACING ENABLED IN D78INT.>
>;END IFN D78TRC

	DEFINE	TRACE,<
IFN	D78TRC,<	PUSHJ	P,TRACE.		;TAKE A TRACE>
>;END DEFINE TRACE
;DL10 HARDWARE IO BITS


	DLB==	060		;DL10 BASE ADDRESS REGISTER

	DLC==	064		;DL10 CONTROL REGISTER

	;DATAO DLC BIT DEFINITIONS FOLLOW

	B.CSB=		1B0	;CLEAR SELECT BITS (LEFT HALF)
	B.SSB==		1B1	;SET SELECTED BITS (LEFT HALF)
	;		1B2	;NOT USED
	B.NXM3==	1B3	;PDP11 #3 NXM 11 INTERRUPT
	B.PE3==		1B4	;PDP11 #3 PAR ERR 11 INTERRUPT
	B.WCO3==	1B5	;PDP11 #3 WORD COUNT OVERFLOW 11 INTERRUPT
	B.NXM2==	1B6	;PDP11 #2 NXM 11 INTERRUPT
	B.PE2==		1B7	;PDP11 #2 PAR ERR 11 INTERRUPT
	B.WCO2==	1B8	;PDP11 #2 WORD COUNT OVERFLOW 11 INTERRUPT
	B.NXM1==	1B9	;PDP11 #1 NXM 11 INTERRUPT
	B.PE1==		1B10	;PDP11 #1 PAR ERR 11 INTERRUPT
	B.WCO1==	1B11	;PDP11 #1 WORD COUNT OVERFLOW 11 INTERRUPT
	B.NXM0==	1B12	;PDP11 #0 NXM 11 INTERRUPT
	B.PE0==		1B13	;PDP11 #0 PAR ERR 11 INTERRUPT
	B.WCO0==	1B14	;PDP11 #0 WORD COUNT OVERFLOW 11 INTERRUPT
	;		1B15	;NOT USED
	;		1B16	;NOT USED
	B.KAIN==	1B17	;1 = KA10 INTERRUPT, 0 = KI10 INTERRUPT.
	;		1B18	;NOT USED
	;		1B19	;NOT USED
	;		1B20	;NOT USED
	B.STP3==	1B21	;PDP11 #3  STOP
	B.STR3==	1B22	;PDP11 #3  START
	;		1B23	;NOT USED
	B.STP2==	1B24	;PDP11 #2  STOP
	B.STR2==	1B25	;PDP11 #2  START
	;		1B26	;NOT USED
	B.STP1==	1B27	;PDP11 #1  STOP
	B.STR1==	1B28	;PDP11 #1  START
	;		1B29	;NOT USED
	B.STP0==	1B30	;PDP11 #0  STOP
	B.STR0==	1B31	;PDP11 #0  START
	;		1B32	;NOT USED
	;		1B33	;NOT USED
	;		1B34	;NOT USED
	;		1B35	;NOT USED

	;DATAI BIT DEFINITIONS FOLLOW

	;BITS 0-2		NOT USED
	;BITS 3-14		SAME AS DATAO DLC
	;BITS 15-20		NOT USED
	B.JE3==		1B21	;PDP11 #3  J EXIST 3
	B.CRD3==	1B22	;PDP11 #3  CON 3 RUN DELAY
	B.CRP3==	1B23	;PDP11 #3  CON 3 REM POWER
	B.JE2==		1B24	;PDP11 #2  J EXIST
	B.CRD2==	1B25	;PDP11 #2  CON 2 RUN DELAY
	B.CRP2==	1B26	;PDP11 #2  CON 2 REM POWER
	B.JE1==		1B27	;PDP11 #1  J EXIST
	B.CRD1==	1B28	;PDP11 #1  CON 1 RUN DELAY
	B.CRP1==	1B29	;PDP11 #1  CON 1 REM POWER
	B.JE0==		1B30	;PDP11 #0  J EXIST
	B.CRD0==	1B31	;PDP11 #0  CON 0 RUN DELAY
	B.CRP0==	1B32	;PDP11 #0  CON 0 REM POWER
	;		1B33	;NOT USED
	;		1B34	;NOT USED
	;		1B35	;NOT USED

	;CONO DLC BIT DEFINITIONS FOLLOW

	;BITS 0-17		DIAGNOSTIC INFORMATION
	B.INIT==	1B18	;CLEAR ALL BITS AND REGISTERS
	B.LOCK==	1B19	;SET I/O BUS LOCK
	B.SET==		1B20	;IF 1: SET ANY SELECTED BITS (21-32)
				;   0: CLEAR ANY SELECTED BITS (21-32)
	B.11I3==	1B21	;INTERRUPT PDP11 #3
	B.11E3==	1B22	;ENABLE PDP11 #3 PORT
	B.10I3==	1B23	;PDP10 INTERRUPT FROM PDP11 #3
	B.11I2==	1B24	;INTERRUPT PDP11 #2
	B.11E2==	1B25	;ENABLE PDP11 #2 PORT
	B.10I2==	1B26	;PDP10 INTERRUPT FROM PDP 11 #2
	B.11I1==	1B27	;INTERRUPT PDP11 #1
	B.11E1==	1B28	;ENABLE PDP11 #1 PORT
	B.10I1==	1B29	;PDP10 INTERRUPT FROM PDP 11 #1
	B.11I0==	1B30	;INTERRUPT PDP11 #0
	B.11E0==	1B31	;ENABLE PDP11 #0 PORT
	B.10I0==	1B32	;PDP10 INTERRUPT FROM PDP11 #0
	B.PIA7==	7	;PIA LEVEL 7
	B.PIA6==	6	;PIA LEVEL 6
	B.PIA5==	5	;PIA LEVEL 5
	B.PIA4==	4	;PIA LEVEL 4
	B.PIA3==	3	;PIA LEVEL 3
	B.PIA2==	2	;PIA LEVEL 2
	B.PIA1==	1	;PIA LEVEL 1
	B.PIA0==	0	;PIA LEVEL 0

	;CONI DLC BIT DEFINITIONS FOLLOW

	;BITS 0-6		;NOT APPLICABLE
	B.8PA3==	1B8	;INDICATES 8K OPTION INSTALLED ON PORT #3
	B.8PA2==	1B9	;INDICATES 8K OPTION INSTALLED ON PORT #2
	B.8PA1==	1B10	;INDICATES 8K OPTION INSTALLED ON PORT #1
	B.8PA0==	1B11	;INDICATES 8K OPTION INSTALLED ON PORT #0
	;BITS 12-16		;NOT APPLICABLE
	B.KA10==	1B17	;IF 0:  INTERRUPTS WILL OCCUR IN KA STYLE
				;   1:  INTERRUPTS WILL OCCUR IN KI STYLE
	;		1B18	;NOT USED
	B.WIN==		1B19	;SUCCESS IN LOCKING
	;		1B20	;NOT USED
	;BITS 21-35		;SEE CONO DLC FOR INFORMATION READ BACK

	BUFSIZ==	201	;DEFAULT DAS78 BUFFER LENGTH
	MAXBUF==	^D256	;MAXIMUM BUFFER SIZE ALLOWED
	LPTNFF==	1B29	;SUPPRESS FREE FORM FEEDS

;BIT DEFINITIONS IN DEVIOS
;
	XCLOSE==	1B0	;SET IF WAITING FOR CLOSE TO HAPPEN
	RDYWAT==	1B1	;SET IF WAITING FOR 11 TO BECOME RDY
	ENBSET==	1B2	;ENABLE (1B27) HAS BEEN SET IN "WS8LS0"
				; BY THE CAL78 UUO

;WINDOW SLOT DEFINITIONS:
;
	OCOD10==	3B35	;MASK FOR OUT TRANSLATION CODE
	OWIL10==	1B33	; 10 OUTPUT WILLING
	OEF10==		1B32	; 10 END OF FILE  (CLOSING)
	;OABA10==	1B31	; 10 OUTPUT ABORT ACKNOWLEDGE
	OAB10==		1B30	; 10 OUTPUT ABORT
	OPAUSE==	1B29	; OUTPUT PAUSE

	ICOD10==	3B27	; 10 INPUT TRANSLATION CODE
	IWIL10==	1B25	; 10 INPUT WILLING
	IEFA10==	1B24	; 10 INPUT END OF FILE ACKNOWLEDGE (CLOSING)
	;IABA10==	1B23	; 10 INPUT ABORT ACKNOWLEDGE
	IAB10==		1B22	; 10 INPUT ABORT
	IPAUSE==	1B21	; INPUT PAUSE

	ORDY11==	1B33	; 11 OUTPUT READY
	OEFA11==	1B32	; 11 OUTPUT END OF FILE ACKNOWLEDGE
	OAB11==		1B31	; 11 OUTPUT ABORT
	;OABA11==	1B30	; 11 OUTPUT ABORT ACKNOWLEDGE
	OPAUSE==	1B29	; OUTPUT PAUSE

	IRDY11==	1B25	; 11 INPUT READY
	IEF11==		1B24	; 11 INPUT END OF FILE (CLOSING)
	IAB11==		1B23	; 11 INPUT ABORT
	;IABA11==	1B22	; 11 INPUT ABORT ACKNOWLEDGE
	IPAUSE==	1B21	; INPUT PAUSE

;WINDOW DEFINITIONS FOR GLOBAL STATUS
;
	D78DEP==	1B35	;DEPOSIT
	D78EXM==	1B34	;EXAM
	D78BAD==	1B33	;BAD ADDRESS
	D78HLD==	1B32	;HOLD

	S0.ENB==	1B27	;ENABLE LINE
	S0.NFF==	1B28	;SUPPRESS FORM FEED ON OPEN

	SX.IBN==	1B27	;BINARY MODE INPUT
	SX.OBN==	1B35	;BINARY MODE OUTPUT

;BYTE POINTER FORMAT FOR DL10  OPERATION
;
;	BITS 0-2=P POSITION OF BYTE IN 10 WORD(EXCEPT FOR S=0 OR 7)
;		P=0 IS LEFTMOST BYTE, ETC.
;
;	BITS 3-5=S	BITS 6-13=WORD COUNT	BITS 18-35=ADR
;
; VALUES OF S ARE:
;
;	S=0/16BITS	IMMEDIATE = BITS 18=35 ARE DATA
;	S=1/16BITS	NOT IMMED - BITS 18-35 AND P DETERMINE LOC IN 10 MEMORY
;	S=2/16BITS	INC POINTER
;	S=3/12BITS	INC POINTER
;	S=4/8BITS	INC POINTER
;	S=5/7BITS	INC POINTER
;	S=6/6BITS	INC POINTER

;MACRO TO BUILD DL10 POINTERS
; 1ST ARG IS SIZE OF BYTE
; 2ND ARG IS NUMBER OF BYTES
; 3RD ARG IS ADR

DEFINE PNTR (A,B,C) <
IFE <A-^D16>,<
	QQ=<B+1>/2
	Q=2>
IFE <A-^D12>,<
	QQ=<B+2>/3
	Q=3>
IFE <A-^D08>,<
	QQ=<B+3>/4
	Q=4>
IFE <A-^D07>,<
	QQ=<B+4>/5
	Q=5>
IFE <A-^D06>,<
	QQ=<B+5>/6
	Q=6>

	BYTE	(3)7,Q(8)-QQ(22)C

>;END DEFINE PNTR
SUBTTL	DL10 BYTE POINTER DEFINITION

COMMENT	\

	 0    2 3    5 6            13 14                    35
	--------------------------------------------------------
	I      I      I               I                        I
	I	P(3) I S(3) I WORD COUNT(8) I    ADDRESS ADR (22)    I
	I      I      I               I                        I
	--------------------------------------------------------

	P	Position of byte in the PDP10 word
		(except when S=0 OR S=7)

	S	Size of byte in number of bits

	WC	Maximum number of PDP-10 words required
		for this transfer (in negative form)

	ADR	Address of indirect PDP-10 word when transfer
		is not immediate.  Data, when the transfer is immediate,
		resides in bits 20 - 35.


	S	MODE	BITS		FUNCTION

	0	I	16	The byte is put in the right-most 16
				bits, 20-35, of the ADR field of
				the Byte Pointer itself.

	1	NI	16	The byte is in location ADR at a
				position determined by the P field. P
				is not incremented.

	2	NI I	16	The incremented pointer determines the
				byte position.  This is similar to the
				PDP-10 ILDB or IDPB operation and is used
				for packing or unpacking characters in
				PDP-10 memory. The pointer is incremented
				first before packing or unpacking.  When
				P=7, the P field is reset to 0 and no
				increment to the address is performed.

	3	NI I	12	Same as S = 2.

	4	NI I	8	Same as S = 2.

	5	NI I	7	Same as S = 2.

	6	NI I	6	Same as S = 2.

	7	I	16	Same as S = 0.

		I    = Immediate
		NI   = Not Immediate
		NI I = Not Immediate incrementing Byte Pointer

\
SUBTTL	PROTOTYPE DEVICE DATA BLOCKS (DDB'S)

	$LOW
;DAS78 INPUT DDB
;
XXIDDB::PHASE	0
	SIXBIT	/XXI/		;(DEVNAM) PHYSICAL DEVICE NAME AND NUMBER
	XWD	HUNGST*6,BUFSIZ	;(DEVCHR) DEVICE CHARACTERISTICS
	Z			;(DEVIOS) DEVICE STATUS BITS
	XXIDSP			;(DEVSER) ADDRESS OF DEVICE DISPATCH TABLE
	DVIN,,1B<35-A>!1B<35-AL>!1B<35-B>;(DEVMOD) BINARY MODE AND ASCII
	Z			;(DEVLOG) LOGICAL DEVICE NAME
	Z			;(DEVBUF) OUTPUT RNG HDR ADR,INPUT RING HDR ADR
	XWD	0,0		;(DEVIAD) CURRENT INPUT BUFFER ADR
	XWD	0,0		;(DEVOAD) CURRENT OUTPUT BUFFER ADR
	Z			;(DEVSTS) WORD FOR DEVICE CONI
	.TYD78,,DEPEVM		;(DEVSTA)
	Z			;(DEVXTR) EXTRA WORD
	Z			;(DEVEVM)
	Z			;(DEVPSI)
	Z			;(DEVESE)
	Z			;(DEVHCW)
	Z			;(DEVCPU)
	Z			;(DEVISN)
	Z			;(DEVJOB) JOB NUMBER, ETC.
	Z			;(DEVCTR) BUFFER ITEM COUNT FOR SHORT
				;	DISPATCH TABLE DEVICES.
XXILCN:	Z			;BITS 0-17 ARE BYTE COUNT
				; BITS 29-32 = LINE NUMBER ON THE PDP11.
				; BITS 33-35 = PDP11 NUMBER
XXIIOW:	Z			;CONTAINS POINTER TO IOWD LIST
XXICNT:	Z			;USED TO FIGURE TRANSFER LENGTH
XP XXIDDS,.			;DEVICE BLOCK SIZE
	DEPHASE

;DAS78 OUTPUT DDB
;
XXODDB::PHASE	0
	SIXBIT	/XXO/		;(DEVNAM) PHYSICAL DEVICE NAME AND NUMBER
	XWD	HUNGST*6,BUFSIZ	;(DEVCHR) DEVICE CHARACTERISTICS
	Z			;(DEVIOS) DEVICE STATUS BITS
	XXIDSP			;(DEVSER) ADDRESS OF DEVICE DISPATCH TABLE
	DVOUT,,1B<35-A>!1B<35-AL>!1B<35-B>;(DEVMOD) BINARY MODE AND ASCII
	Z			;(DEVLOG) LOGICAL DEVICE NAME
	Z			;(DEVBUF) OUTPUT RNG HDR ADR,INPUT RING HDR ADR
	0			;(DEVIAD) CURRENT INPUT BUFFER ADR
	0			;(DEVOAD) CURRENT OUTPUT BUFFER ADR
	Z			;(DEVSTS) WORD FOR DEVICE CONI
	.TYD78,,DEPEVM		;(DEVSTA)
	Z			;(DEVXTR) EXTRA WORD
	Z			;(DEVEVM)
	Z			;(DEVPSI)
	Z			;(DEVESE)
	Z			;(DEVHCW)
	Z			;(DEVCPU)
	Z			;(DEVISN)
	Z			;(DEVJOB)
	Z			;(DEVCTR) BUFFER ITEM COUNT FOR SHORT
				;	DISPATCH TABLE DEVICES.
XXOLCN:	Z			;BITS 0-17 ARE BYTE COUNT
				; BITS 29-32 = LINE NUMBER ON THE PDP11.
				; BITS 33-35 = PDP11 NUMBER
XXOIOW:	Z			;CONTAINS POINTER TO IOWD LIST
XXOCNT:	Z			;NO USED FOR OUTPUT BUT
				; PUT HERE SO XXI AND XXO DDB'S
				;  ARE SAME LENGTH.
XP XXODDS,.			;DEVICE BLOCK SIZE
	DEPHASE

;CHECK THAT THE XXO + XXI DDB'S ARE THE SAME LENGTH
;
IFN	<XXIDDS-XXODDS>,<PRINTX ?D78INT - LENGTH OF XXO AND XXI DDB'S NOT THE SAME.>

;CHECK THAT THE XXO + XXI DDB'S ARE IN SEQUENCE
;
IFN	<XXOLCN-XXILCN>+<XXOCNT-XXICNT>+<IFN FTKL10,<XXOIOW-XXIIOW>>,<
	PRINTX	?D78INT - XXO AND XXI DDB' ARE OUT## OF SEQUENCE.
>

IF2,<IFE	<FTNET>,<PRINTX	%D78INT REQUIRES FTNET TO BE TURNED ON.>>
	$HIGH
;DAS78 DISPATCH TABLE.
;
	JRST	D78OPN		;(-3) HERE ON AN OPEN TO GET BUFFER SIZ
	JRST	D78SYI		;(-2) INIT THE DEVICE
	JRST	D78HNG		;(-1) CALLED IF DEVICE HUNG
XXIDSP:	JRST	D78REL		;(0) RELEASE
	JRST	D78CLO		;(1) CLOSE
	JRST	D78OUT		;(2) OUTPUT
	JRST	D78IN		;(3) INPUT

;COME HERE IF DEVICE IS HUNG
;
D78HNG:	PUSHJ	P,D78SJU	;POINT TO WINDOW AND WINDOW SLOT
	TRACE				;MAKE A TRACE
	MOVE	T1,DEVMOD(F)	;GET DEVMOD WORD TO SEE IF IN OR OUT
	TLNN	T1,DVIN		;IS IT AN INPUT DEVICE?
	  POPJ	P,			;NO, SO JUST EXIT.
	MOVEI	T1,IAB10	;INPUT ABORT BIT
	MOVEM	T1,WS810S##(U)	;SET INPUT ABORT
	SETZM	WS8IBP##(U)	;CLEAR POINTER
	SETZM	WS8ICC##(U)	;CLEAR COUNT
	PJRST	D78WAK		; AND TELL 11 ABOUT IT.

SUBTTL	DAS78 INTERRUPT SERVICE
	ENTRY	D78KII

;THIS IS ENTERED AFTER AN INTERRUPT WITH:
;
;	J	POINTING TO THE BEGINNING OF THE WINDOW
;	P4	CONTAINS THE PORT NUMBER
;
D78KII::
IFE FTKL10,<
	PUSHJ	P,SAVE4##	;SAVE VALUABLES
>	;END OF IFE FTKL10
	HLRZ	P4,M78PNO##(J)	;GET PORT NUMBER
	HRRZ	J,M78PNO##(J)	;AND WINDOW ADDRESS
	SKIPL	M7810S##(J)	;HAS 10 FINISHED INITIALIZATION ?
	  JRST	D78CKN			;NO YET SO GO CHECK NAME
	SETO	P3,		;MAKE -1 SO INCREMENT STARTS AT LINE 0
	HRRZ	P1,M78XIX##(J)	;GET ACTIVITY WORD
SCAN:	JUMPE	P1,NXTPRT	;IF ACTIVITY WORD 0 LOOK AT NEXT PORT
	  LSHC	P1,-1			;SHIFT INTO P2
	AOJ	P3,		;THIS MAKES P3=TO LINE WE'RE CHECKING
	JUMPGE	P2,SCAN		;SEE IF THAT LINE IS ACTIVE
	  HLRZ	F,M78BAT##(P4)		;SET F TO POINT TO
	ADD	F,P3		; THE DDB FOR THE ACTIVE LINE.
	MOVE	F,(F)		;F NOW POINTS TO DDB
	MOVE	S,DEVIOS(F)	;GET STATUS FROM DDB
	PUSHJ	P,D78SJU	;SET "U" POINTING TO WINDOW SLOT
	TRACE				;MAKE A TRACE

;HERE TO CHECK ABORT BITS
	MOVEI	T1,OAB11	;FLAG 11 IS ABORTING OUTPUT
	TDNN	T1,WS811S##(U)	;DOES 11 WANT TO ABORT OUTPUT?
	  JRST	OUTA11			;11 ISN'T ABORTING NOW
	TDNE	T1,WS810S##(U)	;HAD WE ALREADY SEEN HIS ABORT ?
	  JRST	OUTA15			;YES HAVE ALREADY SEEN HIS ABORT
	SETZM	WS8OBP##(U)	;CLEAR DL10 POINTER IN WINDOW
	SETZM	WS8OCC##(U)	; AND ALSO BYTE COUNT.
	HRRZS	XXOLCN(F)	;NO PARTIAL TO SKIP
	SETZM	XXOIOW(F)	;ZONK SAVED WORD IN DDB
	IORM	T1,WS810S##(U)	;SET FLAG WE SAW HIS ABORT
	MOVEI	S,IODTER	;ABORT GIVES THIS BIT TO USER
	IORB	S,DEVIOS(F)	;PUT INTO DDB
	TRNE	S,IOACT
	  PUSHJ P,IODCLR		;SETIOD + CLRACT
	PUSHJ	P,WKJOB		;WAKE UP LOSING JOB
	MOVEI	T1,ORDY11
	JRST	OUTA14
OUTA11:	TDNN	T1,WS810S##(U)	;DID WE ALREADY SEE HIS ABORT ?
	  JRST	OUTA15			;NEITHER 11 OR 10 OUT ABORT
OUTA14:	IORI	T1,OEF10	;NOT CLOSING EITHER
	ANDCAM	T1,WS810S##(U)	;CLEAR ABORT FROM OUR WORD
	PUSHJ	P,D78WAK	;LET 11 NOTICE WE CLEARED OUR COPY
OUTA15:	MOVEI	T1,OAB10	;FLAG FOR 10 INITIATED ABORT
	TDNN	T1,WS810S##(U)	;HAVE WE SET OUR ABORT BIT ?
	  JRST	NOTOAB
	TDNE	T1,WS811S##(U)	;DID 11 REPLY TO ABORT ?
	  JRST	OUTA14			;11 RESPONDED SO CLEAR OUR BIT
;HERE TO CHECK IF 11 WANTS TO PAUSE OUTPUT
NOTOAB:	MOVEI	T1,OPAUSE	;FLAG 11 WANTS TO PAUSE OUTPUT
	TDNN	T1,WS811S##(U)	;DOES 11 WANT TO PAUSE OUTPUT ?
	  JRST	OUTA24			;NO NOW
;HERE BECAUSE 11 WANTS TO HOLD OFF ON OUTPUT FOR A WHILE
	TDNE	T1,WS810S##(U)	;HAVE WE ALREADY TAKEN ACTION ?
	  JRST	OUTA30			;YES - SO CHECK SOMETHING ELSE
	MOVE	T1,WS8OCC##(U)	;GET REMAINING COUNT FOR THE WINDOW
	SETZM	WS8OCC##(U)	;WE ARE NOW DONE WITH POINTER
	HRLM	T1,XXOLCN(F)	;REMEMBER HOW MANY BYTES ARE LEFT
	SKIPN	T1,XXOIOW(F)	;GET OTHER IOWORD
	  JRST	OUTA20			;IF NONE DON'T COUNT
	PUSHJ	P,MAKPNT	;CALCULATE BYTE COUNT
	HRLZS	T2		;PUT COUNT IN LH
	ADDM	T2,XXOLCN(F)	;AND REMEMBER IT ALSO
OUTA20:	TRNN	S,IOACT
	  JRST	OUTA22
	JSP	T1,RELBA	;RELOCATE
	HRRZ	T1,DEVOAD(F)	;POINT TO BUFFER
	EXCTUX	<HRRZ	T1,1(T1)>	;PICK UP NUMBER OF WORDS IN IT
	TRNE	S,16		;ARE WE BINARY MODE ?
	  IMUL	T1,[-4,,0]		;YEH SO 4 BYTES/WORD
	TRNN	S,16		;CHECK AGAIN
	  IMUL	T1,[-5,,0]		;ASCII = 5BYTES/WORD
	ADDM	T1,XXOLCN(F)	;REMEMBER HOW MANY BYTES TO SKIP
OUTA22:	MOVEI	T1,OPAUSE	;BIT TO ACKNOWLEDGE WE SAW HIS
	IORM	T1,WS810S##(U)	;LET 11 KNOW WE HEARD
	TRNE	S,IOACT		;IS DEVICE ACTIVE ?
	  PUSHJ	P,[	MOVEI	T1,DEPOND	;IN CASE
			ANDCAM	T1,DEVAIO(F)	; NONBLOCKING
			MOVSI	T1,DEPADV	;SO BUFFER ADVANCE
			IORM	T1,DEVADV(F)	; WORKS RIGHT
			JRST	DEVERR## ]	;STOP THE DEVICE
	JRST	OUTA30

OUTA24:	TDNN	T1,WS810S##(U)	;WERE WE PAUSEING IT ?
	  JRST	OUTA30			;NOT PAUSING
	ANDCAB	T1,WS810S##(U)	;CLEAR OUR PAUSE FLAG
	PUSHJ	P,D78WAK	;LET 11 KNOW WE'RE BACK
	PUSHJ	P,JCJOB		;WAKE UP ASSOCIATED JOB
	;JRST	OUTA30
OUTA30:	PUSHJ	P,INTCKE	;CHECK IF ENABLE THERE
	MOVE	M,WS811S##(U)	;GET 11 STATUS
	TLNN	S,IOBEG		;SEE IF VIRGIN BUFFER
	  JRST	ONTVIR			;OUTPUT BUFFER NOT VIRGIN
	AND	M,WS810S##(U)	;AND IN 10 STATUS TO SEE IF
	TRNE	M,ORDY11	; 10 WILLING AND 11 READY (OUTPUT)
	  PUSHJ	P,SWKJOB		;CLEAR IOBEG AND WAKE THE JOB
	MOVE	M,WS811S##(U)	;GET 11 OUT STATUS
ONTVIR:	TLZE	S,(RDYWAT)	;SKIP IF NOT WAITING FOR 11RDY
	  JRST	ORYWAT			;11 IS RDY, SO WAKE JOB.
	MOVE	W,WS810S##(U)	;GET 10 STATUS
	TRCN	W,OEF10		;DOES 10 HAVE OUT CLOSE SET?
	  JRST	NOTC10			;NO, 10 OUT CLOSE NOT SET.
	TRNN	M,OEFA11	;DOES 11 HAVE CLOSE ACK SET?
	  JRST	NOACKC			;NO, 11 CLOSE ACK NOT SET.
	MOVEM	W,WS810S##(U)	;YES, 11 CLOSE ACK SET AND 10 OUT
					; CLOSE IS SET SO CLEAR 10 OUT CLOSE.
	PUSHJ	P,WKJOB
	JRST	OUTWAK		;WAKE 11
NOTC10:	TRNE	M,OEFA11	;10 OUT CLOSE NOT SET BUT IS 11
					; OUT CLOSE ACK SET?
	  JRST	INPLOK			;YES, SO LOOK FOR SOMETHING ELSE TO DO
	TRNN	S,IOACT		;IS I/O ACTIVE SET?
	  JRST	INPLOK			;CAN'T BE OUTPUT SO CHECK INPUT
	JUMPGE	S,NOACKC	;JUMP IF NOT WAITING FOR EOF
	  TLZ	S,(XCLOSE)		;CLEAR CLOSE WAIT
	PUSHJ	P,IODCLR	;GET OUT OF IOW AND MAKE INACTIVE
	JRST	INPLOK		;LOOK FOR WORK
NOACKC:	TRNN	S,IOACT		;IO ACTIVE FOR THIS LINE?
	  JRST	INPLOK			;NO, NOW LOOK AT INPUT
	SKIPE	WS8OCC##(U)	;IS CHARACTER COUNT = 0?
	  JRST	INPLOK			;CHARACTER COUNT NON 0
	SKIPN	T1,XXOIOW(F)	;SEE IF WE HAVE AN IOWD ALREADY FOR USE
	JRST	ADVLOK		;NO, WE HAVE TO MAKE ONE.
	SETZM	XXOIOW(F)	;0 IT SO NEXT TIME WE KNOW TO
	PUSHJ	P,MAKPNT	;CONVERT IOWD AND PUT IN WINDOW
					; FETCH A NEW SET OF WORDS.
	MOVEM	T1,WS8OBP##(U)	;SET BYTE POINTER
	HRRZM	T2,WS8OCC##(U)	;AND COUNT
OUTWAK:	PUSHJ	P,D78WAK	;TELL THE PDP11 HE HAS DATA READY
	JRST	INPLOK		;LOOK FOR MORE TO DO
ADVLOK:	PUSHJ	P,ADVOBF	;ADVANCE BUFFERS
	;JRST	INPLOK			;DO INPUT
;HERE TO HANDLE INPUT
;
INPLOK:	MOVSS	F		;GET INPUT DDB ADDRESS
	MOVE	S,DEVIOS(F)	;GET INPUT STATUS
	TRACE				;MAKE A TRACE

;HERE TO CHECK ABORT STATUS FOR INPUT
	MOVEI	T1,IAB11	;FLAG FOR 11 ABORTED INPUT
	TDNN	T1,WS811S##(U)	;IS 11 ABORTING INPUT ?
	  JRST	INPA12			;11 NOT ABORTING
	TDNE	T1,WS810S##(U)	;HAVE WE ALREADY ACCEPTED ABORT ?
	  JRST	INPA15			;YES
	SETZM	WS8IBP##(U)	;CLEAR DL10 POINTER FOR INPUT
	SETZM	WS8ICC##(U)	;CLEAR WINDOW SLOT COUNTER FOR INPUT
	HRRZS	XXILCN(F)	;NO SKIP COUNT NOW
	SETZM	XXIIOW(F)	;CLEAR 2ND PORTION OF IOWORD
	IORM	T1,WS810S##(U)	;LET 11 KNOW WE AGREE
	MOVEI	S,IODTER	;ABORT GIVES THIS BIT TO USER
	IORB	S,DEVIOS(F)	;PUT INTO DDB
	TRNE	S,IOACT
	  PUSHJ	P,DEVERR##		;GIVE USER BAD NEWS
	PUSHJ	P,WKJOB		;WAKE UP LOSING JOB
	MOVEI	T1,IRDY11
	JRST	INPA14		;
INPA12:	TDNN	T1,WS810S##(U)	;HAD WE SEEN AN ABORT FROM 11 ?
	  JRST	INPA15			;NO
INPA14:	ANDCAM	T1,WS810S##(U)	;CLEAR OUR ACKNOWLEDGE
	PUSHJ	P,D78WAK	;LET 11 KNOW WE CLEARED OURS
INPA15:	MOVEI	T1,IAB10	;FLAG WE ABORTED INPUT
	TDNN	T1,WS810S##(U)	;DID WE ABORT INPUT ?
	  JRST	NOTIAB			;IF NOT WE ARE DONE WITH ABORTS
	TDNE	T1,WS811S##(U)	;DID 11 ACKNOWLEDGE OUR ACTION ?
	  JRST	INPA14			;YES SO CLEAR OUR FLAG
;HERE TO SEE ABOUT PAUSING INPUT

NOTIAB:	MOVEI	T1,IPAUSE	;FLAG 11 WANTS TO STALL INPUT
	TDNN	T1,WS811S##(U)	;IS 11 GETTING TTD'S
	  JRST	INPA24			;NOT NOW

;HERE WHEN 11 WANTS TO PAUSE INPUT
	TRNE	T1,WS810S##(U)	;HAVE WE ALREADY SEEN REQUEST ?
	  JRST	INPA30			;YES
	MOVE	T1,WS8ICC##(U)	;GET REMAINING CHAR COUNT
	SETZM	WS8ICC##(U)	;AND CLEAR WINDOW COPY
	HRLM	T1,XXILCN(F)	;SAVE COUNT

	SKIPN	T1,XXIIOW(F)	;GET 2ND IOWORD
	  JRST	INPA20
	PUSHJ	P,MAKPNT
	HRLZS	T2		;PUT COUNT IN LH
	ADDM	T2,XXILCN(F)	;MAKE TOTAL COUNT LEFT

INPA20:	TRNN	S,IOACT
	  JRST	INPA22
	JSP	T1,RELBA	;MAKE IT ADDRESSABLE
	HRRZ	T1,DEVIAD(F)	;GET ADR OF BUFFER
	EXCTUX	<HRRZ	T1,1(T1)>	;PICK UP NUMBER OF WORDS IN IT
	TRNE	S,16		;CHECK FOR BINARY MODE
	  IMUL	T1,[-4,,0]		;FOUR BYTES / WORD
	TRNN	S,16		;CHECK FOR ASCII
	  IMUL	T1,[-5,,0]		;FIVE BYTES / WORD
	ADDM	T1,XXILCN(F)	;LEAVE NUMBER OF BYTES ALREADY READ
INPA22:	MOVEI	T1,IPAUSE	;BIT TO ACKNOWLEDGE WE SAW FLAG
	IORM	T1,WS810S##(U)	;LET 11 KNOW WE HEARD
	TRNE	S,IOACT		;IS DEVICE RUNNING ?
	  PUSHJ	P,DEVERR##		;STOP IT
	JRST	INPA30

INPA24:	TDNN	T1,WS810S##(U)	;WERE WE PAUSING IT ?
	  JRST	INPA30			;NOT PAUSING
	ANDCAM	T1,WS810S##(U)	;CLEAR OUR PAUSE FLAG
	PUSHJ	P,JCJOB		;WAKE UP ASSOCIATED JOB
	PUSHJ	P,D78WAK
	;JRST	INPA30
INPA30:	PUSHJ	P,INTCKE	;CHECK IF ENABLE THERE
	MOVE	M,WS811S##(U)	;GET 11 STATUS.
	TLNN	S,IOBEG		;DO WE HAVE VIRGIN BUFFERS?
	  JRST	INTVIR			;NO, THEY HAVE BEEN USED.
	AND	M,WS810S##(U)	;IF 10 WILLING AND THE 11 RDY
	TRNE	M,IRDY11	; AND VIRGIN BUFFER, THEN WAKE
	  PUSHJ	P,SWKJOB		;THE JOB AND CLEAR IOBEG
	MOVE	M,WS811S##(U)	;GET 11 STATUS
INTVIR:	TLZE	S,(RDYWAT)	;SKIP IF NOT WAITING FOR 11RDY
	  JRST	IRYWAT			;11 IS RDY, SO WAKE JOB.
	MOVE	W,WS810S##(U)	;GET 10 STATUS
	XOR	M,W		;SEE IF PDP11 AND NOT PDP10 HAS
					;IN EOF BIT UP OR PDP10 AND NOT
					;PDP11 HAS IN EOF BIT UP.
	TRNN	M,IEF11		;SEE IF INPUT EOF BIT IS UP
	  JRST	NIEF			;AFTER XOR BIT NOT UP
	TRNN	W,IEFA10	;IF WE'RE GOING TO SET EOF ACK
					; THEN CLEAR WILLING
	ANDCMI	W,IWIL10		;CLEAR WILLING
	TRCE	W,IEFA10	;CHANGE SENSE OF EOF BIT
					; AND SKIP IF SETTING EOF ACK
	JRST	[SKIPN	WS8IBP##(U)	;HAS LAST BEEN GIVEN TO USER?
		   JRST	IINT01		;YES, CLEAR CLOSE ACK
		 TRNN	S,IOACT		;ARE WE IOACTIVE?
		   JRST	SCAN		;CAN'T CONTINUE
		 MOVEM	W,WS810S##(U)	;CLEAR CLOSE ACK
		 JRST	INTCLO]		; AND FINISH CLOSING
	MOVEM	W,WS810S##(U)	;RESET 10 STATUS
	TRNN	S,IOACT		;IS IO ACTIVE?
	JRST	SCAN		;NO, SO CAN'T FINISH CLOSING.
INTCLO:	PUSHJ	P,IINT05	;GIVE USER LAST DATA
	TLO	S,IOEND		;THIS IS THE END
	PUSHJ	P,ADVBFF##	;CALL UUOCON
	  JFCL				;
IFN FTKL10,<
	PUSHJ	P,CSDMP##
>
	SETZM	WS8ICC##(U)	;CLEAR COUNT
	SETZM	WS8IBP##(U)	;CLEAR POINTER
	SETZM	XXIIOW(F)	;SECOND IO WORD NO GOOD
	JRST	IINT06		;MAKE INACTIVE, SET DEVIOS, AND WAKE THE 11
NIEF:	TRNN	S,IOACT		;IS THE INPUT IO-ACTIVE?
	  JRST	SCAN			;NO, LOOK AT NEXT LINE
	TRNE	W,IEFA10	;IS EOF BITS SET?
	  JRST	SCAN			;YES, BOTH 10+11 HAVE BITS UP FOR EOF
	JUMPGE	S,IINT03	;WAITING FOR EOF TO GO AWAY?
	  TLZ	S,(XCLOSE)		;IT HAS SO CLEAR CLOSE WAIT
	PUSHJ	P,IODCLR	;GET OUT OF IOW AND MAKE INACTIVE
	JRST	SCAN		;LOOK FOR WORK.
IINT03:	SKIPE	WS8ICC##(U)	;SEE IF INPUT BYTE COUNT IS 0
	  JRST	SCAN			;INPUT BYTE COUNT .NE. 0 SO
					; LOOK AT NEXT LINE.
	SKIPN	T1,XXIIOW(F)	;SEE IF THERE IS ALREADY A
					; IOWD IN THE DDB FOR US.
	  JRST	NINWRD			;NO WORD, SO WE MUST MAKE SOME MORE
	SETZM	XXIIOW(F)	;0 IT SO NEXT TIME WE KNOW TO
	PUSHJ	P,MAKPNT	;CONVERT IOWD AND PUT IN WINDOW
					; FETCH A NEW SET OF WORDS.
	MOVEM	T1,WS8IBP##(U)	;SET BYTE POINTER
	HRRZM	T2,WS8ICC##(U)	;SET CHARACTER COUNT
	JRST	IINT02		;WAKE PDP11 AND LOOK FOR WORK
NINWRD:	PUSHJ	P,IINT05	;
	PUSHJ	P,ADVBFF##	;ADVANCE INPUT BUFFER
	  JRST	IINT06			;CLEAR ACTIVE AND CONTINUE SCAN
IFN FTKL10,<
	PUSHJ	P,CSDMP##	;FLUSH CACHE
>
	PUSHJ	P,SETACT##	;MAKE IOACT
	PUSHJ	P,D78IN3	;SET WINDOW FOR INPUT
	JRST	SCAN		;LOOK FOR MORE TO DO

IINT01:	MOVEM	W,WS810S##(U)	;SET 10 STATUS
IINT02:	PUSHJ	P,D78WAK	;WAKE 11
	JRST	SCAN		;LOOK FOR MORE TO DO

IODCLR:	PUSHJ	P,SETIOD##	;GET OUT OF IOW
	PJRST	CLRACT##	;SET DEVIOS AND MAKE INACTIVE
IINT06:	PUSHJ	P,CLRACT##	;CLEAR ACTIVE THEN DONE
	JRST	IINT02		;WAKE 11 AND LOOK FOR WORK

;COME HERE WHEN ACTIVITY WORD IS ZERO
;
NXTPRT:	MOVE	P2,P4		;COPY FOR CALL TO "D78WK1" OR "D78WK2".
	SKIPE	P3,M78XIX##(J)	;DID 11 TELL US ANYTHING? (REMEMBER IN P3)
	  SETZM	M78XIX##(J)		;YES, CLEAR ACTIVITY WORD TO TELL
					; HIM WE CAN TAKE MORE.
	SKIPE	P1,SAVACT(P4)	;DO WE NEED TO TELL HIM SOMETHING?
	SKIPE	M78XXI##(J)		;YES, BUT CAN WE TELL HIM?
	  SKIPA				;NOTHING TO TELL HIM OR CAN'T TELL HIM.
	PJRST	D78WK1		;WE HAVE SOMETHING TO TELL HIM AND WE CAN
	JUMPN	P3,D78WK2	;DID 11 TELL US ANYTHING?
	  POPJ	P,			;NO, EXIT INTERRUPT.

IINT05:	PUSHJ	P,SVEUF##	;MAKE USER ADDRESSABLE
	HRRZ	T1,DEVISN(F)	;SET PCS TOO
	PUSHJ	P,SVPCS##
	MOVN	T1,XXICNT(F)	;GET POSITIVE SIZE OF BUFFER
	LDB	T2,[POINT 8,WS8IBP##(U),13]	;GET POINTER LEFT IN THE WINDOW
	ADD	T2,[-1B27+1]	;MAKE NEGATIVE PLUS 1
	ADD	T1,T2		;THIS MAKE THE ACTUAL LENGTH
	HRRZ	T2,DEVIAD(F)	;GET BUFFER ADDRESS
	EXCTXU	<MOVEM	T1,1(T2)>	;GIVE DATA COUNT TO USER
	PJRST	SETIOD##	;GET OUT OF IOW

;HERE ON AN INTERRUPT WHEN 11 IS JUST STARTING
;
D78CKN:	SKIPE	T1,D78NAM##(P4)	;GET NAME 11 GAVE US
					; INDEX INTO TABLE USING PORT #.
	CAME	T1,[SIXBIT /DAS78/]	;DAS78?
	  POPJ	P,			;NO, IGNORE IT.
	SKIPE	T1,M78MOD##(J)	;GET MOD NUMBER
	CAIE	T1,1			;MAKE SURE ITS THIS
	STOPCD	CPOPJ##,DEBUG,D78VI,	;++VERSION INCORRECT
;COME HERE WHEN THE PDP11 IS FIRST RECOGNIZED AS A DAS78 PDP11
;
	SETOM	M78ALI##(J)	;MARK 10 AS ALIVE
	SETZM	M78ADR##(J)	;CLEAR EXAMINE + DEPOSIT ADDRESS
	SETZM	M78DTA##(J)	; AND EXAMINE + DEPOSIT DATA.
	SETOM	M7810S##(J)	;FLAG 10 INITIALIZATION COMPLETE
	SETZM	SAVACT(P4)	;CLEAR BUFFERED ACTIVITY WORD
	POPJ	P,

;COME HERE IF AN OUTPUT UUO WAS DONE AND 10
;WAS WILLING BUT 11RDY WAS NOT UP AND WE FOUND
;11 RDY WITH WAIT BIT SET. WAKE THE JOB.
;
ORYWAT:	PUSHJ	P,RWKJOB	;WAKE THE JOB
	JRST	INPLOK		;LOOK FOR WORK IN INPUT SECTION.

;COME HERE IF AN INPUT UUO WAS DONE AND 10
;WAS WILLING BUT 11RDY WAS NOT UP AND WE FOUND
;11 RDY WITH WAIT FLAG SET IN DEVIOS. WAKE THE JOB
;
IRYWAT:	PUSHJ	P,RWKJOB	;WAKE THE JOB
	JRST	SCAN		;SEE IF SOMETHING ELSE

;HERE AT INTERRUPT LEVEL TO CHECK IF LINE IS ENABLED
;
INTCKE:	MOVE	T1,WS8LS0##(U)	;GET LINE STATUS
	TRNN	T1,S0.ENB	;DID CAL78 ENABLE LINE
	TLZN	S,(ENBSET)		; AND PDP11 CLEAR IT?
	  JRST	INTCK3			;LINE IS ENABLED.
	SETZ	T1,		;ZERO'S
	DPB	T1,PDVSTA##	;CLEAR OUT STATION NUMBER
	MOVE	T1,DEVMOD(F)	;GET DEVICE CHARACTERISTICS
	TLNN	T1,DVOUT	;IS IT XXO DEV
	  JRST	INTCK1			;ITS XXI DEV
	SETZM	WS8OCC##(U)	;0 OUT CHARACTER COUNT
	SETZM	WS8OBP##(U)	; AND POINTER
	JRST	INTCK2		;
INTCK1:	SETZM	WS8ICC##(U)	;0 IN CHARCTER COUNT
	SETZM	WS8IBP##(U)	; AND POINTER
INTCK2:	TRNN	T1,ASSPRG	;DEVICE ASSIGNED?
	  JRST	INTCK4			;NO
	ANDCMI	S,IOACT		;MAKE INACTIVE
	PUSHJ	P,SETIOD##	; AND GET OUT OF IOW IF IN IT.
	IORI	S,IOIMPM	; LIGHT ERROR BIT
	MOVEM	S,DEVIOS(F)	;MAKE DEVIOS RIGHT
	MOVE	T1,DEVMOD(F)	;GET ANOTHER COPY
INTCK4:	POP	P,(P)		;CLEAR ADDR OFF PDL
	TLNN	T1,DVOUT	;DOING OUTPUT?
	  JRST	SCAN			;XXI DEV
	JRST	INPLOK		;OUTPUT SO CHECK INPUT SIDE
INTCK3:	MOVEM	S,DEVIOS(F)	;MAKE IT RIGHT
	POPJ	P,		;RETURN

;HERE ON AN OPEN OR INIT UUO TO GET THE BUFFER SIZE
;
D78OPN:	PUSHJ	P,D78SJU	;SET UP U TO POINT TO THE WINDOW SLOT
	TRACE				;MAKE A TRACE
	MOVSI	S,(XCLOSE!RDYWAT)	;SET TO CLEAR THESE BITS
	ANDCAB	S,DEVIOS(F)	;CLEAR XCLOSE + RDYWAT
	MOVEI	T1,IWIL10	;WILLING BIT
	TRNE	M,16		;CHECK FOR ASCII MODE(M IS INIT WRD)
	  IORI	T1,SX.IBN		;SET BINARY MODE FILE
	MOVE	T2,DEVMOD(F)	;GET DEVICE CHARACTERISTICS
	TLNE	T2,DVIN		;IS DEVICE AN INPUT DEVICE ?
	  IORM	T1,WS810S##(U)		;YES SO SET WILLING
	MOVEI	T1,OWIL10	;SET FOR SETTING OUTPUT WILLING
	TRNE	M,16		;CHECK FOR ASCII MODE(M IS INIT WRD)
	  IORI	T1,SX.OBN		;SET BINARY MODE FILE
	TLNN	T2,DVOUT	;IS DEVICE OUTPUT ?
	  JRST	D78OP1			;DOING INPUT
	MOVEI	T2,S0.NFF	;ASSUME FORM-FEED
	ANDCAM	T2,WS8LS0##(U)	;MAKE IT THAT WAY IN WINDOW
	TRNE	M,LPTNFF	;SUPRESS FORM FEED ON OPEN?
	  IORM	T2,WS8LS0##(U)		;SET BIT SO 11 KNOWS
	IORM	T1,WS810S##(U)	;YES, SO SET OUTPUT WILLING.
D78OP1:	PUSHJ	P,D78WAK	;INTERRUPT 11 SO IT NOTICES LINE
	PJRST	REGSIZ##	;OFF TO USUAL ROUTINE TO GET BUFFER SIZE


;HERE ON A RELEASE UUO
;
D78REL:	PUSHJ	P,D78SJU	;SETUP U TO POINT TO WINDOW SLOT
	TRACE				;MAKE A TRACE
	MOVE	T3,WS810S##(U)	;GET 10 STATUS TO SEE IF WILLING
					; IS SET.  IF IT IS THEN A CLOSE MUST BE DONE.
	MOVE	T2,DEVMOD(F)	;GET DEVICE CHARACTERISTICS
	TLNE	T2,DVIN		;IS DEVICE AN INPUT DEVICE?
	  JRST	RELINP			;IS XXI TYPE DEVICE
	TRNE	T3,OWIL10	;IS WILLING STILL UP ?
	  PUSHJ	P,RLCLOO		;YES SO DO CLOSE PROCEDURE
	JRST	RELEXT		;EXIT RELEASE
RELINP:	TRNE	T3,IWIL10	;SEE IF INPUT IS WILLING
	  PUSHJ	P,RLCLOI		;IT IS, SO DO CLOSE PROCEDURE
RELEXT:	HRRZS	XXOLCN(F)	;ZERO COUNT
	POPJ	P,


;HERE ON A CLOSE UUO
;
D78CLO:	MOVE	T2,DEVMOD(F)	;SEE IF INPUT OR OUTPUT
	TLNN	T2,DVOUT	;IS IT OUTPUT?
	  JRST	CLOIN			;NO, ITS INPUT.
	PUSHJ	P,OUT##		;FINISH WRITING BUFFERS
RLCLOO:	PUSHJ	P,WAIT1##	;WAIT FOR I/O TO BE INACTIVE
	PUSHJ	P,D78SJU	;SET "U" TO POINT TO WINDOW SLOT
	SETZM	WS8OCC##(U)	;CLEAR DATA COUNT
	SETZM	WS8OBP##(U)	;CLEAR DATA POINTER
	MOVEI	T3,OWIL10!OCOD10	;FOR CLEARING WILLING
	ANDCAM	T3,WS810S##(U)	;CLEAR WILLING BEFORE SETTING
					; CLOSE
	MOVEI	T1,OEF10	;CLOSING STATUS BIT
	TLNN	F,OCLOSB	;WAS CHANNEL CLOSED (OR RELEASED) ?
	  MOVEI	T1,OAB10		;NO SO THIS IS AN ABORT
	IORM	T1,WS810S##(U)	;SET CLOSING IN THE WINDOW SLOT
	PUSHJ	P,D78WAK	;TELL 11
CLOCHK:	MOVE	T1,WS810S##(U)	;GET OUR STATUS
	TRNN	S,IODERR!IODTER	;PDP11 ALTER AND WILL?
	TRNN	T1,OEF10	;STILL NEED TO WAIT?
	  POPJ	P,			;NO
	LDB	J,PJOBN##	;PREPARE FOR CALL HIBER
	SETZ	T1
	PUSHJ	P,HIBER##	;WAIT FOR CLOSE TO WORK
	  JFCL
	PUSHJ	P,D78SJU	;RELOAD S,J,& U
	JRST	CLOCHK
CLOIN:	PUSHJ	P,D78SJU	;SET "U" TO POINT AT WINDOW SLOT
RLCLOI:	MOVEI	T3,IWIL10!ICOD10	;FOR CLEARING INPUT WILLING
	ANDCAM	T3,WS810S##(U)	;CLEAR INPUT OR OUTPUT WILLING
	SETZM	WS8ICC##(U)	;CLEAN OUT CHR COUNT
	SETZM	WS8IBP##(U)	;AND BYTE POINTER
	MOVEI	T1,IAB10	;BIT TO ABORT INPUT
	TLNN	F,ICLOSB	;HAS INPUT CLOSE BEEN DONE ?
	  IORM	T1,WS810S##(U)		;NO SO THIS IS AN ABORT
	PJRST	D78WAK		;TELL PDP11 CLOSE.
;HERE WHEN THE DISPATCH TABLE CALLS FOR AN INIT FROM "SYSINI".
;
; THIS STORES THE PDP11 NUMBER IN BITS 33-35 AND LINE NUMBER
; IN BITS 29-32 IN LOCATION "XXILCN" AND "XXOLCN" OF DDB.  THERE
; IS ONE INPUT AND OUTPUT DDB FOR EACH LINE, UP TO A MAXIMUM OF
; 16 FOR EACH PDP11.  ALSO A TABLE IS FILLED WHICH CONTAINS IN THE
; (LH) THE INPUT DDB ADDRESS AND IN THE (RH) THE OUTPUT DDB ADDRESS.
;
D78SYI:	PUSHJ	P,SAVE4##	;SAVE P1, P2, P3, AND P4
IFN D78TRC,<
	PUSHJ	P,SETTRC	;SETUP AOBJN POINTER TO TRACE BUFFER.
>;END IFN D78TRC
	MOVE	T1,F		;ADDRESS OF XXIDDB
	SETZB	P2,P4		;CLEAR P2 FOR STARTING AN INDEX IN THE (RH)
					; AND P4 FOR 0 STATION NUMBER
					; AND DEVICE NUMBER IN THE (LH)
	MOVE	P1,[HRLZM T1,M78DDB##(P2)]	;FOR STORING DDB ADDRESS
						; IN A TABLE FOR EACH LINE.
						;  INPUT GOES TO LH.
	PUSHJ	P,D78IND	;SETUP XXI DDB'S
	MOVEI	T1,XXODDB	;ADDRESS OF XXODDB
	SETZ	P2,		;MAKE 0 FOR STARTING INDEX VALUE
	HRLI	P1,(HRRM T1,(P2))	;FOR STORING OUTPUT DDB ADDRESS
					; FOR EACH LINE IN A TABLE.
D78IND:	MOVE	T2,[M78NUM##,,M78FPO##]	;PUT NEG # OF POSSIBLE PDP11'S
					; IN THE (LH) AND THE FIRST
					;  DAS78 PDP11 IN THE (RH).
D78SY1:	MOVN	T3,M78LIN##(T2)	;GET NUMBER OF LINES
	JUMPE	T3,D78SY3	;JUMP IF NO LINES
	  HRLZS	T3			;PUT NEG # OF LINES IN LH
D78SY2:	HRRZM	T3,XXILCN(T1)	;PUT LINE NUMBER IN DDB
	HRRZ	T4,T2		;GET RID OF JUNK IN LH
					; KEEPING ONLY THE PDP11#.
	IORM	T4,XXILCN(T1)	;PUT PDP11 NUMBER IN DDB
	XCT	P1		;PUT DDB ADDRESS IN TABLE
	DPB	P4,[POINT 6,DEVSTA(T1),35]	;0 FOR STATION
	LDB	T4,[POINT 3,P2,17]	;GET LEAST SIGNIFICANT DEVICE NUMBER
	LDB	P3,[POINT 3,P2,14]	;GET MOST SIGNIFICANT OF DEV NUMBER
	LSH	P3,6		;MAKE THE DEVICE
	IORI	T4,'00'(P3)	; NUMBER INTO
	LSH	T4,6		;  A SIXBIT
	SKIPN	P3		;   NUMBER
	  LSH	T4,6			;
	HRRM	T4,DEVNAM(T1)	;PUT IN THE DDB
	AOBJN	P2,.+1		;+1 TO INDEX TO DDB ADR TABLE
					; AND +1 TO THE DEV NUMBER IN (LH)
	HLRZ	T1,DEVSER(T1)	;GET ADDRESS OF NEXT DDB
	ADDI	T3,7		;ADD 7 SO "AOBJN" INCREMENTS LINE NUMBER
	AOBJN	T3,D78SY2	;ALL LINES DONE?, ALSO INCREMENT LINE NUMBER.
D78SY3:	AOBJN	T2,D78SY1	;ALL PDP11'S DONE?
	POPJ	P,		;DO NEXT DDB

;HERE ON AN OUTPUT UUO

D78OUT:	MOVSI	S,IO		;INDICATE OUTPUT
	IORB	S,DEVIOS(F)	;SET OUT IN DDB
	PUSHJ	P,D78SJU	;SET J AND U
	TRACE				;MAKE A TRACE
	PUSHJ	P,SETMOD	;SET MODE (ASCII OR BINARY)
	MOVEI	T1,OWIL10	;SET WILLING ON OUTPUT
	TDNE	T1,WS810S##(U)	;SEE IF WILLING
	  JRST	D78OUW			;ALREADY WILLING
	IORB	T1,WS810S##(U)	; BECAUSE OF (OPEN,OUT,CLOSE,OUT)
	PUSHJ	P,D78WAK	;TELL 11 THE 10 IS WILLING
D78OUW:	IORB	T1,WS810S##(U)	;MUST GET AGAIN
	TRNE	T1,OPAUSE	;DID WE AGREE NOT TO OUTPUT ?
	  JRST	[	PUSHJ	P,HNGSTP##
			JRST	D78OUT ]
	MOVE	T1,WS811S##(U)	;GET 11 STATUS
	IOR	T1,WS810S##(U)	; AND OR IN 10 STATUS
	TRNE	T1,OAB10!OAB11	;  TO SEE IF ANY ABORT BITS UP.
	  PJRST	KILUUO			;SETUP FOR USER TO BE TOLD OF ABORT
	JSP	T4,CHKENB	;SEE IF LINE IS ENABLED.
					; RETURN IF SO, IF NOT GIVE IOIMPM
	PUSHJ	P,CHKCLO	;SEE IF CLOSING, AND IF SO WAIT
	PUSHJ	P,CHKRDY	;SEE IF 11RDY, IF NOT HIBER
	  POPJ	P,			;SOMETHING WENT WRONG
	SKIPE	T1,WS8OCC##(U)	;OUT CHARACTER COUNT NON 0?
	STOPCD	.,JOB,D78ON,		;++OUTPUT CHARACTER COUNT IS NOT EQUAL TO 0.
	PUSHJ	P,MAKACT	;SET IOACT AND START HUNG COUNT
D78OU3:	JSP	T1,RELBA	;RELOCATE BUFFER ADDRESS
	HRRZ	T1,DEVOAD(F)	;VIRTUAL ADDRESS OF USER OUT BUFFER
	EXCTUX	<HRRZ	T2,1(T1)>	;GET WORD COUNT FROM USER BUFFER RING.
	JUMPE	T2,ADVOBF	;JUMP IF 0 WORDS
	CAILE	T2,MAXBUF	;SEE IF BUFFER LARGER THAN WE ALLOW
	  JRST	[	MOVEI	T1,OAB10	;ABORT OUTPUT
			JRST	BIGBUF	]	;CAUSE THAT'S TOO BIG
	MOVNS	T2		;MAKE NEGATIVE LENGTH OF BUFFER -
	HRLS	T2		; AND PUT 18 BIT NEG LENGTH IN (LH).
	HRRI	T2,@DEVOAD(F)	;RELOCATE BUFFER ADDRESS
	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,MAKIOW	;MAKE AN IOWD LIST TO ADDRESS USER BUFFER.
					; IN A KI-10 THE BUFFER MAY BE
					;  SPLIT ACROSS 2-PAGES.  IN A
					;   KA-10 ONLY 1 POINTER WILL BE MADE.
	MOVEM	T1,WS8OBP##(U)	;SETUP DL10 DATA POINTER
					; TO POINT TO USER BUFFER.
	HRRZM	T2,WS8OCC##(U)	; AND ALSO GIVE 11 THE COUNT.
	MOVE	T1,P2		;T1 POINTS TO IOWD LIST
	PUSHJ	P,RTNIOW##	;RETURN WORDS TO MONITOR
	PJRST	D78WAK		;WAKE THE PDP11

ADVOBF:	PUSHJ	P,SETIOD##	;CLEAR IOWAIT
	PUSHJ	P,ADVBFE##	;ADVANCE BUFFER
	  PJRST	CLRACT##		;CLEAR ACTIVE THEN DONE
					; (NEXT BUFFER IS EMPTY)
	PUSHJ	P,SETACT##	;MAKE IOACT
	JRST	D78OU3		;SET WINDOW FOR OUTPUT
					; (NEXT BUFFER IS FULL)

;HERE ON AN INPUT UUO

D78IN:	MOVSI	S,IO		;INDICATE INPUT
	ANDCAB	S,DEVIOS(F)	;SET INPUT IN DDB
	PUSHJ	P,D78SJU	;SET J AND U
	TRACE				;MAKE A TRACE
	PUSHJ	P,SETMOD	;SET MODE (ASCII OR BINARY)
	MOVE	T1,WS810S##(U)	;GET A COPY OF STATUS
	TRNE	T1,IPAUSE	;WANT TO DEFER INPUT ?
	  JRST	[	PUSHJ	P,HNGSTP##
			JRST	D78IN ]
	MOVE	T1,WS811S##(U)	;GET 11 STATUS
	IOR	T1,WS810S##(U)	; AND OR IN 10 STATUS TO
	TRNE	T1,IAB10!IAB11	;SEE IF ANY ABORT BIT UP.
	  PJRST	KILUUO			;SET TO INFORM USER OF ABORT
	JSP	T4,CHKENB	;SEE IF LINE IS ENABLED.
					; RETURN IF SO, IF NOT GIVE IOIMPM
	PUSHJ	P,CHKCLO	;SEE IF CLOSING DONE, IF NOT WAIT
	PUSHJ	P,CHKRDY	;SEE IF 11RDY, IF NOT HIBER
	  POPJ	P,			;SOMETHING WENT WRONG
	SKIPE	T1,WS8ICC##(U)	;IN CHARACTER COUNT NON 0?
	STOPCD	.,JOB,D78IN0,		;++INPUT CHARACTER COUNT NON 0
	PUSHJ	P,MAKACT	;SET IOACT + HUNG COUNT
D78IN3:	JSP	T1,RELBA	;RELOCATE BUFFER ADDRESS
	HRRZ	T1,DEVIAD(F)	;VIRTUAL ADDRESS OF USER IN BUFFER
	EXCTUX	<HLRZ	T2,(T1)>	;GET BUFFER SIZE FROM BUFFER RING
	SUBI	T2,1		; AND MAKE ONE LESS TO EQUAL REAL LENGTH
	CAILE	T2,MAXBUF	;SEE IF USER BUFFER BIGGER
					; THAN WE ALLOW.
	  JRST	[	MOVEI	T1,IAB10	;ABORT INPUT
			JRST	BIGBUF ]	;CAUSE THA'S TOO BIG
	SKIPGE	XXILCN(F)	;IS THIS PAUSE RECOVERY ?
	  JRST	D78IN6			;YES SO DON'T ZERO BUFFER
	ADDI	T1,2		;POINT TO DATA PORTION OF BUFFER
	EXCTUU	<SETZM	,(T1)>	;ZERO FIRST WORD
	HRL	T1,T1		;BEGINNING ADDR IN LH
	HRRZ	T3,T1		;AND MAKE T3 POINT
	ADDI	T3,-1(T2)	; TO LAST WORD IN BUFFER.
	ADDI	T1,1		;(RH) POINTS TO SECOND DATA WORD
	EXCTUU	<BLT	T1,(T3)>	;ZERO INPUT BUFFER IN USER AREA
D78IN6:	MOVNS	T2		;MAKE NEG LENGTH OF BUFFER.
	HRLS	T2		; IN THE LH
	HRRI	T2,@DEVIAD(F)	;RELOCATE BUFFER ADDRESS
	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,MAKIOW	;MAKE AN IOWD LIST TO ADDRESS USER BUFFER
					; IN A KI-10 THE BUFFER MAY BE
					;  SPLIT ACROSS 2-PAGES.  IN A
					;   KA-10 ONLY 1 POINTER WILL BE MADE.
	MOVEM	T1,WS8IBP##(U)	;SETUP DL10 DATA POINTER
					; TO POINT TO USER BUFFER.
	HRRZM	T2,WS8ICC##(U)	;AND ALSO GIVE 11 THE COUNT
	MOVE	T1,P2		;T1 POINTS TO IOWD LIST
	PUSHJ	P,RTNIOW##	;RETURN WORDS TO MONITOR
	PJRST	D78WAK		;WAKE THE PDP11
;ROUTINE TO TAKE A KA-10 STYLE IOWD AND MAKE A LIST
;OF 22 BIT CHANNEL IOWD'S TO ADDRESS A SPLIT
;BUFFER IN A KI-10.
;
; CALL:	PUSHJ	P,MAKIOW		;T2 MUST CONTAIN KA-10 STYLE IOWD
;	RETURN				;T1 = DL10 POINTER
;					;T2 = NUMBER OF BYTES
;					;T3 = NEG NUMBER OF WORDS
;					;DDB CONTAINS SECOND WORD IN IOWD LIST
;
MAKIOW:	ADDI	T2,1		;POINT TO DATA-1 IN USER BUFFER

	PUSH	P,J		;SAVE J
	LDB	J,PJOBN##	;PUT JOB NUMBER IN J.
	SETZ	P1,		;INDICATE INITIAL AND ONLY CALL
					; TO MAPIO.
	MOVEI	P3,SIM22B	;FAKE A 22-BIT CHANNEL TO MAPIOW
	SUBI	P3,CHB22B##	; SO WE WILL WORK ON MORE THAN 256K
	PUSHJ	P,MAPIO##	;MAKE THE IOWD INTO ABSOLUTE IOWD'S
					; FOLLOWING THE PAGING OF THE JOB.
					;  P2 POINTS TO IOWD LIST
	STOPCD	.,JOB,D78NC,		;++NOT ENOUGH FREE MONITOR CORE
	POP	P,J		;RESTORE J
	MOVE	T1,1(P2)	;SAVE SECOND WORD IN DDB
	MOVEM	T1,XXOIOW(F)	; PUT IT THERE
	SKIPL	T1,(P2)		;GET 1ST IOWD AND MAKE SURE ITS MINUS


	STOPCD	.,JOB,D78PI,		;++POSITIVE IOWD
	MOVE	T2,T1		;COPY IOWORD
	ASH	T2,-^D22	;RIGHT JUSTIFY
	MOVEM	T2,XXICNT(F)	;SAVE SIZE OF BUFFER FOR LATER
	MOVE	T2,XXOIOW(F)	;GET 2ND IOWORD
	ASH	T2,-^D22	;RIGHT JUSTIFY THE WORD COUNT
	ADDM	T2,XXICNT(F)	;AND MAKE TOTAL WORD COUNT FOR BUFFER
	PUSHJ	P,SAVE2##	;GET TWO P'S FOR COUNTER
	HLRE	P1,XXOLCN(F)	;GET NEGATIVE NUM BYTES TO SKIP
	JUMPE	P1,MAKPNT	;IF NONE JUST GO MAKE POINTER
	  HRRZS	XXOLCN(F)		;FORGET PAUSE COUNT
	TRNN	S,16		;IS THIS ASCII MODE ?
	  IDIVI	P1,5			;YES SO 5 BYTES/WORD
	TRNE	S,16		;IS THIS BINARY
	  IDIVI	P1,4			;YES SO 4 BYTES/WORD
	MOVE	T4,T1		;COPY IOWORD
	ASH	T4,-^D22	;LEAVE ONLY THE WORD COUNT
	CAMGE	T4,P1
	  MOVE	T4,P1			;SKIP COUNT IS SMALLER
	SUBM	T4,P1		;DECREASE NUMBER OF WORDS TO SKIP
	IMUL	T4,[-21,,-1]
	ADD	T1,T4
	JUMPL	T1,MKIOW6
	SKIPN	T1,XXOIOW(F)	;GET OTHER IOWD
	STOPCD	.,JOB,D78BI,
	SETZM	XXOIOW(F)
	IMUL	P1,[-21,,-1]
	ADD	T1,P1
MKIOW6:	PUSHJ	P,MAKPNT
MKIOW7:	AOJG	P2,CPOPJ##	;WHEN ALL BYTES HANDLED WE'RE DONE
	ADD	T1,[100000,,0]		;ADVANCE TO NEXT BYTE
	SOJA	T2,MKIOW7	;ADJUST BYTE COUNT

SIM22B:	200000,,0			;TELL "MAPIO" 22 BIT FORMAT

;HERE TO CONVERT A 22BIT CHNL IOWD TO A DL10 BYTE POINTER
;
; CALL	MOVE	T1,<22BIT CHNL IOWD>
;	RETURN WITH DL10 POINTER IN T1 AND POSITIVE BYTE COUNT IN T2
;	AND POSITIVE WORD COUNT IN T3.
;
MAKPNT:
IFN FTKL10,<
	PUSHJ	P,CSDMP##	;FLUSH CACHE
>
	MOVE	T2,T1		;COPY 22BIT CHNL IOWD
	ASH	T2,-^D22	;LEAVE ONLY THE COUNT
	TLZ	T1,777760	;CLEAR COUNT FROM 1ST COPY
	ADDI	T1,1		;DL10 POINTER STARTS OUT AT WORD
	DPB	T2,[POINT 8,T1,13]	;PUT WORD COUNT IN DL10 POINTER
	MOVN	T3,T2		;PUT POSITIVE COUNT HERE
	TRNE	S,16		;DOING IO IN ASCII/AL MODE ?
	  JRST	MKPNT1			;NO SO ASSUME 8BIT BYTES
	IMULI	T2,-5		;MAKE POSITIVE BYTE COUNT
	TLO	T1,(75B5)	;7 BIT BYTE POINTER
	POPJ	P,		;
MKPNT1:	IMULI	T2,-4		;FOUR BYTES/WORD
	TLO	T1,(74B5)	;8BIT BYTES
	POPJ	P,

RELBA:	CONSZ	PI,II.IPA	;AT INTERRUPT LEVEL?
	  PUSHJ	P,SVEUF##	;YES, MAKE THE JOB ADDRESSABLE
	PUSHJ	P,SVPCS##
	PUSHJ	P,SPCS##	;SET FROM DDB
	JRST	(T1)
;HERE ONCE A SECOND FROM THE MONITOR
;
D78SEC::
IFN FTMP,<
	SKIPE	.CPCPN##	;DAS78/DL10 CODE
	POPJ	P,		; ONLY RUNS ON CPU0
> ;END IFN FTMP
	PUSHJ	P,SAVE2##		;SAVE P1 & P2 
	MOVE	P2,[M78NUM##,,M78FPO##]	;(LH) CONTAINS:  MINUS THE NUMBER
					; OF DAS78 PDP11'S BETWEEN THE FIRST
					;  ONE AND THE LAST ONE.  (RH) CONTAINS
					;   THE FIRST DAS78 PDP11.
D78SC1:	SKIPN	J,M78BAT##(P2)	;GET WINDOW ADR FOR NEXT DAS78
	  JRST	D78SC2			;THIS PORT ISN'T ONE
	MOVE	P1,M78BT##(P2)	;SET UP FOR XCT I/O FOR PORT
	XCT	M78CPI##(P1)	;SEE IF PIA ASSIGNMENT
	  XCT	M78SPI##(P1)		;NO, GIVE XXICHN PI ASSIGNMENT
	SETOM	M78ALI##(J)	;DO THIS EVERY SECOND SO THE 11
					; WILL KNOW WE'RE ALIVE.
	SKIPG	M78DWN##(J)	;IS THE PDP11 UP?
	  JRST	D78NTR			;NO, THE 11 IS NOT UP.
	SYSPIF			;TURN OFF INT SYSTEM
	XCT	M78SER##(P1)	;SETUP "R" REGISTER
	XCT	M78GWA##(P1)	;GET BASE ADDRESS INTO T1
	SYSPIN
	ANDI	T1,777700	;KEEP BASE ADDRESS
	CAIE	T1,(J)		;SAME BASE ADDRESS AS WE EXPECT?
	  JRST	D78SC5			;NO, WRONG BASE ADR SO FLAG PORT IS DOWN.
	AOS	T1,M78OK##(J)	;COUNT THE "OK" COUNTER.
	CAIG	T1,5		;IS THE PDP11 STILL OK?
	  JRST	D78SC2			;OK

;HERE TO FLAG PORT IS DOWN
;
	XCT	M78CPE##(P1)	;CLEAR PORT ENABLE
D78SC5:	SETZM	M78DWN##(J)	; AND MARK IT DOWN.
	JRST	D78SC2		;ON TO THE NEXT PORT

;HERE ONCE PER SECOND WHEN THE DAS78 IS NOT UP
;
D78NTR:	XCT	M78I10##(P1)	;SKIP IF PDP11 SET 10 INT BIT
	  JRST	D78SC2			;NO, PDP11 IS NOT UP YET.
	MOVSI	T1,M78ESA##(J)	;SET TO ZERO THE WINDOW
	HRRI	T1,M78ESA##+1(J)	; SINCE THE PDP11 IS COMING UP
	SETZM	M78ESA##(J)	;ZERO FIRST LOCATION SO BLT CAN 0 THE REST
	BLT	T1,@M78END##(P2)	;NOW ZONK IT.
					;M78END IS A TABLE IN COMMON
					;WHICH CONTAINS THE LAST USED LOC
					;IN THE WINDOW.  INDEX INTO IT
					;WITH PORT NUMBER.
	MOVSI	T1,767760	;BUILD SIXBIT DL10 BYTE POINTER
	HRRI	T1,D78NAM##(P2)	; INTO THE DL10 NAME WORD.
	MOVEM	T1,M78NAM##(J)	;PUT THE POINTER IN THE WINDOW.
	SETZM	D78NAM##(P2)	;CLEAR NAME
	HRRZ	T1,M78LIN##(P2)	;GET NUMBER OF LINES ON THIS PORT
	MOVEM	T1,M78NLI##(J)	; AND PUT IT IN THE WINDOW.
	MOVN	T2,T1		;GET NUMBER OF LINES FOR THIS PORT
	HRLZS	T2		; AND PUT IN (LH).
	HLR	T2,M78BAT##(P2)	;POINT TO TABLE OF DDB ADDRESS
					; FOR PORT IN P2.
D78SC3:	SETO	T4,		;SO WE GO THROUGH LOOP TWICE.
	MOVE	T1,(T2)		;GET DDB ADDRESS FOR LINE IN T2
D78SC4:	SETZB	T3,XXOCNT(T1)	;CLEAR OUT COUNT
	SETZM	XXOIOW(T1)	;CLEAR OUT SECOND IOWD
	DPB	T3,[POINT 6,DEVSTA(T1),35]	;SET STATION TO 0.
	MOVSS	T1		;POINT TO XXIDDB
	AOJLE	T4,D78SC4	;DO XXIDDB
	AOBJN	T2,D78SC3	;ALL DDB'S DONE FOR THIS PORT?
	
	XCT	M78SWA##(P1)	;SET WINDOW ADDRESS AND WORD LENGTH
IFN	FTPI,<
	XCT	M78PSI##(P1)	;IF PSISER MUST DO KA STYLE INTERRUPTS
>;END IFN FTPI
	XCT	M78ENP##(P1)	;ENABLE THE PORT
D78SC2:	AOBJN	P2,D78SC1	;LOOP BACK FOR REST OF THE PORTS
	POPJ	P,
;HERE ONCE A MINUTE FROM THE MONITOR
;
D78MIN::
IFN FTMP,<SKIPN	.CPCPN##>	;DAS78/DL10 CODE ONLY RUNS ON CPU0
	SKIPGE	DEBUGF##		;DEBUGGING?
	  POPJ	P,			;YES, NO MESSAGES
	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	MOVE	P1,[M78NUM##,,M78FPO##]	;(LH) CONTAINS:  MINUS THE NUMBER
					; OF DAS78 PDP11'S BETWEEN THE FIRST
					;  ONE AND THE LAST ONE.  (RH) CONTAINS
					;   THE FIRST DAS78 PDP11.
D78MI1:	SKIPE	P2,M78BAT##(P1)	;GET A WINDOW ADDRESS, IF THERE
					; IS NOT A DAS78 WE SHOULD GET 0
	  JRST	D78MI3			;FOUND A DAS78
D78MI2:	AOBJN	P1,D78MI1	;DONE ALL PORTS?
	POPJ	P,		;YES
D78MI3:	SKIPE	M78DWN##(P2)	;PDP11 UP OR SILENCED?
	  JRST	D78MI2			;YES, SO LOOK AT NEXT PORT
	MOVE	U,OPRLDB##	;NO, PRINT MESSAGE ON OPR'S TTY.
	PUSHJ	P,INLMES##	;NOW TELL OPR THE MESSAGE
	ASCIZ	/
%%DAS78  PDP11 #/
	HRRZ	T1,P1		;EXPECTS NUMBER  IN T1
	PUSHJ	P,RADX10##	;PRINT PDP11 NUMBER
	SKIPE	M78HLT##(P2)	;DAS78 PDP11 HALTED?
	  JRST	D78HLT			;YES.
	PUSHJ	P,INLMES##	;NO, JUST SAY NOT UP.
	ASCIZ	/ is not running.
/
	JRST	D78MI2		;LOOK AT NEXT PORT

;COME HERE IF THE DAS78 PDP11 IS ACTUALLY HALTED.
;
D78HLT:	PUSHJ	P,INLMES##	;TELL OPR WHERE PDP11 IS HALTED
	ASCIZ	/ halted at /
	MOVE	T1,M78HLT##(P2)	;GET HALT PC (OR STOP CODE).
	PUSHJ	P,OCTPNT##	;TELL OPR THE ADDRESS.
	PUSHJ	P,INLMES##	;END WITH A PERIOD(.)
	ASCIZ	/.
/
	JRST	D78MI2		;LOOK AT NEXT PORT

SUBTTL	CAL78. UUO

;CALL78 UUO - HERE FROM UUOCON
;
;	CALL:	MOVE	AC,[LENGTH,,BLK]
;		CAL78.	AC,
;		ERROR RETURN
;		SUCCESS RETURN
;	BLK:	PDP11##,,FUNCTION CODE	;FUNCTION CODES 0 AND 1.
;	BLK:	LINE#,,FUNCTION CODE	;FUNCTION CODES .GT. 1.
;		DATA
;
;	FUNCTION CODES:
;
;		0	DEPOSIT
;		1	EXAMINE
;		2	RETURN "LENGTH-1" WORDS IN THE WINDOW SLOT
;			TO THE USER.
;		3	SET "LENGTH-1" WORDS IN THE WINDOW SLOT FROM THE USER
;		4	READ PDP11 STATUS AND PDP10 STATUS.
;			RETURN 11 STATUS IN (LH) AND 10 STATUS IN (RH).
;		5	RETURN WINDOW ADDRESS IN (RH) AND
;			WINDOW SLOT ADDRESS IN (LH).
;		6	RETURN PDP11 PROGRAM VERSION NUMBER
;		7	SET STATION NUMBER (0-77)
;
;	ERROR CODES ON ERROR RETURN:
;
;		1	NOT PRIVILEGED
;		2	UNKNOWN FUNCTION
;		3	ILLEGAL LINE NUMBER
;		4	NOT ENOUGH ARGUMENTS
;		5	NO ANSWER TO DEPOSIT OR EXAMINE
;		6	ILLEGAL ADDRESS ON EXAMINE OR DEPOSIT
;		7	PDP11 IS NOT RUNNING
;		10	ILLEGAL STATION NUMBER
;		11	STATION NUMBER ALREADY EXISTS
;
CALL78::PUSHJ	P,PRUSET##		;RETURN FUNCTION + LINE NUMBER  IN T1
					; AND LENGTH IN T3.
	SKIPL	C78FUN(T1)		;UNPRIVLEDGED BUT CHECK IF PRVS NEEDED
	  SOJA	T3,CAL78A		;PRIVLEDGED OR NO PRVS NEEDED, ALSO
					; DECREASE LENGTH BY 1.
	PJRST	ECOD1##		;**ERROR-1 USER LACKED PRIVLEDGES
CAL78A:	JUMPL	T3,ECOD4##	;**ERROR-4 IF NOT ENOUGHS ARGS SUPPLIED
	HRRZ	T2,T1		;GET FUNCTION CODE AND
	CAIL	T2,C78LNG	; SEE IF FUNCTION CODE TO LARGE
	  PJRST	ECOD2##			;**ERROR-2 UNKNOWN FUNCTION
	HLRZ	T4,T1		;GET LINE NUMBER GIVEN BY USER
	CAIL	T2,C78DE	;CHECK IF DEPOSIT OR EXAM FUNCTION
					; AS DEPOSIT OR EXAM HAVE PDP11 NUMBER
					;  IN LH INSTEAD OF LINE NUMBER.
	  JRST	NOTDE			;NOT DEPOST OR EXAMINE
	CAIG	T4,M78HPO##	;IS THE PORT NUMBER UNREASONABLE
	SKIPN	M78BAT##(T4)		; OR IS THE PORT NOT A DAS78?
	  PJRST	ECOD3##			;**ERROR-3 ILLEGAL PORT NUMBER
	JRST	DOFUN		;DO THE EXAMINE OR DEPOSIT
NOTDE:	CAIL	T4,M.D78L##	;SEE IF LINE NUMBER TO LARGE
					; MAX LINES DETERMINED DURING MONGEN.
	  PJRST	ECOD3##			;**ERROR-3ILLEGAL LINE NUMBER.
	MOVE	F,M78DDB##(T4)	;GET DDB ADDRESS FOR LINE SPECIFIED BY USER
	PUSHJ	P,D78SJU	;SET UP J & U
	JSP	T2,C78CHK	;SEE IF 11 IS RUNNING
DOFUN:	HRRZS	T1		;CLEAR LEFT HALF
	JRST	@C78FUN(T1)	;GO PERFORM FUNCTION

;ROUTINE TO SEE IF 11 IS RUNNING FOR THE
;CALL78 FUNCTION.
;
; CALL:	JSP	T2,C78CHK		;J MUST POINT TO WINDOW
;	RETURN HERE IF 11 IS RUNNING	;AC'S NOT DESTROYED.
;
;	IF 11 IS NOT RUNNING A ERROR CODE OF 7 IS
;	GIVEN TO THE USER.
;
C78CHK:	SKIPN	M78HLT##(J)	;SKIP IF 11 HALTED
	SKIPG	M78DWN##(J)		;SKIP IF 11 UP
	  PJRST	ECOD7##			;**ERROR-7 IF 11 NOT RUNNING.
	JRST	(T2)		;11 IS RUNNING ACCORDING TO
					; THE WINDOW.

PRVUSR==400000				;USER MUST HAVE POKE PRIVILEGES

C78FUN:	XWD	PRVUSR,DEP11	;GO TAKE CARE OF DEPOSIT
	XWD	PRVUSR,EXAM11	;GO TAKE CARE OF EXAMINE
C78DE==	.-C78FUN
	XWD	PRVUSR,D78RDS	;READ LINE STATUS
	XWD	PRVUSR,D78SCH	;SET CHARACTERISTICS
	XWD	PRVUSR,D78RET	;RETURN PDP11 AND PDP10 STATUS
	XWD	PRVUSR,D78ADR	;RETURN WINDOW ADDRESS IN (RH) AND
					; WINDOW SLOT ADDRES IN (LH).
	XWD	0,D78VER	;RETURN PDP11 VERSION NUMBER
	XWD	PRVUSR,SETSTA	;SET THE STATION NUMBER
C78LNG==.-C78FUN

;HERE TO DO THE EXAMINE
;
EXAM11:	SOJL	T3,ECOD4##	;NEED ADDRESS
	  PUSHJ	P,GETWD1##		;GET THE ADDRESS
	MOVE	J,M78BAT##(T4)	;GET WINDOW ADR AGAIN
	JSP	T2,C78CHK	;SEE IF 11 IS RUNNING
	MOVEM	T1,M78ADR##(J)	;PUT ADDRESS IN THE WINDOW
	SETZM	M78DTA##(J)	;CLEAR DATA WORD IN WINDOW
	MOVEI	T3,D78EXM	;GET GLOBAL EXAM BIT
	JRST	EXDP11		;GO DO EXAMINE

;HERE TO DO THE DEPOSIT
;
DEP11:	SUBI	T3,2		;MUST HAVE ADDRESS AND DATA
	JUMPL	T3,ECOD4##	;**ERROR 4 IF YOU DO NOT.
	  PUSHJ	P,GETWD1##		;GET ADDRESS
	MOVE	J,M78BAT##(T4)	;GET WINDOW ADR AGAIN
	JSP	T2,C78CHK	;SEE IF PDP11 IS RUNNING
	MOVEM	T1,M78ADR##(J)	;STORE ADDRESS IN WINDOW
	PUSHJ	P,GETWD1##	;GET DATA
	MOVE	J,M78BAT##(T4)	;GET WINDOW ADR AGAIN
	MOVEM	T1,M78DTA##(J)	;STORE DATA IN WINDOW
	MOVEI	T3,D78DEP	;SET GLOBAL DEPOSIT BIT
EXDP11:	MOVEM	T3,M78GLB##(J)	;PUT GLOBAL BITS IN WINDOW
	MOVE	T1,M78BT##(T4)	;POINT TO I/O INSTRUCTIONS FOR CURRENT PORT.
	XCT	M78I11##(T1)	;SET PDP11 INTERRUPT
	MOVEI	T1,^D250	;SET COUNT FOR A WAIT LOOP
EDWAIT:	MOVE	T2,M78GLB##(J)	;GET GLOBAL WORD FROM WINDOW
	TRNE	T2,D78BAD	;SEE IF PDP11 SET BAD ADDR BIT
	  JRST	BADADD			;REPORT BAD ADDRESS
	JUMPE	T2,EXDPOK	;IF 0 THEN THE PDP11 IS DONE
	SOJN	T1,EDWAIT		;SEE IF TIME HAS EXPIRED
	  PJRST	ECOD5##			;NO RESPONSE FROM PDP11
					; WITHIN OUT ALLOTED TIME-OUT LOOP.
EXDPOK:	MOVE	T1,M78DTA##(J)	;PUT 11 DATA IN T1 AND
	PJRST	STOTC1##	; SKIP RETURN TO USER.
BADADD:	SETZM	M78GLB##(J)	;CLEAR GLOBAL STATUS
	PJRST	ECOD6##		;**ERROR CODE 6 FOR ILLEGAL ADDRESS

;HERE TO RETURN ALL THE WORDS IN A WINDOW SLOT TO THE USER
;
D78RDS:	MOVEI	J,M78SIZ##	;SIZE OF SLOT
	JSP	T2,CHKCNT	;MAKE SURE COUNT IS OK
D78RD1:	HRRZ	T1,(U)		;GET WORD FROM WINDOW SLOT
	PUSHJ	P,PUTWD1##	;GIVE HIM THE WORD
	SOJE	T3,CPOPJ1##	;SEE IF DONE GIVING WORDS
	AOJA	U,D78RD1	;NO, POINT TO NEXT WORD IN WINDOW SLOT
					; AND LOOP TO GIVE IT TO HIM.

;HERE TO SET WORDS IN THE WINDOW SLOT FROM USER BLK
;
D78SCH:	MOVEI	J,WS8SET##	;NUMBER WE ALLOW TO BE SET
	JSP	T2,CHKCNT	;MAKE SURE COUNT IS OK
	PUSHJ	P,GETWD1##	;GET DATA FROM USER
	HRRM	T1,WS8LS0##(U)	;SET STATUS IN WINDOW SLOT
	MOVSI	T4,(ENBSET)	;BIT TO SET IF USER ENABLING LINE, IN THE DDB
	MOVE	T2,[IORM T4,DEVIOS(F)]	;INSTRUCTION TO SET ENABLE SET
	TRNN	T1,S0.ENB	;SETTING LINE ENABLE?
	  HRLI	T2,(ANDCAM T4,(F))	;NO, CLEARING LINE ENABLE
	XCT	T2		;REMEMBER IN THE XXO DDB
	MOVSS	F		;PUT XXI DDB IN RH
	XCT	T2		;REMEMBER IN XXI DDB
D78SH1:	SOJE	T3,CPOPJ1##	;GIVE SKIP RETURN TO USER IF DONE
	ADDI	U,1		;POINT TO NEXT WORD IN WINDOW SLOT
	PUSHJ	P,GETWD1##	;GET NEXT WORD FROM USER
	HRRM	T1,(U)		;PUT IN WINDOW SLOT
	JRST	D78SH1		; AND LOOP FOR MORE

;HERE TO RETURN THE 10 STATUS IN THE (RH)
;AND THE 11 STATUS IN THE (LH).
;
D78RET:	HRRZ	T1,WS810S##(U)	;RETURN PDP10 STATUS IN (RH)
	HRL	T1,WS811S##(U)	;RETURN PDP11 STATUS IN (LH)
	PJRST	STOTC1##	;GIVE USER THE DATA AND A SKIP
					; RETURN.

;HERE TO RETURN THE WINDOW ADDR IN THE (RH)
;AND THE WINDOW SLOT ADDR IN THE (LH).
;
D78ADR:	HRRZ	T1,J		;GET WINDOW ADDRESS
	HRL	T1,U		;GET WINDOW SLOT ADDRESS
	PJRST	STOTC1##	;GIVE SKIP RETURN TO USER

;HERE TO RETURN THE PDP11 VERSION NUMBER.
;
D78VER:	HRRZ	T1,M78MOD##(J)	;GET PDP11 VERSION NUMBER
	PJRST	STOTC1##	;GIVE SKIP RETURN TO USER

;HERE TO SET THE STATION NUMBER
;
SETSTA:	SOJL	T3,ECOD4##	;**ERROR-4 IF NOT ENOUGH ARGS
	  PUSHJ	P,GETWD1##		;GET THE STATION NUMBER.
	JUMPE	T1,SETST4	;IF SETTING TO 0, THEN DON'T CHECK.
	SKIPL	T1			;BAD IF NEGATIVE
	  CAILE	T1,77			;MUST BE 0-77.
	  PJRST	ECOD10##		;**ERROR-10 IF NOT 0-77.
IFN	FTNET,<
	PUSH	P,T4		;SAVE LINE NUMBER
	PUSHJ	P,SRCNDB##	;SEE  IF STATION EXISTS
	  JRST	SETST1			;STATION NOT IN NETWORK.
	POP	P,(P)		;CLEAN UP
	PJRST	ECOD11##	;**ERROR-11 IF  STATION EXISTS
SETST1:	POP	P,T4		;GET THE LINE NUMBER BACK
>;END IFN FTNET
	MOVSI	T2,M78LM##	;MINUS NUMBER OF LINES
	SKIPA	F,M78DDB##	;GET ADDRESS OF FIRST DDB
SETST2:	HLRZ	F,DEVSER(F)	;GET ADDRESS OF NEXT DDB
	CAIN	T4,(T2)		;ARE CHECKING OUR OWN LINE?
	  JRST	SETST3			;YES, DON'T CHECK STATION #
	LDB	T3,PDVSTA##	;GET THE STATION NUMBER FROM DDB
	CAMN	T3,T1		;DOES STATION NUMBER EXIST?
	  PJRST	ECOD11##		;**ERROR-11 IF STATION EXISTS
SETST3:	AOBJN	T2,SETST2	;DONE?
	MOVE	F,M78DDB##(T4)	;GET OUR DDB ADDRESS BACK
SETST4:	DPB	T1,PDVSTA##	;SET XXO STATION NUMBER
	MOVSS	F		;FOR XXI
	DPB	T1,PDVSTA##	;SET XXI STATION NUMBER
	PJRST	CPOPJ1##	;GIVE SKIP RETURN TO USER.

;MAKE USRE THE COUNT IS NOT .GT. WHAT IS IN "J"
; AND IF IT IS TRIM IT TO WHAT IS IN J AND GIVE USER NEW COUNT
;
CHKCNT:	JUMPLE	T3,ECOD4##	;**ERROR-4 IF NO ROOM
	CAMG	T3,J			;SEE IF WE ALLOW THIS MUCH
	  JRST	(T2)			;YES, A-OK
	HRL	T1,1(J)		;GIVE WHAT WE'RE ALLOWED PLUS 1
	HRR	T1,M		;THE ADR OF HIS BLOCK
	PUSHJ	P,STOTAC##	;TELL HIM HOW MUCH WE'LL GIVE
	MOVE	T3,J		;WHAT IS ALLOWED FOR COUNT
	JRST	(T2)		;PROCEED WITH NEW COUNT
SUBTTL	MISCELLANEOUS ROUTINES

;ROUTINE TO SET:
;
;	(RH) J = TO BEGINNING ADDRESS OF WINDOW
;	(RH) U = TO BEGINNING ADDRESS OF WINDOW SLOT
;
; CALL:	PUSHJ	P,D78SJU		;F MUST POINT TO THE CORRECT DDB
;
D78SJU:	MOVE	S,DEVIOS(F)	;GET DEVICE STATUS
	LDB	U,[POINT 4,XXILCN(F),32];NOW GET LINE NUMBER
	IMULI	U,M78SIZ##	;SO WE POINT TO CORRECT SLOT
	LDB	J,[POINT 3,XXILCN(F),35];NOW GET THE PDP11 NUMBER.
	HRRZ	J,M78BAT##(J)	;PUT BASE ADDR FOR WINDOW IN RH
	ADDI	U,M78WIN##(J)	;MAKE ADR OF SUBWINDOW
;
;HERE TO SEE IF THE DAS78 IS RUNNING
;
	SKIPE	M78HLT##(J)	;SKIP IF PDP11 NOT HALTED
	  JRST	D78CH1			;PDP11 PRESENTED A STOPCD
	SKIPLE	M78DWN##(J)	;SKIP IF PDP11 IS NOT RUNNING
	  POPJ	P,			;PDP11 SEEMS TO BE RUNNING SO FAR.
D78CH1:	MOVEI	S,IODERR	;SET HARD ERR SINCE 11
	IORB	S,DEVIOS(F)	; IS NOT RUNNING.
	PJRST	CLRACT##	;CLEAR IOACT AND SET DEVIOS

;HERE TO HAVE DAS78 NOTICE A LINE
;
; CALL:	PUSHJ	P,D78WAK		;F MUST POINT TO THE CORRECT DDB
;	RETURN				;ALL AC'S PRESERVED
;
D78WAK:	PUSHJ	P,SAVE2##	;SAVE P1-P2
	TRACE				;MAKE A TRACE
	LDB	P2,[POINT 4,XXILCN(F),32]	;GET THE LINE NUMBER
	MOVEI	P1,1
	LSH	P1,(P2)
	LDB	P2,[POINT 3,XXILCN(F),35]	;GET PDP11 NUMBER
	SKIPE	M78XXI##(J)	;SKIP IF ACTIVITY WORD IS ZERO
	  JRST	D78WA1			;ACTIVITY WORD IS NOT 0
	IOR	P1,SAVACT(P2)	;"OR" IN THE SAVED ACTIVITY WORD
					; IF IT WASN'T REQUIRED TO SAVE IT
					;  BECAUSE THE ACTIVITY WORD IN
					;   THE WINDOW WAS 0 WE JUST
					;    "OR" IN 0'S.
D78WK1:	SETZM	SAVACT(P2)	;ZERO IT REGARDLESS AS A COPY
					; WAS "OR'ED" INTO P1.
	HRRZM	P1,M78XXI##(J)	;PUT ACTIVITY WORD IN THE WINDOW
D78WK2:	MOVE	P2,M78BT##(P2)	;GET TABLE ADDR OF I/O INSTRUCTIONS
	XCT	M78I11##(P2)	;INTERRUPT THE PDP11
	POPJ	P,

D78WA1:	IORM	P1,SAVACT(P2)	;
					; TO BE "OR'ED" WITH THE ONE
					;  THE NEXT TIME AROUND.
	POPJ	P,		;

	$LOW
SAVACT:	Z				;ACTIVITY WORD BUFFER
	Z
	Z
	Z
	Z
	Z
	Z
	Z
	$HIGH

;ROUTINE TO WAIT FOR CLOSE TO FINISH
;
; CALL:	PUSHJ	P,CHKCLO		;DEVIOS INDICATES IN OR OUT
;
CHKCLO:	PUSHJ	P,D78SJU	;POINT AT THE WINDOW
	MOVEI	T2,OEF10	;ASSUME CHECKING OUTPUT
	MOVE	S,DEVIOS(F)	;GET FRESH COPY OF S
	TLNN	S,IO		;SKIP IF OUTPUT
	  MOVEI	T2,IEF11		;SET TO CHECK FOR INPUT
	PIOFF			;TURN PI OFF
	MOVE	T1,WS811S##(U)	;GET 11 STATUS
	IOR	T1,WS810S##(U)	;INCLUDE 10 STATUS
	TDNN	T1,T2		;SEE IF CLOSING IN PROGRESS
	  PJRST	ONPOPD##		;NO CLOSING, ENABLE PI AND EXIT
	MOVSI	S,(XCLOSE)	;BIT TO INDICATE WAIT FOR CLOSING
	IORB	S,DEVIOS(F)	; PUT BIT IN DDB
	PUSHJ	P,SETACT##	;MAKE DEVICE ACTIVE AND START HUNG COUNT
	PION			;ENABLE PI SYSTEM
	PUSHJ	P,WSYNC##	;GO INTO IOW
	JRST	CHKCLO		;GO AROUND TO MAKE SURE

;ROUTINE TO CHECK IF 11 READY AND IF NOT HIBER
;
;CALL:	PUSHJ	P,CHKRDY		;DEVIOS INDICATES IN OR OUT
;	ERROR RETURN
;	RETURN WHEN READY
;
CHKRDY:	PUSHJ	P,D78SJU	;MAKE SURE U POINTS TO WINDOW SLOT
	TRNE	S,IODTER!IODERR
	  POPJ	P,
	MOVEI	T2,ORDY11	;ASSUME OUTPUT
	TLNN	S,IO		;SKIP IF OUTPUT
	  MOVEI	T2,IRDY11		;SET TO CHECK INPUT RDY
	TDNN	T2,WS810S##(U)	;CHECK FOR ABORT HAPPENED
	  JRST	[	MOVEI	S,IODTER
			IORB	S,DEVIOS(F)
			POPJ	P, ]
	TDNE	T2,WS811S##(U)	;11 READY?
	  JRST	CPOPJ1##			;YES - EXIT
	MOVSI	S,(RDYWAT)	;BIT TO INDICATE WAITING
	IORB	S,DEVIOS(F)	;FLAG WAITING FOR 11RDY
	SETZ	T1,		;
	LDB	J,PJOBN##	;GET JOB NUMBER
	PUSHJ	P,HIBER##	;GO BEDDY BYE TILL 11 IS READY
	  JFCL				;
	JRST	CHKRDY		;CHECK AGAIN

;ROUTINE TO CHECK IF THE LINE IS ENABLED.
;
; CALL:	JSP	T4,CHKENB		;DEVIOS INDICATES IN OR OUT
;
CHKENB:	MOVE	T1,WS8LS0##(U)	;GET THE LINE STATUS WORD.
	TRNE	T1,S0.ENB	;IS THE LINE ENABLED?
	  JRST	(T4)			;YES. RETURN TO IN OR OUT UUO
	SETZ	T1,		;FOR STATION NUMBER
	PIOFF			;DISABLE PI
	MOVE	S,DEVIOS(F)	;MAKE SURE S IS FRESH
	TLZ	S,(ENBSET)	;CLEAR ENABLE SET BIT FROM DDB
	IORI	S,IOIMPM	;LIGHT AN ERROR BIT
	MOVEM	S,DEVIOS(F)	;RESET DEVIOS
	PION			;RE-ENABLE PI
	DPB	T1,PDVSTA##	;STATION NUMBER 0
	TLNN	S,IO		;IN OR OUTPUT
	  JRST	CHKEN1			;MUST BE INPUT
	SETZM	WS8OCC##(U)	;CLEAR OUTPUT COUNT
	SETZM	WS8OBP##(U)	;CLEAR OUTPUT POINTER
	POPJ	P,		;GIVE ERROR TO USER
CHKEN1:	SETZM	WS8ICC##(U)	;CLEAR INPUT COUNT
	SETZM	WS8IBP##(U)	;CLEAR INPUT POINTER
	POPJ	P,		;GIVE ERROR TO USER

;ROUTINE TO SET FILE MODE (ASCII OR BINARY)
;
; CALL:	PUSHJ	P,SETMOD		;S INDICATES IN OR OUT AND FILE MODE
;
SETMOD:	MOVEI	T1,SX.IBN	;ASSUME INPUT
	TLNE	T1,IO		;SEE IF IN OR OUTPUT.
	  MOVEI	T1,SX.OBN		;IT WAS OUTPUT
	ANDCAM	T1,WS810S##(U)	;ASSUME ASCII MODE
	TRNE	S,16		;SEE IF ASCII MODE
	  IORB	T1,WS810S##(U)		;NO, MAKE IT BINARY MODE
	POPJ	P,		;RETURN TO CALLER WITH MODE SET IN WINDOW

;ROUTINE TO SET THE JOB IOACT
;
; CALL:	PUSHJ	P,MAKACT
;	RETURN
;
MAKACT:	PIOFF			;DISABLE PI
	PUSHJ	P,SETACT##	;MAKE JOB IOACT
	PJRST	ONPOPD##	;TURN PI BACK ON.
;ROUTINE TO CLEAR "IOBEG" IN DDB
;AND TO WAKE UP A JOB.
;
; CALL:	PUSHJ	P,SWKJOB		;S=DEVIOS(F)
;	RETURN HERE			;IOBEG CLEAR IN DDB.
;					;T1 AND T2 DESTROYED
;
; CALL:	PUSHJ	P,WKJOB			;
;	RETURN HERE			;T1 AND T2 DESTROYED
;
	$HIGH
SWKJOB:	TLZ	S,IOBEG		;CLEAR VIRGIN BUFFER BIT
RWKJOB:	MOVEM	S,DEVIOS(F)	; IN DDB.
WKJOB:	LDB	T1,PJOBN##	;T1 MUST CONTAIN JOB NUMBER
	JUMPE	T1,CPOPJ##	;IN CASE NO JOB FOR DDB
	PJRST	WAKJOB##		;WAKE UP JOB

;ROUTINE TO SET IODERR IN DEVIOS AND CLEAR IOACT.
;
KILUUO:	MOVEI	S,IODTER	;SET DATA ERROR FOR ABORT
	IORB	S,DEVIOS(F)	;DO IT.
	PJRST	CLRACT##	;CLEAR IOACT AND SET DEVIOS

;COME HERE IF USER BUFFER LARGER THAN WE ALLOW
;
BIGBUF:	IORM	T1,WS810S##(U)	;SET ABORT BIT IN WINDOW
	IORI	S,IOBKTL	;LIGHT AN ERROR BIT
	PJRST	CLRACT##	;RETURN TO USER

;HERE TO WAKE UP A JOB AND DO A .JCONT FOR IT
;
; CALL	PUSHJ	P,JCJOB
;
JCJOB:	PUSHJ	P,WKJOB		;WAKE UP THE JOB
	PUSH	P,U		;
	PUSH	P,F		;
	PUSH	P,J		;SAVE SOME AC'S
	LDB	J,PJOBN##	;GET JOB NUMBER
	PUSHJ	P,TTYSRC##	;SETUP LINE
	  JRST	JCJOB2			;
	MOVSI	T2,LDBCMF##	;ANY FORCED COMMAND
	TDNE	T2,(U)		; FOR THIS JOB ALREADY?
	  JRST	JCJOB2			;YES
	MOVEI	T1,TTFCXJ##	;INDEX FOR FORCE CONTINUE
	PUSHJ	P,TTFORC##	;SETUP FORCED COMMAND
JCJOB2:	POP	P,J		;RESTOR J
	PJRST	FUPOPJ##	;RESTORE F+U AND RETURN
COMMENT	%

THE TRACE ROUTINE SAVES THE FOLLOWING INFORMATION IN A
RING BUFFER [ TRCBUF ] ON EACH TRACE CALL.

	-1,,ADRESS OF THE TRACE CALL (PC-1)
	TIME				;FROM TIME##
	DEVIOS(F)			;DEVIOS FROM THE DDB
	S				;DEVIOS FROM S
	JBTSTS##				;JOB STATUS
	M78XIX##,,M78XXI##			;11 TO 10 ACTIVITY,,10 TO 11 ACTIVITY
	WS8LS0##				;1ST STATUS WORD
	WS8LS1##				;2ND STATUS WORD
	WS811S##,,WS810S##			;11 STATUS,,10 STATUS
	WS8IBP##				;INPUT BYTE POINTER
	WS8OBP##				;OUTPUT BYTE POINTER
	WS8ICC##,,WS8OCC##			;INPUT CHAR COUNT,,OUTPUT CHAR COUNT

THE (RH) OF TRCPNT-1 POINTS TO THE LAST ITEM PLACED IN TRCBUF

%

IFN	D78TRC,<

	STOREN==0			;SET COUNT OF STORE CALLS TO 0

	DEFINE	STORE,<
	STOREN==STOREN+1		;COUNT TIMES WE CALL STORE
					; SO ITEMS TRACED WILL NOT
					; BE WRAPPED AROUND.
	PUSHJ	P,STORE.	;PUT C(T2) INTO TRCBUF
	>;END DEFINE STORE

;ROUTINE TO MAKE A TRACE
;
; CALL:	PUSHJ	P,TRACE.		;F POINTS TO DDB
;					;J POINTS TO WINDOW
;					;U POINTS TO WINDOW SLOT
;	RETURN				;ALWAYS
;
TRACE.:	CONO	PI,PIOFF##	;DISABLE PI SYSTEM DURING TRACE
	PUSH	P,T1		;SAVE SOME AC'S
	PUSH	P,T2		;
	MOVE	T1,TRCPNT	;GET AOBJN POINTER TO TRCBUF
	HRRO	T2,-2(P)	;GET PC FROM WHERE WE CAME
	SUBI	T2,1		;MAKE IT THE TRACE CALL ADDRESS
	STORE				;PUT -1,,ADDRESS INTO TRCBUF
	MOVE	T2,TIME##	;GET THE CURRENT TIME
	STORE				;PUT CURRENT TIME INTO TRCBUF
	MOVE	T2,DEVIOS(F)	;GET STATUS FROM DDB
	STORE				;PUT DDB STATUS INTO TRCBUF
	MOVE	T2,S		;GET THE DEVICE STATUS IN S
	STORE				;PUT DEVICE STATUS FROM S INTO TRCBUF
	LDB	T2,PJOBN##	;GET JOB NUMBER
	MOVE	T2,JBTSTS##(T2)	;GET THE JOB STATUS
	STORE				;SAVE JOB STATUS IN TRCBUF
	HRL	T2,M78XIX##(J)	;GET 11 TO 10 ACTIVITY WORD
	HRR	T2,M78XXI##(J)	;GET 10 TO 11 ACTIVITY WORD
	STORE				;SAVE 11 TO 10,,10 TO 11
	MOVE	T2,WS8LS0##(U)	;GET 1ST STATUS WORD
	STORE				;PUT 1ST STATUS WORD INTO TRCBUF
	MOVE	T2,WS8LS1##(U)	;GET 2ND STATUS WORD
	STORE				;PUT 2ND STATUS WORD INTO TRCBUF
	HRL	T2,WS811S##(U)	;GET 11 STATUS
	HRR	T2,WS810S##(U)	;GET 10 STATUS
	STORE				;PUT 11 STATUS,,10 STATUS INTO TRCBUF
	MOVE	T2,WS8IBP##(U)	;GET INPUT BYTE POINTER
	STORE				;PUT INPUT BYTE POINTER INTO TRCBUF
	MOVE	T2,WS8OBP##(U)	;GET OUTPUT BYTE POINTER
	STORE				;PUT OUTPUT BYTE POINTER INTO TRCBUF
	HRL	T2,WS8ICC##(U)	;GET INPUT CHARACTER COUNT
	HRR	T2,WS8OCC##(U)	;GET OUTPUT CHARACTER COUNT
	STORE				;PUT ICC,,OCC INTO TRCBUF
	POP	P,T2		;RESTORE AC'S WE USED
	POP	P,T1		;
	PJRST	ONPOPJ##	;TURN INTERRUPT SYSTEM BACK ON

;HERE TO PUT THE CONTENTS OF T2 INTO TRCBUF
;
; CALL:	PUSHJ	P,STORE.		;T2 CONTAINS DATA TO BE STORED
;					;T1 CONTAINS A AOBJN POINTER TO TRCBUF
;	RETURN				;ALWAYS
;
STORE.:	MOVEM	T2,(T1)		;PUT C(T2) INTO "TRCBUF"
	AOBJN	T1,.+2		;UPDATE COUNT AND POINTER TO TRCBUF
SETTRC:	  MOVE	T1,[XWD	-TRCSIZ,TRCBUF]	;RESET COUNT AND POINTER
	MOVEM	T1,TRCPNT	;UPDATE POINTER TO BUFFER
	POPJ	P,		;RETURN TO CALLER

	$LOW

TRCPNT:	XWD	-TRCSIZ,TRCBUF	;AOBJN POINTER TO TRCBUF
TRCBUF:	BLOCK	STOREN*TRCNUM	;BEGINNIN OF THE TRACE BUFFER
TRCSIZ==.-TRCBUF				;SIZE OF THE TRACE BUFFER IN WORDS

D78PAT:	BLOCK	PATD78		;PATCH AREA FOR DAS78

	$HIGH

>;END IFN D78TRC
	$LIT

D78END::END