Google
 

Trailing-Edge - PDP-10 Archives - BB-F493Z-DD_1986 - 10,7/dzcom.mac
There are 4 other files named dzcom.mac in the archive. Click here to see a list.
	.TITLE	KDZMC - KMC11 MICROCODE TO SUPPORT THE DZ11
	.IDENT	/V1.0/
;
; COPYRIGHT (C)	1978
; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON
; A SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH
; THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS
; SOFTWARE, OR ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED
; OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON
; EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO AGREES TO
; THESE LICENSE TERMS.  TITLE TO AND OWNERSHIP OF THE
; SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC
;
; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COM-
; MITMENT BY DIGITAL EQUIPMENT CORPORATION.
;
; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DEC.
;
; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING
;
MAXDEV=6.
 
; DZ-11 INTERFACE RELATED EQUATES
 
; CONTROL AND STATUS REGISTER
 
;	LOW BYTE
 
DZCLR=BIT4	;CLEAR
DZSCN=BIT5	;MASTER SCAN ENABLE
DZRDN=BIT7	;RECEIVE DONE
 
;	HIGH BYTE
 
DZTXD=BIT7	;TRANSMIT DONE
 
; RECEIVE BUFFER REGISTER
 
;	HIGH BYTE
 
DZPE=BIT4	;PARITY ERROR
DZFE=BIT5	;FRAMING ERROR
DZOVR=BIT6	;OVERRUN
DZDVL=BIT7	;DATA VALID
 
; LINE PARAMETER REGISTER
 
;	HIGH BYTE 
DZREN=BIT4	;RECEIVE ENABLE
 
 SP.CRM=5	;CURRENT RAM POINTER (SP.RM0 + RCV OR XMT OFFSET)
 SP.XST=6	;TRANSMIT STATUS
 SP.COR=6	;RELATIVE VALUE IN CORE TABLE
 SP.CST=7	;CHARACTER STATUS (RCV)
		;NEXT LINE READY STATUS (XMT)
 SP.SAV=7	;HOLDING ACROSS SUBROUTINES REGISTER
 SP.CHR=10	;RECEIVE CHARACTER
 SP.LN=11	;CURRENT LINE NUMBER
 SP.POL=12	;DEVICE COUNTER FOR POLLING
 SP.RM0=13	;RAM ADDRESS 0-7 FOR CURRENT LINE TABLE
 SP.RM1=14	;RAM ADDRESS 8-9 FOR CURRENT LINE TABLE
 SP.SB1=15	;OUTER SUBROUTINE RETURN ADDRESS
 SP.SUB=16	;INNER SUBROUTINE RETURN ADDRESS
 
 
; CONTROL/BUFFER OUT CODES
 
C.BAOX=0	;BA OUT FOR TRANSMIT
C.BAOR=4	;BA OUT FOR RECEIVE
C.CLOX=1	;CONTROL OUT FOR TRANSMIT
C.CLOR=5	;CONTROL OUT FOR RECEIVE
; ERROR CODE DEFINITIONS
 
ER.CPE=2		;CHARACTER PARITY ERROR
ER.FRE=4		;FRAMING ERROR
ER.ABO=6		;ABORT (CONTROL O TYPE FUNCTION)
ER.NBA=14		;NO BUFFER AVAILABLE (RECEIVE)
ER.NXM=20		;NON EXISTENT MEMORY
ER.OVR=24		;RECEIVER OVERRUN
ER.KIL=26		;KILL COMPLETE
ER.SRC=30		;SPECIAL RECEIVE CHARACTER
.PAGE
	.SBTTL	TABLE OFFSET DEFINITIONS
 
BIT0=1
BIT1=2
BIT2=4
BIT3=10
BIT4=20
BIT5=40
BIT6=100
BIT7=200
 
; RAM TABLE OFFSET PER DZ11 LINE
 
L.STS=0			;STATUS
L.SILO=0		;RECEIVE CHARACTER SILO INDICATOR
	LS.EPX=BIT7	;ECHO PLEX
	LS.FUL=BIT4	;SILO FULL
	LS.FDX=0	;FULL DUPLEX
	LS.SIL=BIT0!BIT1 ;RECEIVER SILO COUNT
 
L.RECO=L.STS+1			;RECEIVE ECHO BUFFER
 L.REC1=L.RECO			;FIRST ECHO CHARACTER
 L.REC2=L.RECO+1		;SECOND ECHO CHARACTER
 L.REC3=L.RECO+2		;THIRD ECHO CHARACTER
 
L.XBD=L.RECO			;CURRENT TRANSMIT BUFFER DESCRIPTOR (5 BYTES)
 L.XBDC=L.XBD			;COUNT LOW BYTE
 L.XBDA=L.XBD+2			;ADDRESS LOW BYTE
 L.XBDF=L.XBD+4			;FLAG BITS BYTE
 
	;FLAG BIT DEFINITIONS (L.XBDF)
 
	LX.FST=BIT7		;FLAG FOR FIRST CHARACTER UN-TRANSMITTED
	LX.FNL=BIT5		;FINAL DESCRIPTOR FLAG
	LX.PIC=BIT4		;TRANSFER PARAMETERS IN CORE FLAG
	LX.EXM=BIT2!BIT3	;EXTENDED MEMORY BITS
	LX.XAL=BIT1		;ALTERNATE BUFFER ASSIGNED
	LX.XBF=BIT0		;TRANSMIT BUFFER ASSIGNED
 
L.OXC=L.XBD+5			;ODD TRANSMIT CHARACTER
 
L.RBD=L.OXC+1			;CURRENT RECEIVE BUFFER DESCRIPTOR (5 BYTES)
 L.RBDC=L.RBD			;COUNT LOW BYTE
 L.RBDA=L.RBD+2			;ADDRESS LOW BYTE
 L.RBDF=L.RBD+4			;FLAG BITS BYTE
 
	;FLAG BIT DEFINITIONS (L.RBDF)
 
	LR.BNR=BIT6		;BINARY MODE IN PROGRESS (RECEIVE)
	LR.FNL=BIT5		;FINAL DESCRIPTOR FLAG
	LR.EXM=BIT2!BIT3	;EXTENDED MEMORY BITS
	LR.RAL=BIT1		;RECEIVE ALTERNATE ASSIGNED
	LR.RBF=BIT0		;RECEIVE BUFFER ASSIGNED
 
L.MODE=L.RBDF+1		;MODE TABLE ADDRESS (3 BYTES)
L.CURM=L.MODE+2		;CURRENT RECEIVE MODE
	LM.RMD=BIT7!BIT6!BIT5	;CURRENT RECV MODE
	LM.EXM=BIT3!BIT2	;EXTENDED MEMORY BITS
 
L.RUBO=L.CURM+1			;CURRENT RUBOUT CHARACTER
L.LNG=20		;LENGTH OF A LINE'S ENTRY
 
; CORE TABLE OFFSET PER LINE
 
C.RDP=0			;CURRENT RECEIVE DESCRIPTOR POINTER
C.REX0=C.RDP+2		;RECEIVE EXTENDED MEMORY BITS
C.ARLP=C.REX0+2		;ALTERNATE RECEIVE LINK POINTER
C.REX1=C.ARLP+2		;EXTENDED MEM BITS FOR ALTERNATE LINK POINTER
 
C.XDP=C.REX1+2		;CURRENT TRANSMIT DESCRIPTOR POINTER
C.XEX0=C.XDP+2		;TRANSMIT EXTENDED MEMORY BITS
C.AXLP=C.XEX0+2		;ALTERNATE TRANSMIT LINK POINTER
C.XEX1=C.AXLP+2		;TRANSMIT EXTENDED MEMORY BITS (CONTINUED)
 
C.BIP=C.XEX1+2		;BUFFER IN PROGRESS VALUES (6 BYTES)

C.LNG=40		;LENGTH IN BYTES
 
; RAM OFFSET PER COMM IOP
 
P.LTA=1775		;MEMORY LINE TABLE ADDRESS FOR CURRENT LINE
P.MSTA=P.LTA-3		;MEMORY STORAGE TABLE ADDRES (3 BYTES)
P.SLOT=P.MSTA-1		;NPR SILO NEXT OUT POINTER
P.SLIN=P.SLOT-1		;NPR SILO NEXT IN POINTER
P.PORT=P.SLIN-1		;PORT STATUS BYTE
P.LNG=7			;LENGTH OF AN ENTRY IN THE POLLING LIST
P.PLST=P.PORT-<P.LNG*MAXDEV>	;START OF POLLING LIST
 
 P.RST=0		;TIMER RESTART VALUE
 P.TIME=P.RST+1		;TIMER VALUES
 P.CSR=P.TIME+1		;CSR ADDRESS (2 BYTES)
 P.TCR=P.CSR+2		;TRANSMIT CONTROL REGISTER IMAGE
 P.NRB=P.TCR+1		;NO RECEIVE BUFFER INDICATOR
 P.RCH=P.NRB+1		;RECEIVED CHARACTER
	SENTRY=6	;SIZE OF A SILO ENTRY
	NMSENT=34.	;NUMBER OF SILO ENTRIES
P.NPR=P.PLST-<SENTRY*NMSENT>	;NPR SILO
	SILOED=P.PLST-SENTRY	;LAST ENTRY IN SILO
.PAGE
.PAGE
	.SBTTL	INIT - INITIALIZATION
;+
; **INIT-INITIALIZATION ROUTINE**
;
; INPUTS:
;	BRG = 0 (MASTER CLEAR)
;	MAR = 0 (MASTER CLEAR)
; OUTPUTS:
;	RAM IS CLEARED EXCEPT FOR THE COUNTERS IN THE POLLING LIST
;	WHICH ARE SET TO MINUS ONE TO INDICATE NO ACTIVE DEVICES.
;	THE CSR'S ARE ALSO CLEARED
;-
$KDZMC::
INIT:
	OUT	BR,SELB!OINCON	;ZERO THE INPUT CONTROL CSR
	OUT	BR,SELB!OOCON	;ZERO THE OUTPUT CONTROL CSR
10$:	MEMINC	IMM,0		;ZERO THE NEXT MEMORY LOCATION
	SPBR	IBUS,NPR,SP0	;READ THE NPR CONTROL REGISTER
	BRWRTE	BR,<ADD!SP0>	;SHIFT IT LEFT
	BR7	20$		;OVERFLOWED MAR TO 10 BITS - ALL DONE
	ALWAYS	10$		;KEEP ZEROING RAM
20$:	LDMAP	IMM,P.PORT	;LOAD MAR HIGH WITH ADDRESS OF PORT STATUS BYTE
	LDMA	IMM,P.PORT	;LOAD MAR LOW
	MEMADR	RDOSET,INCMAR	;ADDRESS OF ROUTINE TO CHECK FOR OUTPUT COMPLETIONS
	MEMINC	IMM,P.NPR	;INITIALIZE COMPLETION SILO IN POINTER
	MEM	IMM,377		;INITIALIZE COMPLETION SILO OUT POINTER (LOGICAL ZERO)
	BRWRTE	IMM,P.PLST+P.RST,LDMAR	;LOAD MAR LOW WITH ADDRESS OF COUNTER BYTE IN
				;THE POLLING LIST - MAR ALREADY SET
	SP	BR,SELB,SP.RM0	;SAVE ADDRESS IN RAM ADDRESS SCRTACH PAD
	BRWRTE	IMM,MAXDEV-1	;MAXIMUM NUMBER OF DEVICES GENED FOR
	SP	BR,SELB,SP.POL	;SAVE IT IN POLLING SCRATCH PAD
30$:	MEM	IMM,377		;INITIALIZE COUNTER TO MINUS ONE
	BRWRTE	IMM,P.LNG	;LENGTH OF POLLING LIST
	SP	BR,<ADD!LDMAR>,SP.RM0 ;POINT TO NEXT ENTRY IN THE POLLING LIST
	SP	BR,DECA,SP.POL	;ONE LESS COUNTER TO INITIALIZE
	C	30$		;BUT MORE TO GO IT CARRY SET
	.SBTTL	IDLE - IDLE LOOP
;+
; **IDLE-LOOP BETWEEN PORT AND DEVICE SERVICE
;
; INPUTS:
;	P.PORT = ADDRESS OF NEXT PORT SERVICE ROUTINE
;
; OUTPUTS:
;	IF THE PGMCLK BIT IN THE MISC REG HAS EXPIRED,
;	THE DEVICES ARE POLLED AND SERVICED BY THE TIMER ROUTINE
;	IN ANY CASE, THE NEXT PORT ROUTINE IS BRANCHED TO.
;
;	MAR = P.PORT
;	ALL PORT ROUTINES RETURN TO IDLE
;-

IDLE:
	LDMAP	IMM,P.PLST	;POINT TO POLLING LIST (MAR HI)
	SPBR	IBUS,UBBR,SP0	;READ THE BUS REQUEST REGISTER AND
				;STORE THE IMAGE IN SP0 AND THE BRG
	BR4	TIMER		;BRANCH IF THE TIMER HAS EXPIRED
IDLE1:	LDMA	IMM,P.PORT	;LOAD MAR TO POINT TO PORT STATUS
				;NOTE: MAR HI MUST BE PRESET.
	.ALWAY	MEMX,SELB,P0	;TIMER HAS NOT EXPIRED YET, CHECK THE
				;DATA PORT TO SEE IF ANY PROCESSING IS REQUIRED
				;RAM CONTAINS THE ADDRESS OF THE APPROPRIATE
				;SERVICE ROUTINE
				; RQISET --> WAITING FOR RQI TO SET
				; RDICLR --> WAITING FOR RDYI TO CLEAR
				; RDOSET --> WAITING FOR A COMPLETION
				; RDOCLR --> WAITING FOR RDYO TO CLEAR
	.SBTTL	DATA PORT PROCESSING ROUTINES
;+
; **RDOCLR-WAITING FOR READY OUT TO BE CLEARED BY THE PDP-11**
;
; INPUTS:
;	MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
;	THIS ROUTINE WAITS FOR READY OUT TO BE CLEARED BY THE PDP-11
;	THUS SIGNALING IT IS DONE.  IT ALSO CHECKS IF OUTPUT INTERRUPTS
;	ARE REQUESTED IN THE MEANTIME AND WILL GENERATE ONE IF THEY WERE
;	NOT REQUESTED WHEN RDYO WAS SET.
;
;	WHEN RDYO IS CLEARED, CONTROL IS PASSED TO RQISET TO CHECK
;	FOR PENDING PORT REQUESTS
;
;	NOTE: THESE EXISTS THE POSSIBILITY OF AN INTERRUPT BEING GENERATED
;	IF IEO IS CLEARED AT ANY TIME AFTER IT IS TESTED BY THE MICROPROCESSOR
;	(APPROX A 1.5US WINDOW)
;-

RDOCLR:
	BRWRTE	IBUS,OCON		;READ CONTROL CSR BSEL2
	BR7	RDOST1			;READY OUT STILL SET, CHECK INTERRUPTS
;
; ENTER HERE IF AN OUTPUT INTERRUPT HAS ALREADY BEEN GENERATED
;
RDOCL1:
	BRWRTE	IBUS,OCON		;READ OUTPUT CONTROL CSR
	BR7	IDLE			;READY OUT STILL SET
	BRWRTE	IMM,0			;CLEAR OUTPT CONTROL CSR
	OUT	BR,SELB,OOCON		;..
	MEMADR	RQISET			;LOOK FOR RQI NEXT
	ALWAYS	IDLE			;BACK TO IDLE LOOP
;+
; **RDOSET-MICROPROCESSOR COMPLETION POSTING**
;
; INPUTS:
;	MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
;	CHECK THE COMPLETION SILO TO SEE IF ANY COMPLETIONS ARE PENDING.
;	IF THERE ARE POST THE COMPLETION TO THE PDP-11
;	 SILO POINTERS (P.SLOT,P.SLIN) ARE UPDATED
;	 AND WAIT FOR RDYO TO CLEAR (RDOCLR)
;	OTHERWISE CHECK TO SEE IF THE PDP-11 HAS ANY INPUT DATA (RQISET)
;-
RDOSET:	MEMADR	RQISET		;GO THROUGH RQISET NEXT TIME.
	LDMA	IMM,P.SLOT	;SET MAR TO NPR SILO NEXT OUT POINTER
	LDMA	MEMX,SELB	;POINT NPR TO NEXT OUT ENTRY
	Z	IDLE		;THE POINTER IS ZERO THEREFORE THE SILO IS EMPTY
 
; A COMPLETION OUTPUT IS PENDING IN THE NPR SILO. MAR POINTS TO THE
; NEXT ENTRY
 
	OUT	MEMI,SELB,OLINEN ;WRITE THE LINE NUMBER BYTE
 
	OUT	MEMI,SELB,OPORT1 ;WRITE PORT BYTE 1
	OUT	MEMI,SELB,OPORT2 ;AND PORT BYTE 2
 
	OUT	MEMI,SELB,OPORT3 ;WRITE PORT BYTE 3
	OUT	MEMI,SELB,OPORT4 ;AND PORT BYTE 4
 
	OUT	MEMI,SELB,OOCON ;WRITE THE NEW OUTPUT CNTRL CSR
 
