Google
 

Trailing-Edge - PDP-10 Archives - 7.01A_PCL20_KMCSRC_19830513 - pc2ser.mac
There are 2 other files named pc2ser.mac in the archive. Click here to see a list.
	TITLE PC2SER - SERVICE FOR PCL11-B CONTROLLER ON THE 2020(PCL20) - V006
	SUBTTL	J. Francis	20-Feb-81
	SEARCH	F,S
	SALL

;THIS SOFTWARE IS FURNISHED UNDER LICENSE AND MAY ONLY BE USED OR
;COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1979,1980,1981,1983 BY DIGITAL EQUIPMENT CORP.,MAYNARD, MASS.

XP VPC2SR,006		;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP

	IFNDEF	FTDBUG,<FTDBUG==-1>

DEFINE E$MSG0(TEXT),<[ASCIZ /TEXT/]>

DEFINE E$MSG1(TEXT),<[ASCIZ /TEXT
/]>
DEFINE E$MSG2(TEXT),<[ASCIZ /
TEXT/]>
DEFINE E$MSG3(TEXT),<[ASCIZ /
TEXT
/]>
DEFINE E$TYPE(CODE,TEXT),<
	MOVEI	T1,E$MSG'CODE <TEXT>
	PUSHJ	P,CONMES##>

	ENTRY	PC2SER
PC2SER:
SUBTTL	PCL20/PCL11-B REGISTER DEFINITIONS

;OFFSETS INTO THE EXTERNAL PAGE REGISTER

PCXTCR==0		;TRANSMITTER COMMAND REGISTER
PCXTSR==2		;TRANSMITTER STATUS REGISTER
PCTSDB==4		;TRANSMITTER SOURCE DATA BUFFER
PCTSBC==6		;TRANSMITTER SOURCE BYTE COUNT
PCTSBA==10		;TRANSMITTER SOURCE BUS ADDRESS
PCTMMR==12		;TRANSMITTER MASTER/MAINTENCE REGISTER
PCTCRC==14		;TRANSMITTER SOURCE CYCLIC REDUNDANCY CHECK REGISTER

PCXRCR==20		;RECEIVER COMMAND REGISTER
PCXRSR==22		;RECEIVER STATUS REGISTER
PCRDDB==24		;RECEIVER DESTINATION DATA REGISTER
PCRDBC==26		;RECEIVER DESTINATION BYTE COUNT
PCRDBA==30		;RECEIVER DESTINATION BUS ADDRESS
PCRCRC==34		;RECEIVER CYCLIC REDUNDANCY CHECK REGISTER

;BIT ASSIGNMENTS FOR THE PCL20 TRANSMITTER COMMAND/CONTROL REGISTER


STRTXM==1B35			;START TRANSMISSION
TXINIT==1B34			;TRANSMITTER INITIALIZE
INHADI==1B33			;INHIBIT BUS ADDRESS INCREMENT-ALSO FOR RCV
DTORDY==1B32			;DATA OUTPUT READY
EXTADR==3B31			;EXTENDED BUS ADDRESS FIELD-ALSO FOR RCV
INTENA==1B29			;TRANSMIT INTERRUPT ENABLE-ALSO FOR RCV
RDSILO==1B28			;READ SILO ENABLE
DSTCOD==37B27			;DESTINATION ADDRESS CODE FIELD
SNDWRD==1B22			;SEND WORD
TXXNPR==1B21			;TRANSMIT VIA NPR
TXXRIB==1B20			;RETRY IF BUSY

;BIT ASSIGNMENTS FOR THE TRANSMITTER MASTER MAINTENANCE REGISTER

TXMADR==37B35			;MASTER ADDRESS SILO FIELD
PCMSTR==1B27			;MASTER BIT
PCSECD==1B26			;SECONDARY BIT
PCMSTN==1B25			;MASTER NOW BIT
CHNOPN==1B24			;CHANNEL OPEN BIT
AUTADR==1B23			;AUTOADDRESSING BIT
CLRADR==1B22			;CLEAR ADDRESS SILO
AIPRDY==1B21			;ADDRESS INPUT READY BIT
AOPRDY==1B20			;ADDRESS OUTPUT READY BIT

;BIT ASSIGNMENT FOR THE TRANSMITTER STATUS REGISTER


TXRSPA==3B35			;RESPONSE FIELD A
TXRSPB==3B33			;RESPONSE FIELD B
TBSBSY==1B31			;TDM BUS BUSY
TXSORE==1B30			;SOFTWARE REJECT
TXBUSY==1B29			;TRANSMITTER BUSY
SUCTXF==1B28			;SUCCESSFUL TRANSFER-ALSO FOR XMIT
DTIRDY==1B27			;DATA INPUT READY
OVERUN==1B26			;DATA OVERRUN
TIMOUT==1B25			;SEND/RCV WORD TIME OUT-ALSO FOR XMIT
MSTDWN==1B24			;MASTER DOWN
TXMERR==1B23			;TRANSMISSION ERROR-XMIT AND RCV
MEMOFL==1B22			;BUS ADDRESS OVERFLOW FOR NPR XFER-XMIT AND RCV
NONEXM==1B21			;NON-EXISTENT MEMORY ADDRESSING ERROR-XMIT AND RCV
TXXERR==1B20			;TRANSMITTER ERROR


;BIT ASSIGNMENT FOR THE RECEIVER COMMAND/CONTROL REGISTER


RCVDAT==1B35			;RECEIVE DATA
RCINIT==1B34			;RECEIVER INITIALIZE

RDIRDY==1B32			;RECEIVE DATA INPUT READY



LDSILO==1B28			;LOAD DATA SILO
IDENTC==37B27			;RECEIVE IDENTIFICATION CODE FIELD
RCVWRD==1B22			;RECEIVE WORD
RCVNPR==1B21			;RECEIVE VIA NPR
REJECT==1B20			;RECEIVER SOFTWARE REJECT BIT	


;BIT ASSIGNMENT FOR RECEIVER STATUS REGISTER


RCRSPA==3B35			;RCV RESPONSE FIELD A
RCRSPB==3B33			;RCV RESPONSE FIELD B

RCHOPN==1B31			;RECEIVE CHANNEL OPEN
REJCOM==1B30			;REJECT SEQUANCE COMPLETED
RCBUSY==1B29			;RECEIVE BUSY WITH XFER

RDORDY==1B27			;DATA SILO OUTPUT READY
RBCOFL==1B26			;RCV BYTE COUNT OVERFLOW

RCVPAR==1B24			;RCV WORD PARITY OR CRC ERROR



RCVERR==1B20			;RECEIVER ERROR
SUBTTL	SYMBOL DEFINITIONS

;DEVICE DEPENDENT BITS IN LH OF DEVIOS

PCIPWT==1B21			;INPUT QUEUE WAITING - BUSY
PCOBSY==1B22			;OUTPUT BUSY
USERWT==1B23			;DRVR WAIT ON USER RESPONSE FROM A PSI FLAG WORD INTERRUPT
PCIACT==1B19			;INPUT XFER ACTIVE
PCOACT==1B20			;OUTPUT XFER ACTIVE
REJACT==1B29			;USER REJECT DEVOP ACTIVE


;DEVICE DEPENDENT BITS IN RH OF DEVIOS

IFLGWD==1B29			;INCLUDE FLAG WORD IN DATA BUFFER
ACPTRD==1B28			;ACCEPT AND READ FLAG, SET NORMALLY BY USER
ENIPUT==1B27			;USER SELECTED ENABLE INPUT RCV
USERIB==1B26			;USER SELECTED RIB BIT FOR XMIT
INHRCV==1B25			;INHIBIT RCV ENABLE ON RCV DONE


PCLPRV==1B18			;PCL PRIVILEDGE BIT FOR MASTER REGISTER

ADRMIN==^D20			;MINIMUM SILO ADDRESSING ENTRIES
ADRMAX==^D50			;MAXIMUM SILO ADDRESSING ENTRIES

.ERSPC==70			;SPECIAL DEVICE CONTROLLER ERROR TYPE - (PCL20)


IONXM%==1			;ERROR CODE FOR NON-EXISTANT MEMORY
IOOFL%==2			;ERROR CODE FOR ADDRESS OVERFLOW
IOTOT%==4			;ERROR CODE FOR TIMEOUT
IOOVR%==20			;ERROR CODE FOR OVERRUN
IOBCO%==40			;ERROR CODE FOR BYTE COUNT OVERFLOW
IOTXM%==1000			;ERROR CODE FOR TRANSMISSION ERROR
IOMDN%==2000			;ERROR CODE FOR MASTER DOWN

;EVENT WAIT CODE FOR PCL20

EV.RJT==77			;EVENT WAIT CODE FOR REJECT SEQ.
SUBTTL	PCL SPECIFIC DDB DEFINITIONS

;PROTOTYPE DEFINITION FOR PCL20 INTERRUPT SERVICE ENTRY AND DDB - PCLDDB

	.TYPCL==57			;DEVICE TYPE CODE FOR PCL20
	PCLTYP==57B27
	PCLCBI==M.PC0I			;PCL INPUT CHANNEL DATA BLOCK NUMBER
	PCLCBO==M.PC0O			;PCL OUTPUT CHANNEL DATA BLOCK NUMBER
	DCV2IO=4000			;FLAG TO INDICATE FULL DUPLEX DEVICE
	PDVTIM=1400			;DEVICE HUNG TIME CONSTANT
	BFRSZE=205			;DEFAULT BUFFER SIZE
	MXFRBF=BFRSZE*6/4		;MAX BUFFER SIZE FOR FORMATTING
	REJMAX=^D7			;MAX # REJECT REASONS

IF2	<%%REJ==-1>
DEFINE DOREJ,<
IFNDEF %%REJ,<%%REJ==-1>
	%%REJ==%%REJ+1
	REJ2(\%%REJ)>

DEFINE	REJ2(N),<
	JSP	T1,REJ'N'X
IFGE	N-REJMAX,<PRINTX ?REJECT CODE TOO LARGE, INCREASE REJMAX>
	>

DEFINE CNTREJ,<
IFNDEF %%REJ,<%%REJ==-1>
	%%REJ==%%REJ+1
IFGE	%%REJ-REJMAX,<PRINTX ?REJECT CODE TOO LARGE, INCREASE REJMAX>
	AOS	REJTAB+%%REJ(F);;	;COUNT THE EVENT
>

DEFINE	CHNMAC	(Z)	<
	CHN'Z'CB##>			;END OF CHNMAC MACRO


	PCLMOD==1_I			; Only Image Mode

DEFINE	PCLDDB	(N)	<

	ENTRY	PC'N'INT,PC'N'DDB,PC'N'DDS

DEFINE	CHNLOC	(PI)	<
	PC'N'CHL=CH'PI'##
>	;END OF CHNLOC MACRO

CHNLOC	\PC'N'CHN			;GET PC'N'CHL DEFINED NOW

PC'N'INT::
P'N'TINT:	0			;TRANSMIT INTERRUPT VECTOR ENTRY
	EXCH	T1,PC'N'INT		;GET INTERRUPT PC
	MOVEM	T1,PC'N'CHL		;PUT INTO -10 STYLE INTERRUPT HANDLER
	HRRZM	T1,'N'TYINT		;FLAG TRANSMIT INTERRUPT
	EXCH	T1,PC'N'INT		;AND RESTORE T1
	JRST	P'N'XINT		;GO DO COMMON THINGS
'N'TYINT:	0			;FLAG WORD FOR INTERRUPT TYPE
P'N'RINT:	0			;RECEIVER INTERRUPT VECTOR ENTRY
	EXCH	T1,P'N'RINT		;GET INTERRUPT PC
	MOVEM	T1,PC'N'CHL		;PUT INTO -10 STYLE INTERRUPT HANDLER
	HRROM	T1,'N'TYINT		;FLAG RECEIVER INTERRUPT
	EXCH	T1,P'N'RINT		;RESTORE T1
P'N'XINT:	JSR	PC'N'SAV##	;SAVE AC'S
					;GO SETUP F AND JSP TO INTERRUPT CODE
;PCL DDB BLOCK

PC'N'JSP:	MOVE	T4,'N'TYINT	;SETUP T4 TO IDENTIFY INTERRUPT TYPE
	JSP	F,PCLINT	;THIS INSTRUCTION MUST ALWAYS BE JUST BEFORE DDB
PC'N'DDB::PHASE	0			;THE FIRST DDB LOCATION
	SIXBIT /PC'N'/			;(0) DEVNAM
	XWD PDVTIM!DCV2IO,BFRSZE	;(1) DEVCHR
	0				;(2) DEVIOS
	XWD 0,PCLDSP			;(3) DEVSER
	XWD DVIN+DVOUT,PCLMOD		;(4) DEVMOD
	0				;(5) DEVLOG
	0				;(6) DEVBUF
	XWD R,0				;(7) DEVIAD
	XWD R,0				;(10) DEVOAD
	0				;(11) DEVSTS
	XWD DEPLEN!PCLTYP,DEPEVM	;(12) DEVSTA
	0				;(13) DEVXTR
	0				;(14) DEVEVM
	0				;(15) DEVPSI
	0				;(16) DEVESE
	0				;(17) DEVHCW
	0				;(20) DEVCPU
	0				;(21) DEVJOB
PCIPTR::0				;INPUT DATA POINTER WORD
PCOBYT::0				;OUTPUT BYTE POINTER
PCIBYT::0				;INPUT BYTE POINTER
TFLGWD:	0				;LOCATION TO STORE XMIT FLAG WORD
RFLGWD:	0				;LOCATION OF RECIEVE FLAG WORD
ONEWRD:	0				;ONE WORD RECEIVE WORD
PCLDAP::0
PCLDAE::BLOCK	20			;SYSERR BLOCK
REGBLK::BLOCK	20			;STORAGE BLOCK FOR REGISTER DATA
PCLTST::0				;MORE TRANSMITTER STATUS
PCLRST::0				;MORE RECEIVER STATUS
PCLVEC::PCLBIV+VOFSET			;PCL11-B 11 STYLE INTERRUPT VECTOR ADDRESS
PCLBAS::PCLBDA+BOFSET			;PCL11-B BASE DEVICE ADDRESS
PCLTVI::JSR	P'N'TINT		;INTERRUPT INSTRUCTION FOR THIS PCL
PCLRVI::JSR	P'N'RINT		;RECEIVER INTERRUPT INSTRUCTIO
PCLTBL::PC'N'BLK			;POINTER TO PCLN BLOCK AREA
PCTRTY::0				;TRANSMIT NODE RETRY COUNT
PCRRTY::0				;RECEIVE NODE RETRY COUNT
PCICDB:: CHNMAC	\PCLCBI			;POINTER TO INPUT CHANNEL DATA BLOCK
PCOCDB:: CHNMAC \PCLCBO			;POINTER TO OUTPUT CHANNEL DATA BLOCK
IFN FTDBUG,<
DVOPFC:	0				;LAST DEVOP FUNCTION CODE
TIMDT0:	0				;FLG WD INT ENTRY
TIMDT1:	0				;FLG WD INT EXIT
TIMERR:	0				;TIME AT ERROR
TIMIN0:	0				;IN UUO ENTRY
TIMIN1:	0				;IN UUO EXIT
TIMACP:	0				;ACP & RD DEVOP
TIMING:	0				;RCV STARTED
TIMRD0:	0				;RCV INT DONE
TIMRD2:	0				;RCV DONE EXIT
TIMOU0:	0				;OUT UUO ENTRY
TIMOU1:	0				;OUT UUO EXIT
TIMERC:	0				;ENABLE RCV DEVOP
TIMDON:	0				;STOP ROUTINE, EXIT
REJTAB:	BLOCK	REJMAX			;TABLE OF REJECT COUNT BY TYPE
>	; END IFN FTDBUG

	DEPHASE

XP	PC'N'DDS,.-PC'N'DDB		;SIZE OF THE DDB
PC'N'BLK::PHASE 0			;START OF PCLN DATA BLOCK AREA(INTERFACE SPECIFIC)
PCLTAB:	BLOCK	21			;TABLE OF DDB ADDRESSES FOR PC(N)
PCINIT::0				;PCL INITIALIZE FLAG WORD
PCLBSY:	0				;PCL BUSY WORD;LH-INPUT BUSY, RH-OUTPUT BUSY

	DEPHASE


>;END OF PCLDDB DEFINITION



DEFINE	PCLN	<			;GENERATE A SYMBOL EQUAL TO CONFIGURED # OF PCL20
PCLN==0					;INTERFACES ON THIS SYSTEM
VOFSET==0
BOFSET==0
IFDEF	PCAN,	<			;IS PCA DEFINED
IFG	PCAN,	<			;IS IT REALLY
PCLN==PCLN+1
PCLY==PCAN
PCLDDB	A				;GENERATE DDB FOR PCA

>;END OF IFG PCAN
>;END OF IFDEF PCAN

IFDEF	PCBN,	<			;IS PCB DEFINED
IFG	PCBN,	<			;IS IT REALLY
PCLN==PCLN+1
BOFSET=BOFSET+40			;SET BASE ADDRESS OFFSET
PCLDDB	B				;GENERATE DDB FOR PCB

>;END OF IFG PCBN
>;END OF IFDEF PCBN

IFDEF	PCCN,	<			;IS PCC DEFINED
IFG	PCCN,	<			;IS IT REALLY
PCLN==PCLN+1
BOFSET=BOFSET+40			;SET BASE ADDRESS OFFSET
PCLDDB	C				;GENERATE DDB FOR PCC

>;END OF IFG PCCN
>;END OF IFDEF PCCN

IFDEF	PCDN,	<			;IS PCD DEFINED
IFG	PCDN,	<			;IS IT REALLY
PCLN==PCLN+1
BOFSET=BOFSET+40			;SET BASE ADDRESS OFFSET
PCLDDB	D				;GENERATE DDB FOR PCD

>;END OF IFG PCDN
>;END OF IFDEF PCDN
>;END OF PCLN DEFINITION
DEFINE SPASGDDB(DEV,CHAN,DEVMNY),<
	DEV'CHN=CHAN			;;DEFINE PI CHANNEL FOR DEVICE
	DEV'N=DEVMNY			;;DEFINE NUMBER OF DEICES
>

;
;FIRST DEFINE NUMBER OF DEVICES

SPCDDB
;NOW GENERATE PCLN AND ALL PCLDDB'S NEEDED

PCLN					;START HERE
SUBTTL	PCL SYSERR DATA BLOCK DEFINITIONS


;WORDS ARE IN EACH PCL NODE DDB FOR DAEMON ERROR REPORTING


.HCNAM==0			;DEVICE NAME
.HCTYP==1			;CONTROLLER/DEVICE TYPE

	HC.CTL==77B5		;CONTROLLER TYPE BYTE
	.CTPC2==77		;TYPE FOR PCL20
	HC.DEV==77B11		;DEVICE TYPE BYTE
	.DEPCL==77		;PCL
	HC.RTY==777777B35	;RETRY COUNT FIELD
	.RTNON==1B17		;NON-RECOVERABLE FLAG

.HCUID==2			;PPN OF USER
.HCPGM==3			;PROGRAM NAME
.HCSBP==4			;SUB-BLOCK POINTER
				; (XWD .HCL30-.HCSBP,,.HCL20)
.HCL20==5			;UBA STATUS REGISTER
.HCL21==6			;UBA MAP SLOT
.HCL22==7			;PCXTCT,,PCXTSR
.HCL23==10			;PCTSDB,,PCTSBC
.HCL24==11			;PCTSBA,,PCTMMR
.HCL25==12			;PCTCRC,,0
.HCL26==13			;PCXRCR,,PCXRSR
.HCL27==14			;PCRDDB,,PCRDBC
.HCL30==15			;PCRDBA,,PCRCRC

.HCSIZ==16			;SIZE OF BLOCK
SUBTTL	PCL SERVICE DISPATCH TABLE


;PCL20 DRIVER SERVICE DISPATCH TABLE

	JRST	PCLONL		;(-5)SEE IF THE PCL IS ON-LINE NOW
	JRST	PCLDVP		;(-4)PCL20 DEVOP. UUO DISPATCH
	JRST	REGSIZ##	;(-3)OPEN CALL, GET BUFFER SIZE FROM DDB
	JRST	PCLINI		;(-2)INITIALIZE PCL NETWORK
	JRST	PCLHNG		;(-1)HUNG DEVICE ERROR
PCLDSP::JRST	PCLREL		;(0)RELEASE
	JRST	PCLCLS		;(1)CLOSE
	JRST	PCLOUT		;(2)OUTPUT
	JRST	PCLINP		;(3)INPUT
	POPJ	P,		;(4)ENTER
	POPJ	P,		;(5)LOOKUP
	POPJ	P,		;(6)DUMP OUTPUT
	POPJ	P,		;(7)DUMP INPUT
SUBTTL	SYSTEM START-UP DEVICE PCL INITIALIZATION

;PCLINI IS CALLED AT SYSTEM INITIALIZATION TIME FOR EACH DEVICE NODE

PCLINI:	PUSHJ	P,SAVE2##		;SAVE P1 AND P2
	HRRZ	P1,PCLTBL(F)		;SETUP POINTER TO DDB ADDRESS TABLE
	MOVE	P2,PCLBAS(F)		;GET BASE ADDRESS
	MOVE	T1,P2			;GET BASE ADDRESS INTO T1
	PUSHJ	P,UBGOOD##		;CHECK IF GOOD ADDRESS
	SKIPA				;NO
	PJRST	PCINI1			;YES-CONTINUE
	MOVSI	T1,DVOFLN##		;GET OFF-LINE BIT
	IORM	T1,DEVCHR(F)		;MARK PCL OFF-LINE
	PJRST	CPOPJ1##		;SKIP RETURN
PCINI1:	HRRZ	T1,PCLVEC(F)		;GET BASE INTERRUPT VECTOR ADDRESS
	MOVE	T4,PCINIT(P1)		;GET INITALIZED FLAG WORD
	JUMPL	T4,PCINI2		;JUMP IF NEG. ALREADY BEEN INIT'ED
	MOVEI	T3,TXINIT		;BIT PCL INIT BIT
	BSIO	T3,PCXRCR(P2)		;RESET RECEIVER
	BSIO	T3,PCXTCR(P2)		;RESET TRANSMITTER
	LSH	T1,-2			;DIVIDE BY 4
	HLRZ	T3,PCLBAS(F)		;GET UBA NUMBER
	ADD	T1,.EPVIT##-1(T3)	;ADD INTERRUPT TABLE ADDRESS
	DMOVE	T2,PCLTVI(F)		;GET INTERRUPT INSTRUCTONS
	DMOVEM	T2,(T1)			;PUT INTO VECTOR TABLE
					;NOW DO SYSERR SETUP
PCINI2:	MOVSI	T1,-.HCSIZ		;GET LENGTH OF ERROR BLOCK
	HRRI	T1,PCLDAE(F)		;MAKE AOBJN POINTER
	MOVEM	T1,PCLDAP(F)		;AND SAVE IT
	HRRZ	T3,DEVNAM##(F)		;GET RH OF DEVICE NAME
	LDB	T1,PUNIT##		;GET UNIT NUMBER FROM DDB DEVJOB LOCATION
	MOVEI	T2,20000		;GET UNIT NUMBER TO CONVERT ZERO TO
	TRNE	T1,37			;TEST FOR UNIT ZERO
	PJRST	PCINI4			;NO, NOT ZERO
	IORM	T2,DEVJOB(F)		;YES, CONVERT UNIT ZERO
	MOVEI	T1,20			;GET NODE ADDRESS FOR ZERO
PCINI4:	ADD	T1,P1			;MAKE ADDRESS INTO TABLE
	MOVEM	F,(T1)			;STORE DDB ADDRESS IN TABLE
	TRZE	T3,100			;TEST BIT 29AND CLEAR IF SET
	PUSHJ	P,FIXNAM		;GO FIX UP NAME IF 29 SET
	MOVE	T1,DEVNAM##(F)		;GET DEVICE NAME
	MOVEM	T1,PCLDAE+.HCNAM(F)	;SAVE IT
	MOVE	T1,[XWD .HCL30-.HCSBP,.HCL20]	;GET SUB-BLOCK POINTER
	MOVEM	T1,PCLDAE+.HCSBP(F)	;SAVE IT
	MOVSI	T1,DVOFLN		;GET OFF-LINE BIT
	ANDCAM	T1,DEVCHR(F)		;ASSUME PCL ON-LINE
	PUSHJ	P,PCLONL		;IS IT REALLY
	 IORM	T1,DEVCHR(F)		;NO-SET OFF-LINE BIT
	MOVEI	T1,INTENA		;GET INTERRUPT ENABLE BIT
	JUMPL	T4,PCINI3		;TEST INITIALIZED FLAG, JMP IF NEG.
	WRIO	T1,PCXTCR(P2)		;SET XMIT INTERRUPT ENABLE
	IORI	T1,RCVWRD		;SET RCV WORD BIT TO ALLOW FLG WORDS
	WRIO	T1,PCXRCR(P2)		;SET RCV INTERRUPT ENABLE