; INCREMENT THE NEXT OUT POINTER
 
	LDMA	IMM,P.SLIN	;SET MAR TO POINT TO NPR SILO NEXT IN OFFSET
	SP	MEMI,SELB,SP1	;SAVE THE NEXT IN POINTER IN SP1
	SP	MEMX,SELB,SP0	;SAVE THE NEXT OUT POINTER IN SP0
	MEM	IMM,P.NPR	;ASSUME THE SILO IS GOING TO WRAP AROUND
	BRWRTE	IMM,SILOED	;OFFSET TO LAST SILO ENTRY
	COMP	BR,SP0		;COMPARE CURRENT OUT POINTER WITH END OF SILO
	Z	50$		;IT DID WRAP AROUND - ALREADY SET UP
	BRWRTE	IMM,SENTRY	;GET THE SIZE OF A SILO ENTRY
	MEM	BR,ADD,SP0	;INCREMENT NEXT OUT POINTER AND SAVE IT
 
; IF SILO IS NOW EMPTY "ZERO" THE NEXT OUT POINTER
 
50$:	COMP	MEMX,SP1		;COMPARE OUT POINTER TO IN POINTER
	Z	70$		;THEY ARE THE SAME
	ALWAYS	80$		;THEY ARE DIFFERENT
70$:	MEM	IMM,377		;THE SILO IS EMPTY - SET NEXT OUT POINTER
				;TO A LOGICAL ZERO (-1)
80$:	LDMA	IMM,P.PORT	;SET MAR TO POINT TO PORT STATUS
RDOST1:
	SPBR	IBUS,INCON,SP0		;READ INPUT CONTROL CSR
	BR4	RDOST2			;OUTPUT INTERRUPT REQUESTED
	MEMADR	RDOCLR			;STATE TO WAITING FOR READY OUT CLEARING
	ALWAYS	IDLE			;BACK TO IDLE LOOP

RDOST2:	MEMADR	RDOCL1			;STATE TO WAITING FOR READY OUT CLEARING
	BRWRTE	IMM,300			;MASK FOR BUS REQUEST AND XX4
RDOST3:	OUT	BR,SELB,OBR		;GENERATE AN INTERRUPT
	ALWAYS	IDLE			;BACK TO IDLE LOOP
;+
; **RQISET-REQUESTED IN SET, THE PDP-11 HAS REQUESTED THE DATA PORTS
;
; INPUTS:
;	MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
;	CHECK TO SEE IF REQUEST IN HAS BEEN SET BY THE PDP-11. IF SO,
;	SET READY IN AND LET THE PDP-11 SET UP A COMMAND IN THE DATA PORTS
;	IF INPUTS INTERRUPTS ARE REQUESTED, GENERATE ONE
;	TRANSFER CONTROL TO RDICLR TO WAIT UNTIL THE PDP-11 IS DONE
;-

RQISET:	BRWRTE	IBUS,INCON		;READ INPUT CONTROL CSR
	BR7	10$			;REQUEST IN SET
	ALWAYS	RDOSET			;SEE IF ANY COMPLETIONS TO POST

10$:	SP	IMM,20,SP0		;MASK TO SET READY IN
	OUT	SELA,OOCON		;SET IN OUPUT CONTROL CSR
	BR0	RQIST1			;INTERRUPT ENABLE IS SET
	MEMADR	RDICLR			;STATE TO WAITING FOR RDI TO CLEAR
	ALWAYS	IDLE			;BACK TO IDLE LOOP

RQIST1:	MEMADR	RDICL1			;STATE TO WAITING FOR RDYI TO CLEAR
	BRWRTE	IMM,200			;MASK FOR BUS REQUEST AND XX0
	ALWAYS	RDOST3			;GENERATE AN INTERRUPT
;+
; **RDICLR-WAIT FOR READY IN TO CLEAR (DATA PORTS HAVE BEEN SET UP)**
;
; INPUTS:
;	MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
;	CHECK TO SEE IF THE PDP-11 HAS CLEARED READY IN SIGNIFYING
;	THAT IT HAS SET UP THE DATA PORTS.  IF SO THEN DISPATCH TO THE
;	PROPER ROUTINE TO HANDLE THE REQUEST BASED ON
;	BIT 0&1 OF THE CONTROL CSR BSEL2
;-
 
; RDYI CLEAR ROUTINE IS ENTERED HERE IS INTERRUPT ENABLE WAS NOT
; SET WHEN THE COMMIOP SET READY IN. IF IN THE  MEANTIME INTERRUPT ENABLE
; WAS SET, IT WILL BE SEEN HERE AND AN INTERRUPT WILL BE GENERATED
 
	.ENABL	LSB
RDICLR:
	BRWRTE	IBUS,OCON		;READ OUTPUT CONTROL CSR
	BR4	5$			;READY IN STILL SET
	ALWAYS	10$			;PDP-11 CLEARED RDYI, DONT BOTHER
					;CHECKING FOR IEI JUST PROCESS THE DATA
5$:	BRWRTE	IBUS,INCON		;READ INPUT CONTROL CSR
	BR0	RQIST1			;INTERRUPT REQUESTED
RDICL1:
	BRWRTE	IBUS,OCON		;READ OUTPUT CONTROL CSR
	BR4	IDLE			;RDYI STILL SET
; READY IN CLEAR
10$:	MEMADR	RDOSET		;ADDRESS OF ROUTINE TO CHECK FOR COMPLETIONS
	SPBR	IBUS,LINENM,SP.LN ;SAVE THE LINE NUMBER IN SP.LN
	SP	BR,SELB,SP0	;SAVE LINE NUMBER IN SP0 TOO
	BRWRTE	IMM,P.PLST-P.LNG ;GET ADDRESS OF POLLING LIST - ONE ENTRY
	SP	BR,SELB,SP17	;SAVE IT IN SP17
15$:	BRWRTE	IMM,P.LNG	;LENGTH OF A POLLING LIST ENTRY
	SP	BR,ADD,SP17,LDMAR ;INCREMENT TO NEXT LIST ENTRY
	BRWRTE	IMM,10,INCMAR	;8 LINES PER DZ'S
	SP	BR,SUB,SP0,INCMAR ;SEE IF WE HAVE THE RIGHT POLLING LIST ENTRY
	C	15$		;NOT YET
	OUTPUT	MEMI,SELB,OBA1 ;SAVE THE CSR ADDRESS IN OUTADDRESS
	OUTPUT	MEMI,SELB,OBA2 ; ..
	BRADDR	16$		;RETURN HERE AFTER CALCULATING
	ALWAYS	TBLADR		;LINE TABLE  ADDRESS
16$:	BRWRTE	IMM,14		;SET EX.MEM. BITS IN OBR FOR BASEIN AND CONIN
	OUT	BR,SELB,OBR
	BRWRTE	IBUS,OCON	;GET ORIGINAL IMAGE OF OUTPUT CONTROL CSR
	BR1	20$		;BIT 1 SET
	BR0	CONIN		;BIT 1=0 AND BIT 0=1 -> CONTROL IN REQUEST
	ALWAYS	BAIN		;BIT 0&1=0 -> BUFFER ADDRESS IN REQUEST
20$:	BR0	BASEIN		;BIT 1=1 BIT 0=1 -> BASE IN REQUEST
	.DSABL	LSB
 
; ABOVE THREE ROUTINES RETURN HERE AFTER REQUEST HAS BEEN PROCESSED
 
RQICL2:	BRWRTE	IMM,0			;CLEAR READY IN
	OUT	BR,SELB,OOCON		;..
	SPBR	IBUS,UBBR,SP0		;READ MISC. REGISTER
	BR0	NXMERR			;NON-EXISTENT MEMORY
	ALWAYS	IDLE			;BACK TO IDLE LOOP
	.SBTTL	TIMER - TIMER SERVICE
;+
; **TIMER-TIMER SERVICE ROUTINE**
;
; INPUTS:
;	BRG & SP0 = IMAGE OF BUS REQUEST REGISTER
;	MAR HI = POLLING LIST PAGE
;
; OUTPUTS:
;	EACH DEVICES TIMER COUNTER IS DECREMENTED AND TESTED FOR
;	AN EXPIRATION.  IF THE COUNTER WENT TO ZERO THE DEVICE
;	IS POLLED TO SEE IF IT HAS A TRANSMIT DONE OR A RECEIVE DONE
;	AND IF SO IT IS SERIVICED.  IF NONE OF THE DEVICES REQUIRES
;	SERVICING THE MODEM TIMER IS DECREMENTED AND IF IT EXPIRED
;	MODEM CHANGES ARE CHECKED.
;	WHEN A DEVICE DONE SERVICE ROUTINE IS FINISHED THIS ROUTINE
;	CONTINUES WITH THE NEXT DEVICE.
;-
	.ENABL	LSB
TIMER:	BRWRTE	IMM,121		;MASK TO CLEAR ALL BUT TIMER, XX4 AND NXM
				;N.B. THIS MASK IS GUARANTEED TO KEEP THE
				;TIMER SET TO A ONE SINCE THE TIMER EXPIRES
				;TO A ONE CONDITION
	OUT	BR,<AANDB!OBR>	;AND THE MASK WITH THE PREVIOUS CONTENTS OF
				;THE BUS REQUEST REGISTER RESETING THE
				;TIMER
	BRWRTE	IMM,-10		;STORE DZ11 BEGINNING COMPARE VALUE.
	SP	BR,SELB,SP.POL	;SAVE THIS NUMBER IN SP.POL.
	BRWRTE	IMM,P.PLST-P.LNG ;SET UP POLLING ADDRESS REGISTER.
	SP	BR,SELB,SP17
	ALWAYS	10$
 
; RECEIVE DONE AND TRANSMIT DONE ROUTINES RETURN HERE
; MAIN POLLING LOOP
 
TIMRTN:	LDMAP	IMM,P.PLST	;POINT TO POLLING LIST
	BRWRTE	IMM,P.NRB	;OFFSET TO RECEIVE CHARACTER INDICATOR
	LDMA	BR,ADD,SP17	;POINT TO IT FOR THE CURRENT DZ
	SPBR	MEMX,SELB,SP.CST ;CHARACTER PRESENT?
	BR7	65$		;YES.

10$:
	SPBR	IBUS,UBBR,SP0	;READ MISC. REGISTER
	BR0	NXMERR		;NON-EXISTENT MEMORY ERROR
	BRWRTE	IMM,10		;ONE LESS DEVICE TO POLL.
	SP	BR,ADD,SP.POL
	BRWRTE	IMM,MAXDEV*10	;GET LAST DEVICE VALUE.
	COMP	BR,SP.POL	;ALL DEVICES CHECKED?
	Z	IDLE1		;ALL DONE - BACK TO IDLE LOOP

	BRWRTE	IMM,P.LNG	;GET THE LENGTH OF AN ENTRY IN THE POLLING LIST
	SP	<BR!LDMAR>,ADD,SP17 ;POINT TO NEXT ENTRY AND LOAD THE MAR
	BRWRTE	MEMI,SELB	;SAVE THE RESTART VALUE IN THE BRG
				;AND INCREMENT THE MAR
				;IN CASE THE TIMER EXPIRED
	Z	10$		;THE DEVICE IS NOT ACTIVE
	SP	MEMX,SELB,SP0	;READ THE COUNTER FOR THIS DEVICE
	MEM	BR,<DECA!SP0>	;DECREMENT THE COUNTER AND WRITE IT
				;BACK TO MEMORY
	C	10$		;LOOK AT NEXT DEVICE'S COUNTER

; TIMER HAS EXPIRED - SEE IF THERE ARE ANY "DONES" PENDING
; INPUTS:
;	BRG = RESET VALUE

30$:	MEMINC	BR,SELB		;RESET THE COUNTER TO THE INITIAL VALUE
	OUTPUT	MEMI,<SELB!IBA1> ;STORE THE LOW BYTE OF THE DEVICES
				;CSR INTO THE LOW BYTE OF THE INPUT BUFFER
				;ADDRESS REGISTER
	OUTPUT	MEMI,<SELB!IBA2> ;DO THE SAME WITH THE HIGH BYTE
	BRWRTE	<IMM!INCMAR>,15	;MASK TO SET EXTENDED MEMORY BITS
				;AND DO AN INPUT NPR
	OUT	BR,<SELB!ONPR>	;START THE NPR
40$:	BRWRTE	IBUS,NPR	;READ THE NPR REQUEST REGISTER
	BR0	40$		;WAIT FOR THE NPR TO COMPLETE
	SP	IBUS,INDAT2,SP.CST ;READ THE HIGH BYTE OF THE DEVICES CSR
	BRWRTE	IBUS,INDAT1	;READ THE LOW BYTE OF THE DEVICES CSR
	BR7	60$		;RECEIVE DONE SET
45$:	BRWRTE	BR,<SELA!SP.CST> ;RETRIEVE HIGH BYTE OF CSR
	BR7	50$		;TRANSMIT DONE SET
	ALWAYS	TIMRTN		;NOTHING TO DO HERE - CHECK NEXT COUNTER
;
; TRANSMIT DONE FOUND SET
;
50$:	BRADDR	XMTDON		;WRITE ADDRESS OF TRANSMIT DONE SERVICE
				;ROUTINE TO THE BRG
	ALWAYS	70$		;BRANCH TO COMMON DONE CODE TO FIND TABLE ADDRESSES
;
; RECEIVE DONE FOUND SET
;
60$:	BRWRTE	MEMX,SELB	;RECEIVE BUFFER UNASSIGNED?
	BR4	45$		;YES, DO NOT READ CHARACTER.
	BR7	45$		;IF ENTRY ALREADY PRESENT DON'T READ ANOTHER

	SP	IBUS,IIBA1,SP0	;READ THE LAST INPUT DATA ADDRESS (LOW BYTE)
				;WHICH IS THE CSR ADDRESS OF THE DEVICE
	BRWRTE	IMM,2		;PREPARE TO ADD TWO TO THIS ADDRESS
	OUTPUT	BR,<ADD!IBA1>	;ADD TWO TO THIS ADDRESS GETTING THE ADDRESS
				; OF CSR2 WHICH CONTAINS THE RECEIVE
				;CHARACTER IN THE LOW BYTE AND THE LINE
				;NUMBER IN THE HIGH BYTE
	BRWRTE	IMM,15		;MASK TO SET EXTENDED MEMORY BITS
				;AND TO START THE NPR
	OUT	BR,<SELB!ONPR>	;START THE NPR TO READ CSR2

80$:	BRWRTE	IBUS,NPR	;READ THE NPR STATUS REGISTER
				;NOTE: THIS IS NECESSARY IN THE CASE THAT
				;A RECEIVE DONE WAS FOUND AND CSR2 WAS
				;REQUIRED. IN ANY CASE THE LINE NUMBER
				;THAT GENERATED THE DONE IS IN
				;BITS 0-2 OF THE HIGH BYTE OF THE INPUT DATA
	BR0	80$		;NPR TO READ CSR2 (IF NECESSARY) IS NOT
				;DONE YET
 
	MEMINC	IBUS,INDAT2
	MEM	IBUS,INDAT1
	ALWAYS	45$		;GET ANY TRANSMIT COMPLETE PROCESSED.

65$:	BRWRTE	IMM,7		;MASK TO CLEAR ALL BUT LINE NUMBER
	MEMINC	BR,AANDB,SP.CST	;CLEAR CHARACTER PRESENT FLAG
	SP	MEMX,SELB,SP.CHR ;GET RECEIVE CHARACTER.
	BRADDR	RCVDON		;WRITE ADDRESS OF RECEIVE DONE ROUTINE TO THE
				;BRG
 
 
70$:	SP	BR,SELB,SP.SB1	;SAVE DISPATCH ROUTINE ADDRESS IN SP.SB1
; CALCULATE THE COMM IOP LINE NUMBER FROM THE DEVICE NUMBER AND THE
; LINE NUMBER ON THE DEVICE
 
	BRWRTE	IMM,7		;MASK TO ISOLATE THE LINE NUMBER
	BRWRTE	BR,<AANDB!SP.CST> ;ISOLATE THE LINE NUMBER
				;AND SAVE THE STATUS.
	BRWRTE	BR,<ADD!SP.POL> ;ADD THE LINE NUMBER TO THE SHIFTED
	SP	BR,SELB,SP.LN	;DEVICE NUMBER RESULTING IN A "VIRTUAL" LINE NUMBER
 
; CALCULATE ADDRESS OF THE LINE'S MEMORY TABLE AND RAM TABLE
 
	BRADDR	DISPAT		;RETURN HERE AFTER CALCULATING
	ALWAYS	TBLADR		;LINE TABLE ADDRESS

DISPAT:	.ALWAY	BR,<SELA!SP.SB1>,P2 ;BRANCH TO RECEIVE OR TRANSMIT DONE ROUTINE
				;THE FOLLOWING LOCATIONS HAVE BEEN SET UP
				;FOR ENTRY TO THE "DONE" PROCESSOR:
				; SP.RM1 -> BITS 8&9 OF RAM TABLE ADDRESS
				; SP.RM0 -> BITS 0-7 OF RAM TABLE ADDRESS
				; MAR --> RAM TABLE ADDRESS
				; P.LTA+2 -> BITS 16&17 OF MEM STORAGE TABLE ENTRY
				; P.LTA+1 -> BITS 8-15 OF MEM STORAGE TABLE ENTRY
				; P.LTA -> BITS 0-7 OF MEM STORAGE TABLE ENTRY
				; SP.LN --> LINE NUMBER
				;IF RECV DONE, SP.CHR AND SP.CSR CONTAIN THE
				;CHARACTER AND ANY ERROR BITS
	.DSABL	LSB
	.SBTTL	TBLADR - ROUTINE TO CALCULATE CORE AND RAM TABLE ADDRESS FOR A LINE
;+
; **TBLADR-CORE AND RAM LINE TABLE ENTRY ADDRESS**
;
; INPUTS:
;	SP.LN = LINE NUMBER
;	MAR HI = PAGE WHERE P.MSTA IS LOCATED
; OUTPUTS:
;	P.LTA = LINE'S CORE TABLE ADDRESS
;	SP.RM0 & SP.RM1 = LINE'S RAM  TABLE ADDRESS (LOW, HIGH)
;	MAR = LINE'S RAM TABLE ADDRESS
;
; NOTE:
;	THIS ROUTINE IS HIGHLY CONFIGURATION DEPENDENT.  IT ASSUMES THE NUMBER
;	OF BYTES IN THE LINE TABLE IS 18 DECIMAL AND THE NUMBER OF BYTES
;	IN THE CORE TABLE ENTRY IS 32 DECIMAL.
.IIF NE	40-C.LNG	.ERROR	TBLADR ROUTINE MUST BE RE-WRITTEN
.IIF NE 20-L.LNG	.ERROR	TBLADR ROUTINE MUST BE RE-WRITTEN
;
;	USES SCRATCH PADS 0, 1, 2, AND 3
;-
TBLADR:	SP	BR,SELB,SP.SUB	;SAVE RETURN  POINT.
	BRWRTE	IMM,0		;STORE HIGH ORDER OF RAM ADDRESS.
	SP	BR,SELB,SP.RM1
	BRWRTE	BR,SELA!SP.LN	;GET THE LINE NUMBER
	SP	BR,SELB,SP.RM0	;STORE IT IN A SCRATCH REGISTER
	SP	BR,TWOA,SP.RM0	;LINE NUMBER X 2.
	SP	BR,TWOA,SP.RM0	;LINE NUMBER X 4.
	SP	BR,TWOA,SP.RM0	;LINE NUMBER X 10.
	SP	BR,APLUSC,SP.RM1 ;SAVE FIRST CARRY.
	SPBR	BR,TWOA,SP.RM0	;LINE NUMBER X 20.
	SP	BR,SELB,SP1	;SAVE LINE NUMBER X 20.
	SPBR	BR,TWOAC,SP.RM1 ;SAVE SECOND CARRY.
	SP	BR,SELB,SP0	;SAVE HIGH BYTE OF LINE NUMBER X 20.
	SP	BR,TWOA,SP1	;LINE NUMBER X 40
	SP	BR,TWOAC,SP0	;SAVE THIRD CARRY.
 
; SCRATCH PAD SUMMARY:
;	SP.RM0 AND SP.RM1 CONTAIN THE LINE # * 20 (16.)
;	SP1 AND SP0 CONTAIN THE LINE # * 40 (32.)
;
; SP1 AND 2 CONTAIN THE OFFSET FOR THIS LINE'S CORE TABLE.
; SP.RM0 AND RM1 ALMOST CONTAIN THE OFFSET FOR THIS LINE'S RAM TABLE.
; AN ADJUSTMENT MUST BE MADE TO INSURE NO LINE'S TABLE CROSSES AN PAGE
; BOUNDARY.
 
10$:	LDMA	IMM,P.MSTA	;GET STARTING ADDRESS OF MEM STORAGE TABLE
	SP	MEMI,ADD,SP1	;ADD LINE TABLE OFFSET TO START ADDRESS
	SP	MEMI,ADDC,SP0	;ADD ON HIGH BYTE
	SP	MEMX,SELB,SP2	;RETRIEVE EXTENDED MEMORY BITS
	C	70$		;CARRY CAUSED BY ADD TO HIGH BYTE
20$:	LDMA	IMM,P.LTA	;POINT MAR TO SLOT FOR LINE TABLE ADDRESS
	MEMINC	BR,SELA!SP1	;LOAD MEM WITH LOW BYTE OF OFFSET
	MEMINC	BR,SELA!SP0	;LOAD HIGH BYTE
	BRWRTE	IMM,14		;MASK TO TAKE CARE OF EXTENDED MEM BITS OVERFLOW
	MEM	BR,<AANDB!SP2>	;LOAD EXTENDED MEMORY BITS
	LDMAP	BR,<SELA!SP.RM1> ;LOAD PAGE ADDRESS OF THIS LINE'S RAM TABLE
	LDMA	BR,<SELA!SP.RM0> ;POINT TO LINE'S RAM TABLE ENTRY
	RTNSUB	SP.SUB,P0	;OTHERWISE WE ARE ALL DONE
 
70$:	BRWRTE	IMM,4		;ADD ONE TO EXTENDED MEM BITS
	SP	BR,ADD,SP2	;..
	ALWAYS	20$		;RETURN
	.SBTTL	PAGE ZERO OFF-PAGE RETURNS
;	*	*	*	*	*	*
;	*	*	*	*	*	*
	.SBTTL	STFSLO-STUFF NPR SILO SUBROUTINE
 
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
;										;
;		S T U F F  N P R  S I L O					;
;										;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
; INPUTS:
 
;	THE THREE SILO WORDS MUST ALREADY BE IN RAM STARTING AT LOCATION 
;	POINTED TO BY P.SLIN.
;	SP.SUB=RETURN ADDRESS IN PAGE THREE
; OUTPUTS:
;	SILO POINTERS ARE UPDATED. IF THERE WAS A SILO OVERFLOW, BIT 15 OF
;	THE FIRST WORD IS SET TO 1.
 
STFSLO:	SP	BR,SELB,SP.SUB	;STORE  RETURN POINT.
; CHECK IF SILO IS EMPTY OR FULL
 
	LDMA	IMM,<P.SLIN>		;GET NEXT IN
	SP	MEMI,SELB,SP0		;INTO SP0
	BRWRTE	MEMX,SELB		;AND NEXT OUT INTO BRG.
	Z	30$			;SILO IS EMPTY
	COMP	BR,SP0			;NEXTIN=NEXT OUT?
	Z	40$			;YES,SILO IS FULL
 
; SILO IS NOT FULL
; INCREMENT NEXT IN BY ONE ENTRY LENGTH
10$:
	LDMA	IMM,<P.SLIN&377>	;MAR=ADDRESS OF NEXT IN POINTER
	BRWRTE	IMM,SILOED		;OFFSET OF LAST ENTRY
	COMP	BR,SP0			;NEXT IN=LAST ENTRY IN SILO?
	Z	20$			;YES,WRAP NEXT IN
	BRWRTE	IMM,SENTRY		;BR=ONE ENTRY SIZE
	MEM	BR,<ADD!SP0>		;INCREMENT P.SLIN BY ONE ENTRY SIZE
	RTNSUB	SP.SUB,P3		;RETURN
 
; WRAP NEXT IN
20$:	MEM	IMM,P.NPR			;SET NEXT IN=P.NPR
	RTNSUB	SP.SUB,P3

; SILO IS EMPTY,SET NEXT OUT=NEXT IN
 
30$:	MEM	BR,<SELA!SP0>		;STORE NEXT IN P.SLOT
	ALWAYS	10$			;STORE ONE ENTRY
 
; SILO IS FULL, SET ERROR BIT IN CURRENT NEXT IN RAM LOCATION
 
40$:	LDMA	SELA,SP0		;ADDRESS FIRST BYTE OF SILO ENTRY
	MEM	IMM,200			;LOAD ERROR BIT INTO IT
	RTNSUB	SP.SUB,P3		;RETURN
	.SBTTL	BASEIN-BASE IN SERVICE ROUTINE
 
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
;									;
;			B A S E  I N					;
;									;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
; INPUTS:
;	CSR3			= LINE NUMBER
;	CSR4,CSR5,CSR7 7:6	= MEMORY STORAGE TABLE ADDR. IF LINE#=0
;	CSR6 7:3,CSR7 4:0	= CSR# OF DZ-11 FOR THE CURRENT LINE
; OUTPUTS:
;	THE DZ-11 CORRESPONDING TO THE CURRENT LINE NUMBER IS CLEARED
;	AND ITS MASTER SCANNER STARTED. CSR NUMBER OF THR DZ-11 IS
;	STORED IN RAM.
;	IF THE LINE NUMBER SUPPLIED IS ZERO, ADDRESS OF MEMORY STORAGE
;	TABLE IS STORED IN RAM. THE DELAY TABLE IS BUILT WITHIN THE
;	MEMORY STORAGE AREA SUPPLIED.
; PERFORMANCE:
;	WORST CASE EXECUTION TIME = (TO BE DETERMINED)
 
BASEIN:
 
;ADDRESS RAM LOCATION OF DZ-11 CSR
	LDMAP	IMM,P.PLST
	LDMA	BR,<SELA!SP17>

; SAVE CURRENT DZ-11 CSR# IN RAM, OUT BA AND IN BA
 
	SP	IBUS,PORT3,SP1,INCMAR ;LOAD CSR#7:0 INTO SP1
	BRWRTE	IMM,370,INCMAR ; MASK TO STRIP 3 LSB'S OF CSR# 
	MEM	BR,AANDB,SP1	; STRIP LSB'S & STORE IN RAM
	OUTPUT	MEMX,SELB,IBA1 ; STORE IN INBA7:0
	OUTPUT	MEMI,SELB,OBA1 ;STORE IN OUTBA 7:0 & INC. MAR
 
	SP	IBUS,PORT4,SP0	;LOAD  CSR#15:8 INTO SP0
	BRWRTE	IMM,340		;MASK TO SET 3 MSB'S TO 1'S
	MEM	BR,<AORB!SP0>	;SAVE IT IN RAM WITH HIGH ORDER BITS
 
	OUTPUT	MEMX,<SELB!IBA2>	;STORE IT IN INBA 15:8
	OUTPUT	MEMX,<SELB!OBA2>	;STORE IT IN OUTBA 15:8
; INBA 15:0 AND OUTBA 15:0 ARE NOW SET TO DZ-11 CSR#
 
; EXTENDED ADDRESS BITS SET IN RQICLR
; CLEAR DZ-11 AND START ITS MASTER SCANNER
; FOLLOWING PORTION OF THE CODE IS NOT OPTIMIZED FOR PERFORMANCE IN
; ORDER TO SAVE CRAM RESOURCES. EVENTHOUGH IT TAKES 15 MICRO SECS
; FOR THE DZ-11 TO CLEAR ITSELF, THE WAIT LOOP HERE IS NOT EXPECTED TO
; ADVERSELY AFFECT THE PERFORMANCE SINCE THERE WILL BE A MAXIMUM
; OF ONLY  SIX(ONE FOR EACH DZ-11) BASE IN'S PER COMIOP.
 
	BRWRTE	IMM,DZCLR	;OUTDATA=CLEAR DZ BIT
	OUTPUT	BR,<SELB!OUTDA1>
 
; START DATOB NPR
	BRWRTE	IMM,DATOB	;BYTE OUT NPR 
	OUT	BR,<SELB!ONPR>	;START NPR
 
; WAIT FOR NPR TO COMPLETE
10$:	BRWRTE	IBUS,NPR	;NPR REG--->BR
	BR0	10$		;WAIT TILL NPR IS COMPLETE

; NOW WAIT FOR CLEAR TO COMPLETE
15$:	BRWRTE	IBUS,UBBR
	BR4	20$
	ALWAYS	15$

; NOW POLL DZ-11 TO SEE IF CLEAR IS FINISHED(IT TAKES ABOUT 15 USECS)
20$:
	BR0	RQICL2		;IF NXM SET SKIP THE REST AND GO BACK TO
				;PROCESS THE ERROR
	BRWRTE	IMM,DZSCN	;DZ-11 MASTER SCAN BITS
	OUTPUT	BR,<SELB!OUTDA1>;INTO OUTDATA
	BRWRTE	IMM,<DATI!14>	;START WORD IN NPR WITH EXT INBA SET TO 1'S
	OUT	BR,<SELB!ONPR>
 
; WAIT FOR NPR TO COMPLETE
25$:	BRWRTE	IBUS,NPR	;WAIT FOR NPR COMPLETTION
	BR0	25$
 
	BRWRTE	IBUS,INDAT1	; LOAD INDATA LB IN BR
	BR4	15$		;CLEAR IN PROGRESS,WAIT
	BRWRTE	IMM,DATOB	;SET MASTER SCANNER
 
; START DATOB NPR
	OUT	BR,<SELB!ONPR>	;START BYTE OUT NPR
 
;WAIT FOR NPR TO SET MASTER SCAN TO COMPLETE
30$:	BRWRTE	IBUS,NPR
	BR0	30$
 
;CHECK TO SEE IF BASE IN CONTAINS MEMORY STORAGE TABLE ADDRESS
 
	BRWRTE	BR,DECA,SP1	;DECREMENT IMAGE OF PORT3 SAVED FROM ABOVE
	BR0	BASEXT		;IF BIT 0 WAS CLEAR THEN THE DEC WILL SET IT
				;OTHERWISE IT WAS SET
; SAVE MST ADDRESS IN RAM
 
	LDMA	IMM,<P.MSTA&377>	;SET MAR TO MST STORAGE AREA
	BRADDR	BASEXT		;SHIFT EX.MEM. BITS, THEN EXIT.
XMSHFT:	SP	BR,SELB,SP.SUB
	MEMINC	IBUS,PORT1	;STORE LOW BYTE OF MST ADDRESS
	MEMINC	IBUS,PORT2	;STORE HIGH BYTE OF MST ADDRESS
 
; STORE EXTENDED ADDRESS
 
	BRWRTE	IBUS,PORT4	;GET EXTENDED ADDRESS BITS.
	SP	IMM,300,SP0	;MASK TO ISOLATE EXT ADDR BITS
	BRWRTE	BR,<AANDB!SP0>	;STRIP UNWANTED BITS
	BRSHFT			;SHIFT IT FOUR TIMES SO THAT THE
	BRSHFT			;EXT BITS ARE ALIGNED WITH EXT
	BRSHFT			;BITS IN NPR & BUS REQ.
	BRSHFT			;REGISTERS
	MEM	BR,<SELB>	;SAVE IT IN RAM
 
	RTNSUB	SP.SUB,P1
	.ENABL	LSB
	.SBTTL	INCIN/INCINH - EIGHTEEN BIT ADD TO INPUT ADDRESS
;+
; **INCIN/INCINH-ROUTINE TO DO 18 BIT TO THE INPUT ADDRESS**
;
; CALLING SEQUENCE:
;	CALLSB	SP.SUB,INCIN,ADDEND	;ADD "ADDEND" TO IN BA AND DO
;					;AN NPR WITH BUS HOLD CLEAR
;	CALLSB	SP.SUB,INCINH,ADDEND	;ADD "ADDEND TO IN BA AND DO
;					;AN NPR WITH BUS HOLD SET
;
; INPUTS:
;	INPUT BUFFER ADDRESS MUST BE SET UP IN THE I/O BUS INCLUDING
;	THE EXTENDED MEMORY BITS IN THE NPR CONTROL REGISTER
;
;	BRG = ADDEND
;
; OUTPUTS:
;	THE INPUT ADDRESS IS INCREMENTED BY THE BRG CONTENTS, THE NPR IS STARTED
;	AND THE ROUTINE WAITS FOR IT TO COMPLETE.
;-
INCIN2:	SP	BR,SELB,SP.SUB	;STORE RETURN POINT.
	BRWRTE	IMM,2		;READ IN NEXT WORD FROM CORE.

INCIN:	SP	IBUS,IIBA1,SP0	;GET THE CURRENT LOW BYTE OF THE INPUT ADDRESS
	OUTPUT	BR,<ADD!IBA1>	;NEW LOW BYTE OF INPUT ADDRESS
	SP	IBUS,IIBA2,SP0	;GET THE HIGH BYTE OF THE INPUT ADDRESS
	OUTPUT	BR,<APLUSC!IBA2> ;ADD ANY CARRY FROM PREVIOUS ADD TO HIGH BYTE
	SP	IBUS,NPR,SP0	;GET PREVIOUS NPR REGISTER CONTENTS
	C	50$		;A PLUS C CAUSED A CARRY TO EXTENDED MEMORY BITS
30$:	BRWRTE	IMM,14		;MASK TO CLEAR EXT. MEM. BIT OVERFLOW
	SP	BR,AANDB,SP0	;MASK OFF UNWANTED BITS
	OUT	BR,<INCA!ONPR>	;WRITE THE NPR REGISTER AND START THE NPR
40$:	BRWRTE	IBUS,NPR	;READ THE NPR CONTROL REGISTER
	BR0	40$		;WAIT FOR THE NPR TO FINISH
	RTNSUB	SP.SUB,P3	;RETURN TO CALLER
 