PCINI3:	SETOM	PCINIT(P1)		;SET PCL INITIALIZED WORD
	PJRST	CPOPJ1##		;SKIP RETURN, FORCE CALL FOR EACH PCL DEVICE NODE
;HERE TO FIX DDB NAME UNIT IDENTIFICATION FOR HEX NOTATION
;ENTER WITH DEVNAM IN T3

FIXNAM:	LDB	T1,[POINT 3,T3,35]	;GET UNIT NUMBER BYTE
	SUBI	T1,2			;SUBTRACT 2 FOR TEST
	JUMPL	T1,FIX89		;TEST IF GREATER THAN 9 CODE
	TRC	T3,60			;YES, SET FOR HEX CODE
	SUBI	T3,1			;ADJUST FOR A
	PJRST	FIXEND			;THAT'S ALL

FIX89:	TRC	T3,10			;ADJUST CODE FOR 8 & 9
FIXEND:	HRRM	T3,DEVNAM(F)		;PUT BACK IN DDB NAME RH
	POPJ	P,			;RETURN
SUBTTL	PCL20 INTERRUPT SERVICE

;GENERAL INTERRUPT SERVICE FOR ALL PCL20 INTERRUPTS

PCLINT::PUSHJ	P,SAVE4##		;START INTERRUPT SERVICE
	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS 
	SKIPG	T4			;IS IT A XMIT INTERRUPT
	SKIPA	T3,[RDIO T1,PCXRCR(T2)]	;NO, GET RCV INSTRUCTION
	MOVE	T3,[RDIO T1,PCXTCR(T2)]	;SETUP XMIT INSTRUCTION
	XCT	T3			;DO IT
	LDB	T3,[POINT 5,T1,27]	;GET THE DC/ID CODE BITS
	PUSHJ	P,FSETUP		;GO SET F TO PROPER VALUE
	PUSHJ	P,SVEUF##		;GET PAGING RIGHT (??)
	SKIPG	T4			;IS IT XMIT INTERRUPT
	SKIPA	T3,[RDIO T1,PCXRSR(T2)]	;NO, GET OTHER INSTRUCTION
	MOVE	T3,[RDIO T1,PCXTSR(T2)]	;GET INSTRUCTION
	XCT	T3			;DO IT
	MOVE	P1,PCLTBL(F)		;SETUP POINTER ADDRESS
	JUMPL	T4,PCINT1		;IS IT RECEIVER INTERRUPT, IF YES JMP
	TLO	S,IO			;SET IO BIT IN STATUS FOR OUT DIRECTION
	HRLM	T1,DEVSTS(F)		;SAVE XMIT STATUS IN LH DEVSTS
	PJRST	PCINT2			;GO CONTINUE
PCINT1:	HRRM	T1,DEVSTS(F)		;SAVE RCV STATUS IT IN RH DEVSTS
	TLZ	S,IO			;SET IO BIT IN STATUS FOR IN DIRECTION
	TRNE	T1,RDORDY		;IS THIS A RCV FLAG WORD INTERRUPT
	PJRST	TDTRDY			;YES, GO SERVICE IT
PCINT2:	TRNE	T1,TXXERR		;CHECK FOR ERROR - XMIT OR RCV
	PJRST	PCLERR			;YES, GO SERVICE ERROR
	TRNE	T1,SUCTXF		;IS SUCCESFUL XFER DONE
	PJRST	XFERDN			;YES, GO HANDLE IT
	TRNE	T1,TXSORE!REJCOM	;IS IT SORE(XMIT) OR REJECT COMP(RCV)
	PJRST	SOR%RJ			;YES, GO PROCESS IT
	JUMPL	T4,PURINT		;TEST INTERRUPT TYPE, JMP IF RCV
	TRNE	T1,TBSBSY		;WAS IT TDM BUS BUSY?
	PJRST	SOFBSY			;YES, GO HANDLE BUSY BY SOFTWARE
	MOVEI	T1,PCMSTN/400		;GET "MASTER NOW" BIT
	TIONB	T1,PCTMMR+1(T2)		;IS BIT SET IN MASTER REGISTER ?
	JRST	PUTINT			;NO, UNKNOWN XMIT INTERRUPT
	BCIOB	T1,PCTMMR+1(T2)		;YES, CLEAR BIT FROM REGISTER
	JRST	MSTRNW			;GO SAY WE ARE NOW MASTER

;HERE TO GET CORRECT DDB ADDRESS IN F

FSETUP:	SKIPN	T3			;TEST FOR ZERO STATE
	MOVEI	T3,20			;YES, SETUP FOR NODE ZERO
	ADD	T3,PCLTBL(F)		;MAKE ADDRESS
	MOVE	T1,(T3)			;GET DDB ADDRESS FROM TABLE
	HRR	F,T1			;SET F FROM TABLE
	PUSHJ	P,IOSET##		;SETUP R AND S AC'S
	LDB	J,PJOBN##		;SETUP J WITH JOB NUMBER
	POPJ	P,			;RETURN
SUBTTL	VARIOUS INTERRUPT SERVICE ROUTINES

;HERE ON SUCCESFUL TRANSFER

XFERDN:	TRNE	T1,TXSORE!REJCOM	;IS ALSO SORE(XMIT) OR REJECT COMP(RCV) SET
	PJRST	TRUNCT			;YES, THEN MESSAGE WAS TRUNCATED
	JUMPL	T4,RCVDNX		;NO, JMP IF RCV INTERRUPT, SERVICE XFER DONE
	PUSHJ	P,RDRGXS		;READ ABBRIVIATED STATUS
					;IT WAS A XMIT XFER DONE INTERRUPT
	MOVEI	T3,SUCTXF		;GET BIT TO CLEAR
	BCIO	T3,PCXTSR(T2)		;RESET TRANSMITTER SECTION STATUS
TXFRND:	HLLZS	PCLBSY(P1)		;CLEAR INTERFACE XMIT BUSY FLAG
	PUSHJ	P,CLRXMT		;CLEAR INTERFACE
	TLZ	S,PCOACT		;CLEAR NODE ACTIVE BIT
	PUSHJ	P,STOIOS##		;UPDATE DDB STATUS
	PUSHJ	P,ADVBFE##		;GO ADVANCE BUFFER, GET USEBIT CLEARED
	PJRST	PCSTOP			;NEXT BUFFER NOT AVAILABLE , RETURN TO USER
	TRNE	S,740000		;ARE ERRORS INDICATED IN STATUS
	PJRST	PCSTOP			;YES, SHUT DOWN
	PJRST	PCOUTG			;RETURN TO OUTPUT ANOTHER BUFFER

CLRXMT:	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS
	MOVEI	T3,TXINIT		;GET BIT TO CLEAR
	BSIO	T3,PCXTCR(T2)		;CLEAR INTERFACE
XMTENA:	MOVEI	T3,INTENA		;GET INTERRUPT ENABLE
	BSIO	T3,PCXTCR(T2)		;TURN IT ON AGAIN
	POPJ	P,			;RETURN

CLRRCV:	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS
	MOVEI	T3,RCINIT		;GET CLEAR BIT
	BSIO	T3,PCXRCR(T2)		;CLEAR INTERFACE
	MOVEI	T3,RCVWRD!INTENA	;GET BITS TO SET
	SKIPL	ONEWRD(F)		;SKIP IF ONE WORD FLAG SET
	TRNE	S,INHRCV		;IS INHIBIT RCV SET
	MOVEI	T3,INTENA		;YES, GET JUST INT ENABLE
	BSIO	T3,PCXRCR(T2)		;SET IN REGISTER
	POPJ	P,			;RETURN
RCVDNX:	PUSHJ	P,RDRGST		;READ REGISTER STATUS
	MOVE	P1,PCLTBL(F)		;SETUP POINTER ADDRESS
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMRD0(F)		;SAVE IT
>; END IFN FTDBUG
	TLNE	S,USERWT		;WAS THIS A FLAG WORD ONLY TRANSFER
	PJRST	RCVONE			;YES, FLAG IT AND DO ENDING
	TLNE	S,PCIACT		;IS THIS NODE IN ACTIVE RECEIVE
	PJRST	RCVEND			;YES
;	TAG RCLOST CAN BE REACHED IF AN XMIT NODE HAS SENT A FLAG WORD ONLY
;	TRANSFER TO THIS IMPROPERLY OPENED RECEIVE NODE.
RCLOST:	LDB	T1,PUNIT		;GET UNIT NUMBER
	ADD	P1,T1			;ADD TO BASE TABLE ADDRESS
	HLRZ	T1,(P1)			;GET TABLE ENTRY
	AOS	T1			;INCREMENT COUNT
	HRLM	T1,(P1)			;RESTORE ENTRY IN TABLE
	MOVE	T1,DEVMOD(F)		;GET DEVMOD WORD
	TRNN	T1,ASSPRG		;IS NODE ASSIGNED
	PJRST	PCRCVI			;NO, RESET RCV AND EXIT
LOSTRC:	PJRST	PURINT			;YES, RECEIVE IS LOST
RCVEND:	HRRZS	PCLBSY(P1)		;CLEAR INTERFACE RCV BUSY FLAG
	MOVEI	T3,SUCTXF		;GET CLEAR RECEIVER BIT
	TLNE	S,REJACT		;IS THIS A TRUNCATE
	IORI	T3,REJCOM		;YES,OR IN REJECT COMP BIT
	BCIO	T3,PCXRSR(T2)		;RESET RECEIVER SECTION STATUS
	TLZ	S,PCIACT!IO		;CLEAR SOME BITS
	MOVEI	T3,RCVNPR		;GET BIT TO CLEAR
	BCIO	T3,PCXRCR(T2)		;CLEAR IT
	RDIO	T3,PCRDBC(T2)		;READ THE RECEIVER BYTE COUNT
	HRLM	T3,PCIPTR(F)		;SAVE IT FOR LATER
	HRRZS	PCIBYT(F)		;CLEAR LEFT SIDE OF LOCATION
	PUSHJ	P,GTDIBC		;GET DEFAULT BYTE COUNT
	HLRZ	T4,PCIPTR(F)		;GET ENDING BYTE COUNT
	SKIPE	T4			;TEST FOR ZERO AND JUMP
	ANDI	T1,177777		;MASK TO 16-BIT COUNT
	SUB	T4,T1			;GET NUMBER BYTES XFERED
	HRRZ	T1,DEVIAD(F)		;GET INPUT BUFFER ADDRESS
	EXCTXU	<HRRM	T4,1(T1)>	;STORE BYTE COUNT IN BUFFER HEADER
	MOVE	T3,RFLGWD(F)		;GET RCV FLAG WORD
	TRNE	S,IFLGWD		;IS FLAG WRD TO BE INCLUDED IN BUFFER
	EXCTXU	<MOVEM	T3,2(T1)>	;STORE FLG WD IN FIRST WORD OF BUFFER
	HRRM	T4,PCIBYT(F)		;SAVE BYTE COUNT FOR LATER
	JRST	RCVND1			;GO SEE IF MORE INPUT TO COME
RCVONE:	SETOM	ONEWRD(F)		;SET ONE WORD FLAG
RCVND1:	TLZ	S,PCIACT		;CLEAR INPUT ACTIVE
	PUSHJ	P,ADVBFF##		;GO ADVANCE BUFFER, GET USEBIT SET
	PJRST	RCVSTP			;NEXT BUFFER NOT AVAILABLE
	TRNE	S,740K			;[TL] ERRORS?
	 PJRST	RCVSTP			;[TL] YES, SHUT THE RECEIVER DOWN
	PUSHJ	P,CLRRCV		;GO CLEAR THE RECEIVER
	TLO	S,PCIPWT		;SET INPUT WAITING
	PJRST	PCLSTP			;DO STOP AND SETIOD, RETURN TO MONITOR