50$:	BRWRTE	IMM,4		;VALUE TO ADD TO INCREMENT EXTENDED MEMORY
	SP	BR,ADD,SP0	;ADD ANY CARRY FROM HIGH BYTE ADD AND SET NPR REQUEST
	ALWAYS	30$		;BRANCH TO COMMON CODE
	.DSABL	LSB
	.SBTTL	INCOUT/INCOUH/INCOB/INCOBH-OUT NPR TO CURRENT ADDRESS+OFFSET
 
 
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;									;
;		INCREMENT OUTBA AND OUTPUT  SUBROUTINE			;
;									;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **
 
; INPUTS:
;	BR	=INCREMENT
;	SP.SUB	=RETURN ADDRESS
;	FOUR ENTRY POINTS INCOUT,INCOUH,INCOB,INCOBH
 
; OUTPUTS:
;	THE DEVICE ADDRESS (OUT BA 17:0) FOR AN OUT NPR OPERATION
; IS INCREMENTED BY A FACTOR EQUAL TO THE CONTENTS OF BR.
; THEN A BYTE OR WORD TRANSFER WITH OR WITHOUT BUSHOLD IS PERFORMED DEPENDING
; ON THE ENTRY POINT.
; RETURNED TO THE ADDRESS IN CURRENT PAGE SPECIFIED BY SP.SUB
; 
; REGISTERS USED:
;	BR,UBBR,SP0,SP1,SP.SUB
; 
; REGISTERS DESTROYED (OR CHANGED)
;	BR,UBBR,SP0,SP1
; 
; ENTRY POINT TO DO BYTE NPR (ALWAYS ADDS TWO)
INCOB:	SP	BR,SELB,SP.SUB	;STORE RETURN POINT.
	BRWRTE	IMM,2		;WRITE OUT LAST BYTE TO CORE.
	SP	IMM,DATOB,SP1	;MASK FOR BYTE TRANSFER
	ALWAYS	INCOT1		;COMMON CODE
 
; ENTRIES TO DO WORD TRANSFER

INCOU2:	SP	BR,SELB,SP.SUB	;STORE RETURN POINT.
	BRWRTE	IMM,2		;WRITE OUT NEXT WORD TO CORE.
	ALWAYS	INCOT0

INCOUT:
	BRWRTE	IBUS,UBBR	;SAVE XX4 AND NXM.
	SP	IMM,101,SP1
	BRWRTE	BR,<AANDB!SP1>
	OUT	BR,<OBR!AORB!SP0> ;STORE EX.MEM. BITS IN OBR.

	BRWRTE	BR,<SELA!SP.COR> ;GET CORE OFFSET VALUE.
INCOT0:	SP	IMM,DATO,SP1	;MASK TO DO WORD TRANSFER.
INCOT1:				;INCREMENT VALUE IS IN BR.
; INCREMENT OUTBA 7:0
 
	SP	IBUS,IOBA1,SP0	;READ OUTBA7:0 INTO SP0
	OUTPUT	BR,<ADD!OBA1>	;ADD INCREMENT AND RESTORE (SP0 SELECTED)
 
; INCREMENT OUTBA 15:0
 
10$:	SP	IBUS,IOBA2,SP0	;READ OUTBA15:8 INTO SP0
	OUTPUT	BR,<APLUSC!OBA2> ;ADD CARRY TO OUTBA15:8(SP0 SELECTED)
	C	30$		;CARRY,INCREMENT EXTENDED ADDRESS
;NOW DO THE NPR
40$:
	SP	IBUS,NPR,SP0	;GET NPR REGISTER INTO SP0
	BRWRTE	IMM,155		;STRIP NPR CONTROL BITS
	BRWRTE	BR,<AANDB!SP0>	;SAVE RESULTS IN BR
	BRWRTE	BR,<AORB!SP1>	;OR IN THE NEW NPR CONTROL BITS
	OUT	BR,<SELB!ONPR>	;LOAD THE NEW BYTE INTO NPR REGISTER
50$:	BRWRTE	IBUS,NPR	;WAIT FOR NPR TO COMPLETE
	BR0	50$

	RTNSUB	SP.SUB,P3
; 
; INCREMENT OUTBA 17:16
; 
30$:	SP	IBUS,UBBR,SP0	;LOAD UBBR INTO SP0
	BRWRTE	IMM,4		;ADD ONE TO EXT. ADDRESS
	SP	BR,ADD,SP0	
	BRWRTE	IMM,115		;MASK TO SET CLOCK BIT=0
	OUT	BR,<AANDB!OBR>	;STORE UPDATED VALUE INTO UBBR
	ALWAYS	40$		;NPR AND RETURN
	.SBTTL	CONIN-CONTROL IN SERVICE ROUTINE
 
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
;									;
;			C O N T R O L  I N				;
;									;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
; STORE MODE TABLE ADDRESS IN RAM
 
CONIN:
 
; P.LTA NOW CONTAINS THE CORE ADDRESS OF CURRENT LINE TABLE
; SP.RM0,SP.RM1 CONTAIN THE RAM ADDRESS OF CURRENT LINE TABLE
 
	BRWRTE	IMM,L.MODE	;SET MAR TO RAM ADDRESS OF LINE TABLE
	LDMA	BR,<ADD!SP.RM0>
	BRADDR	5$		;MOVE EX.MEM. BITS TO 2&3.
	ALWAYS	XMSHFT

;DZ11'S CSR WAS STORED IN OUTBA IN RQICLR.
; OUTBA IS NOW POINTING TO CURRENT DZ-11 CSR, NOW ISOLATE LINE SPEED
 
5$:	SPBR	IBUS,PORT4,SP0	;LINE SPEED INTO SP0
	BR4	10$		;SET A SPEED.
	ALWAYS	20$

10$:	BRWRTE	IMM,37		;STRIP EXTRANEOUS BITS.
	SP	BR,AANDB,SP0
	BRWRTE	BR,AXORB!SP0	;COMPLEMENT RESULTS.
	BRSHFT			;HALF TIMER SPEED.
	LDMAP	IMM,P.PLST	;SET UP POLLING TABLE
	LDMA	BR,<SELA!SP17>
	SP	BR,SELB,SP1	;SAVE CALCULATED POLLING RATE
	NODST	MEMX,SUB,SP1	;SUBTRACT CURRENT RATE FROM CALCULATED
	C	20$		;CURRENT IS GREATER, LEAVE ALONE
	MEM	SELA,SP1	;OTHERWISE USER FASTER RATE
20$:	OUTPUT	BR,<SELA!OUTDA2> ;WRITE OUT SPEED.

; PROCESS STOP CODE , PARITY ENABLE, PARITY SELECT AND LINE#
 
	BRWRTE	IMM,7		;STRIP UNWANTED BITS
	BRWRTE	BR,<AANDB!SP.LN>
	SP	IBUS,PORT3,SP0	;GET LINE FLAGS
	OUTPUT	BR,<AORB!OUTDA1>  ;STORE FLAGS ,LINE # ETC IN OUTDATA LB
; WRITE IT INTO DZ-11 CSR+2 (IE ITS LINE PARAMETER REGISTER)
	BRADDR	RQICL3
	ALWAYS	INCOU2
	.SBTTL	BAIN-BUFFER ADDRESS IN SERVICE ROUTINE
 
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
;										;
;	B U F F E R  A D D R E S S  I N  S E R V I C E  R O U T I N E		;
;										;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
BAIN:
 
; SP.RM0,SP.RM1 NOW CONTAINS RAM TABLE ADDRESS OF CURRENT LINE
; THE BRG CONTAINS THE IMAGE OF OCON
; CHECK IF IT IS A READ OR WRITE
	BRSHFT			;SHIFT THE I/O BIT INTO POSITION 1
	BR1	BAREAD		;BUFFER ADDRESS IN FOR READ

; BUFFER ADDRESS IN FOR A WRITE (TRANSMIT)
 
BAWRIT:	BRWRTE	IMM,C.CLOX	;STORE TERMINATION TYPE:
	SP	BR,SELB,SP.SAV	;XMT/CNTL OUT
	BRWRTE	IMM,C.XDP	;STORE POINTER TO CORE TRANSMIT AREA.
	SP	BR,SELB,SP.COR
	BRWRTE	IMM,L.XBD	;STORE FULL POINTER TO TRANSMIT
RANDX:	BRWRTE	BR,ADD,SP.RM0	;AREA OF RAM IN CURRENT
	SP	BR,SELB,SP.CRM	;RAM REGISTER.

	BRWRTE	IMM,L.XBDF-L.XBD ;STORE POINTER TO RAM FLAGS.
	LDMA	BR,ADD,SP.CRM	;POINT TO BUFFER FLAGS WORD.
 
; CHECK FOR A KILL COMMAND
	BRWRTE	IBUS,PORT4
	BR4	KILLAL		;KILL ALL
 
; STORE BUFFER DESCRIPTOR LIST ADDRESS 15:0 IN OUTDATA
 
BAIN0:	OUTPUT	IBUS,PORT1,OUTDA1
	OUTPUT	IBUS,PORT2,OUTDA2
 
	BRWRTE	IMM,L.XBDF-L.XBDC ;POINT TO FLAGS INDICATOR.
	LDMA	BR,ADD,SP.CRM

	SPBR	MEMX,SELB,SP2	;GET FLAGS.
	BR1	RQICL2		;BOTH BUFFERS IN USE.
	BR0	BASEC		;PRIMARY BUFFER IN USE.

	BRWRTE	IMM,LX.XBF+LX.PIC ;GET PRIMARY BUFFER ASSIGNED INDICATOR.
				;SET PARAMETERS IN CORE ONLY FLAG.

BACONT:	MEM	BR,AORB,SP2	;STORE NEW BUFFER ASSIGNED INDICATOR.

;ASSIGN NEW BUFFER LIST

	BRADDR	BAIN2		;STORE  OFF-PAGE RETURN POINT.
	SP	BR,SELB,SP.SUB
	BRADDR	INCOUT		;STORE ENTRY ADDRESS.
	SP	BR,SELB,SP1
	ALWAYS	ADDLTO

BAIN1: 
; STORE EXTENDED ADDRESS OF LIST INTO CORE

	SP	IBUS,PORT4,SP4	;GET EXT ADD
	BRWRTE	IMM,300		;ISOLATE EXT ADDRESS
	SPBR	BR,AANDB,SP4
	OUTPUT	BR,SELB,OUTDA1 ;STORE IT IN OUTDA1
	BRADDR	BAIN4		;SHIP IT OUT.
	ALWAYS	INCOB

BAIN3:	BRWRTE	SELA,SP2	;IS PRIMARY BUFFER BEING ASSIGNED?
	BR0	RQICL2		;NO, SECONDARY.

	BRWRTE	IBUS,OCON	;GET OUTPUT CONTROL BYTE
	BRSHFT
	BR1	BAIN5		;READ OPERATION,IDLE

	LDMA	SELA,SP.RM0
	BRWRTE	MEMX,SELB	;ECHOING IN PROGRESS?
	BR4	RQICL2		;YES.

; START TRANSMITTER IF BAIN WAS FOR TRANSMISSION
 
	BRADDR	BAIN6		;NO. START TRANSMITTER AND
	ALWAYS	K		;COMPLETE TRANSMIT SET-UP.

BAIN5:	SP	IBUS,PORT1,SP3	;STORE ADDRESS OF DESCRIPTOR
	SP	IBUS,PORT2,SP2	;INTO SCRATCH PAD REGISTERS
	CALLSR	SP.SB1,STNWD3,RQICL8 ;CALL DESCRIPTOR SET-UP ROUTINE.
 
BASEC:	BRWRTE	IMM,<C.AXLP-C.XDP> ;POINT TO ALTERNATE BUFFER AREA.
	SP	BR,ADD,SP.COR

	BRWRTE	IMM,LX.XAL	;SET ALTERNATE BUFFER ASSIGNED INDICATOR.
	ALWAYS	BACONT
 
; BUFFER ADDRESS IN FOR A READ (RECEIVE)
 
BAREAD:
	LDMAP	IMM,P.PLST	;LOAD MAR HI TO POLLING LIST PAGE
	BRWRTE	IMM,P.NRB	;OFFSET TO RECEIVE CHARACTER INDICATOR
	LDMA	BR,ADD,SP17	;POINT TO IT FOR CURRENT DEVICE
	BRWRTE	IMM,7		;MASK TO ISOLATE CHANNEL NUMBER
	BRWRTE	BR,AANDB,SP.LN	;GET IT
	SP	IMM,20,SP0	;GET MASK FOR "NO RECV BUFFER" FLAG
	SP	MEMX,AXORB,SP0	;IF THE FLAG WAS SET IT WILL BE CLEARED
				;SO THAT COMPARE BELOW WILL CHECK IF THE
				;LINE NUMBERS MATCH.
				;IF THE FLAG WAS CLEAR IT WILL BE SET
				;SO THAT THE COMPARE WILL FAIL REGARDLESS
				;OF THE LINE NUMBER - THIS INDICATES THAT
				;NO LINES ON THIS DEVICE ARE WAITING FOR
				;A RECEIVE BUFFER
	COMP	BR,SP0		;IS THIS LINE WAITING FOR A RECEIVE BUFFER?
	Z	10$		;YES
5$:	LDMAP	SELA,SP.RM1	;POINT TO PAGE WITH CURRENT LINE TABLE
	BRWRTE	IMM,L.RUBO	;POINT TO RUBOUT CHARACTER
	LDMA	BR,ADD,SP.RM0	;..
	MEM	IBUS,PORT3	;SAVE USER SUPPLIED RUBOUT CHARACTER
	BRWRTE	IMM,C.CLOR	;STORE TERMINATION TYPE IN CASE OF A KILL
	SP	BR,SELB,SP.SAV	;RCV/CNTL OUT
	BRWRTE	IMM,C.RDP	;STORE POINTER TO CORE AREA.
	SP	BR,SELB,SP.COR
	BRWRTE	IMM,L.RBD	;STORE FULL POINTER TO RECEIVE
	ALWAYS	RANDX
 
; PREPARE TO PROCESS THE PREVIOUSLY RECEIVED CHARACTER SINCE THERE IS NOW
; ONE BEING ASSIGNED
 
10$:
	MEM	IMM,0		;ASSUME THIS IS A KILL
	BRWRTE	IBUS,PORT4	;IS IT REALLY?
	BR4	5$		;YES, ALL DONE - FINISH PROCESSING THE BUFFER ASSIGN
	BRWRTE	IMM,200		;MASK TO SET CHARACTER PRESENT FLAG SO
				;POLLING LOOP WILL PROCESS IT
	MEM	BR,AORB,SP0	;SET IT
	ALWAYS	5$		;BACK TO PROCESS BUFFER ASSIGN
.PAGE
	.SBTTL	KILLAL-KILLCR-KILL I/O SERVICE ROUTINE
 
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
;										;
;			K I L L  I / O						;
;										;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
;ENTRY TO KILL ALL READ OR WRITE IO
 
KILLAL:	SP	IMM,LX.FNL,SP0	;SET "FINAL THREAD" FLAG.
	MEM	MEMX,<AORB!SP0>
	BRWRTE	IMM,LX.FNL+LX.EXM+LX.XBF ;CLEAR ALL OTHER FLAGS.
	SP	BR,SELB,SP0
	MEM	MEMX,<AANDB!SP0>

	BRWRTE	IMM,ER.KIL	;SAVE ERROR TYPE
	SP	BR,SELB,SP.CHR	;SAVE IN CHARACTER SCRATCH PAD
	BRADDR	KILLRT		;STORE RETURN POINT.
	SP	BR,SELB,SP.SB1
	ALWAYS	COMPLT		;KILL ALL BUFFERS FOR EITHER
				;TRANSMIT OR RECEIVE.

; EXIT FROM KILL PROCESSOR
 
KILLEX:
	SPBR	IBUS,PORT4,SP0	;SP0=PORT4
	BRSHFT			;BAIN WITH KILL?
	BR4	BAIN0		;YES
BASEXT:	ALWAYS	RQICL2		;NO,EXIT
.PAGE
	.SBTTL	PAGE ONE OFF-PAGE RETURNS
;	*	*	*	*	*	*
;	*	*	*	*	*	*
.PAGE
;NAME
;-----------------------------------------
;!    !    !    !    !    !    !    !    !
;!    !    !    !    !    !    !    !    !
;-----------------------------------------
;L.STS,L.SILO
;-----------------------------------------
;!ECO/!    !    !    !    !    !  SILO   !
;!FULL!    !    !    !    !    !  COUNT  !
;-----------------------------------------
;L.MODE (LM.RMD,LM.EXM)
;-----------------------------------------
;! CURRENT RCV. !    ! EX.MEM. !    !    !
;!    !MODE!    !    !  BITS   !    !    !
;-----------------------------------------
;L.XBDF
;-----------------------------------------
;!1ST !    !LAST! IN ! EX.MEM. !ALT.!XMT.!
;!CHAR!    !LINK!CORE!  BITS   !XMT.!ASN.!
;-----------------------------------------
;L.RBDF
;-----------------------------------------
;!    !BIN-!LAST!    ! EX.MEM. !ALT.!RCV.!
;!    !ARY !LINK!    !  BITS   !RCV.!ASN.!
;-----------------------------------------
;L.*BDF
;-----------------------------------------
;!1ST !BIN-!LAST! IN ! EX.MEM. !ALT.!BUF.!
;!CHAR!ARY !LINK!CORE!  BITS   !BUF.!ASN.!
;-----------------------------------------
.PAGE
	.SBTTL	ADDLT* - STORE LINE TABLE ADDRESS FOR ADDITION
;+
; THE LINE TABLE ADDRESS IS STORED IN BOTH THE INPUT AND OUTPUT
; BUS ADDRESS LOCATIONS.
; THE EXTENDED MEMORY BITS FOR OUTPUT ARE NOT STORED IN OBR,
; BUT IN SP0, TO PREVENT UNNECESSARY AND LENGTHY CALCULATIONS.
; FROM THIS CODE, CONTROL PASSES TO INCIN, INCOUT, OR INCOB, AND
; RETURNS FROM THERE.
; ON ENTRY:
;	BR - OFFSET TO ADD TO LINE TABLE ADDRESS
;		(FOR ADDLT4: BR - RETURN ADDRESS)
;	SP0 - UNDETERMINED
;	SP1 - ENTRY ADDRESS (INCIN, INCOUT, OR INCOB)
;	SP.COR - OFFSET FROM START OF CORE LINE TABLE
;		(FOR ADDLT4: SP.COR - UNDETERMINED)
;	SP.SUB - RETURN ADDRESS
; ON EXIT:
;	BR - OFFSET TO ADD TO LINE TABLE ADDRESS
;	SP0 - EX.MEM. OF LINE TABLE ADDRESS
;	SP1 - ENTRY ADDRESS (INCIN, INCOUT, OR INCOB)
;	SP.COR - OFFSET FROM START OF CORE LINE TABLE
;	SP.SUB - RETURN ADDRESS
;-
ADDLT4:	SP	BR,SELB,SP.SUB	;STORE RETURN POINT.
	BRWRTE	IMM,C.BIP+4	;STORE OFFSET FOR CORE STORAGE
	SP	BR,SELB,SP.COR	;OF STARTING COUNT VALUE.

ADDLTO:
ADDLTI:	LDMA	IMM,P.LTA	;GET ADDRESS OF LINE
	LDMAP	IMM,P.LTA	;TABLE ADDRESS.

	OUTPUT	MEMX,<SELB!IBA1> ;STORE AS INPUT ADDRESS.
	OUTPUT	MEMI,<SELB!OBA1> ;STORE AS OUTPUT ADDRESS.
	OUTPUT	MEMX,<SELB!IBA2>
	OUTPUT	MEMI,<SELB!OBA2>
	OUT	MEMX,<SELB!ONPR>
	SP	MEMX,SELB,SP0	;SAVE OUTPUT EX.MEM. BITS.
	LDMAP	BR,<SELA!SP.RM1>

	.ALWAY	BR,<SELA!SP1>,P1 ;GO TO SPECIFIED ROUTINE.
.PAGE
	.SBTTL	K & L - SUBROUTINE TO ENABLE AND DISABLE TRANSMISSION
;+
; PRIMATIVE K
; TURNS ON TRANSMIT SCANNER BIT FOR THE CURRENT LINE.
;  ENTERED WITH:
;	BR=RETURN ADDRESS
;	SP0=UNDETERMINED
;	SP1=UNDETERMINED
;	SP2=UNDETERMINED
;	SP.SUB=UNDETERMINED
;  EXITED WITH:
;	SP0=377
;	SP1=CHANNEL BIT MASK
;	SP2=2
;	SP.SUB=RETURN ADDRESS
;-
;+
; PRIMATIVE L
; TURNS OFF TRANSMIT SCANNER BIT FOR THE CURRENT LINE.
;  ENTERED WITH:
;	BR=RETURN ADDRESS
;	SP0=UNDETERMINED
;	SP1=UNDETERMINED
;	SP2=UNDETERMINED
;	SP.SUB=UNDETERMINED
;  EXITED WITH:
;	SP0=377
;	SP1=CHANNEL BIT MASK
;	SP2=202
;	SP.SUB=RETURN ADDRESS
;-
XON:	BRADDR	METATS		;TURN ON TRANSMIT INTERRUPT.

K:	SP	IMM,2,SP2	;MARK K AS SUBROUTINE.
	ALWAYS	K.L

XOFF:	BRADDR	METATS		;TURN OFF TRANSMIT INTERRUPT.

L:	SP	IMM,202,SP2	;MARK L AS SUBROUTINE.

K.L:	SP	BR,SELB,SP.SUB

	LDMAP	IMM,P.PLST	;POINT TO CSR ADDRESS
	LDMA	BR,<INCA!SP17>	;GET OFFSET TO P.CSR.
	BRWRTE	<IMM!INCMAR>,4	;STORE OFFSET TO SCANNING REGISTER.
	SP	BR,SELB,SP0	;(POINT TO CSR IN POLLING TABLE.)

	OUTPUT	MEMI,<OBA1!ADD!SP0> ;STORE ADDRESS OF SCANNING
	OUTPUT	MEMI,<SELB!OBA2> ;REGISTER FOR TRANSFER.
	BRWRTE	IMM,101		;PREPARE UBBR FOR OBR.
	SP	IBUS,UBBR,SP0
	SP	BR,AANDB,SP0
	BRWRTE	IMM,14		;SET EX.MEM. BITS.
	OUT	BR,<AORB!OBR>

	SP	IMM,1,SP1	;GET CHANNEL BIT MASK.

	BRWRTE	IMM,7		;GENERATE CHANNEL NUMBER OF
	BRWRTE	BR,<AANDB!SP.LN> ;THIS DZ11 FROM LINE NUMBER.
	SP	BR,SELB,SP0

5$:	SPBR	BR,DECA,SP0	;IS THIS LINE THE CHANNEL?
	Z	10$		;YES.
	SP	BR,TWOA,SP1	;NOT YET. SHIFT BIT IN CHANNEL
				;BIT MASK.
	ALWAYS	5$		;CONTINUE SEARCH.

10$:	NODST	BR,<TWOA!SP2>	;SET OR CLEAR SCANNER?
	C	20$		;CLEAR IT.

	MEM	MEMX,<AORB!SP1>	;SET SCAN ENABLE BIT FOR
				;THIS CHANNEL.

15$:	OUTPUT	MEMX,<SELB!OUTDA1> ;STORE NEW SCAN VALUE FOR CHANNEL.
	BRWRTE	IMM,DATOB	;START BYTE OUT TRANSFER
	OUT	BR,<SELB!ONPR>	;OF NEW SCAN VALUE.
	LDMAP	BR,<SELA!SP.RM1> ;RESTORE HIGH MAR.

16$:	BRWRTE	IBUS,NPR	;NEW VALUE STORED YET?
	BR0	16$		;NO.

	RTNSUB	SP.SUB,P3	;RETURN TO CALLER.

20$:				;GET THE COMPLEMENT
	SP	BR,AXORB,SP1	;OF CHANNEL BIT MASK.
				;(BR=377 FROM 5$.)
	MEM	MEMX,<AANDB!SP1> ;CLEAR SCAN ENABLE BIT FOR
	ALWAYS	15$		;THIS CHANNEL ONLY.
;
	.SBTTL	CARRIAGE RETURN ROUTINES
;
CARTDY:	BRADDR	OUTEST		;ECHO CARRIAGE RETURN, LINE
	ALWAYS	CARENT		;FEED, BUT DO NOT STORE CHAR.

CARRET:	BRADDR	STORE		;STORE CHAR. AFTER ECHOING
CARENT:	SP	BR,SELB,SP.SB1	;CARRIAGE RETURN, LINE FEED.
;+
; SETS UP ECHO OF CARRIAGE RETURN, AND LINE FEED.
;  ENTERED WITH:
;	SP.CHR=UNDETERMINED
;	SP0=UNDETERMINED
;	SP1=UNDETERMINED
;	SP2=UNDETERMINED
;	SP3=TRANSMIT AND ECHOPLEX/FULL DUPLEX FLAGS
;  EXITED WITH:
;	SP.CHR=0
;	SP0=377
;	SP1=CHANNEL BIT MASK
;	SP2=2
;	SP3=UNCHANGED
;	NO OTHER REGISTER CHANGED.
;  RETURNS THROUGH ECHO SUBROUTINE
;-
	BRWRTE	BR,<SELA!SP3>	;CAN AN ECHO BE PERFORMED?
	BR7	A1		;NO. LINE IS FULL-DUPLEX.
				;CONTINUE WITHOUT ECHOING.
	BR0	RET		;NO. XMIT IN PROGRESS. EXIT.

	LDMA	BR,<SELA!SP.RM0> ;SET ECHO COUNT TO TWO.
	MEMINC	IMM,221
	MEMINC	IMM,215		;STORE CARRIAGE RETURN.
	MEM	IMM,212		;STORE LINE FEED.
	ALWAYS	AA		;START SCANNER.
	.SBTTL	CNTLR - PRIMATIVE FOR CONTROL R
R:	BRWRTE	IMM,L.RBDC	;SAVE COUNT REMAINING IN BUFFER.
	LDMA	BR,<ADD!SP.RM0>
	SP	MEMI,SELB,SP0
	SP	MEMX,SELB,SP1
	BRWRTE	IMM,30		;INDICATE THAT A CONTROL R HAS
				;BEEN RECEIVED.
	ALWAYS	CNTOUT		;ISSUE A CONTROL OUT TO THIS
				;EFFECT AND EXIT.
;
	.SBTTL	CURSORS-ROUTINES TO HANDLE CURSOR RIGHT, CURSOR LEFT,
;	AND RUBOUT WITH BACKSPACING.
;
CURGHT:	BRADDR	NOSTOR		;ECHO CHARACTER FOR CURSOR
				;RIGHT, DO NOT STORE THE CHAR,
	ALWAYS	A		;THEN UPDATE COUNT AND ADDRESS.

CURLFT:	BRADDR	NXCURL		;SET BACK COUNT AND ADDRESS.
	ALWAYS	F
NXCURL:	BRADDR	OUTEST		;ECHO CURSOR LEFT CHARACTER
	ALWAYS	A		;WITHOUT STORING IT.

NXRUB:	BRADDR	OUTEST		;EXIT FROM A TO OUTEST.
	SP	BR,SELB,SP.SB1
;+
; ECHOES BACKSPACE, RUBOUT REPLACEMENT CHARACTER, AND BACKSPACE.
;  ENTERED WITH:
;	SP0=UNDETERMINED
;	SP1=UNDETERMINED
;	SP2=RUBOUT CHARACTER
;	SP3=TRANSMIT AND ECHOPLEX/FULL DUPLEX FLAGS
;  EXITED WITH:
;	NO REGISTERS CHANGED.
; RETURNS THROUGH ECHO SUBROUTINE.
;-
	BRWRTE	BR,<SELA!SP3>	;CAN AN ECHO BE PERFORMED?
	BR7	A1		;NO. LINE IS FULL-DUPLEX.
				;CONTINUE WITHOUT ECHOING.
	BR0	RET		;NO. XMIT IN PROGRESS. EXIT.

	LDMA	BR,<SELA!SP.RM0> ;SET ECHO COUNT TO THREE.
	MEMINC	IMM,222
	MEMINC	IMM,210		;STORE BACKSPACE AS FIRST
				;CHARACTER TO ECHO.
	MEMINC	SELA,SP2	;FOLLOWED BY USER RUBOUT CHARACTER
	MEM	IMM,210		;BACKSPACE AS NEXT CHARACTERS
				;TO ECHO.
	ALWAYS	AA		;START SCANNER.
.PAGE
	.SBTTL	XMTDON - TRANSMISSION COMPLETE ROUTINE
	.ENABL	LSB
;+
; START OF CHARACTER TRANSMITTED PROCESSING CODE.
; CONTROL COMES FROM IDLE LOOP.
; ENTERED WHEN THE TRANSMIT SCANNER HAS FOUND A LINE READY TO ACCEPT
; A CHARACTER FOR TRANSMISSION.
; POSSIBLE ACTIONS:
;	ECHOING OF RECEIVE CHARACTER
;	TRANSMISSION OF CHARACTER FROM TRANSMIT BUFFER
;	INSTALLATION OF TRANSMIT BUFFER FOLLOWED BY CHARACTER
;	  TRANSMISSION
;	TURNING OFF OF TRANSMIT SCANNER FOR LINE
;-
XMTDON:
	BRWRTE	IMM,L.XBDF	;OFFSET TO FLAGS BYTE
	LDMA	BR,ADD,SP.RM0	;SET MAR
	SPBR	MEMX,SELB,SP.XST	;SAVE FLAGS BYTE
	BR4	XCORE		;TRANSMIT JUST STARTING.
				;BRING BUFFER DESCRIPTOR INFO IN FROM CORE
	LDMA	BR,<SELA!SP.RM0> ;POINT TO SILO/STATUS.
	SPBR	MEMX,SELB,SP.SAV ;HOLD SILO COUNT.
;L.STS,L.SILO
;-----------------------------------------
;!ECO/!    !    !SILO!    !    !  SILO   !
;!FULL!    !    !FULL!    !    !  COUNT  !
;-----------------------------------------
;DETERMINE IF CHARACTER WAS TRANSMITTED OR ECHOED.
	BR4	50$		;YES.

;L.XBDF
;-----------------------------------------
;!1ST !    !LAST! IN ! EX.MEM. !ALT.!XMT.!
;!CHAR!    !LINK!CORE!  BITS   !XMT.!ASN.!
;-----------------------------------------
	BRWRTE	SELA,SP.XST,INCMAR	;TEST TRANSMIT STATUS
	BR0	100$		;LINE IS TRANSMITTING.
				;GO SEND NEXT CHARACTER.
	BRADDR	RET3		;TURN OFF SCANNER AND EXIT.
	ALWAYS	L

XCORE:	BRADDR	XMTDON		;STORE RETURN POINT.
	SP	BR,SELB,SP.SB1
	BRWRTE	IMM,L.XBDC	;STORE RAM POINTER OFFSET
	BRWRTE	BR,ADD,SP.RM0	;GET ADDRESS OF THIS OFFSET FOR CURRENT LINE
	SP	BR,SELB,SP.CRM	;SAVE IT
	BRWRTE	IMM,C.XDP	;STORE CORE OFFSET
	ALWAYS	XMTSRT		;READ IN BUFFER DESCRIPTOR INFO

50$:	MEMINC	BR,<DECA!SP.SAV> ;DECREMENT SILO COUNTER.
	OUT	MEMI,SELB,OUTDA1	;STORE NEXT ECHO CHARACTER
	SP	MEMI,SELB,SP0	;SAVE FOLLOWING ECHO CHARACTER IF ANY
	SP	MEMX,SELB,SP1	;AND NEXT
	LDMA	INCA,SP.RM0	;RESET TO START OF SILO
	MEMINC	SELA,SP0	;STORE POSSIBLE ECHO CHARACTERS.
	MEM	SELA,SP1

	ALWAYS	PRINT		;ECHO CHARACTER. EXIT.
.PAGE
;
;TRANSMISSION OF TRANSMIT CHARACTER.
;
100$:	SPBR	MEMX,SELB,SP0	;READ LOW ORDER COUNT
	Z	XMCNT1		;COUNT MAY HAVE GONE TO ZERO.

	MEMINC	DECA,SP0	;DECREMENT COUNT AND STORE IT BACK.
	INCMA			;POINT TO LOW ADDR BYTE

XMRET1:	SPBR	MEMX,SELB,SP0	;READ LOW ADDRESS BYTE
	OUT	BR,SELB,IBA1	;SET UP FOR INPUT TRANSFER
	MEMINC	INCA,SP0	;INCREMENT THE ADDRESS
	SP	MEMX,SELB,SP0	;GET THE HIGH ADDR BYTE
	BR0	XMCNT2		;WAS THE ORIGINAL ADDR ODD?
XMRET2:	OUT	SELA,IBA2,INCMAR	;SET UP HIGH ADDR FOR INPUT TRANSFER
				;AND SET MAR TO L.XBDF

;L.XBDF
;-----------------------------------------
;!1ST !    !LAST! IN ! EX.MEM. !ALT.!XMT.!
;!CHAR!    !LINK!CORE!  BITS   !XMT.!ASN.!
;-----------------------------------------
	BRWRTE	IMM,LX.EXM+LX.XBF
	BRWRTE	BR,<AANDB!SP.XST>
	OUT	BR,<SELB!ONPR>	;SET NPR RQ AND EX.MEM. BITS.

	BRWRTE	IMM,377-LX.FST-LX.PIC ;CLEAR FIRST CHAR. FLAG (AND
	MEMINC	BR,<AANDB!SP.XST> ;IN CORE FLAG). POINT TO L.OXC.

105$:	BRWRTE	IBUS,NPR	;IS TRANSFER COMPLETE?
	BR0	105$		;NO.

	OUT	IBUS,INDAT2,OUTDA1	;SET TO PRINT ODD CHARACTER
	BRWRTE	IBUS,IIBA1	;WORD TRANSFER? (CHANGE SET-UP?)
	BR0	PRINT		;NO, CONTINUE PROCESSING.

	MEM	IBUS,INDAT2	;YES. SAVE ODD CHARACTER.
	OUT	IBUS,INDAT1,OUTDA1	;STORE EVEN CHAR. IN OUT DATA.