RCVSTP:
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMRD2(F)		;SAVE IT
>; END IFN FTDBUG
	TLZ	S,REJACT		;WAS THIS A TRUNCATED MSG
	PUSHJ	P,PCSTOP		;YES, EXIT AND RETURN WITH CURRENT S BITS
	PJRST	CLRRCV			;ENABLE RECEIVE INTERRUPT
;HERE FOR A SOFTWARE REJECTED MESSAGE

SOR%RJ:	TRO	S,IOIMPM!IODEND		;SET ERROR BIT IN STATUS
	JUMPGE	T4,TXFRND		;JMP IF XMIT INTERRUPT, HANDLE SOFTWARE REJECT

RREJCP:	MOVEI	T3,REJCOM		;RCV REJECT COMPLETE - GET BIT TO CLEAR
	BCIO	T3,PCXRSR(T2)		;CLEAR THEM
	MOVE	T3,DEVMOD(F)		;GET DEVMOD STATUS
	TRNN	T3,ASSPRG		;HAS DDB BEEN OPEN
	PJRST	PCRCVI			;NO, INITIALIZE THE RECEIVER TO RCV ANOTHER FLG WD
	TLZE	S,REJACT		;YES, WAS USER REJECTING MESSAGE
	PJRST	REJDON			;YES, GO WAKE UP USER
	PJRST	PCRCVI			;NO, TURN ON RECEIVER AGAIN
REJDON:	PUSHJ	P,STOIOS##		;UPDATE DDB STATUS
	PUSHJ	P,PCSTPI		;FINISH AND RETURN TO USER
	PJRST	CLRRCV			;DONE WITH REJECT, GO ENABLE RCV AND EXIT

;HERE FOR TRUNCATED MESSAGES

TRUNCT:	TRO	S,IOBKTL!IOIMPM		;SET ERROR BITS IN STATUS
	JUMPL	T4,RCVDNX		;JMP IF RCV, HANDLE RCV TRUNCATED
	PJRST	TXFRND			;GO FINISH THRU XMIT DONE

;HERE FOR MASTER NOW INTERRUPT

MSTRNW:	MOVE	T3,PCLTBL(F)		;GET POINTER TO PCL BLOCK
	PUSH	P,U			;SAVE U ON STACK
	MOVE	U,OPRLDB##		;GET LDB OF CONSOLE
	PUSHJ	P,CRLF##		;PRINT CRLF
	HLRZ	T2,DEVNAM(F)		;GET INTERFACE NAME
	PUSHJ	P,PRNAME##		;PRINT IT
	E$TYPE	(0,< NOW PCL NETWORK MASTER>)
	PJRST	UPOPJ##			;RESTORE U AND RETURN FROM INTERRUPT

SOFBSY:	PUSHJ	P,RDRGXS		;READ REGISTERS
	MOVEI	T3,TXXRIB		;GET RIB BIT
	TIOE	T3,PCXTCR(T2)		;TEST IF SET
	JRST	PUTINT			;YES, SHOULD NOT GET SOFT BUSY IF RIB BIT IS SET
SFTBSY:	TRO	S,220000		;FLAG SOFT BUSY CONDITION IN STATUS
	PJRST	TXFRND			;EXIT
;HERE TO TEST RCV DATA SILO OUTPUT READY
;THIS INTERRUPT/BIT USED TO INDICATE A FLAG WORD RECEIVED

TDTRDY:	TRNE	T1,RCVERR		;IS RCV ERROR SET
	JRST	PCLERR			;YES, GO DO ERROR SERVICE
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMDT0(F)		;SAVE
>; END IFN FTDBUG
	RDIO	T3,PCRDDB(T2)		;NO, READ THE RCV SILO BUFFER
	MOVE	T1,DEVMOD(F)		;GET DEVMOD WORD
	TRNN	T1,ASSPRG		;HAS DDB BEEN OPENNED
	DOREJ				;NO, REJECT THE FLAG WORD/MESSAGE
	TRNN	S,ENIPUT		;IS SOMEONE WAITING ON INPUT THIS NODE
	DOREJ				;NO, GO REJECT IT
	LDB	T1,PUNIT##		;GET UNIT NUMBER
	HRL	T3,T1			;SAVE IT WITH FLAG WORD
	MOVEM	T3,RFLGWD(F)		;STORE RECEIVE FLAG WORD
	MOVE	P1,PCLTBL(F)		;GET POINTER ADDRESS TO DATA BLOCK
	PUSHJ	P,RDRGST		;GO READ REGISTER DATA
	MOVEI	T1,INTENA		;GET INTERRUPT ENABLE
	BCIO	T1,PCXRCR(T2)		;CLEAR RCV INTERRUPT ENABLE
	TRNE	S,ACPTRD		;IS USER ACCEPT AND READ BIT ALREADY SET
	PJRST	RCVINP			;YES, GO SETUP A DMA INPUT TRANSFER
					;FOR THIS NODE IS WAITING ON INPUT
;**********************************************************************
	HLRZ	T1,DEVPSI(F)
	SKIPE	JBTPIA##(J)
	TRNN	T1,IR.PFW
	DOREJ	
;**********************************************************************
	MOVEI	T1,IR.PFW		;NO, GET PCL CONDITION FOR INTERRUPT
	PUSHJ	P,PSIDVB##		;GIVE USER FLAG WORD INTERRUPT
	TLO	S,USERWT		;SET WAIT BIT FOR USER RESP TO FLG WRD
	PUSHJ	P,STOIOS##		;SAVE STATUS IN DDB
	MOVE	T2,PCLBAS(F)		;GET PCL ADDRESS
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMDT1(F)		;SAVE
>; END IFN FTDBUG
	SETZM	T3			;CLEAR T3
	PJRST	ENARCV			;ENABLE RCV INTERRUPTS AND EXIT

RCVINP:	TLNN	S,PCIPWT		;IS INPUT BUFFER WAITING
	DOREJ				;NO, REJECT MESSAGE
	PJRST	PCINPT			;YES, GO INPUT MORE
DEFINE	REJ3(N),<
REJ'N'X:	JSP	T1,REJMSG>

$$RJ==0
REPEAT	REJMAX,<
REJ3(\$$RJ)
$$RJ==$$RJ+1>

REJMSG:	SUBI	T1,REJ0X		;COMPUTE REJECT REASON #
	ADDI	T1,REJTAB-1(F)		;COMPUTE TABLE ENTRY ADDRESS
	AOS	(T1)			;COUNT THE REJECT
	MOVEI	T1,REJECT		;GET REJECT BIT
	BSIO	T1,PCXRCR(T2)		;DO THE REJECT
	SETZM	T3			;CLEAR T3
	PJRST	PCRCVI			;GO ENABLE RCV INTERRUPTS

PUTINT:	STOPCD	CPOPJ,JOB,UTI		;UNEXPECTED TRANSMIT INTERRUPT
PURINT:	STOPCD	CPOPJ,JOB,URI		;UNEXPECTED RECEIVE INTERRUPT
SUBTTL	ERROR INTERRUPT ROUTINE - DISPATCH

PCTERR:	TRNE	T1,OVERUN		;DATA OVERRUN ERROR?
	PJRST	OVRNER			;YES, HANDLE IT
	TRNE	T1,MSTDWN		;IS MASTER DOWN?
	PJRST	MSTRDN			;YES, HANDLE IT
	PJRST	PCLER1			;NO


PCRERR:	TRNE	T1,RBCOFL		;BYTE COUNT OVERFLOW?
	PJRST	BCOVFL			;YES, HANDLE IT
	TRNE	T1,RCVPAR		;PARITY ERROR?
	PJRST	PARERR			;YES, HANDLE IT
	PJRST	PCLER1			;NO

;ENTRY POINT FOR ANY PCL11-B ERROR

PCLERR:
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMERR(F)		;SAVE
>; END IFN FTDBUG
	PUSHJ	P,RDRGST		;READ INTERFACE REGISTERS
	TRNE	T1,NONEXM		;NON-EXISTENT MEMORY ERROR?
	PJRST	NXMERR			;YES, HANDLE IT
	TRNE	T1,MEMOFL		;ADDRESS OVERFLOW ERROR?
	PJRST	OFLERR			;YES, HANDLE IT
	TRNE	T1,TXMERR		;TRANSMISSION ERROR?
	PJRST	TRNSER			;YES, HANDLE IT
	TRNE	T1,TIMOUT		;TIME OUT ERROR?
	PJRST	TOTERR			;YES, HANDLE IT
	JUMPL	T4,PCRERR		;IS IT RCV INTERRUPT, JMP IF YES
	PJRST	PCTERR			;NO, XMIT INTERRUPT

PCLER1:	STOPCD	CPOPJ,JOB,UPE		;++UNEXPECTED PCL20 ERROR

;HERE TO GIVE THE USER AN I/O ERROR,TRIGGER PSI,AND DISMISS INTERRUPT

PCLIOE:	DPB	T3,PDVESE##		;STORE THE ERROR CODE
	TRO	S,300000		;SET STATUS ERROR BITS
	PUSHJ	P,PCLSYR		;DO SYSERR REPORTING
	TLNE	S,IO			;TEST WHICH IO, SKIP IF RECEIVE
	PJRST	TXFRND			;NO, XMIT - CLEAR TRANSMITTER
	PJRST	RCVND1			;RCV - CLEAR RECEIVE
SUBTTL	ERROR INTERRUPT ROUTINE - HANDLER

NXMERR:	MOVEI	T3,IONXM%		;LOAD ERROR CODE FOR NXM
	PJRST	PCLIOE			;GO DO COMMON ERROR ENDING

OFLERR:	MOVEI	T3,IOOFL%		;LOAD ERROR CODE FOR OVERFLOW
	PJRST	PCLIOE			;DO COMMON ERROR ENDING

TRNSER:	MOVEI	T3,IOTXM%		;LOAD ERROR CODE FOR TRANSMISSION ERR
	PJRST	PCLIOE			;GO DO COMMON ENDING

PARERR:	MOVEI	T3,IOPAR%		;LOAD ERROR CODE FOR PARERR
	PJRST	PCLIOE			;DO COMMON ERROR ENDING THINGS

OVRNER:MOVEI	T3,IOOVR%		;LOAD ERROR CODE FOR OVERRUN
	PJRST	PCLIOE			;DO COMMON ERROR ENDING

TOTERR:	JUMPGE	T4,XMTOER		;JUMP IF THIS IS XMIT TIMEOUT
TOTER1:	MOVEI	T3,IOTOT%		;LOAD ERROR CODE FOR TIMEOUT
	PJRST	PCLIOE			;DO COMMON ERROR ENDING

XMTOER:	MOVEI	T3,TXXRIB		;GET RIB BIT
	TIOE	T3,PCXTCR(T2)		;TEST IF SET
	TRNN	T1,TBSBSY		;WAS TBS BUSY SET IN STATUS
	PJRST	TOTER1			;NO, GIVE ERROR CONDITION
	PJRST	SFTBSY			;YES, SOFT BUSY TIME OUT

MSTRDN:	PUSH	P,U			;SAVE U
	MOVE	U,OPRLDB		;GET NEW LDB FOR OPERATOR
	PUSHJ	P,CRLF##		;GIVE A CRLF
	HLRZ	T2,DEVNAM(F)		;GET DEVICE NAME
	PUSHJ	P,PRNAME		;TYPE NAME
	E$TYPE	(1,< MASTER DOWN>)	;PRINT REST OF MESSAGE
	POP	P,U			;RESTORE U
	MOVEI	T3,IOMDN%		;LOAD ERROR CODE FOR MASTER DOWN
	PJRST	PCLIOE			;DO COMMON ERROR ENDING