.PAGE
	.SBTTL	PRINT - SUBROUTINE TO TRANSMIT CHARACTER
;+
; ROUTINE FOR SENDING A SINGLE CHARACTER OUT VIA THE DZ11.
;	OUTDA1 - CHARACTER TO TRANSMIT
;-
PRINT:	LDMAP	IMM,P.PLST	;POINT TO CSR ADDRESS.
	LDMA	BR,<SELA!SP17>


	BRWRTE	<IMM!INCMAR>,6	;STORE LOW SIXTEEN BITS FOR
	SP	<BR!INCMAR>,SELB,SP0 ;ADDRESS OF CHARACTER-
	OUTPUT	MEMI,<ADD!OBA1>	;TRANSMITTING REGISTER.
	OUTPUT	MEMX,<SELB!OBA2>

	BRWRTE	IMM,101		;PREPARE UBBR FOR OBR.
	SP	IBUS,UBBR,SP0
	SP	BR,AANDB,SP0
	BRWRTE	IMM,14		;SET EX.MEM.BITS (ALWAYS 1'S.)
	OUT	BR,<AORB!OBR>

	BRWRTE	IMM,DATOB	;SET UP FOR A BYTE
				;OUTPUT TRANSFER.
	OUT	BR,<SELB!ONPR>	;SET NPR RQ BIT.
.PAGE
	.SBTTL	RET - RETURN POINT FOR CHARACTER PROCESSING

RET:	BRWRTE	IBUS,NPR	;COMPLETE ANY PENDING
	BR0	RET		;TRANSFERS.
	ALWAYS	TIMRTN
.PAGE
XMCNT1:	MEMINC	DECA,SP0	;DECREMENT LOW BYTE.
	MEMINC	MEMX,ADD,SP0	;ADD MINUS ONE TO HIGH COUNT.
				;STORE RESULT BACK.
	Z	XMCOMP		;COUNT IS ZERO.
				;BUFFER HAS COMPLETED.

	ALWAYS	XMRET1		;GET NEXT CHARACTER.

;GET CHARACTER FROM ODD BYTE.
XMCNT2:	MEM	APLUSC,SP0	;STORE NEW HIGH BYTE.
	C	115$		;CARRY FORCES ADDITION TO
				;THE EXTENDED MEMORY BITS.
	BRWRTE	SELA,SP.XST	;READ XMIT STATUS BYTE
110$:	BR7	XMRET2		;FIRST CHARACTER FLAG SET.
				;DO NPR TO GET ODD 1ST CHAR.
				;FROM CORE.

	BRWRTE	IMM,377-LX.PIC,INCMAR	;POINT TO L.XBDF.
				;(CLEAR ANY EX.MEM. OVERFLOW.)
	MEMINC	BR,<AANDB!SP.XST> ;STORE STATUS.
	OUT	MEMX,SELB,OUTDA1	;GET CHAR. FROM ODD BYTE HOLDER.
	ALWAYS	PRINT		;CONTINUE PROCESSING.

;L.XBDF
;-----------------------------------------
;!1ST !    !LAST! IN ! EX.MEM. !ALT.!XMT.!
;!CHAR!    !LINK!CORE!  BITS   !XMT.!ASN.!
;-----------------------------------------
115$:	BRWRTE	IMM,4		;INCREMENT EX.MEM. BITS.
	SPBR	BR,ADD,SP.XST	;OVERFLOW WILL BE CLEARED.
	ALWAYS	110$
.PAGE
	.SBTTL	XMCOMP - TRANSMIT BUFFER HAS COMPLETED
;
XMCOMP:
	BRWRTE	IMM,C.BAOX	;STORE TRANSFER TYPE INDICATOR.
	SP	BR,SELB,SP.SAV
	BRWRTE	IMM,C.XDP	;STORE CORE PARAMETERS FOR FETCHING
	SP	BR,SELB,SP.COR	;A NEW DESCRIPTOR FROM CORE.
	BRWRTE	IMM,L.XBDC	;STORE RAM PARAMETERS.
	ALWAYS	H.XR		;CALL COMPLETION SUBROUTINE,
				;AND GET NEXT BUFFER, IF ANY.
				;EXIT.
	.DSABL	LSB
	.SBTTL	RCVDON - RECEPTION COMPLETION
	.ENABL	LSB
;+
; START OF CHARACTER RECEIVED PROCESSING CODE
; CONTROL COMES FROM IDLE LOOP
; ENTERED WHEN THE RECEIVER SILO HAS FOUND A CHARACTER RECEIVED
; ON A LINE.
; POSSIBLE ACTIONS:
;	DISCARDING OF CHARACTER BECAUSE THE ECHO OF A PREVIOUS
;	  CHARACTER IS STILL IN PROGRESS
;	SENDING OF RECEIVE CONTROL OUT BECAUSE:
;	  1) THE CHARACTER IS BAD
;	  2) THERE IS NO RECEIVE BUFFER ASSIGNED
;	PROCESSING OF THE CHARACTER
;-
RCVDON:	BRWRTE	IMM,160		;GET ERROR BIT MASK.
	SPBR	BR,AANDB,SP.SAV	;MASK OFF NON-ERROR BITS.
	SP	BR,SELB,SP1	;SET SP1 TO A ZERO (ASSUMING NO ERRORS)
				;IN CASE OF BINARY RECEIVE
;L.STS,L.SILO
;-----------------------------------------
;!ECO/!    !    !SILO!    !    !  SILO   !
;!FULL!    !    !FULL!    !    !  COUNT  !
;-----------------------------------------
	SPBR	MEMX,SELB,SP3	;STORE STATUS INDICATOR.
	BR4	RET		;ECHO IN PROGRESS.

	BRWRTE	BR,DECA,SP.CST	;ANY ERROR BITS SET?
	Z	4$		;NO, CONTINUE.

	BR4	1$		;YES, EITHER BIT 5 OR 6.

	BRWRTE	IMM,ER.CPE	;YES, BIT 4. SET UP "RECEIVE
	ALWAYS	3$		;CONTROL OUT, PARITY ERROR."

1$:	BRWRTE	BR,TWOA,SP.CST	;WAS BIT 6 SET?
	BR7	2$		;YES.

	BRWRTE	IMM,ER.FRE	;NO, BIT 5. SET UP "RECEIVE
	ALWAYS	3$		;CONTROL OUT, BREAK DETECTED."

2$:	BRWRTE	IMM,ER.OVR	;SET UP "RECEIVE CONTROL OUT,
3$:	SP	BR,SELB,SP.CHR	;SAVE ERROR CODE IN CHARACTER SP
	BRWRTE	IMM,C.CLOR	;CONTROL OUT CODE
	ALWAYS	H1		;POST THE COMPLETION
.PAGE
;+
; CALCULATES OFFSET FROM START OF MODE TABLE
; TO CURRENT CHARACTER OF CURRENT MODE.
; FETCHES BYTE OF NEW MODE CODE AND FUNCTION CODE
; FROM MODE TABLE IN CORE.
; STORES RESULTANT BYTE IN SP.SAV AND THE BR.
;-
4$:				;NOTE THAT SP.CST IS SP.SAV.
				;WITHOUT ERRORS, VALUE IS ZERO, FOR
				;BINARY MODE AND CARRY FROM SP0.

	BRWRTE	IMM,L.RBDF	;GET RECEPTION FLAGS.
	LDMA	BR,<ADD!SP.RM0>
	SP	MEMI,SELB,SP4

	BRWRTE	<BR!INCMAR>,<TWOA!SP4> ;BINARY MODE?
	BR7	RCVMOR		;YES. LEAVE FUNCTION CODE AS
				;ZERO. DO NO XON/XOFF PROCESSING.
;L.MODE (LM.RMD,LM.EXM)
;-----------------------------------------
;! CURRENT RCV. !    ! EX.MEM. !    !    !
;!    !MODE!    !    !  BITS   !    !    !
;-----------------------------------------
	SP	<IMM!INCMAR>,340,SP0 ;SEPARATE RECEIVE MODE FROM
	SP	MEMX,AANDB,SP0	;EX.MEM. BITS.

	SP	BR,TWOA,SP0	;MULTIPLY RECEIVE MODE BY
	SP	BR,APLUSC,SP.SAV ;FOUR.  MOVE ANY OVERFLOW
	SP	BR,TWOA,SP0	;TO SPECIAL COUNTER.
	SP	BR,TWOAC,SP.SAV

	BRWRTE	IMM,177		;GET CURRENT CHARACTER AS
	BRWRTE	BR,<AANDB!SP.CHR> ;A SEVEN-BIT INDEX.
	SP	BR,ADD,SP0	;ADD TO LOW BYTE OFFSET.
				;(THERE IS NO CARRY.)

	BRWRTE	IMM,L.MODE	;GET MODE ADDRESS FROM RAM.
	LDMA	BR,<ADD!SP.RM0>
	OUTPUT	MEMI,<ADD!IBA1!SP0> ;STORE LOW EIGHT BITS OF MODE
				;MODE TABLE ADDRESS OFFSET FOR
				;THIS CHARACTER.

	BRWRTE	MEMI,<ADDC!SP.SAV> ;GET NEXT EIGHT BITS WITH
				;ANY OFFSET.
	OUTPUT	BR,<SELB!IBA2>	;STORE NEXT EIGHT BITS.
	SP	MEMX,SELB,SP0	;SAVE OUT EX.MEM. BITS.
	C	20$		;ADD OVERFLOW TO EX.MEM. ALSO.

5$:	BRWRTE	IMM,14		;GET EX.MEM. BITS WITHOUT
	SP	BR,AANDB,SP0	;ANY MODE BITS.
;L.MODE (LM.RMD,LM.EXM)
;-----------------------------------------
;! CURRENT RCV. !    ! EX.MEM. !    !    !
;!    !MODE!    !    !  BITS   !    !    !
;-----------------------------------------
	OUT	BR,<INCA!ONPR>	;START TRANSFER.

6$:	BRWRTE	IBUS,NPR	;TRANSFER DONE YET?
	BR0	6$		;NO.

	BRWRTE	IBUS,IIBA1	;IS INFORMATION IN LOW BYTE?
	BR0	14$		;NO, IN HIGH BYTE.

	SPBR	IBUS,INDAT1,SP.SAV ;YES. REMOVE FROM LOW BYTE.
	ALWAYS	15$		;STORE MODE&FUNCTION IN SP0.

;L.MODE (LM.RMD,LM.EXM)
;-----------------------------------------
;! CURRENT RCV. !    ! EX.MEM. !    !    !
;!    !MODE!    !    !  BITS   !    !    !
;-----------------------------------------
20$:	BRWRTE	IMM,4		;ADD THE CARRY BIT TO
	SP	BR,ADD,SP0	;EX.MEM..
	ALWAYS	5$
				;GETS CURRENT RECEIVE MODE.
				;POINTS TO CORRECT LOCATION
				;IN  MODE TABLES FOR THIS
				;CHARACTER. GETS MODE&FUNCTION FROM CORE.
14$:	SPBR	IBUS,INDAT2,SP.SAV ;REMOVE FROM HIGH BYTE.
15$:	SP	IMM,340,SP0	;MASK OFF AND SAVE
	SP	BR,AANDB,SP0	;THE NEW RECEIVE MODE.

;L.MODE (LM.RMD,LM.EXM)
;-----------------------------------------
;! CURRENT RCV. !    ! EX.MEM. !    !    !
;!    !MODE!    !    !  BITS   !    !    !
;-----------------------------------------
	BRWRTE	IMM,37		;MASK OFF NEW MODE,
	SP	BR,AANDB,SP.SAV	;LEAVING THE FUNCTION CODE.
	SP	BR,SELB,SP1
	MEM	MEMX,<AANDB!SP1> ;SAVE EX.MEM. BITS.
	MEMINC	MEMX,<AORB!SP0>	;MERGE NEW AND EX.MEM..
	SP	MEMX,SELB,SP2	;SAVE RUBOUT CHARACTER JUST IN CASE

	BRWRTE	IMM,17		;REMOVE META FLAG BIT.
	BRWRTE	BR,<AANDB!SP.SAV>
	SP	BR,SELB,SP1	;SAVE FUNCTION CODE LESS META FLAG
	SP	DECA,SP1	;WAS THE FUNCTION ZERO?
	Z	XON		;YES, WAS AN X-ON
	SP	DECA,SP1	;WAS THE FUNCTION A ONE
	Z	XOFF		;YES, WAS AN X-OFF
				;OTHERWISE FALL INTO RCVMOR
.PAGE
;SP4=L.RBDF
;-----------------------------------------
;!    !BIN-!LAST!    ! EX.MEM. !ALT.!RCV.!
;!    !ARY !LINK!    !  BITS   !RCV.!ASN.!
;-----------------------------------------
;
; SP3=L.SILO
;
RCVMOR:	BRWRTE	SELA,SP4	;IS RECEIVE BUFFER ASSIGNED?
	BR0	100$		;LINE IS RECEIVING.
	LDMAP	IMM,P.PLST	;POINT TO PAGE WITH POLLING LIST
	BRWRTE	IMM,P.NRB	;OFFSET TO RECEIVE CHARACTER FLAG
	LDMA	BR,ADD,SP17	;POINT TO IT FOR CURRENT DEVICE
	SP	IMM,20,SP0	;FLAG TO STOP RECEIVE CHARACTER PROCESSING
				;ON THIS DEVICE UNTIL USER ASSIGNS A BUFFER
	MEM	MEMX,AORB,SP0	;SET IT
	SPBR	IMM,0,SP0	;INDICATE NO BUFFER ASSIGNED
	SP	BR,SELB,SP1	;FOR CHARACTER RECEIVED.
	BRWRTE	IMM,ER.NBA	;SEND CONTROL OUT TO USER.

CNTOUT:	LDMAP	IMM,P.SLIN	;POINT TO USER SILO ENTRY POINT.
	LDMA	IMM,P.SLIN
	LDMA	MEMX,SELB

	MEMINC	SELA,SP.LN	;STORE LINE NUMBER.
	MEMINC	SELA,SP0	;STORE ANY COUNT.
	MEMINC	SELA,SP1
	MEMINC	BR,SELB		;STORE ERROR TYPE.
	MEMINC	SELA,SP.CHR	;STORE CHARACTER RECEIVED.
	MEMINC	IMM,C.CLOR!200	;INDICATE A RECEIVER CONTROL OUT.

	BRADDR	IDLE3		;MAKE UP COMPLETE SILO ENTRY.
	ALWAYS	STFSLO		;EXIT.
;PROCESSING OF A NORMALLY RECEIVED CHARACTER
;L.RBDF
;-----------------------------------------
;!    !BIN-!LAST!    ! EX.MEM. !ALT.!RCV.!
;!    !ARY !LINK!    !  BITS   !RCV.!ASN.!
;-----------------------------------------
100$:	BRWRTE	IMM,L.XBDF	;POINT TO TRANSMIT FLAGS.
	LDMA	BR,<ADD!SP.RM0>
	BRWRTE	IMM,200		;CHANGE STATE OF BIT 7
	SP	BR,AXORB,SP3	;IN SCRATCH PAD 3
	SP	BR,AORNB,SP3	;SET BIT 0 (AS WELL AS 1-6)
	BRWRTE	MEMX,SELB	;TRANSMIT IN PROGRESS?
	BR0	106$		;YES. LEAVE BIT 0 ON IN SP3.
	SP	BR,DECA,SP3	;NO. TURN OFF TRANSMIT FLAG.
;+
; SP3:
;	BIT7=1 => FULL DUPLEX
;	BIT7=0 => ECHOPLEX
;	BIT0=1 => TRANSMISSION IN PROGRESS
;	BIT0=0 => NO CURRENT TRANSMISSION
;-
106$:
	BRADDR	JMPTBL
	.ALWAY	BR,<ADD!SP1>,P2	;ENTER SUBROUTINE SEQUENCE
				;USED TO PROCESS THE RECEIVED CHARACTER.
	.DSABL	LSB
.PAGE
;
;TABLE OF ACTIONS FOR CHARACTERS
;  (ENTRY 0 USED BY BINARY OPERATION)
;
JMPTBL:	ALWAYS	STORE
	ALWAYS	ECHO
	ALWAYS	CARRET
	ALWAYS	CARTDY
	ALWAYS	CURGHT
	ALWAYS	CURLFT
	ALWAYS	RUBOUT
	ALWAYS	R
	ALWAYS	OUTEST
;END OF JMPTBL
 
 
	.SBTTL	PAGE TWO OFF-PAGE RETURNS
;	*	*	*	*	*	*
KILLRT:	ALWAYS	KILLEX
RQICL8:	ALWAYS	RQICL2		;RETURN TO IDLE.
;	*	*	*	*	*	*
	.SBTTL	COMPLT - ROUTINE PROCESSES A COMPLETED BUFFER

COMP30:	SP	BR,TWOA,SP4	;MOVE RECEIVE MODE BITS
	SP	BR,TWOAC,SP4	;FROM BITS 5-7 TO BITS 0-2.
	SP	BR,TWOAC,SP4
	SP	BR,TWOAC,SP4
	BRWRTE	IMM,7		;CLEAR NON-MODE BITS.
	SP	BR,AANDB,SP4	;STORE THE RESULT
	MEM	MEMX,<AORB!SP4>	;WITH ANY META OR ERROR INDICATOR.
	ALWAYS	COMP4		;CONTINUE.