BCOVFL:	MOVEI	T3,IOBCO%		;LOAD ERROR CODE FOR BC OVERFLOW
	DPB	T3,PDVESE##		;STORE ERROR CODE
	MOVEI	T1,RCVNPR!INTENA	;GET BIT FOR CLEAR
	BCIO	T1,PCXRCR(T2)		;CLEAR OUT NPR BIT
	MOVEI	T1,RBCOFL		;GET BIT FOR CLEAR
	BCIO	T1,PCXRSR(T2)		;CLEAR IT
	CNTREJ				;COUNT THIS REJECT TYPE
	MOVEI	T1,REJECT		;GET REJECT BIT
	BSIO	T1,PCXRCR(T2)		;TRUNCATATE THE MESSAGE NOW
	TLO	S,REJACT		;SET REJECT ACTIVE IN STATUS
	PUSHJ	P,STOIOS##		;UPDATE STATUS IN DDB
	SETZM	T3			;CLEAR T3
	PJRST	ENARCV			;ENABLE RCV INTERRUPT AND EXIT
SUBTTL	CHECKS FOR PCL ON-LINE & HUNG

PCLONL:	JRST	CPOPJ1##		;PRETEND ALWAYS ON-LINE

PCLHNG:	TLNN	S,IO			;IF NODE IS DOING OUTPUT
	TLNN	S,PCIPWT		;OR IF INPUT REALLY ACTIVE
	JRST	PCHNG1			;THEN DEVICE REALLY IS HUNG
	WRPI	PI.OFF			;NO INTERRUPTS FOR NOW
	TDZ	S,[XWD PCIPWT,IOACT]	;CLEAR STATUS BITS
	MOVEM	S,DEVIOS(F)		;STORE STATUS IN DDB
;	PUSHJ	P,RTEVM##		;UNMAP BUFFERS, ETC.
	WRPI	PI.ON			;REENABLE INTERRUPTS
	JRST	CPOPJ1##		;TAKE SKIP RETURN (DEVICE IS O.K.)

PCHNG1:	PUSHJ	P,SAVE4##		;ENSURE ALL ACS ARE PRESERVED
	MOVE	P1,PCLTBL(F)		;GET ADDRESS OF PCX: TABLE
	AOS	(P)			;SKIP RETURN TO AVOID HUNG MESSAGE
	TRO	S,700000		;SET ERROR BITS FOR HUNG DEVICE
	TLNE	S,IO			;XMT OR RCV ?
	JRST	TXFRND			;XMT - RESET TRANSMITTER
	JRST	RCVND1			;RCV - RESET RECEIVER



RDRGXS:	MOVNI	T3,12			;GET COUNT FOR NUMBER OF REGISTERS TO READ
	SKIPA				;
RDRGST:	MOVNI	T3,16			;GET COUNT AND NEGATE
	MOVEI	P4,REGBLK(F)		;GET ADDRESS OF DATA BLOCK
	MOVE	P3,[RDIO P2,PCXTCR(T2)]	;GET READ INSTRUCTION
	HRLM	T3,P4			;CONSTRUCT IOWD WORD IN P4
REGST1:	XCT	P3			;READ A REGISTER
	MOVEM	P2,(P4)			;STORE REGISTER DATA
	ADDI	P3,2			;INCREMENT TO NEXT REG
	AOBJN	P4,REGST1		;+1 COUNTER, LOOP IF STILL NEG
	POPJ	P,			;RETURN
SUBTTL	DEVOP UUO INTERFACE - DISPATCH

;HERE ON A DISPATCH FROM UUOCON
;	F=DDB
;	T1=FUNCTION
;
;THE FOLLOWING ARE ERROR CODES WHICH CAN RESULT FOR THE PCL DEVOP UUO'S
;
;
;ERROR CODE	TYPE UUO		DESCRIPTION
;
;	-1	NEUTRAL		NOT A REAL ERROR CONDITION. UNIT WAS ALREADY
;				IN NEUTRAL STATE WHEN REQUESTED.
;		REJECT/ACCEPT	INDICATES A ONE WORD ONLY TRANSFER OCCURED FOR 
;				THIS TRANSMISSION.
;	1	GENERAL		FUNCTION CODE = 0. SHOULD NEVER OCCUR AT
;				DRIVER LEVEL SINCE UUOCON CHECKS FOR ZERO
;	2	GENERAL		FUNCTION CODE NOT VALID FOR PCL20 DRIVER
;	3	GENERAL		CHECK OF THE PCL UBA ADDRESS FAILED
;	4	GENERAL		TEST OF JOB ASSIGNED TO THE DEVICE NODE FAILED
;	5	NEUT/MSTR/SECD	CHECK IF JOB PRIVILEGE TO MODIFY MASTER FAILED
;	6	MSTR/SECD	NUMBER VALUE SPECIFIED FOR ADDRESS SILO LOAD
;				WAS EITHER ZERO OR ONE
;	7	MSTR/SECD	NUMBER VALUE SPECIFIED FOR SILO ADDRESS LOAD
;				WAS GREATER THAN 50 DECIMAL.
;	10	MSTR/SECD	GET WORD FAILED ON A FETCHING A WORD FROM
;				USERS ARGUMENT BLOCK.
;	11
;	12	MSTR/SECD	ADJUCENT ADDRESS CHECK FAILED.
;	13	MSTR/SECD	FIRST AND LAST ADDRESSES MATCH.
;	14	MASTER		MASTER BIT DID NOT SET IN TMMR
;				WHEN MASTER REQUESTED. COULD BE ANOTHER MASTER
;				ALREADY CONTROLING THE TDM BUS.
;	15	SECONDARY	SECONDARY OR MASTER NOW BIT DID NOT SET IN TMMR
;				WHEN SECONDARY REQUESTED.
;	16	SECONDARY	ILLEGAL SECONDARY REQUEST WHEN TMMR ALREADY SET
;				FOR MASTER STATE.
;	17	NEUTRAL		NEUTRAL STATE DID NOT SET WHEN REQUESTED
;
;	20	REJECT/ACCEPT	REJECT DEVOP GIVEN WITH NO ACTIVE TRANSFER PENDING
;				ACCEPT/REJECT DEVOP GIVEN WHEN NOT IN USER WAIT STATE
;	21	GENERAL		PUT WORD FAILED ON A STORE OF A WORD TO THE USERS ARGUMENT
;				BLOCK
;	22	REJECT/ACCEPT	ERROR STATUS SET IN DDB. TRANSFER CANNOT PROCEED
;
PCLDVP:	MOVSI	T2,-PCLDVL		;GET TABLE LENGTH SETUP AOBJN PTR
	PUSHJ	P,SAVE4##		;SAVE P1 THRU P4
PCLDV1:	HLRZ	T3,PCLDVT(T2)		;GET FUNCTION
	CAME	T1,T3			;DO CODE MATCH?
	AOBJN	T2,PCLDV1		;NO, GO LOOP
	JUMPGE	T2,ECOD2##		;NO MATCH, GIVE ERROR RTN
	CAIE	T1,1000			;READ XMT STATUS ?
	CAIN	T1,1004			;READ RCV STATUS ?
	SKIPA	T3,J			;YES - ALWAYS MATCH
	LDB	T3,PJOBN##		;NO  - TEST DDB OWNERSHIP
	CAME	T3,J			;JOB NUMBERS MATCH ?
	 JRST	ECOD4##			;NO  - RETURN ERROR TO USER
IFN FTDBUG,<MOVEM T1,DVOPFC(F)>		;SAVE LAST DEVOP. FUNCTION CODE
	HRRZ	T4,PCLDVT(T2)		;GET DISPATCH ADDRESS
	JRST	(T4)			;DISPATCH TO INDIVIDUAL DEVOP. ROUTINE


PCLDVT:	XWD 0,ECOD1##			;NO FUNCTION CODE SPECIFIED
	XWD 1,DVREJT			;REJECT RECEIVE TRANSFER
	XWD 2,DVACPR			;ENABLE INPUT TO ACCEPT AND READ CURRENT MESSAGE
	XWD 3,DVERCV			;ENABLE RECEIVER FOR INPUT
	XWD 11,DVTRTY			;SET TRANSMITTER RETRY CNT
	XWD 12,DVRRTY			;SET RECEIVER RETRY CNT
	XWD 1000,DVTSTS			;READ TRANSMITTER STATUS
	XWD 1004,DVRSTS			;READ RECEIVER STATUS
	XWD 1005,DVRFLG			;READ OF CURRENT STORED RCV FLAG WORD
	XWD 1006,DVRERG			;READ SAVED ERROR STATUS REGISTERS
	XWD 2000,DVNEUT			;SET DEVICE NEUTRAL
	XWD 2004,DVMSTR			;SET DEVICE MASTER
	XWD 2005,DVSECD			;SET DEVICE TO SECONDARY MASTER
	PCLDVL==.-PCLDVT		;DISPATCH TABLE LENGTH
;HERE TO REJECT A MESSAGE VIA DEVOP.

DVREJT:	PUSHJ	P,SETBAS		;SETUP UBA BASE ADDRESS
	TRNE	S,300000		;TEST FOR ERRORS
	PJRST	DVER22			;YES, GIVE ERROR RETURN AND EXIT
	TLZN	S,USERWT		;IS DRIVER WAITING ON USER
	PJRST	DACPR1			;NO, GIVE ERROR RETURN
	TLO	S,REJACT		;SET REJECT ACTIVE BIT IN STATUS
	PUSHJ	P,STOIOS##		;UPDATE DDB STATUS
	CNTREJ
	MOVEI	T3,REJECT!INTENA	;SET REJECT BIT IN RCR
	BSIO	T3,PCXRCR(T2)		;DO IT
;	MOVE	S,DEVIOS(F)		;GET STATUS FROM DDB
;	TLNE	S,REJACT		;TEST FOR REJECT COMPLETE
;	PJRST	.-2			;WAIT IN THIS LOOP
DRJEND:	PJRST	RTZER##			;GIVE GOOD RETURN

;HERE FOR ACCEPT AND READ DEVOP. ROUTINE

DVACPR:	PUSHJ	P,SETBAS		;SETUP UBA BASE ADDRESS
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMACP(F)		;SAVE
>; END IFN FTDBUG
	TRNE	S,300000		;TEST IF ERRORS IN STATUS
	PJRST	DVER22			;YES, EXIT
	TLZN	S,USERWT		;IS THIS NODE WAIT FOR USER RESPONSE
	PJRST	DACPR1			;NO, GIVE ERROR CODE AND RETURN
	MOVE	P1,PCLTBL(F)		;SETUP P1
	MOVEI	T1,INTENA		;GET BIT
	BCIO	T1,PCXRCR(T2)		;CLEAR INTERRUPT ENABLE
	PUSHJ	P,RCVINP		;GO TURN ON INPUT TO RCV MESSAGE
	PJRST	RTZER1##		;GIVE DEVOP. RETURN

DACPR1:	PUSHJ	P,PCRCVE		;ENABLE RECEIVER
	SKIPL	ONEWRD(F)		;WAS THIS A ONE WORD TRANSFER
	PJRST	ECOD20##		;GIVE ERROR CODE AND RETURN
	SETZM	ONEWRD(F)		;YES, CLEAR FLAG AND RETURN CODE
	PJRST	RTM1##			;GIVE -1 RETURN CODE IN AC

DVER22:	PUSHJ	P,PCSTPI		;GO RESET DEVICE BUFFERS, ETC.
	PUSHJ	P,PCRCVI		;REENABLE RECEIVER INTERRUPTS
	PJRST	ECOD22##		;RETURN ERROR CODE TO THE USER
;HERE TO ENABLE RECEIVER FOR INPUT

DVERCV:
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMERC(F)		;SAVE IT
>; END IFN FTDBUG
	PUSHJ	P,SETBAS		;SETUP UBA BASE ADDRESS
	SETZM	ONEWRD(F)		;CLEAR ONE WORD FLAG
	PUSHJ	P,PCRCVE		;ENABLE RECEIVE
	PJRST	RTZER1			;GIVE A GOOD RETURN

;HERE TO SET RETRY COUNTS

DVTRTY:	PUSHJ	P,FTCHWD		;GET TRANSMIT RETRY CNT FROM USER
	MOVEM	T1,PCTRTY(F)		;SAVE COUNT
	PJRST	RTZER1##		;GIVE GOOD RETURN

DVRRTY:	PUSHJ	P,FTCHWD		;GET RECEIVER RETRY CNT FROM USER
	MOVEM	T1,PCRRTY(F)		;SAVE COUNT IN DDB BLOCK
	PJRST	RTZER1##		;GIVE GOOD RETURN

;HERE TO READ PCL11-B REGISTER STATUS