COMP40:	NODST	SELA,SP10,INCMAR
	Z	COMP6		;COUNT WENT TO ZERO. STARTING COUNT
				;IN CORE IS CORRECT.
	ALWAYS	COMP5		;STORE CORRECT COUNT.
.PAGE
	.SBTTL	RUBOUT - CHARACTER DELETION
RUBOUT:	BRADDR	NXRUB		;SET BACK COUNT AND ADDRESS.
;+
; PRIMATIVE F
; DELETES THE PREVIOUSLY ENTERED CHARACTER, IF ANY.
;  ENTERED WITH:
;	SP0=UNDETERMINED
;	SP1=UNDETERMINED
;	SP.CHR=RUBOUT CHARACTER IF ENTERED FROM "RUBOUT"
;		OTHERWISE RECEIVED CHARACTER
;	SP.COR=UNDETERMINED
;  EXITED WITH:
;	SP0=DESTROYED
;	SP1=DESTROYED
;	SP.CHR=UNCHANGED
;	SP.COR=C.BIP+4
;	NO OTHER REGISTER CHANGED.
;  RETURNS THROUGH SP.SB1
;-
F:	SP	BR,SELB,SP.SB1	;STORE RETURN LOCATION.
	BRADDR	INCIN		;FETCH THE BUFFER STARTING
	SP	BR,SELB,SP1	;COUNT FROM CORE.
	BRADDR	F1
	ALWAYS	ADDLT4
F2:	BRWRTE	IMM,L.RBDC	;POINT TO CURRENT BUFFER COUNT.
	LDMA	BR,<ADD!SP.RM0>
	SP	MEMX,SELB,SP0	;GET LOW BYTE OF CURRENT COUNT.
	BRWRTE	IBUS,INDAT1	;COMPARE LOW ORDER BYTES OF
	COMP	BR,SP0		;THE TWO COUNTS.
	Z	15$		;EQUAL.

	MEMINC	BR,<INCA!SP0>	;INCREMENT COUNT OF UNRECEIVED
	SP	MEMX,SELB,SP0	;CHARACTERS BY ONE.
	MEMINC	BR,<APLUSC!SP0>
	SP	MEMX,SELB,SP0	;DECREMENT POINTER.
	MEMINC	BR,<DECA!SP0>
	Z	20$		;BYTE UNDERFLOWED.
10$:	RTNSUB	SP.SB1,P2	;RETURN TO CALLER.

15$:	SP	<IBUS!INCMAR>,INDAT2,SP0 ;COMPARE HIGH ORDER BYTES OF
	COMP	MEMX,SP0	;THE TWO COUNTS.
	Z	OUTEST		;NOW BACK AT START OF BUFFER.

	OUTPUT	BR,<INCA!OIDAT1!SP0> ;CHANGE COMPARISON VALUE.
	ALWAYS	F2		;GO THROUGH COMPARES AGAIN.
				;THIS TIME WILL FALL THROUGH.

20$:	SP	MEMX,SELB,SP0	;DECREMENT HIGH ADDRESS.
	MEMINC	BR,<DECA!SP0>
	Z	25$		;GONE TO ZERO.
	RTNSUB	SP.SB1,P2	;RETURN TO CALLER.
;L.RBDF
;-----------------------------------------
;!    !BIN-!LAST!    ! EX.MEM. !ALT.!RCV.!
;!    !ARY !LINK!    !  BITS   !RCV.!ASN.!
;-----------------------------------------
25$:	BRWRTE	IMM,4		;DECREMENT EX.MEM.BITS.
	SP	MEMX,SELB,SP0	;NO UNDERFLOW CARE NEED
	MEM	BR,<SUB!SP0>	;BE TAKEN.
	RTNSUB	SP.SB1,P1	;RETURN TO CALLER.
.PAGE
ECHO:	BRADDR	STORE		;EXIT TO STORING THE CHARACTER
				;AFTER ECHOING THE CHARACTER.
;+
; PRIMATIVE A
; STORES CHARACTER IN RECEIVE SPECIAL ECHO BUFFER.
; STARTS TRANSMIT SCANNER FOR LINE, IF NECESSARY.
;  ENTERED WITH:
;	SP.CHR=CHARACTER TO BE TRANSMITTED
;	SP0=UNDETERMINED
;	SP1=UNDETERMINED
;	SP2=UNDETERMINED
;	SP3=TRANSMIT AND ECHOPLEX/FULL DUPLEX FLAGS
;  EXITED WITH:
;	SP.CHR=UNCHANGED
;	SP0=377
;	SP1=CHANNEL BIT MASK
;	SP2=2
;	SP3=UNCHANGED
;	NO OTHER REGISTER CHANGED.
;  RETURNS THROUGH SP.SB1
;-
A:	SP	BR,SELB,SP.SB1	;STORE RETURN POINT.

	BRWRTE	BR,<SELA!SP3>	;LINE IN ECHOPLEX MODE?
	BR7	A1		;NO, FULL DUPLEX. EXIT.
	BR0	RET		;YES, BUT TRANSMIT IS IN PROGRESS.
				;DO NOTHING.

	LDMA	BR,<SELA!SP.RM0> ;POINT TO RECEIVE ECHO COUNTER.
	MEMINC	IMM,220		;SET ECHO COUNT TO ONE.
	MEM	BR,<SELA!SP.CHR> ;STORE CHARACTER.

AA:	BRADDR	A1		;START SCANNER. EXIT TO CALLER.
	ALWAYS	K

A1:	RTNSUB	SP.SB1,P3	;EXIT.
.IIF NE	<A1-START>/1000-3	.ERROR ;PAGE 3 RELOCATION ERROR - A1
.PAGE
	.SBTTL	STORE - STORE CHARACTER IN USER-ASSIGNED BUFFER.
STORE:	BRWRTE	IMM,L.RBDA	;POINT TO RECEIVE BUFFER
	LDMA	BR,<ADD!SP.RM0> ;ADDRESS.
	OUTPUT	MEMI,<SELB!OBA1> ;STORE TRANSFER ADDRESS.
	OUTPUT	MEMI,<SELB!OBA2>

	SP	MEMX,SELB,SP0	;GET FLAGS INDICATOR.
	BRWRTE	IMM,14		;MASK OFF JUST EX.MEM. BITS.
	SP	BR,AANDB,SP0
;L.RBDF
;-----------------------------------------
;!    !BIN-!LAST!    ! EX.MEM. !ALT.!RCV.!
;!    !ARY !LINK!    !  BITS   !RCV.!ASN.!
;-----------------------------------------
	BRWRTE	IBUS,UBBR	;SAVE XX4 AND NXM BITS FROM UBBR.
	SP	IMM,101,SP1
	BRWRTE	BR,<AANDB!SP1>
	OUT	BR,<AORB!OBR>	;SEND OUT EX.MEM. BITS.

	BRWRTE	BR,<SELA!SP.CHR> ;STORE CHARACTER.
	OUTPUT	BR,<SELB!OUTDA1>
	OUTPUT	BR,<SELB!OUTDA2>

	BRWRTE	IMM,DATOB	;PERFORM A BYTE TRANSFER.
	OUT	BR,<SELB!ONPR>	;START TRANSFER.
.PAGE
	.ENABL	LSB
	.SBTTL	NOSTOR - INCREMENT BUFFER POINTER AND COUNTER.
NOSTOR:	BRWRTE	IMM,L.RBDC	;POINT TO DATA COUNTER.
	LDMA	BR,<ADD!SP.RM0>

	SP	MEMX,SELB,SP1	;GET LOW BYTE OF COUNT.
	MEMINC	BR,<DECA!SP1>	;STORE DECREMENTED COUNT.
	SP	BR,DECA,SP1	;IS THIS THE LAST CHARACTER?
	C	5$		;NO.
	MEM	MEMX,<ADD!SP1>	;ADD MINUS ONE TO HIGH BYTE.
5$:	SP	MEMI,SELB,SP0	;STORE COUNT VALUE AS FLAG.

	SP	MEMX,SELB,SP1	;INCREMENT CHARACTER POINTER.
	MEMINC	BR,<INCA!SP1>
	SP	MEMX,SELB,SP1	;GET HIGH BYTE OF MEMORY
	MEMINC	BR,<APLUSC!SP1>	;INCREMENTED.
	C	20$		;OVERFLOW. INCREMENT EX.MEM..

10$:	BRWRTE	BR,<SELA!SP0>	;GET ZERO/NON-ZERO FLAG.
	Z	ZERBUF		;COUNT GONE TO ZERO.

OUTEST:	BRWRTE	BR,<SELA!SP.SAV> ;META CHARACTER?
.IIF NE <OUTEST-START>/1000-3	.ERROR	;OUTEST AND RET3 ARE NOT ON PAGE 3
	BR4	ENDBUF		;YES.
RET3:	ALWAYS	RET		;EXIT.
;L.RBDF
;-----------------------------------------
;!    !BIN-!LAST!    ! EX.MEM. !ALT.!RCV.!
;!    !ARY !LINK!    !  BITS   !RCV.!ASN.!
;-----------------------------------------
20$:	SP	IMM,4,SP4	;INCREMENT EX.MEM. BITS.
	MEM	MEMX,<ADD!SP4>	;(CAN IGNORE BIT 4 OVERFLOW.)
	ALWAYS	10$
	.DSABL	LSB
 
; TEST FOR META ON FUNCTION 27 (CONTROL O)
 
METATS:	BRWRTE	SELA,SP.SAV	;META CHARACTER
	BR4	10$		;YES
	ALWAYS	RET		;OTHERWISE JUST RETURN
10$:	BRWRTE	IMM,ER.ABO	;PREPARE TO GIVE CONTROL OUT WITH THE ABORT CODE
	ALWAYS	CNTOUT		;POST THE COMPLETION
	.SBTTL	ZERBUF - RECEIVE BUFFER COMPLETION ROUTINE
	.SBTTL	ENDBUF - RECEIVE BUFFER COMPLETION ROUTINE
;+
; THIS CODE INITIATES THE COMPLETION PROCESSING FOR A RECEIVE
; BUFFER.  TRANSMIT BUFFER COMPLETION AND TRANSMIT BUFFER START-UP
; (AFTER CHARACTER ECHO COMPLETION) ENTER AT H.XR.
; CONTROL PASSES TO COMPLT OR TO XMTSRT.
; ON EXIT:
;	SP0 - ENTRY ADDRESS
;	SP.SB1 - RETURN ADDRESS (RET OR XRETRY)
;	SP.COR - OFFSET WITHIN CORE LINE TABLE ADDRESS
;	SP.CRM - OFFSET WITHIN RAM TABLE
;	SP.SAV - MODE TYPE:
;*  0=TRANSMIT
;*  4=RECEIVE
;*
;*  0=BA OUT
;*  1=CONTROL OUT
;*:.0=NORMAL TERMINATION
;*:.1=ERROR TERMINATION
;*
;* 10=PARITY ERROR
;* 20=FRAMING ERROR
;* 30=ABORT
;* 60=RECEIVER ERROR
;     (HARDWARE OR NO BUFFER)
;*100=NON-EXISTANT MEMORY
;*120=RECEIVE BUFFER OVERFLOW
;*130=KILL COMPLETE
;*200=META TERMINATION
;-
H.META:	BRWRTE	IMM,200!C.BAOR	;INDICATE A GOOD RECEIVE
				;BUFFER OUT ENDED BY A META-
	ALWAYS	H1		;CHARACTER.
 
ZERBUF:	BRWRTE	IMM,L.RBDC	;POINT TO CURRENT BUFFER
	LDMA	BR,<ADD!SP.RM0>	;COUNTER.
	MEM	BR,<DECA!SP0>	;STORE -2 IN LOW BYTE.

ENDBUF:	BRWRTE	IBUS,NPR	;ANY TRANSFER COMPLETE?
	BR0	ENDBUF		;NOT YET.

	BRWRTE	BR,<SELA!SP.SAV> ;RE-CHECK MODE TYPE.
	BR4	H.META		;BUFFER ENDED ON META CHARACTER.
	BRWRTE	IMM,C.BAOR	;INDICATE A GOOD RECEIVE
				;BUFFER OUT.

H1:	SP	BR,SELB,SP.SAV	;STORE RECEIVE TYPE CODE.

	BRWRTE	IMM,C.RDP	;STORE CORE RECEIVE BUFFER
	SP	BR,SELB,SP.COR	;ADDRESS.
	BRWRTE	IMM,L.RBDC	;STORE RAM RECEIVE
H.XR:	BRWRTE	BR,<ADD!SP.RM0>	;BUFFER ADDRESS IN
	SP	BR,SELB,SP.CRM	;CURRENT RAM REGISTER.

	BRADDR	RET		;STORE RETURN.
	SP	BR,SELB,SP.SB1
				;FALL INTO COMPLT TO POST COMPLETION
				;AND SET UP NEXT BUFFER
	.SBTTL	COMPLT - ROUTINE PROCESSES A COMPLETED BUFFER
;+
; PERFORMS COMPLETION AND FETCHING OF NEXT BUFFER.
;	SP0=UNDEFINED
;	SP1=UNDEFINED
;	SP2=UNDEFINED
;	SP3=UNDEFINED
;	SP4=UNDEFINED
;	SP.CRM=CURRENT RAM POINTER
;	SP.COR =CORE POINTER
;	SP.SAV=COMPLETION CODE (0=XMIT DONE, 4=RECV DONE, 5=RECV CNTRL OUT
;		1=XMIT CNTRL OUT)
;	SP.CHR=LAST CHARACTER(RECEIVE) OR ERROR CODE IF CONTROL OUT
;-
COMPLT:
;SUBROUTINE CALL:
;**	CALLSB	SP.SUB,ADDLTI(TO INCIN),@SP.COR
	BRADDR	INCIN		;REQUEST INPUT TRANSFER.
	SP	BR,SELB,SP1
	BRADDR	COMPL1		;SET UP SUBROUTINE RETURN.
	SP	BR,SELB,SP.SUB
	BRWRTE	BR,<SELA!SP.COR> ;GET OFFSET TO CORE.
	ALWAYS	ADDLTI		;CALL ROUTINE TO HAVE OFFSET ADDED
				;TO LINE TABLE ADDRESS, AND
				;START NPR IN TRANSFER FROM
				;RESULTANT LOCATION.
COMPL1:	BRWRTE	IMM,L.CURM	;SAVE CURRENT MODE VALUE.
	LDMA	BR,<ADD!SP.RM0>
	SP	MEMX,SELB,SP4
	LDMAP	IMM,P.SLIN	;POINT TO SILO INPUT AREA
	LDMA	IMM,P.SLIN	;FOR THE NEXT ENTRY.
	LDMA	MEMX,SELB

	MEMINC	SELA,SP.LN	;AND LINE NUMBER.

	MEM	IBUS,INDAT1	;STORE FIRST 16 BITS OF
	SP	MEMX,SELB,SP3	;DESCRIPTOR ADDRESS.
	OUTPUT	MEMI,SELB,OBA1
	MEM	IBUS,INDAT2
	SP	MEMX,SELB,SP2
	OUTPUT	MEMI,SELB,OBA2
;
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=CURRENT RECEIVE MODE
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;SP7=TYPE INDICATOR FLAGS
;SP10=LAST CHARACTER
.PAGE
	MEMINC	SELA,SP.CHR	;STORE ENDING CHARACTER OR ERROR CODE
	MEM	IMM,20		;ASSUME META CHARACTER BY SETTING META FLAG
	BRWRTE	SELA,SP.SAV	;META CHARACTER END BUFFER?
	BR7	COMP30		;YES.
	MEM	IMM,0		;NO META CHARACTER
COMP2:	BRWRTE	SELA,SP.CRM	;IS THIS DRIVEN BY RECEPTION?
				;(SP.CRM=SP.LN*20+7, NOT =SP.LN*20+1)
	BR1	COMP30		;YES.

COMP4:	BRADDR	1$		;GET 3RD BYTE OF DESCRIPTOR
	ALWAYS	INCIN2		;ADDRESS.
1$:	SP	IBUS,UBBR,SP0	;SAVE XX4 AND NXM.
	BRWRTE	IMM,101
	SP	BR,AANDB,SP0
	SPBR	IBUS,INDAT1,SP4  ;EX.MEM. BITS ARE IN BITS 6&7.
	BRSHFT			;MOVE EX.MEM. BITS TO 2&3.
	BRSHFT
	BRSHFT
	BRSHFT
	OUT	BR,AORB,OBR	;STORE EX.MEM. BITS IN OBR
	OUT	BR,SELB,ONPR	;AND ONPR.
	OUTPUT	IBUS,IOBA1,IBA1 ;STORE DESCRIPTOR ADDRESS
	OUTPUT	IBUS,IOBA2,IBA2 ;IN INPUT REGISTER.

	MEMINC	MEMX,AORB,SP4 ;STORE EX.MEM. BITS.
	BRWRTE	IMM,200		;OR IN READY OUT BIT
	MEMINC	BR,AORB,SP.SAV	;WITH COMPLETION CODE
;
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;SP7=UNIMPORTANT
;
	BRADDR	5$		;CALL NPR TRANSFER QUEUE.
	ALWAYS	STFSLO

5$:	LDMAP	SELA,SP.RM1	;POINT TO BUFFER COUNT.
	LDMA	SELA,SP.CRM	;GET CURRENT COUNT.

	SP	MEMI,SELB,SP7	;GET LOW BYTE OF COUNT.
	SP	MEMI,SELB,SP10	;GET HIGH BYTE OF COUNT
	SP	INCA,SP7,INCMAR	;SAVE COUNT.
	Z	COMP40		;COULD BE ZERO.

	SP	BR,APLUSC,SP10,INCMAR	;ADD CARRY FROM INCREMENTING
COMP5:
				;LOW BYTE OF COUNT.
.PAGE
;
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;SP7=LOW BYTE OF CURRENT COUNT
;SP10=HIGH BYTE OF CURRENT COUNT
;OBA=DESCRIPTOR ADDRESS
;IBA=DESCRIPTOR ADDRESS
;
	BRADDR	44$		;READ IN STARTING COUNT.
	ALWAYS	INCIN2
 
; MAR IS POINTING TO FLAGS BYTE

44$:
	BRWRTE	MEMX,SELB	;READ THE FLAGS BYTE
	BR0	45$		;THERE IS A REAL BUFFER ASSIGNED
	ALWAYS	COMP6		;NO BUFFER ASSIGNED (FROM KILL)
				;DONT WRITE A COUNT OUT
45$:	BRWRTE	SELA,SP7	;CALCULATE RECEIVED BYTE
	SP	IBUS,INDAT1,SP0 ;COUNT. STORE BACK INTO CORE.
	OUTPUT	BR,SUB,OUTDA1
	BRWRTE	SELA,SP10
	SP	IBUS,INDAT2,SP0
	OUTPUT	BR,SUBC,OUTDA2

	BRADDR	COMP6		;SEND OUT TO SECOND WORD
	ALWAYS	INCOU2		;OF DESCRIPTOR.
 
; MAR IS POINTING TO L.*BDF

COMP6: 
 
;L.*BDF
;-----------------------------------------
;!1ST !BIN-!LAST! IN ! EX.MEM. !ALT.!BUF.!
;!CHAR!ARY !LINK!CORE!  BITS   !BUF.!ASN.!
;-----------------------------------------
	BRWRTE	MEMX,SELB	;IS THIS THE FINAL DESCRIPTOR?
	BRSHFT
	BR4	50$		;YES. GET NEXT DESCRIPTOR CHAIN,
				;IF ANY.
	BRWRTE	IMM,6		;GET DESCRIPTOR OFFSET.
	ALWAYS	STNWDS		;STORE NEW DESCRIPTOR.
.PAGE
;PROCESSING FOR FINAL THREAD IN A DESCRIPTOR LINK.
;L.*BDF
;-----------------------------------------
;!1ST !BIN-!LAST! IN ! EX.MEM. !ALT.!BUF.!
;!CHAR!ARY !LINK!CORE!  BITS   !BUF.!ASN.!
;-----------------------------------------
50$:				;IS THERE AN ALTERNATE LINK
				;TO THE CHAIN?
	BR0	55$		;YES.
	MEM	IMM,0		;NO. ZERO ALL INDICATOR FLAGS.
	RTNSUB	SP.SB1,P2	;EXIT.

55$:	BRWRTE	IMM,377-LX.XAL-LX.FNL ;CLEAR FLAG FOR ALTERNATE
	SP	BR,SELB,SP0	;LINK PRESENT & LAST DESC..
	MEM	MEMX,<AANDB!SP0>

	BRWRTE	IMM,C.AXLP-C.XDP ;GET RELATIVE ADDRESS OF
	BRWRTE	BR,<ADD!SP.COR>	;DESCRIPTOR POINTER.
	SP	BR,SELB,SP.SAV	;SAVE OFFSET.
;
;SP0=UNIMPORTANT
;SP1=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP2=UNIMPORTANT
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;SP7=NEW DESCRIPTOR CORE POINTER
;SP10=UNIMPORTANT
;
;**	CALLSB	SP.SUB,ADDLTI(TO INCIN),@SP.SAV
XMTSRT:	BRADDR	INCIN		;REQUEST INPUT TRANSFER.
	SP	BR,SELB,SP1
	BRADDR	COMPL5		;SET UP SUBROUTINE RETURN.
	SP	BR,SELB,SP.SUB
	BRWRTE	BR,<SELA!SP.SAV> ;RETRIEVE CORE OFFSET.
	ALWAYS	ADDLTI		;HAVE OFFSET IN THE BR ADDED
				;TO LINE ADDRESS, AND START
				;NPR IN FROM RESULT.
COMPL5:	SP	IBUS,INDAT1,SP3	;STORE LINK STARTING
	SP	IBUS,INDAT2,SP2	;ADDRESS.

	BRADDR	60$		;READ IN EX.MEM. BITS.
	ALWAYS	INCIN2

60$:	SP	IBUS,INDAT1,SP4	;STORE FROM LOW BYTE.
	BRWRTE	IMM,0		;GET DESCRIPTOR OFFSET.
	.SBTTL	STNWDS - ROUTINE TO STORE AND START A NEW DESCRIPTOR
	.ENABL	LSB
;+
; SUBROUTINE FOR TRANSFERRING IN THE NEW DESCRIPTOR PARAMETERS
; AND STORING THEIR POINTER'S ADDRESS IN CORE.
; USED BY BOTH RECEIVE AND TRANSMIT.
; USED BY BOTH FIRST AND OTHER ENTRIES IN A LINK.
;-
;BR=0 (NEW LINK) OR 6 (NEXT ENTRY IN LINK)
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP5=CURRENT RAM POINTER (SP.CRM)
;SP6=CORE POINTER (SP.COR)
;
STNWDS:	SPBR	BR,ADD,SP3	;ADD OFFSET IN BR TO ADDRESS IN
	OUTPUT	BR,<SELB!OUTDA1> ;SP2-SP4. SAVE TO WRITE INTO
				;CORE TABLE.
	SPBR	BR,APLUSC,SP2	;ADD ANY CARRY.
	OUTPUT	BR,<SELB!OUTDA2>
	C	2$		;CARRIES INTO EX.MEM.
	ALWAYS	3$

2$:	BRWRTE	IMM,100		;ADD IN EX.MEM. INCREMENT.
	SP	BR,ADD,SP4	;(EX.MEM. IN BITS 6&7.)
.PAGE
;
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;
;	THE ADDRESS OF THE NEW CURRENT DESCRIPTOR
;	IS STORED IN CORE AT THE PRIMARY BUFFER
;	LOCATION AT C.*DP.
;
;SUBROUTINE CALL:
;**	CALLSB	SP.SUB,ADDLTO(TO INCOUT),@SP.ST
3$:	BRADDR	INCOUT		;REQUEST OUTPUT TRANSFER.
	SP	BR,SELB,SP1
	BRADDR	STRET1		;SAVE RETURN POINT.
	SP	BR,SELB,SP.SUB
	ALWAYS	ADDLTO		;HAVE OFFSET IN SP.COR ADDED
				;TO LINE TABLE ADDRESS, AND
				;START NPR OUT TRANSFER FROM
				;RESULTANT LOCATION.
STRET1:	BRWRTE	BR,<SELA!SP4>	;YES. STORE EX.MEM. BYTE AS
	OUTPUT	BR,<SELB!OUTDA1> ;DATA.
	BRADDR	STNWD3
	ALWAYS	INCOB
.PAGE
;ENTRY POINT FOR START-UP AFTER
;SETTING ON TRANSMIT SCANNER ENABLE FOR LINE.
;
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;
STNWD3:	SP	TWOA,SP4	;SHIFT EX.MEM. BITS FROM
	SP	TWOAC,SP4	;BITS 6&7 TO BITS 2&3.
	SP	TWOAC,SP4
	SP	TWOA,SP4
	SP	TWOA,SP4
;
;	READ IN BUFFER ADDRESS IN CORE
;	FROM DESCRIPTOR ADDRESS IN SP2-4.
;
	BRWRTE	SELA,SP3	;GET STARTING ADDRESS FROM
	OUTPUT	BR,SELB,IBA1	;DESCRIPTOR ADDRESS.
	BRWRTE	SELA,SP2	;HIGH BYTE
	OUTPUT	BR,SELB,IBA2
	LDMA	INCA,SP.CRM	;POINT TO ADDRESS LOCATION
	BRWRTE	INCA,SP4,INCMAR	;IN RAM.
	OUT	BR,SELB,ONPR	;START WORD IN TRANSFER.

15$:	BRWRTE	IBUS,NPR	;FIRST WORD OF DESCRIPTOR IN?
	BR0	15$		;NOT YET.

	MEMINC	IBUS,INDAT1	;YES, STORE AS NEW BUFFER
	MEM	IBUS,INDAT2	;ADDRESS.
;
;	READ IN BUFFER COUNT IN CORE
;	FROM DESCRIPTOR ADDRESS.
;
	BRADDR	20$		;POINT TO NEXT WORD OF DES-
	ALWAYS	INCIN2		;CRIPTOR, AND START TRANSFER.
20$:	LDMA	BR,<SELA!SP.CRM> ;POINT TO RAM AREA TO
				;STORE NEW BUFFER COUNT.
;SP0=UNIMPORTANT
;SP1=UNIMPORTANT
;SP2=HIGH BYTE OF DESCRIPTOR ADDRESS
;SP3=LOW BYTE OF DESCRIPTOR ADDRESS
;SP4=DESCRIPTOR ADDRESS EX.MEM. BITS
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;
	SP	IBUS,INDAT1,SP0	;STORE AS NEW BUFFER
	SP	IBUS,INDAT2,SP1	;COUNT.

	MEMINC	BR,<DECA!SP0>	;STORE COUNT (DECREMENTED BY ONE
				;FOR ALU PURPOSES).
	OUTPUT	BR,<DECA!OUTDA1> ;SAVE STARTING COUNT MINUS ONE.
	C	21$		;NO UNDERFLOW.
	SP	BR,DECA,SP1	;UNDERFLOW. CORRECT HIGH BYTE.
21$:	MEM	BR,<SELA!SP1>
	OUTPUT	MEMI,<SELB!OUTDA2> ;STORE HIGH BYTE OF COUNT.
				;STORED IN CORE ONLY ON RECEIVE SIDE.
;
;	READ IN BUFFER FLAGS AND EX.MEM. IN CORE
;	FROM DESCRIPTOR ADDRESS.
;
	BRADDR	22$		;POINT TO NEXT WORD OF DES-
	ALWAYS	INCIN2		;CRIPTOR,AND START LAST TRANSFER IN.
;INDAT1
;-----------------------------------------
;!  MODE TYPE   !    !    !    !    !MODE!
;!    !    !    !    !    !    !    !FLAG!
;-----------------------------------------
;INDAT2
;-----------------------------------------
;!FIN.!BIN-!    !    ! EX.MEM. !    !ECO-!
;!DES.!ARY !    !    !  BITS   !    !PLEX!
;-----------------------------------------
22$:
	SP	<IBUS!INCMAR>,INDAT2,SP1 ;EX.MEM. BITS AND BINARY AND
				;FINAL DESCRIPTOR FLAGS.
	BRWRTE	IMM,14,INCMAR	;MASK FOR EXTENDED MEMORY BITS
	SP	MEMX,SELB,SP0	;SAVE OLD FLAG VALUES.
	MEM	BR,AANDB,SP1
	BRWRTE	IMM,LX.XAL+LX.XBF ;SAVE BUFFER ASSIGNMENT
	SP	BR,AANDB,SP0	;VALUES FROM OLD FLAGS.
	MEM	MEMX,<AORB!SP0> ;STORE BACK WITH EX.MEM. BITS.
;L.*BDF
;-----------------------------------------
;!1ST !BIN-!LAST! IN ! EX.MEM. !ALT.!BUF.!
;!CHAR!ARY !LINK!CORE!  BITS   !BUF.!ASN.!
;-----------------------------------------
	BRWRTE	IMM,<LX.FST+LR.BNR+LX.FNL+LX.XBF>
	SP	BR,SELB,SP0	;STORE POSSIBLE FLAGS.
	BRWRTE	TWOA,SP1	;SHIFT HIGH BYTE OF DESCR FLAGS WORD LEFT
				;SETTING C BIT IF LAST DECSR FLAG WAS SET
	BR7	26$		;BINARY FLAG IS SET

	BRWRTE	IMM,377-LR.BNR	;IT IS NOT. SET NO FLAG FOR IT.
	SP	BR,AANDB,SP0
26$:	C	27$		;IS CARRY SET THEN THIS IS THE FINAL DESCR

	BRWRTE	IMM,377-LX.FNL	;OTHERWISE CLEAR THE BIT
	SP	BR,AANDB,SP0	;..
27$:	MEM	MEMX,<AORB!SP0>	;ADD IN FLAGS TO INDICATOR.
	BRWRTE	BR,<SELA!SP.CRM> ;CALLED BY RECEPTION?
				;(SP.CRM=SP.LN*20+7)
	BR1	30$		;YES.
	RTNSUB	SP.SB1,P2	;NO, TRANSMISSION.
.PAGE
;SP0=UNIMPORTANT
;SP1=CONTENTS OF INDAT2
;SP2=CONTENTS OF INDAT1
;SP5=CURRENT RAM POINTER
;SP6=CORE POINTER
;
30$:	LDMA	BR,<SELA!SP.RM0> ;POINT TO STATUS INDICATOR.
	SP	IMM,200,SP0	;START IT AS ECHOPLEX.
	MEM	MEMX,<AORB!SP0>

;L.STS,L.SILO
;-----------------------------------------
;!ECO/!    !    !SILO!    !    !  SILO   !
;!FULL!    !    !FULL!    !    !  COUNT  !
;-----------------------------------------
;INDAT2
;-----------------------------------------
;!FIN.!BIN-!    !    ! EX.MEM. !    !ECO-!
;!DES.!ARY !    !    !  BITS   !    !PLEX!
;-----------------------------------------
	BRWRTE	SELA,SP1	;FULL-DUPLEX?
	BR0	35$		;NO, ECHOPLEX.

	MEM	MEMX,AXORB,SP0	;SET FLAG TO FULL-DUPLEX.
				;TURN OFF BIT 7 SET ABOVE

35$:	BRADDR	INCOUT		;STORE STARTING RECEIVE
	SP	BR,SELB,SP1	;COUNT IN BUFFER IN PROGRESS
	BRADDR	STNWD5		;AREA IN CORE.
	ALWAYS	ADDLT4

STNWD5:	SPBR	IBUS,INDAT1,SP2	;CHANGE TO NEW MODE?
	BR0	41$		;YES.
	RTNSUB	SP.SB1,P2	;RETURN TO CALLER.
;INDAT1
;-----------------------------------------
;!  MODE TYPE   !    !    !    !    !MODE!
;!    !    !    !    !    !    !    !FLAG!
;-----------------------------------------
41$:	BRWRTE	IMM,L.CURM	;POINT TO CURRENT MODE INDICATOR.
	LDMA	BR,ADD,SP.RM0
	BRWRTE	IMM,37		;STORE MASK TO CLEAR RCV. BITS.
	SP	MEMX,SELB,SP0
	SP	BR,AANDB,SP0	;CLEAR OLD RECEIVE BITS
	BRWRTE	DECA,SP2	;CLEAR NEW MODE FLAG
	MEM	BR,AORB,SP0	;STORE NEW MODE.
	RTNSUB	SP.SB1,P2	;RETURN TO CALLER.
	.DSABL	LSB
.PAGE
	.SBTTL	NXMERR - NONEXISTENT MEMORY ERROR
;+
; **NXMERR-ROUTINE TO REPORT A NON-EXISTENT MEMORY ERROR*
;
; INPUTS:
;	SP0=IMAGE OF UBBR REGISTER
;-
NXMERR:
	BRWRTE	IMM,100		;MASK TO CLEAR NXM BIT
	OUT	BR,AANDB,OBR	;CLEAR ALL BUT XX4 BIT
	BRWRTE	IMM,ER.NXM	;GET ERROR CODE
	ALWAYS	CNTOUT		;GENERATE A CONTROL OUT
	.SBTTL	PAGE THREE OFF-PAGE RETURNS
;	*	*	*	*	*	*
BAIN2:	ALWAYS	BAIN1		;RETURN TO BUFFER ADDRESS IN ROUTINE
BAIN4:	ALWAYS	BAIN3		;RETURN TO BUFFER ADDRESS IN ROUTINE
BAIN6:	ALWAYS	BAIN5		;RETURN TO BUFFER ASSIGNMENT ROUTINE.
RQICL3:	ALWAYS	RQICL2		;RETURN TO CLEAR BSEL2.
F1:	ALWAYS	F2
IDLE3:	ALWAYS	IDLE		;RETURN TO IDLE LOOP
;	*	*	*	*	*	*
	$KDZML==.-$KDZMC+63./64.	;LENGTH OF MICROCODE IN 32. WORD BLOCKS
	.END