DVTSTS:	SKIPA	T4,[RDIO T1,PCXTCR(T2)]	;SETUP READ REGISTER CMD
DVRSTS:	MOVE	T4,[RDIO T1,PCXRCR(T2)]	;SETUP READ REGISTER CMD
	PUSHJ	P,SETBAS		;GET BASE ADDRESS
	MOVEI	T3,7			;SETUP LOOP COUNT FOR 7 REGISTERS
DVSTS1:	XCT	T4			;READ THE REGISTER
	CAM				;NOP NEEDED TO PROTECT PC FROM
	CAM				;READ SILO INTERRUPTS
	PUSHJ	P,PUTWR1##		;PUT STATUS WRD IN USER BLOCK
	PJRST	ECOD21##		;STORE FAILED
	ADDI	T2,2			;ADJUST TO NEXT REGISTER
	SOSE	T3			;READ ALL STATUS
	PJRST	DVSTS1			;NO, LOOP
	PJRST	RTZER1			;YES - GIVE GOOD RETURN

;HERE TO READ THE CURRENT RECEIVED FLAG WORD

DVRFLG:	MOVE	T1,RFLGWD(F)		;GET THE CURRENT RECEIVE FLAG WORD
	PUSHJ	P,PUTWR1##		;STORE IT IN THE USERS ARGUMENT BLOCK
	PJRST	ECOD21##		;PUT WORD FAILED
	PJRST	RTZER1##		;GIVE A GOOD RETURN

;HERE TO READ ERROR REGISTERS SAVED ON LAST ERROR

DVRERG:	MOVE	T1,PCLDAE+.HCL26(F)	;GET RECEIVER STATUS REGISTER
	HRL	T1,PCLDAE+.HCL22(F)	; ADD TRANSMITTER "   "   "
	PJRST	STOTC1##		;SKIP RETURN WITH ANSWER IN AC
;HERE TO SET INTERFACE TO NEUTRAL STATE


DVNEUT:	PUSHJ	P,SETBAS		;SETUP T2 WITH PCL BASE ADDR.
	RDIO	T3,PCTMMR(T2)		;READ MASTER REGISTER
	TRNN	T3,PCSECD!PCMSTR	;TEST MSTR AND SECD BITS
	PJRST	RTM1S			;EXIT - ALREADY NEUTRAL
	PUSHJ	P,CKPVBT		;CHECK PRIVILEDGE BIT
	PUSH	P,U			; SAVE U FOR LATER
	MOVE	U,OPRLDB##		;SETUP U TO POINT TO OPR
	MOVEM	T2,P4			;SAVE PCL BASE ADDRESS FOR LATER
	PUSHJ	P,MESAGA		;PRINT HEADER MSG TO OPR
	MOVEI	T1,E$MSG2 <BACKUP SECONDARY BEING REMOVED >
	TRNE	T3,PCMSTR		;TEST IF MASTER SET
	PJRST	DNEUT2			;NO, ITS SECONDARY - TELL OPR
	MOVEI	T1,E$MSG2 <NETWORK WILL BE LOSING PRIMARY MASTER>
	TRNN	T3,PCMSTN		;IS THIS PCL MASTER NOW
	PUSHJ	P,CONMES##		;NO - MASTER ONLY SET,TELL OPR
	MOVEI	T1,E$MSG2 <MASTER BEING REMOVED >
DNEUT2:	PUSHJ	P,CONMES		;YES, MASTER OF NETWORK - TELL
					;OPR NETWORK LOSING PRIME
					;NETWORK MASTER!!!!!
DNEUT1:	MOVEI	T3,PCMSTN!PCSECD!PCMSTR	;GET BITS TO CLEAR
	MOVE	T2,P4			;RESTORE BASE ADDR. TO T2
	RDIO	T1,PCTMMR(T2)		;READ TMMR STATUS
	BCIO	T3,PCTMMR(T2)		;CLEARING BITS FOR NEUTRAL
	MOVE	P1,PCLTBL(F)		;SETUP ADDRESS TO PCL BLOCK
	RDIO	T1,PCTMMR(T2)		;STATE NOW, READ RESULTING STATE
	TRNE	T1,PCSECD!PCMSTR	;TEST MASTER AND SECD NOT SET
	PJRST	DNER17			;BITS DID NOT CLEAR FOR NEUTRAL
	PUSHJ	P,CRLF##		;SEND OPR A CRLF
	HLLZ	T2,DEVNAM(F)		;GET DEVICE NAME
	PUSHJ	P,PRNAME##		;PRINT IT
	E$TYPE	(0,< DEVICE BEING SET NEUTRAL>)
	PJRST	DVRTN1			;GIVE GOOD RETURN


DNER17:	E$TYPE	(3,<?? NEUTRAL STATE FAILED TO SET ??>)
	POP	P,U			;RESTORE U
	PJRST	ECOD17##		;GIVE ERROR CODE, BITS DIDN'T CLEAR
;HERE TO SETUP FOR MASTER OR SECONDARY

DVMSTR:	TDZA	P1,P1			;SET FLAG FOR MASTER DEVOP
DVSECD:	SETO	P1,			;SET FLAG FOR SECONDARY DEVOP
	MOVE	P2,PCLTBL(F)		;GET ADDRESS TO PCL BLOCK
	PUSHJ	P,CKPVBT		;SAVE T1-CHECK PRIV BIT
	PUSH	P,U			;SAVE U
	MOVE	U,OPRLDB##		;POINT U TO OPR
	PUSHJ	P,MESAGA		;PRINT HEADER
	PUSHJ	P,SETBAS		;SET T2 TO PCL BASE ADDRESS
	PUSHJ	P,CKADRS		;GO CHECK ADDRESS FOR SILO LOAD
	PJRST	UPOPJ##			;ERROR RETURN
	PUSHJ	P,LDADRS		;GO LOAD ADDRESS SILO
DMEXIT:	PJRST	UPOPJ			;ERROR RETURN - EXIT
	PUSH	P,[DMEXIT]		;PUSH ERROR RETURN ON STACK
	RDIO	T3,PCTMMR(T2)		;GET MASTER REGISTER STATUS
	TRNN	T3,PCSECD!PCMSTR	;TEST FOR NEUTRAL
	PJRST	DMSTR3			;BY-PASS OTHER CHECKING
	MOVEI	T1,PCSECD		;GET SECONDARY BIT
	TION	T1,PCTMMR(T2)		;TEST FOR IT
	JUMPL	P1,ECOD16##		;NO,MASTER MUST BE SET - ILLEGAL IF
					;SECD REQUESTED,JMP & GIVE ERROR RTN
	TIOE	T1,PCTMMR(T2)		;TEST IF MASTER SET
	JUMPE	P1,DMSTR4		;NO, SECD BUT WANTS MASTER - OK
	JUMPE	P1,DMSTR6		;YES, MASTER - JMP IF WANTS MASTER
	JRST	DSECD1			;NO, WANTS SECONDARY - OK
DMSTR4:	E$TYPE	(2,<BACKUP SECONDARY BEING REMOVED >)
DMSTR3:	JUMPL	P1,DSECD1		;TEST WHICH DEVOP, JMP IF SECONDARY
DMSTR5:	MOVEI	T1,E$MSG2 <NEW NETWORK MASTER BEING SET >
	MOVEI	T3,PCMSTR/400		;GET MASTER BIT
	BSIOB	T3,PCTMMR+1(T2)		;SET HIGH BYTE
	TIONB	T3,PCTMMR+1(T2)		;TEST IF MASTER BIT SET
	PJRST	ECOD14##		;MASTER DID NOT SET, COULD BE ANOTHER MASTER ON BUS
DMSTR1:	PUSHJ	P,CONMES		;YES-TELL OPR YOU ARE NOW NETWORK MASTER
DMSTR6:	POP	P,			;GET RID OF ERROR ADDRESS
	PJRST	DVRTN			;DO ENDING AND RETURN
;HERE TO SETUP SECONDARY

DSECD1:	E$TYPE	(2,<BACKUP SECONDARY BEING SET >)
	MOVEI	T1,PCSECD/400		;GET SECONARDY BIT
	BSIOB	T1,PCTMMR+1(T2)		;SET HIGH BYTE, SECONDARY BIT
	TIOEB	T1,PCTMMR+1(T2)		;TEST SECONDARY SET
	JRST	DSECD2			;YES, GO END
	MOVEI	T3,PCMSTR		;NO, GET MASTER  BIT
	MOVEI	T1,E$MSG2 <SECONDARY NOW NETWORK MASTER>
	TIOE	T3,PCTMMR(T2)		;TEST IF MASTER 
	PJRST	DMSTR1			;YES, GOT MASTERSHIP-TELL OPR
	RDIO	T3,PCTMMR(T2)		;NO - ERROR, NOTHING SET
	PJRST	ECOD15##		;GIVE ERROR RETURN
DSECD2:	POP	P,			;POP ERROR ADDRESS OFF STACK
; ****	PJRST	DVRTN			;DO ENDING AND RETURN

DVRTN:	MOVEI	T3,AUTADR/400		;GET AUTO-ADDRESS BIT
	JUMPL	P4,DVRTN2		;DO WE WANT AUTO-ADR
	BCIOB	T3,PCTMMR+1(T2)		;NO, WANTS SILO ADDRESSING
	MOVEI	T1,E$MSG2 <SILO ADDRESSING ENABLED>
	SKIPA				;SKIP AND PRINT THIS MESSAGE
DVRTN2:	MOVEI	T1,E$MSG2 <AUTO ADDRESSING ENABLED >
	PUSHJ	P,CONMES		;PRINT IT
DVRTN1:	E$TYPE	(3,<END OF PCL STATUS UPDATE>)
	POP	P,U			;RESTORE U
	PJRST	RTZER1			;RETURN


RTM1S:	SETOM	T1			;SET T1 ALL ONES FOR RETURN
	AOS	(P)			;ADJUST STACK FOR SKIP RETURN
	PJRST	STOTAC##		;GO RETURN

;HERE TO PRINT MASTER REGISTER STATUS CHANGING MESSAGE

MESAGA:	PUSHJ	P,CRLF##		;TYPE A CRLF
	E$TYPE	(2,<PCL NETWORK STATUS UPDATE >)
	E$TYPE	(2,<MASTER SECTION MAY BE BEING MODIFIED ON>)
	HLRZ	T2,DEVNAM(F)		;GET DEVICE NAME
	PUSHJ	P,PRNAME##		;PRINT DEVICE NAME
	POPJ	P,			;RETURN
SUBTTL	ADDRESS SILO ROUTINES


CKADRS:	PUSH	P,M			;SAVE M FOR LOAD CYCLE
	PUSH	P,[CKEXIT]		;PUSH ERROR RETURN ADDRESS ON STACK
	PUSHJ	P,GETWR1##		;GET FIRST WORD
	PJRST	ECOD10##		;ERROR RETURN
	SKIPGE	P4,T1			;TEST FOR AUTO ADDRESSING, SAVE IN P4
	PJRST	SAUTAD			;GO SET AUTADR MODE BIT
	CAIG	P4,1			;IS IT GOOD VALUE - NOT ZERO AND ONE
	PJRST	ECOD6##			;NO - VALUE SPECIFIED IS ZERO-ERROR
	CAIGE	P4,ADRMIN		;IS NUMBER AT LEAST 20 DECIMAL
	SETOM	P3			;NO-FLAG REPEAT COUNT NEEDED
	CAILE	P4,ADRMAX		;IS NUMBER GREATER THAN 50 DECIMAL
	PJRST	ECOD7##			;YES - GIVE ERROR RETURN
	TRC	T1,-1			;COMPLEMENT NUMBER
	ADDI	T1,2			;ADJUST FOR PROPER COUNT
	HRLZ	T3,T1			;SETUP COUNT IN T3
	PUSHJ	P,GETWR1		;GET FIRST ADDRESS VALUE
	PJRST	ECOD10			;ERROR RETURN - EXIT
	MOVE	P2,T1			;SAVE FIRST WORD
CKADR2:	MOVE	T4,T1			;SETUP FOR FIRST COMPARE
	PUSHJ	P,GETWR1		;GET NEXT ADDRESS VALUE
	PJRST	ECOD10			;ERROR RETURN - EXIT
	CAMN	T1,T4			;COMPARE ADJACENT VALUES
	PJRST	ECOD12##		;ERROR, VALUES COMPARE
	AOBJN	T3,CKADR2		;DONE ALL VALUES - JUMP IF NOT
	CAMN	T1,P2			;COMPARE FIRST AND LAST VALUES
	PJRST	ECOD13##		;ERROR-FIRST AND LAST =
	POP	P,			;REMOVE ERROR ADDRESS FROM STACK
CKADR1:	AOS	-1(P)			;GIVE SKIP RETURN
CKEXIT:	PJRST	MPOPJ##			;RESTORE M, RETURN
SAUTAD:	POP	P,			;GET RID OF ERROR ADDRESS
	AOS	-1(P)			;ADJUST RETURN TO SKIP LOAD CYCLE
	AOS	-1(P)			;
LDADRS:	MOVEI	T3,CLRADR!AUTADR	;GET BITS FOR SILO LOAD
	BSIO	T3,PCTMMR(T2)		;SET CLEAR ADDRESS SILO AND SET AUTO ADR
	SKIPGE	P4			;CHECK FOR AUTO ADR FLAG
	PJRST	CKADR1			;EXIT - AUTO ADDRESS MODE
	MOVEI	T3,RDSILO		;
	BCIO	T3,PCXTCR(T2)		;MAKE SURE READ SILO BIT CLEAR
	SETZM	T3			;CLEAR T3 FOR COUNT
	HRRI	M,1(M)			;INCREMENT M TO POINT TO FIRST ADDR.
	MOVE	P2,M			;SAVE M FOR LATER
LDADS2:	HRR	T1,P4			;GET NUMBER OF ADDRESSES
	TRC	T1,-1			;COMPLEMENT THE NUMBER
	AOS	T1			;ADJUST FOR PROPER COUNT
	HRL	T3,T1			;SETUP COUNT
	MOVE	M,P2			;RESTORE M FOR LOOP
LDADS1:	PUSHJ	P,GETWR1		;GET ADDRESS VALUE
	PJRST	ECOD10			;ERROR RETURN - EXIT
LDADS3:	RDIO	T4,PCTMMR(T2)		;READ TMMR STATUS
	TRNN	T4,AIPRDY		;TEST IF WE CAN LOAD AN ADDRESS IN SILO
	JRST	LDADS3			;NO, NOT YET - WAIT IN THIS LOOP
	WRIOB	T1,PCTMMR(T2)		;LOAD ADDRESS INTO SILO
	AOBJN	T3,LDADS1		;DONE LOAD
	JUMPGE	P3,LDEXIT		;YES - TEST REPEAT SEQ FLAG
	HRRZ	T1,T3			;REPEAT CYCLE NEEDED
	CAIGE	T1,ADRMIN		;IS MIN. NUMBER OF ADDRESSES BEEN LOADED
	JUMPA	LDADS2			;NO-CONTINUE LOAD BY REPEATING SEQ
LDEXIT:	AOS	(P)			;ADJUST STACK FOR RETURN
	POPJ	P,			;TAKE SKIP RETURN

;HERE TO GET A WORD FROM USERS ARGUMENT BLOCK

FTCHWD:	PUSHJ	P,GETWR1##		;GET USER ARGUMENT WORD
	SKIPA
	POPJ	P,			;RETURN
	POP	P,			;FETCH FAILED
	PJRST	ECOD10##		;EXIT

;HERE TO SETUP AND TEST PCL BASE ADDRESS

SETBAS:	MOVE	T2,PCLBAS(F)		;GET PCL BASE ADDRESS
	MOVE	T1,T2			;T1 MUST HAVE ADDRESS
	PUSHJ	P,UBGOOD##		;GO CHECK UBA THERE
	SKIPA				;BAD UBA,ADDRESS OR BUS
	POPJ	P,			;YES, RETURN
	POP	P,(P)			;ADJUST STACK
	PJRST	ECOD3##			;EXIT

;HERE TO CHECK FOR PRIVILEDGED USER

CKPVBT:	MOVEI	T1,PCLPRV		;SETUP T1 WITH PRIV BIT
	PUSHJ	P,PRVBT##		;GOTO CHECK ROUTINE
	POPJ	P,			;OK, GOOD RETURN-CAN MODIFY MASTER SECTION
	POP	P,			;NO - FORGET IT,BAD GUY!!!
	PJRST	ECOD5##			;EXIT
SUBTTL	OUT/OUTPUT PCL20 UUO SERVICE

PCLOUT:	PUSHJ	P,SAVE4##		;SAVE P1 - P4
	TLO	S,IO			;FLAG OUTPUT
	MOVE	P1,PCLTBL(F)		;GET POINTER ADDRESS
	HRLZ	T1,PCLBSY(P1)		;GET BUSY WORD
	SKIPL	T1			;SKIP IF BUSY
	TLNE	S,PCOBSY		;;IS IT SET
	PJRST	PCBUSY			;YES,INTERFACE TRANSMITTER NOT AVAILABLE
	TLO	S,PCOBSY		;OK, INTERFACE AVAILABLE TO USE
PCOUTG:	HRRZ	T1,DEVOAD(F)		;GET CURRENT BUFFER ADDRESS
	EXCTUU	<SKIPL	@T1>		;TEST IF BUFFER READY
	POPJ	P,			;NO, BUFFER NOT AVAILABLE - EXIT
	MOVE	P1,PCLTBL(F)		;GET ADDRESS TO CONTROL BLOCK
	HLLOS	PCLBSY(P1)		;SET INTERFACE XMIT BUSY FLAG
IFN FTDBUG,<
	MOVE	T1,TIME##		;GET TIME
	MOVEM	T1,TIMOU0(F)		;SAVE IT
>; END IFN FTDBUG
	PUSHJ	P,PCSETO		;SETUP USER'S OUT BUFFER
	PJRST	STOIOS##		;ERROR IN BUFFER SETUP, EXIT
	TRO	S,IOACT			;SET IO ACTIVE
	TLO	S,PCOACT		;SET OUTPUT ACTIVE
;HERE TO START PCL OUTPUT GOING

PCLOGO:	PUSHJ	P,STOIOS##		;UPDATE STATUS FIRST
	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS OF PCL
	MOVEI	T1,INTENA		;GET BIT
	BCIO	T1,PCXTCR(T2)		;CLEAR INT ENABLE
	MOVN	T1,PCOBYT(F)		;GET NEGATIVE BYTE COUNT
	TRNN	S,IOWC			;IS BIT SET
	SOS	T1			;NO, ADJUST BYTE COUNT
	WRIO	T1,PCTSBC(T2)		;SET IN BYTE COUNT REGISTER
	RDIO	T1,PCTSBC(T2)		;
	MOVE	P3,PCOCDB(F)		;GET OUTPUT CHANNEL BLOCK ADDRESS
	MOVE	T1,CHNIEA##(P3)		;GET -11 STYLE ADDRESS
	WRIO	T1,PCTSBA(T2)		;SET IN BUS ADDRESS REGISTER
	RDIO	T3,PCTSBA(T2)		;
	LSH	T1,-14			;ISOLATE TWO HIGH ORDER ADDRESS BITS
	TRZ	T1,777717		;MASK FOR PROPER POSITION
	MOVE	T3,TFLGWD(F)		;GET THE FLAG WORD
	WRIO	T3,PCTSDB(T2)		;LOAD INTO THE DATA SILO
	RDIO	T3,PCTSDB(T2)		;
	IORI	T1,SNDWRD		;GET INTERFACE START BITS
	LDB	T3,PUNIT		;GET DESTINATION NODE ADDRESS
	LSH	T3,10			;SHIFT INTO POSITION
	IOR	T1,T3			;COMBINE WITH OTHER BITS
	TRNE	S,USERIB		;DOES USER WANT RIB BIT SET
	IORI	T1,TXXRIB		;YES, SET RIB BIT IN TCR
	IORI	T1,STRTXM!TXXNPR	;GET ENABLE BITS
	WRIO	T1,PCXTCR(T2)		;SET IN COMMAND REGISTER
IFN FTDBUG,<
	MOVE	T1,TIME##		;GET TIME
	MOVEM	T1,TIMOU1(F)		;SAVE IT
>; END IFN FTDBUG
	PUSHJ	P,RDRGXS		;GO READ IF REGISTERS
	RDIO	T1,PCXTCR(T2)		;READ COMMAND REG
	HRLM	T1,PCLTST(F)		;SAVE FOR REFERANCE
	RDIO	T3,PCXTSR(T2)		;READ STATUS
	HRRM	T3,PCLTST(F)		;SAVE IT
PCOEND:	PUSHJ	P,STOIOS##		;STORE STATUS, SET HUNG TIMER
	MOVEI	T1,INTENA		;GET INTERRUPT ENABLE BIT
	BSIO	T1,PCXTCR(T2)		;SET XMIT ENABLE INTERRUPTS
	POPJ	P,			;EXIT TO MONITOR
SUBTTL	IN/INPUT PCL20 UUO SERVICE

PCLINP:	PUSHJ	P,SAVE4			;SAVE P1 - P4
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMIN0(F)		;SAVE
>; END IFN FTDBUG
	TLNE	S,PCIPWT		;IS THIS NODE WAITING TO RECEIVE
	PJRST	PCBUSY			;YES, BUSY - GO EXIT
	MOVE	T1,DEVIAD(F)		;GET AND SAVE INPUT BUFFER ADDRESS
	MOVEM	T1,PCIPTR(F)		;FOR USE LATER AT INTERRUPT
	MOVE	T2,PCLBAS(F)		;GET PCL BASE ADDRESS
	TLO	S,PCIPWT		;SET NODE WAITING
	TRO	S,IOACT			;SET IO ACTIVE BIT
	PUSHJ	P,STOIOS##		;UPDATE STATUS
	PUSHJ	P,RDRGST		;READ REGISTER DATA
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMIN1(F)		;SAVE
>; END IFN FTDBUG
	POPJ	P,			;RETURN
;HERE TO GET PCL INPUT GOING
PCINPT:	HRRZ	T3,DEVIAD(F)		;GET ADDRESS OF CURRENT INPUT BUFFER
	EXCTUU	<SKIPGE	@T3>		;TEST IF BUFFER AVAILABLE
	DOREJ				;BUFFER NOT AVAILABLE, REJECT MESSAGE
	HRROS	PCLBSY(P1)		;SET INTERFACE RCV BUSY FLAG
	PUSHJ	P,PCSETI		;GO SETUP BUFFER
	 PJRST	STOIOS			;ERROR IN BUFFER SETUP, NON-SKIP RETURN
	TLZ	S,PCIPWT		;CLEAR INPUT WAIT BIT
	TLO	S,PCIACT		;SET INPUT NOW ACTIVE
	MOVEM	S,DEVIOS(F)		;UPDATE DDB STATUS
	PUSHJ	P,GTDIBC		;GET INPUT BYTE COUNT
	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS OF I/O REGISTER
	HRLM	T1,PCIPTR(F)		;SAVE COUNT FOR REFERENCE
	WRIO	T1,PCRDBC(T2)		;SET IN BYTE COUNT REGISTER
	MOVE	P3,PCICDB(F)		;GET INPUT CHANNEL BLOCK ADDRESS
	MOVE	T1,CHNIEA##(P3)		;GET -11 STYLE ADDRESS
	HRLM	T1,PCIBYT(F)		;SAVE ADDRESS FOR REFERANCE
	WRIO	T1,PCRDBA(T2)		;SET IN BUS ADDRESS REGISTER
	LSH	T1,-14			;GET TWO HIGH ORDER ADDRESS BITS ISOLATED
	TRZ	T1,777717		;MASK FOR PROPER POSITION
	IORI	T1,RCVDAT!RCVNPR	;OR IN THE TRANSFER ENABLE BITS
	MOVEI	T3,RCVERR		;GET ERROR BIT
	TIOE	T3,PCXRSR(T2)		;TEST FOR RCV ERROR SET
	PJRST	PCINER			;YES, EXIT DON'T START A TRANSFER
	BSIO	T1,PCXRCR(T2)		;SET IN COMMAND REGISTER
	RDIO	T1,PCXRCR(T2)		;READ WHAT WAS WRITTEN
	HRLM	T1,PCLRST(F)		;SAVE FOR LATER
	RDIO	T3,PCXRSR(T2)		;READ STATUS
	HRRM	T3,PCLRST(F)		;SAVE IT
	PUSHJ	P,RDRGST		;READ REGISTER DATA
PCIEND:	PUSHJ	P,STOIOS##		;STORE STATUS,SET HUNG TIMER
PCIND1:
IFN FTDBUG,<
	MOVE	T3,TIME##		;GET TIME
	MOVEM	T3,TIMING(F)		;SAVE
>; END IFN FTDBUG
	MOVEI	T3,INTENA		;GET ENABLE BITS
	BSIO	T3,PCXRCR(T2)		;SET IN COMMAND REGISTER
	POPJ	P,			;RETURN

PCINER:	TRZ	S,IOACT			;CLEAR IO ACTIVE BIT
	PUSHJ	P,STOIOS##		;STORE STATUS
;	PUSHJ	P,RTEVM##		;RETURN EVM FOR BUFFER
	PJRST	PCIND1			;DO ENDING
SUBTTL	SETUP NEXT BUFFER ROUTINES

PCSETI:	HRRZ	T3,DEVIAD(F)		;GET ADDRESS OF CURRENT IN BUFFER
	EXCTUX	<HRRZ	T4,1(T3)>	;GET COUNT FROM BUFFER HEADER
	TRNN	S,IOWC			;IS USER SPECIFYING BYTE COUNT
	IMULI	T4,4			;NO, CONVERT WORDS TO BYTES
	HRRZ	T2,T3			;GET CURRENT BUFFER ADDRESS
	HRL	T2,T4			;FORM IOWD IN T2
	AOS	T2			;BUMP T2 FOR IOWD, DO THIS BUFFER
	MOVEM	T2,PCIPTR(F)		;SAVE BYTE COUNT AND ADDRESS OF BUFFER
	MOVEM	T4,PCIBYT(F)		;SAVE COUNT FOR LATER
	HRRZ	P1,DEVIAD(F)		;GET ADDRESS OF CURRENT BUFFER
	EXCTUX	<HLL	T2,@P1>		;GET CURRENT INPUT BUFFER SIZE
	TLZ	T2,400000		;CLEAR USE BIT
	TLCE	T2,777777		;SET WORD COUNT NEGATIVE
	TRNE	S,IFLGWD		;IF USER WANTS FLAG WORD IN DATA BUFFER
	AOBJP	T2,NOMSG		; ADJUST ADDRESS TO FIRST DATA LOCATION
	MOVE	P3,PCICDB(F)		;GET POINTER TO IN CHANNEL DATA BLOCK
	PJRST	PBUFST			;

PCSETO:	HRRZ	T1,DEVOAD(F)		;GET ADDRESS OF CURRENT OUT BUFFER
	EXCTUX	<HRRZ	T4,1(T1)>	;GET BYTE COUNT FROM BUFFER HEADER
	TRNE	S,IOWC			;IS USER SPECIFYING BYTE COUNT
	JRST	PSETO1			;YES - LEAVE COUNT AS IT IS
	IMULI	T4,4			;NO, CONVERT WORDS TO BYTES
	SUBI	T4,2			;BUT REMEMBER ONLY 2 BYTES IN 1ST WORD
PSETO1:	JUMPLE	T4,NOMSG		;TEST FOR ZERO LENGTH, JMP IF YES
	MOVEM	T4,PCOBYT(F)		;SAVE COUNT FOR LATER
	EXCTUX	<MOVE	T1,2(T1)>	;GET FLAG WORD INTO T1
	MOVEM	T1,TFLGWD(F)		;SAVE IT IN THE DDB
	MOVEI	P1,2(T4)		; Get # of bytes (+2, for rounding)
	LSH	P1,-2			; Convert byte-count to word-count
	HRRZ	T2,DEVOAD(F)		;GET UVA OF BUFFER
	HRROI	T2,3-1(T2)		;GET ADDRESS-1 FOR MAPIO
	TLC	T2,(P1)			;FORM IOWD
	MOVE	P3,PCOCDB(F)		;GET POINTER TO OUT CHANNEL DATA BLOCK
;	PJRST	PBUFST			;

PBUFST:	SETZ	P1,			;CLEAR P1
	PUSHJ	P,MAPIO##		;GO SETUP UNIBUS ADAPTER REGISTERS
	STOPCD	CPOPJ,JOB,MGL		;+++MAPIO GOT LOST
	AOS	(P)			;GIVE SKIP RETURN
	POPJ	P,			;RETURN
;HERE TO GET THE MAX DEFAULT BYTE COUNT FOR SELECTED DATA MODE
;	RETURNS WITH NEGATIVE BYTE COUNT IN T1

GTDIBC:	TLNE	S,PCIPWT		;IS THIS INPUT START UP
	SKIPE	PCIBYT(F)		;TEST FOR ZERO COUNT
	PJRST	GTUCNT			;NO, TAKE USER SUPPLIED COUNT
	HRRZ	T1,DEVIAD(F)		;GET CURRENT INPUT BUFFER ADDRESS
	EXCTUX	<HLRZ	T1,@T1>		;GET CURRENT INPUT BUFFER SIZE
	TRZ	T1,400000		;CLEAR USE BIT
	IMULI	T1,4			;IMAGE MODE, MAKE IMAGE COUNT
	MOVEM	T1,PCIBYT(F)		;SAVE COUNT FOR FORMATTER
	MOVN	T1,T1			;GET NEGATIVE OF COUNT IN T1
	POPJ	P,			;RETURN
GTUCNT:	TRNE	S,IOWC			;IS USER WC BIT SET
	SOS	PCIBYT(F)		;YES, ADJUST FOR BYTE COUNT
	SOS	PCIBYT(F)		;ADJUST COUNT
	MOVN	T1,PCIBYT(F)		;JUST GET BYTE COUNT
	POPJ	P,			;RETURN


PCRCVI:	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS
	MOVEI	T3,RCINIT		;GET BIT TO CLEAR RECEIVER SO THAT THE
	BSIO	T3,PCXRCR(T2)		;TIMEOUT ONE SHOT CAN GET RESET
	RDIO	T1,PCXRCR(T2)		;READ RCV COMMAND REGISTER
PCRCVE:	MOVEI	T3,RCVWRD		;GET BITS FOR SETTING
ENARCV:	TRO	T3,INTENA		;SET ENABLE BIT
	BSIO	T3,PCXRCR(T2)		;THEN INITIALIZE RCV TO RECEIVE ANOTHER FLG WD
	POPJ	P,			;RETURN

NOMSG:	POP	P,T1			;CLEAN UP STACK
	TRO	S,IOIMPM		;SET ERROR BIT IN STATUS
	HLLZS	PCLBSY(P1)		;CLEAR OUT BUSY
	PJRST	PCSTOP			;SHUT DOWN THIS IO
SUBTTL	CLOSE UUO

PCLCLS:	MOVE	T2,PCLBAS(F)		;GET BASE ADDRESS
	TLNE	S,IO			;TEST WHICH IO
	PJRST	XMTENA			;ENABLE XMIT
	PJRST	PCRCVE			;ENABLE RCV

SUBTTL	RELEASE UUO

PCLREL:	PUSHJ	P,PCLCLS		;DO CLOSE THINGS
	TRO	S,IODEND		;SET EOF BIT IN STATUS
PCSTOP:	TLNN	S,IO			;IS THIS INPUT OR OUTPUT RELEASE ?
PCSTPI:	TLZA	S,USERWT!PCIPWT!PCIACT	;CLEAR INPUT BITS
PCSTPO:	TLZ	S,PCOBSY!PCOACT		;CLEAR OUTPUT BITS
	TRZ	S,IOACT			;CLEAR ACTIVE
;	PUSHJ	P,RTEVM##		;RETURN EVM FOR BUFFER

;HERE TO STOP THE PCL AND START THE USER

PCLSTP:	PUSHJ	P,STOIOS##		;STORE STATUS IN DDB
IFN FTDBUG,<
	MOVE	T1,TIME##		;GET TIME
	MOVEM	T1,TIMDON(F)		;SAVE IT
>; END IFN FTDBUG
	PJRST	SETIOD##		;CLEAR IO WAIT, REQUE IF NEEDED
;EXIT AND RETURN TO MONITOR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

PCBUSY:	TRO	S,200000		;SET AN ERROR BIT
	PJRST	PCLSTP			;STOP AND RETURN
SUBTTL	DAEMON ERROR REPORTING FOR SYSERR

;HERE TO DO DAEMON ERROR REPORTING FOR SYSERR

PCLSYR:	MOVE	T1,PCLBAS(F)		;GET PCL BASE ADDRESS IN T1
	MOVE	U,PCICDB(F)		;GET IN CHANNEL BLOCK ADDRESS
	TLNE	S,IO			;IS THIS INPUT ERROR??
	MOVE	U,PCOCDB(F)		;NO, OUTPUT. GET CHANNEL ADDRESS
	RDIO	T2,@CHNUBA##(U)		;READ UBA STATUS REGISTER
	MOVEM	T2,PCLDAE+.HCL20(F)	;SAVE IT
	RDIO	T3,PCXTSR(T1)		;GET STATUS REGISTER
	LSH	T3,-4			;POSITION 2 BIT ADDRESS EXTENSION
	RDIO	T2,PCTSBA(T1)		;GET REST OF BUS ADDRESS
	DPB	T3,[POINT 2,T2,19]	;PUT IN HIGH ORDER BITS
	IDIVI	T2,UBAMUL		;COMPUTE MAP REGISTER OFFSET
	ADDI	T2,UBAEXP		;ADD IN THE BASE ADDRESS
	HLL	T2,CHNUBA##(U)		;PUT IN PROPER UBA NUMBER
	RDIO	T3,(T2)			;READ OUT MAP SLOT OF LAST WORD XFER'ED
	MOVEM	T3,PCLDAE+.HCL21(F)	;SAVE IT
	RDIO	U,PCXTCR(T1)		;GET STATUS REGISTER
	RDIO	T2,PCXTSR(T1)		;GET STATUS REGISTER
	HRLI	T2,(U)			;PUT IN LH OF T2
	MOVEM	T2,PCLDAE+.HCL22(F)	;SAVE IT
	RDIO	U,PCTSDB(T1)		;GET REGISTER
	RDIO	T2,PCTSBC(T1)		;GET REGISTER
	HRLI	T2,(U)			;PUT IN LH OF T2
	MOVEM	T2,PCLDAE+.HCL23(F)	;SAVE IT
	RDIO	U,PCTSBA(T1)		;GET REGISTER
	RDIO	T2,PCTMMR(T1)		;GET REGISTER
	HRLI	T2,(U)			;PUT IN LH OF T2
	MOVEM	T2,PCLDAE+.HCL24(F)	;SAVE IT
	RDIO	T2,PCTCRC(T1)		;GET REGISTER
	HRLZ	T2,T2			;SWAP HALVES
	MOVEM	T2,PCLDAE+.HCL25(F)	;SAVE IT
	RDIO	U,PCXRCR(T1)		;GET REGISTER
	RDIO	T2,PCXRSR(T1)		;GET REGISTER
	HRLI	T2,(U)			;PUT IN LH OF T2
	MOVEM	T2,PCLDAE+.HCL26(F)	;SAVE IT
	RDIO	U,PCRDDB(T1)		;GET REGISTER
	RDIO	T2,PCRDBC(T1)		;GET REGISTER
	HRLI	T2,(U)			;PUT IN LH OF T2
	MOVEM	T2,PCLDAE+.HCL27(F)	;SAVE IT
	RDIO	U,PCRDBA(T1)		;GET REGISTER
	RDIO	T2,PCRCRC(T1)		;GET REGISTER
	HRLI	T2,(U)			;PUT IN LH OF T2
	MOVEM	T2,PCLDAE+.HCL30(F)	;SAVE IT
	MOVE	T2,JBTPPN##(J)		;PICK UP PPN
	MOVEM	T2,PCLDAE+.HCUID(F)	;SAVE IT
	MOVE	T2,JBTPRG##(J)		;PICK UP PROGRAM NAME
	MOVEM	T2,PCLDAE+.HCPGM(F)	;SAVE IT
	MOVEI	T1,.ERSPC		;GET SYSERR TYPE FOR THIS DEVICE
	HRLI	T1,PCLDAP(F)		;POINTER TO AOBJN POINTER
	PJRST	DAEERR##		;CALL DAEMON
	XLIST	; **** LITERALS ****
	LIT
	LIST

PCLEND:	END