perm filename IOELEV.73[KL,SYS]1 blob sn#209174 filedate 1976-04-03 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00033 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002		.TITLE IOELEVEN
C00006 00003
C00009 00004
C00012 00005
C00014 00006	.IFNZ DL10P
C00018 00007	.IFNZ DTE20P
C00022 00008	.IFNZ DTE20P
C00025 00009	.IFNZ DTE20P
C00029 00010
C00031 00011
C00035 00012
C00039 00013
C00041 00014	.IFNZ DTE20P
C00044 00015	.IFNZ DL10P
C00050 00016	.IFNZ DTE20P
C00053 00017
C00057 00018
C00060 00019
C00063 00020
C00065 00021
C00069 00022
C00071 00023
C00074 00024
C00076 00025
C00079 00026
C00080 00027
C00083 00028	.IFNZ MDMP
C00085 00029
C00088 00030	.IFNZ DL10P
C00089 00031
C00091 00032
C00092 00033
C00097 ENDMK
C⊗;
	.TITLE IOELEVEN

	.SBTTL DEFINITIONS

A=%0		;TEMP/ARG/CHAR
B=%1		;TEMP/ARG
C=%2		;TEMP/ARG
D=%3		;TEMP/ARG
H=%4		;USUALLY INDEX IN HARDWARE UNIT TABLES
I=%5		;USUALLY LINE NUMBER TIMES 2
SP=%6		;STACK POINTER
PC=%7		;PROGRAM POINTER
PS=177776	;PROGRAM STATUS
SWR=177570	;SWITCHES
RTI=RTT		;11/40 HARDWARE MISFEATURE

.PRINT /MACHINE NAME = /
.TTYMAC MNAM
%TTYFLG==%TTYFLG+1
.PRINT /MNAME
/
%TTYFLG==%TTYFLG-1
.MACRO .IFM MCHN		;REFERS TO PDP11 NAME
.IF IDN MCHN,MNAM
.ENDM .IFM
.MACRO MCONDX MCHN		;REFERS TO ITS SYSTEM NAME, USUALLY THE SAME
.IF IDN MCHN,MNAM
.ENDM MCONDX
.MACRO MNAME BODY		;INSERT ITS SYSTEM NAME INTO BODY IN PLACE OF "MCHN"
.IRP MCHN,<MNAM>
BODY
.ENDM
.ENDM MNAME
.ENDM ;TTYMAC

.IFM MC-DL			;MC'S DL-10 PDP11
.MACRO MCONDX MCHN
.IF IDN MCHN,MC
.ENDM
.MACRO MNAME BODY
.IRP MCHN,<MC>
BODY
.ENDM
.ENDM MNAME

DL10P==1	;HAS DL10
DTE20P==0	;DOES NOT HAVE DTE20
NFTTY==2	;2 * # OF FIRST TTY THIS 11
NFDHTY==2	;2 * # OF FIRST TTY ON A DH11
NDHS==1		;NUMBER OF DH11'S
MDMP==1		;HAS DM11BB MODEM SCANNER
CTYIDX==LASTTY	;TTY INDEX FOR KL11 CTY
GOULDP==0	;DOESN'T HAVE GOULD LPT (ANYMORE)
MAXBSZ==250.	;MAXIMUM TYPEOUT BUFFER SIZE
.MACRO ASPIRP BODY	;DEFINE LINE NUMBERS WITH AUTOSPEED
.IRP N,<4,5,6,7>
BODY
.ENDM
.ENDM
.ENDC ;MC-DL

.IFM MC		;MC CONSOLE 11
DL10P==0	;DOES NOT HAVE DL10
DTE20P==1	;HAS DTE20
NFTTY==0	;2 * # OF FIRST TTY THIS 11
NFDHTY==2	;2 * # OF FIRST TTY ON A DH11
NDHS==0		;NUMBER OF DH11'S
MDMP==0		;NO DM11BB MODEM SCANNER
CTYIDX==0	;TTY INDEX FOR KL11 CTY (T00 = SYSTEM CONSOLE)
GOULDP==0	;DOESN'T HAVE GOULD LPT
MAXBSZ==250.	;MAXIMUM TYPEOUT BUFFER SIZE
.ENDC ;MC-DL

.IIF NDF NDHS, .ERROR MACHINE NAME NOT RECOGNIZED

.IIF NZ DL10P, .IIF Z NFTTY, .ERROR TTY # 0 DOESN'T WORK WITH DL10 PROTOCOL

NCT==<16.*NDHS>+1  ;16 LINES ON EACH DH11 + 1 FOR CTY
NLTTY==NFTTY+<2*NCT> ;2 * # OF FIRST TTY NOT THIS 11
LASTTY==NLTTY-2	;LAST VALID TTY INDEX
CTYHWR==2*NDHS	;HARDWARE INDEX FOR KL11 CTY

;KL11 TTY

TKS=177560
		;1.1 READER ENABLE
		;1.7 INTERRUPT ENABLE
		;1.8 INPUT AVAILABLE
		;2.3 BUSY
TKB=177562
		;1.1-1.8 INPUT CHARACTER
TPS=177564
		;1.3 MAINTENANCE LOOP-BACK
		;1.7 INTERRUPT ENABLE
		;1.8 OUTPUT READY
TPB=177566
		;1.1-1.8 OUTPUT CHARACTER

.IFNZ MDMP	;DM11-BB MODEM SCANNER

MDMCSR=170500
		;1.1-1.4 MODEM CHANNEL #
 MDMBSY==20	;1.5 SCAN BUSY (R.O.)
 MDMSCN==40	;1.6 SCANNER ON
 MDMIEN==100	;1.7 INTERRUPT ENABLE
 MDMDON==200	;1.8 DONE - SCANNER HAS FOUND SOMETHING
 MDMSTP==400	;1.9 STEP SCANNER TO NEXT LINE (W.O.) 1.2 USEC.
		;2.1 MAINTENANCE MODE
 MDMCLR==2000	;2.2 CLEAR RTS, DTR, SEC TX, LINE EN FOR ALL LINES (W.O.)
 MDMCSN==4000	;2.3 CLEAR SCAN - CLEAR CSR AND MODEM STATUS MEMORY (W.O.) 19 USEC
 MDM2RX==10000	;2.4 SECONDARY RECIEVE CHANGED ON SELECTED MODEM (R.O.)
 MDMCTS==20000	;2.5 CLEAR TO SEND CHANGED ON SELECTED MODEM (R.O.)
 MDMCAR==40000	;2.6 CARRIER DETECT CHANGED ON SELECTED MODEM (R.O.)
 MDMRNG==100000	;2.7 RING CHANGED ON SELECTED MODEM (R.O.)
MDMLSR=170502	;STATUS OF SELECTED LINE
 LINENB==1	;1.1 ENABLE SCANNING OF LINE
 LINDTR==2	;1.2 DATA TERMINAL READY
 LINRQS==4	;1.3 REQUEST TO SEND (FORCE BUSY ON 103E)
 LIN2TX==10	;1.4 SECONDARY TRANSMIT
 LIN2RX==20	;1.5 SECONDARY RECEIVE (R.O.)
 LINCTS==40	;1.6 CLEAR TO SEND (R.O.)
 LINCAR==100	;1.7 CARRIER DETECT (R.O.)
 LINRNG==200	;1.8 RING (R.O.)
.ENDC ;MDMP

; KW11-L LINE FREQ CLOCK

LKS=177546	;1.8 CLOCK FLAG
		;1.7 INTER ENB
HNGDLY==3*60.	;CLEAR TO SEND OFF FOR 3 SECONDS => HANGUP

.IFNZ GOULDP
;DEFINITIONS FOR GOULD LPT

GLPCSR=166000	;COMMAND STATUS REGISTER (NONSTANDARD)
 ;COMMAND CODES
 %GCFF==0	;TOP-OF-FORM COMMAND
 %GCGRF==1	;GRAPHIC MODE COMMAND
 %GCCUT==2	;CUT COMMAND (NO CUTTER ON THIS MACHINE, THOUGH)
 %GCON==3	;TURN PRINTER ON
 %GCOFF==4	;TURN PRINTER OFF
 %GCLSL==5	;LAST LINE (GRAPHIC MODE).  => 2 MORE SCAN LINES.
 %GCION==6	;INTERRUPT ON
 %GCIOF==7	;INTERRUPT OFF
 %GCADV==201	;ADVANCE ONE LINE
 ;STATUS BITS
 %GSNRD==400	;NOT READY
 %GSDON==2000	;TRANSFER COMPLETE
 %GSBSY==4000	;BUSY
 %GSVAC==10000	;VACUUM FAULT
 %GSPAP==20000	;PAPER LOW
 %GSTIM==40000	;TIMEOUT
 %GSERR==50400	;ALL ERROR BITS

GLPWC=166002	;NEGATIVE WORD COUNT REG

GLPCA=166004	;CURRENT ADDRESS REG

GLPBSZ==132.	;BUFFER SIZE (# CHARS PER LINE)

NGLPBF==7	;NUMBER OF BUFFERS
 GB.STA==0	;BUFFER STATE - DON'T CHANGE ORDER OF %GB CODES
  %GBIDL==0	;0 IDLE
  %GBMP==2	;2 ACTIVE AT M.P. LEVEL
  %GBWRT==4	;4 IN WRITE QUEUE
  %GBPI==6	;6 ACTIVE AT P.I. LEVEL
  %GBDMA==8	;8 ACTIVE AT D.M.A. LEVEL
 GB.NXT==2	;CIRC POINTER TO NEXT BUFFER
 GB.FF==4	;IF NON-ZERO, FF BEFORE THIS BUFFER
 GB.NL==6	;NUMBER OF BLANK LINES BEFORE THIS BUFFER
 GB.PNT==10	;-> NEXT BYTE TO INSERT
 GB.DAT==12	;DATA BEGINS HERE
 GB.LEN==GB.DAT+GLPBSZ	;TOTAL NUMBER OF BYTES PER BUFFER

.ENDC ;GOULDP

;STANDARD MACROS

.MACRO PUSH X
.IRP Y,<X>
	MOV Y,-(SP)
.ENDM
.ENDM

.MACRO POP X
.IRP Y,<X>
	MOV (SP)+,Y
.ENDM
.ENDM

.MACRO CALL X
	JSR PC,X
.ENDM

.MACRO RET
	RTS PC
.ENDM

.MACRO SETOM LOC
 ZZ===%COMPAT		;DON'T CARE WHETHER .+2 OR .+4 GETS STORED
 %COMPAT===0
	MOV PC,LOC
 %COMPAT===ZZ
.ENDM

.MACRO MASK LEVEL
	PUSH PS
	MOV #<LEVEL>←5,PS
.ENDM

.MACRO UNMASK
	POP PS
.ENDM

.MACRO W
.=.+2
.ENDM

.MACRO T TAG	;usage is T TAG: <crlf> STMNT
.=.-NFTTY
TAG
.=.+NFTTY
.ENDM

.MACRO CONC A,B,C,D,E,F,G
A'B'C'D'E'F'G
.ENDM

.MACRO INFORM A,B,C,D,E,F,G
.IF P1
.PRINT /A'B'C'D'E'F'G
/
.ENDC
.ENDM

.MACRO MSG X
.NCHR ZZ,↑\X\
	.WORD ZZ
	.ASCII \X\
	.EVEN
.ENDM
.IFNZ DL10P
	.SBTTL DL10 CONTROL AREA

ZZ==.
.=100000

DLXCSR: W	;DL10 11-SIDE CONTROL & STATUS REG
		;1.1-1.2 PIA
 DLXIEN=4	;1.3 ENABLE DLX11I TO INTERRUPT
 DLXEEN=10	;1.4 ENABLE ERRORS TO INTERRUPT
		;1.5 UNUSED
 DLXPRT=40	;1.6 PORT ENABLE (R.O.)
 DLXZWC=100	;1.7 CLEAR DLXWCO (W.O.)
 DLXWCO=200	;1.8 WORD COUNT OVERFLOW
 DLXZPA=400	;1.9 CLEAR DLXPAR (W.O.)
 DLXPAR=1000	;2.1 PAR ERR IN 10 MEM
 DLXZNX=2000	;2.2 CLEAR DLXNXM (W.O.)
 DLXNXM=4000	;2.3 NXM IN 10 MEM
 DLXZ10=10000	;2.4 CLEAR DLX10I (W.O.)
 DLX10I=20000	;2.5 INTERRUPT PDP10
 DLXZ11=40000	;2.6 CLEAR DLX11I (W.O.)
 DLX11I=100000	;2.7 INTERRUPT PDP11

VERS:	W	;.BYTE FIRST LINE, # OF LINES
		;SET BY -10.  USED TO CHECK CONSISTENCY.

DLXUP:	W	;SET BY 11 WHEN COMES UP, CLEARED WHEN SEEN BY 10
		;AND WHAT IF SOMEONE CLEARS CORE?? - CTL BY PORT ENABLE
DLXDWN:	W	;CLEARED BY 10 EVERY 1/2 SECOND WHILE ITS IS RUNNING


TYILIN:	W	;TYPEIN STATUS WORD - LINE NUMBER
		;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
TYICHR:	W	;TYPEIN CHARACTER - GOES WITH PRECEDING WORD

TYOSTS:	W	;STATUS WORD (OUTPUT DONE LINE #)
		;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
TYOBSZ:	W	;BUFFER SIZE FOR LINE WITH OUTPUT DINE (SET BY 11)

TYOPNT:	W	;BUFFER POINTER FOR TTY OUTPUT
		;SET BY 10
TYOCNT:	W	;BUFFER LENGTH FOR TTY OUTPUT
		;SET BY 10
TYOLIN:	W	;LINE NUMBER FOR TTY OUTPUT
		;SET BY 10, CLEARED BY 11

HNGLIN:	W	;0000NN - LINE # NN HUNG UP
		;01RTNN - LINE # NN HAS SPEED RCV=R, XMT=T (SEE TTYTYP FOR CODES)
		;SET BY 11, CLEARED BY 10 - INTERRUPTS 10

LPRLIN:	W	;LINE NUMBER FOR SETTING LINE PARAMETERS
		;SET BY 10, CLEARED BY 11
LPRLPR:	W	;DH11 LPR REGISTER FOR SETTING LINE PARAMETERS
		;SET BY 10
LPRBSZ:	W	;BUFFER SIZE FOR SETTING LINE PARAMETERS
		;SET BY 10

EXDSTS:	W	;STATUS WORD (EXAMINE/DEPOSIT 11 CORE)
		;1 = EXAMINE, 2 = DEPOSIT
		;SET BY 10, CLEARED BY 11
EXDADR:	W	;ADDRESS FOR ABOVE
		;SET BY 10
EXDDAT:	W	;DATA WORD FOR ABOVE
		;SET BY 10 (DEPOSIT) OR 11 (EXAMINE)

GLPPTR:	W	;BUFFER POINTER FOR GOULD OUTPUT
GLPCTR:	W	;NUMBER OF BYTES YET TO BE GOBBLED
GLPTER:	W	;ERROR STATUS, SET BY 11
GLPGRF:	W	;GRAPHIC MODE IF NON-ZERO, SET BY 10

TTYST:	W	;LINE# TO START OUTPUT ON (I.E. SET OUTPUT DONE)
		;SET BY 10, CLEARED BY 11
;↑ ADD MORE HERE, E.G. IMP
DLXHGH::
.=ZZ
.ENDC ;DL10P
.IFNZ DTE20P
	.SBTTL DTE20 CONTROL AREA

;LOCATIONS 400-437 ARE JUST BETWEEN US AND ITS
;LOCATIONS 440-457 ARE KNOWN ABOUT BY KLDCP ALSO

;EPTDDT==441	;START ADDRESS OF PDP10 NON TIME SHARING DDT
DTEFLG==444	;NON TIME SHARING TYPEIN/TYPEOUT DONE FLAG (SET BY 11, CLEARED BY 10)
DTEF11==450	;USED BY NON TIMESHARING TYPEIN COMMAND TO RETURN THE CHAR (SET BY 11)
DTECMD==451	;NON TIME SHARING COMMAND (SET BY 10)
;COMMANDS THAT CAN GO IN DTECMD:
 ;0-377 CHAR TO BE TYPED OUT
 %DTTYI==3400	;TYPE IN, CHAR RETURNED IN DTEF11
 %DTCLN==1001	;60 CYCLE CLOCK ON
 %DTCLF==1000	;60 CYCLE CLOCK OFF
 ;THERE ARE MILLIONS OF OTHERS, BUT WHO NEEDS 'EM?
DTECLK==445	;60 CYCLE CLOCK FLAG (SET BY 11, CLEARED BY 10)
;DTESWR==457	;SIMULATED SWITCH REGISTER (SET BY 11)

;THE FOLLOWING LOCATIONS ARE ONLY USED IN TIME SHARING AND NOT KNOWN ABOUT BY KLDCP

DTEVER==400	;I/O VERSION NUMBER.  LH=FIRST LINE #, RH=NUMBER OF LINES.
		;SET BY 10, CHECKED BY 11

DTECHK==401	;INCREMENTED BY 11 60 TIMES PER SECOND, CLEARED BY 10 EVERY 1/2 SECOND
		;USED TO CHECK THAT 10 IS GETTING INTERRUPTS OK

DTETRN==402	;DATA TRANSFER CONTROL.  SET BY 10, SETOMED BY 11 WHEN TRANSFER COMPLETE
		;THIS CONTROLS USE OF THE DTE20 "BYTE TRANSFER" FACILITY.
		;RH=ONE OF THE FOLLOWING:
 %DTTYO==1	;TELETYPE OUTPUT, LH=LINE#
 %DTETI==2	;ETHERNET INPUT
 %DTETO==3	;ETHERNET OUTPUT
 ;↑ ADD MORE LATER
DTECNT==403	;# BYTES TO TRANSFER (SET BY 10)

DTELSP==404	;LINE# TO SET SPEED OF (SET BY 10, SETOMED BY 11)
DTELPR==405	;DH11 LINE-PARAMETER-REGISTER,,BUFFER SIZE

DTEOST==406	;LINE# TO START OUTPUT ON (SET OUTPUT DONE).  (SET BY 10, SETOMED BY 11)

	;407 NOT USED

DTETYI==410	;TELETYPE INPUT
		;LH=LINE#, RH=CHAR RECEIVED.  (SET BY 11, SETOM'ED BY 10)

DTEODN==411	;TELETYPE OUTPUT DONE
		;LH=LINE#, RH=BUFFER SIZE.  (SET BY 11, SETOM'ED BY 10)

DTEHNG==412	;HANGUP/DIALIN WORD  (SET BY11, SETOM'ED BY 10)
		;LH=LINE#, 1.1-1.6 = SPEED CODES AS IN LH(TTYTYP), 2.7=1 => DIALIN

;↑ ADD MORE HERE, NOT TO EXCEED LOCATION 437
;.IFNZ DTE20P

;IOELEVEN RESIDES IN THE BOTTOM 16K OF THE CONSOLE PDP11, ALONG WITH 11DDT.
;THE UPPER 12K CONTAIN KLDCP.  THE FOLLOWING CALLS TO KLDCP ARE USED.
;THEY RETURN WITH C-BIT SET IF THEY LOSE (MICROCODE HUNG).

TENSW=EMT!145	;UPDATE LOCATION DTESWR FROM THE SWITCHES

EXAM=EMT!103	;EXAMINE PDP10 MEMORY
 ;BEFORE CALL, REGISTER A HAS ADDRESS OF 3 BYTES CONTAINING PDP10 ADDRESS (LOW BITS FIRST)
 ;AFTER CALL, REGISTER A HAS ADDRESS OF 3 WORDS CONTAINING CONTENTS (LOW BITS FIRST)

EXAMT=EMT!104	;EXAMINE PDP10 MEMORY
 ;.WORD PDP10-ADDRESS
 ;.WORD ADDRESS OF 3-WORD DATA BLOCK

DPOS=EMT!105	;DEPOSIT PDP10 MEMORY
 ;BEFORE CALL, REGISTER A HAS ADDRESS OF 3 WORDS CONTAINING CONTENTS
 ;AND REGISTER B HAS ADDRESS OF 3 BYTES CONTAINING ADDRESS

DPOST=EMT!106	;DEPOSIT PDP10 MEMORY
 ;.WORD PDP10-ADDRESS
 ;.WORD ADDRESS OF 3-WORD DATA BLOCK

D10MON=EMT!111	;DEPOSIT PDP10 MEMORY, -1
 ;.WORD PDP10-ADDRESS

$PMSG=EMT!25	;PRINT MESSAGE ON TTY
 ;.WORD ADDRESS OF ASCIZ MESSAGE

$CNTLC=100004	;JUMP HERE TO "CONTROL C" BACK TO KLDCP

;WHEN KLDCP IS IDLE, AND IN "ITS MODE", IT DOES JSR PC,3000
;WHICH CALLS IOELEVEN'S MAIN PROGRAM.  RETURN WITH "C" SET
;TO READ AND EXECUTE ONE KLDCP COMMAND LINE.  RETURN WITH "C"
;CLEAR TO PRINT KL10 HALTED OR CLOCK ERROR STOP MESSAGE.
;LOCATIONS 3004, 3006 MUST CONTAIN .RAD50/IOELEV/
;IOELEV WILL RUN ON KLDCP'S STACK.
;.IFNZ DTE20P
;INFORMATION ABOUT THE DTE20.
;EXCEPT FOR BYTE TRANSFER, WE USE THE TIME-TESTED SUBROUTINES PROVIDED BY KLDCP.

;THE INTERRUPT VECTOR IS AT 774, BUT WE CAN'T USE IT BECAUSE WOULD HAVE
;TO COORDINATE THINGS WITH KLDCP, WHICH IS OBVIOUSLY IMPOSSIBLE.

DLYCNT=174400	;2.6-2.7 UNIBUS ADDRESS EXTENSION FOR BYTE TRANSFER DMA
		;1.1-2.5 14-BIT 2'S COMPLEMENT OF NUMBER OF HALF-MICROSECONDS
		;	 TO DELAY BETWEEN PI0 INTERRUPTS IN BYTE TRANSFER

TO10AD=174420	;ADDRESS (WORD OR BYTE) OF TO-10 BYTE TRANSFER DATA

TO10BC=174414	;1.1-2.3 NEGATIVE BYTE COUNT, 2.7 LAST XFER
		;NORMALLY SET BY 10 WITH DATAO DTE,

TO11AD=174422	;ADDRESS (WORD OR BYTE) OF TO-11 BYTE TRANSFER DATA

TO11BC=174416	;1.1-2.3 NEGATIVE BYTE COUNT FOR TO-11 BYTE TRANSFER
		;2.5=1 => TO-11 TRANSFER IS 8-BIT BYTES, =0 => 16-BIT WORDS
		;2.6=1 => "ASCIZ" MODE (WHICH WE DON'T USE, OF COURSE)
		;2.7=1 => LAST XFER, UPON COMPLETION INTERRUPT BOTH 10 AND 11
		;   =0 => ONLY INTERRUPT 11.  11 CAN CHANGE TO11AD, TO11BC, CONTINUE.
		;WRITING INTO THIS REGISTER TRIGGERS OFF A TO-11 BYTE TRANSFER.
		;THE TRANSFER HAPPENS USING DMA (NPR) IN 11, PI LEVEL 0 IN 10.

STATUS=174434	;DTE20 STATUS REGISTER
  ;READS:
 %STDNI==100000	;2.7 TO10 XFER DONE WITHOUT ERROR
 %STERI==20000	;2.5 TO10 XFER ABORTED BY ERROR
 %STINV==4000	;2.3 PDP10 IS INTERRUPTING PDP11
 		;2.1 PDP11 MEMORY PARITY ERROR IN TO10 XFER
		;1.9 PDP11 IS INTERRUPTING PDP10
 %STDNO==200	;1.8 TO11 XFER DONE WITHOUT ERROR
 		;1.6 TO11 XFER STOPPED DUE TO ZERO BYTE (IN ASCIZ MODE)
		;1.5 TO11 XFER OR PDP10 EXAMINE ENCOUNTERED EBUS PARITY ERROR
		;1.4 1 => RESTRICTED MODE
		;1.3 0 => EXAMINE/DEPOSIT IN PROGRESS, 1 => DONE
 %STERO==2	;1.2 TO11 XFER ABORTED BY ERROR
		;1.1 1 => DTE ENABLED TO INTERRUPT PDP11
  ;WRITES:
 %STCLI==51000	;2.6+2.4+2.1 CLEAR TO10 XFER DONE AND ERROR FLAGS
 %STUNV==2000	;2.2 CLEAR PDP10 INTERRUPTING PDP11
 %STINX==400	;1.9 SET PDP11 INTERRUPTING PDP10
 %STCLO==121	;1.7+1.5+1.1 CLEAR TO11 XFER DONE AND ERROR FLAGS
		;1.6 ENABLE INTERRUPTS
		;1.4 DISABLE INTERRUPTS

DIAG1=174430	;DIAGNOSTIC WORD 1, INCLUDES FLAGS
 %D1ERR==4000	;2.3 KL10 CLOCK ERROR STOP
 %D1RUN==2000	;2.2 KL10 RUN INDICATOR
 %D1HLT==1000	;2.1 KL10 HALT INDICATOR

DIAG3=174436	;DIAGNOSTIC WORD 3, INCLUDES FLAGS
 %D3BYT==1	;1.1 WRITING 0 SETS TO10 XFER IN WORD MODE, 1 BYTE MODE
		;THERE'S NOTHING ELSE OF THE SLIGHTEST USE IN THIS REGISTER,
		;SO IT'S OK TO WRITE IT AT ANY TIME.
.ENDC ;DTE20P

	.SBTTL LOW CORE

.IFZ DTE20P		;IF USING DTE20, THESE ARE SET UP BY KLDCP
.=4
	TRAP4
	340
	TRAP10
	340
;	TRAP14		;SET UP BY 11DDT
;	340
.=20
	TRAP10	;IOT
	340
	PWRFAL
	340
	TRAP10	;EMT
	340
	TRAP10	;TRAP
	340
.ENDC ;DTE20P

.IFNZ MDMP
.=300
	MDMBRK	;DM11-BB
	240	;INTERRUPTS ON BR4 BUT WE MASK TO BR5 ANYWAY
.ENDC ;MDMP
.=310	
.REPT NDHS
CONC DH,\.RPCNT+1,IBK	;DH11 #n RECEIVE
	240
CONC DH,\.RPCNT+1,OBK	;DH11 #n TRANSMIT & ERROR
	240
.ENDR ;NDHS
.=60
	CTYIBK	;KL11 CTY
	240	;AGAIN INTERRUPTS ON BR4 BUT MASK TO BR5 SO CAN USE DH11 ROUTINES W/O FEAR
	CTYOBK
	240
.=100
	CLKBRK	;KW11-L 60-CYCLE CLOCK
	300	;ON BR6

.IFNZ GOULDP
.=174
	GLPBRK
	300	;BR5 BUT NEED TO LOCK OUT CLOCK SO MASK 6
.ENDC ;GOULDP

.IFZ DTE20P	;IF DTE20, KLDCP SUPPLIES THE STACK
.=1000
STKBAS::
.IFF ;DTE20P
.=3000		;ENTRY VECTOR
	JMP @#INIT
SADR=.-2		;ARG OF THE JMP@# IS CHANGED AFTER INITIALIZATION
	.RAD50 /IOELEV/
.ENDC ;DTE20P

	.SBTTL CONFIGURATION

; TABLES INDEXED BY H (PER HARDWARE UNIT)

.MACRO DHTE AD
.REPT NDHS
 <AD>+<20*.RPCNT>
.ENDR
.ENDM

DHSCR:	DHTE 160020	;SYSTEM CONTROL REGISTER
			;1.1-1.4 LINE NUMBER
			;1.5-1.6 MEMORY ADDRESS EXTENSION
 DHRENB==100		;1.7 RECEIVER INTERRUPT ENABLE
			;1.8 RECEIVER INTERRUPT
			;1.9 CLEAR NXM FLAG
			;2.1 MAINTENANCE MODE
 DHSNXM==2000		;2.2 NXM FLAG (GENERATES XMT INTERRUPT)
			;2.3 MASTER CLEAR
 DHSENB==10000		;2.4 STORAGE SILO FULL INTERRUPT ENABLE
 DHTENB==20000		;2.5 TRANSMITTER & NXM INTERRUPT ENABLE
			;2.6 STOARGE FULL INTERRUPT
 DHTDON==100000		;2.7 TRANSMITTER DONE INTERRUPT
	GARB		;FOR CTY

DHNRC:	DHTE 160022	;NEXT RECEIVED CHARACTER
			;1.1-1.8 THE CHARACTER
			;1.9-2.3 LINE NUMBER
 %DXPAR==10000		;2.4 CHAR HAS WRONG PARITY
 %DXBRK==20000		;2.5 FRAMING ERROR (BREAK)
 %DXOVR==40000		;2.6 OVERRUN, PREVIOUS CHARS LOST
			;2.7 1 => THIS WORD VALID

DHLPR:	DHTE 160024	;LINE PARAMETER REGISTER
			;1.1-1.2 CHARACTER LENGTH 0=5, 1=6, 2=7, 3=8 (PARITY BIT EXTRA)
			;1.3 1 => EXTRA STOP BIT
			;1.5 ENABLE PARITY
			;1.6 0 -> ODD PARITY, 1 => EVEN
			;1.7-2.1 RECEIVER SPEED
			; 0 OFF, 1 50, 2 75, 3 110, 4 134.5, 5 150, 6 200, 7 300
			; 10 600, 11 1200, 12 1800, 13 2400, 14 4800, 15 9600, 16 A, 17 B
			;2.2-2.5 TRANSMITTER SPEED, SAME CODES AS RECEIVER
			;2.6 HALF DUPLEX
			;2.7 ECHOPLEX

DHCA:	DHTE 160026	;CURRENT ADDRESS

DHBC:	DHTE 160030	;BYTE COUNT (MINUS)

DHBAR:	DHTE 160032	;BUFFER ACTIVE REGISTER
			;BIT = 1 IF XMT ACTIVE ON CORRESP LINE, NUMBERED RIGHT TO LEFT

DHBCR:	DHTE 160034	;BREAK CONTROL REGISTER
			;BIT = 1 => SEND BREAK ON CORRESP LINE, NUMBERED RIGHT TO LEFT

DHSSR:	DHTE 160036	;SILO STATUS REGISTER
			;1.1-1.6 SILO ALARM LEVEL
			;1.7-1.8 READ EXTENDED ADDRESS (R.O.)
			;1.9-2.5 SILO FILL LEVEL (R.O.)
			;2.7 MAINTENANCE PATTERN (W.O.)

DHOAC:	.REPT NDHS	;BIT ON IF SOFTWARE THINKS LINE'S TRANSMITTER IS ACTIVE
	 0
	.ENDR

DHTYNO:	.REPT NDHS	;TTY INDEX OF FIRST LINE ON THIS DH11
	 NFDHTY+<40*.RPCNT>
	.ENDR

CTYCA:	0		;CURRENT ADDRESS FOR CTY OUTPUT
CTYBC:	0		;POSITIVE BYTE COUNT FOR CTY OUTPUT
CTYOAC:	0		;NON-ZERO => CTY OUTPUT ACTIVE
GARB:	0		;GARBAGE WORD FOR MOV DHLSEL(I),@DHSCR(H) IN CASE OF CTY

	.BLKB NFTTY	;AVOID LABEL OVERLAPPAGE

;TABLES INDEXED BY I (PER LINE)

T HDWR:			;HARDWARE UNIT INDEX, GOES IN H
.IIF NZ DTE20P, CTYHWR	;CTY IS FIRST LINE ON DTE20
	.REPT NDHS
	 ZZ==.RPCNT*2
	 .REPT 16.
	  ZZ		;16 LINES ON EACH DH-11
	 .ENDR
	.ENDR
.IIF Z DTE20P,	CTYHWR		;CTY IS LAST LINE EXCEPT ON DTE20

T DHLSEL:		;DH11 LINE SELECT WORDS
.IIF NZ DTE20P,	0		;NONE FOR CTY
	.REPT NDHS
	 .REPT 16.
	  DHTENB+DHRENB+.RPCNT
	 .ENDR
	.ENDR
.IIF Z DTE20P,	0		;NONE FOR CTY

T DHLBIT:		;BIT CORRESPONDING TO THIS LINE IN DHBAR, ETC.
.IIF NZ DTE20P,	0		;NONE FOR CTY
	.REPT NDHS
	 .REPT 16.
	  1←.RPCNT
	 .ENDR
	.ENDR
.IIF Z DTE20P,	0		;NONE FOR CTY

T BUFPNT:		;BUFFER POINTERS
	.REPT NCT
	 BUFFRS+<.RPCNT*MAXBSZ>
	.ENDR

T BUFSIZ:		;BUFFER SIZES (I.E. AMOUNT TO USE AT CURRENT SPEED)
	.REPT NCT
	 0		;SET DURING INITIALIZATION
	.ENDR

T NRMIPC:		;NORMAL INPUT CHARACTER PROCESSING ROUTINES
.IIF NZ DTE20P, RCV	;CTY NORMAL INPUT
	.REPT 16.*NDHS
	 DHNRMI		;DH11 TTY NORMAL INPUT
	.ENDR
.IIF Z DTE20P,	RCV	;CTY NORMAL INPUT
.IIF NE .-NRMIPC-NLTTY, .ERROR BARF AT NRMIPC

T TTYIPC:		;CURRENT INPUT CHAR PROCESSING ROUTINES
	.BLKW NCT	;SET UP AT INIT TIME
.IIF NE .-TTYIPC-NLTTY, .ERROR BARF AT TTYIPC

T AUTOSP:		;IF NON-ZERO, LINE GOES INTO AUTOSPEED WHEN DIALED UP
			;IF MINUS ALSO WHEN BREAK SEEN
	.REPT NCT
	 ASPIRP ↑\
	  .IIF EQ .RPCNT+<NFTTY/2>-N, 1	;THIS LINE AUTOSPEED ON DIALUP
	  .IELSE .IIF EQ .RPCNT+<NFTTY/2>+N, -1	;ALSO ON BREAK
	  .IELSE 0	;THIS LINE NOT AUTOSPEED
\
	.ENDR
.IIF NE .-AUTOSP-NLTTY, .ERROR BARF AT AUTOSP

.MCONDX MC
M2LMAP:			;MAP FROM DM11-BB CHANNEL NUMBERS TO TTY INDICES
	2*1		;0 T01
	0		;1 NONE
	0		;2 NONE
	2*4		;3 T04
	2*5		;4 T05
	2*6		;5 T06
	2*7		;6 T07
	0		;7 NONE
	0		;10 NONE
	0		;11 NONE
	0		;12 NONE
	0		;13 NONE
	0		;14 NONE
	0		;15 NONE
	0		;16 NONE
	0		;17 NONE
.IIF NE .-M2LMAP-40, .ERROR BARF AT M2LMAP
.ENDC ;MC

T DIALED:		;0 IF LINE NOT DIALED UP (OR NO MODEM CONTROL ON THIS LINE)
	.REPT NCT	;+ IF DIALED UP (CLEAR TO SEND IS ON)
	 0		;- IF CLEAR TO SEND DROPPED, INC EACH TICK, REACHES 0 => HUNG UP
	.ENDR

;MISC VARIABLES

DLXOFF:	-1		;NON-ZERO IF DL10 PORT TURNED OFF BY 10
NO.ITS:	-1		;NON-ZERO IF HAVEN'T ESTABLISHED COMMUNICATION WITH ITS YET
VERSN:	.BYTE NFTTY/2,NCT	;I/O VERSION NUMBER
WAKE:	0		;CLOCK INTERRUPT WAKE UP MAIN PROGRAM FLAG
CLKENB:	0		;KL10 WANTS 11 TO RELAY CLOCK INTERRUPTS
KLDCPF:	0		;NON-ZERO => USER WANTS TO GIVE A COMMAND TO KLDCP

	.SBTTL RING BUFFERS

.MACRO RING SIZE
	99$		;IN-POINTER
	99$		;OUT-POINTER
	0		;NUMBER OF WORDS IN RING
	<SIZE>		;MAX NUMBER ALLOWED
	<2*<SIZE>>+99$	;MAX ADDRESS ALLOWED
	99$		;MIN ADDRESS ALLOWED
99$:	.BLKW <SIZE>	;BUFFER
.ENDM

RINGIN==0
RINGOT==2
RINGCT==4
RINGSZ==6
RINGTP==10
RINGBT==12
RINGBF==14

; DEFINE THE RING BUFFERS

TYORNG:	RING NCT	;OUTPUT-DONE RING, CONTENTS = LINE NUMBER PDP10 STYLE

HNGRNG:	RING NCT	;HANGUP RING, CONTENTS = LINE NUMBER PDP10 STYLE

TYIRSZ==NCT*4		;2 CHARS PER TTY (2 WORDS PER CHAR)
TYIRNG:	RING TYIRSZ	;TTY INPUT RING, FIRST WORD IS CHARACTER, SECOND LINE NUMBER



;MOV #RING,B
;MOV WORD,A
;CALL PUT

PUT:	CMP RINGCT(B),RINGSZ(B)
	BLT 1$
	 BPT		;BLOATED
1$:	PUSH C
	MOV RINGIN(B),C
	MOV A,(C)+
	CMP C,RINGTP(B)
	BLO 2$
	 MOV RINGBT(B),C
2$:	MOV C,RINGIN(B)
	POP C
	INC RINGCT(B)
	RET

;MOV #RING,B
;CALL GET
;WORD RETURNED IN A
; IT IS AN ERROR TO CALL THIS IF RING IS EMPTY

GET:	TST RINGCT(B)
	BGT 1$
	 BPT		;EMPTY
1$:	PUSH C
	MOV RINGOT(B),C
	MOV (C)+,A
	CMP C,RINGTP(B)
	BLO 2$
	 MOV RINGBT(B),C
2$:	MOV C,RINGOT(B)
	POP C
	DEC RINGCT(B)
	RET
.IFNZ DTE20P
	.SBTTL DTE20 SUBROUTINES

;THE DTE20 MUST NOT BE HACKED AT INTERRUPT LEVEL, BECAUSE KLDCP USES IT TOO.
;THE FOLLOWING THREE LOCATIONS ARE ARGS TO/FROM THE FOLLOWING TWO SUBROUTINES.

LH:	0	;LOW 16 BITS OF LEFT HALF
RH:	0	;LOW 16 BITS OF RIGHT HALF
SNB:	0	;SIGN BIT (0 IF +, NON-0 IF -)

;JSR B,HWEXAM
; .WORD ADDR
;EXAMINE PDP10 LOC, SPLIT INTO HALFWORDS, SET LH, RH, SNB
;RETURNS WITH "Z" SET IF LOCATION HAS POSITIVE SIGN, "Z" CLEAR IF MINUS SIGN

HWEXAM:	PUSH <A,C>	;SAVE REGS
	PUSH <#0,(B)+>	;PUT PDP10 ADDRESS ONTO PDL
	MOV SP,A	;SET UP POINTER TO ADDRESS
	EXAM		;EXAMINE LOCATION, SET A TO POINT TO 3-WORD RESULT BUFFER
	 BCS UHUNG	;BRANCH IF UCODE HUNG
	MOV (A)+,RH	;LOW 16 BITS => RH
	MOV (A)+,C	;PICK UP MIDDLE 16 BITS
	MOV (A)+,A	;PICK UP HIGH 4 BITS
	ROR A		;LSHC <A,C>,-2 TO GET PDP10 LH INTO C
	ROR C
	ROR A
	ROR C	
	MOV C,LH
	BIC #177775,A	;LEAVE SIGN BIT IN 1.2 OF A
	MOV A,SNB
	ADD #4,SP	;POP ADDRESS OFF PDL
	POP <C,A>	;RESTORE REGS
	TST SNB
	RTS B		;RETURN SKIPPING IN-LINE PARAMETER

;JSR B,HWDEP
; .WORD ADDR
;ASSEMBLE LH, RH, SNB INTO PDP10 AND DEPOSIT IN ADDR

HWDEP:	PUSH <A,B,C>
	MOV LH,C
	CLR A
	TST SNB
	BEQ 1$
	MOV #2,A
1$:	ASL C
	ROL A
	ASL C
	ROL A
	PUSH <A,C,RH>	;PUSH HIGH, MIDDLE, AND LOW BITS
	MOV SP,A	;POINTER TO DATA
	PUSH <#0,(B)>	;PUSH HIGH AND LOW ADDRESS
	MOV SP,B	;POINTER TO ADDRESS
	DPOS		;DO THE DEPOSIT
	 BCS UHUNG	;BRANCH IF UCODE HUNG
	ADD #10.,SP	;POP ADDRESS AND DATA OFF PDL
	POP <C,B,A>
	TST (B)+	;SKIP TRAILING PARAMETER
	RTS B

UHUNG:	$PMSG
	 .WORD 1$
	JMP $CNTLC

1$:	.ASCIZ/?MICROCODE HUNG/

.ENDC ;DTE20P
.IFNZ DL10P
	.SBTTL MAIN LOOP FOR DL10

MAIN:	BIT #DLX11I,DLXCSR	;10 REQUESTING SERVICE?
	BEQ 1$
	BIS #DLXZ11,DLXCSR	;YES, CLEAR FLAG
	BR 2$			;AND GO CHECK FOR THINGS TO DO

1$:	TST WAKE		;NO, CHECK ANYWAY IF 60 CYCLE CLOCK HAS TICKED
	BEQ MAIN		;NEITHER, JUST WAIT
	CLR WAKE

; CHECK UP/DOWN

2$:	BIT #DLXPRT,DLXCSR	;PORT TO 10 ENABLED?
	BNE 4$			;YES
3$:	SETOM NO.ITS		;NO, FLAG THERE IS NO ITS
	SETOM DLXOFF		;AND THAT WE THINK DL10 PORT IS OFF
	BR MAIN

4$:	TST DLXOFF		;DID DL10 JUST TURN ON?
	BEQ CHKOST
	CLR DLXOFF		;YES, SO REMEMBER THAT,
	CMP VERS,VERSN
	BEQ 5$
	BPT			;-10 AND -11 PROGRAMS NOT SAME CONFIG
5$:	SETOM DLXUP		;TELL 10 WE'RE UP
6$:	TST DLXUP		;AND WAIT FOR IT TO AGREE
	BNE 6$
	CLR NO.ITS		;NOW THERE IS AN ITS

; CHECK FOR OUTPUT-START FROM -10

CHKOST:	MOV TTYST,A		;LINE# TO START OUTPUT
	BEQ CHKOUT		;NONE.
	CLR TTYST		;TELL -10 IT'S BEEN PICKED UP
	MOV #TYORNG,B	
	CALL PUT		;PUT IN RING, LATER WILL SEND IT BACK TO 10

; CHECK FOR TTY OUTPUT SENT BY -10

CHKOUT:	MOV TYOLIN,I		;OUTPUT TO BE DONE?
	BEQ CHKIN		;NO.
	ASL I			;YES, GET LINE INDEX
	MOV TYOCNT,C		;AND NUMBER OF CHARS
	CMP I,#NFTTY		;CHECK RANGE OF LINE NUMBER
	BLO 12$
	CMP I,#NLTTY
	BLO 13$
12$:	 BPT			;LINE NUMBER OUT OF RANGE

13$:	CALL TYOSER		;CALL OUTPUT HANDLER
	CLR TYOLIN		;TELL 10 WE'VE GOBBLED THE OUTPUT

; CHECK FOR TTY INPUT TO BE SENT TO -10

CHKIN:	TST TYIRNG+RINGCT
	BEQ CHKDON		;NO STATUS TO BE STORED
	TST TYILIN
	BNE CHKDON		;PREVIOUS STATUS NOT PICKED UP
	MOV #TYIRNG,B
	CALL GET
	MOV A,TYICHR		;GIVE INPUT CHARACTER TO 10
	CALL GET
	MOV A,TYILIN		;GIVE LINE NUMBER TO 10
	BIS #DLX10I,DLXCSR	;SEND INTERRUPT TO 10

; CHECK FOR OUTPUT-DONE TO BE SENT TO -10

CHKDON:	TST TYORNG+RINGCT
	BEQ CHKHNG		;NO STATUS TO BE STORED
	TST TYOSTS
	BNE CHKHNG		;PREVIOUS STATUS NOT PICKED UP
	MOV #TYORNG,B
	CALL GET
	MOV A,I
	ASL I
	MOV BUFSIZ(I),TYOBSZ	;TELL -10 HOW MANY CHARS TO GIVE
	MOV A,TYOSTS		;GIVE OUTPUT DONE TO 10
	BIS #DLX10I,DLXCSR	;WITH INTERRUPT

; CHECK FOR HANGUPS TO BE SENT TO -10

CHKHNG:	TST HNGRNG+RINGCT	;ANY HANGUPS TO BE REPORTED?
	BEQ CHKLPR		;NO
	TST HNGLIN
	BNE CHKLPR		;PREVIOUS STATUS NOT PICKED UP
	MOV #HNGRNG,B
	CALL GET
	MOV A,HNGLIN		;GIVE LINE NUMBER TO 10
	BIS #DLX10I,DLXCSR	;WITH INTERRUPT

; CHECK FOR REQUEST FROM -10 TO SET LINE PARAMETERS

CHKLPR:	MOV LPRLIN,I		;LINE PARAMETERS TO BE SET?
	BEQ CHKEXD		;NO.
	ASL I			;YES, GET LINE INDEX
	MOV LPRLPR,A		;AND DH11 PARAMETER REGISTER VALUE
	MOV LPRBSZ,B		;AND BUFFER SIZE
	CALL SPARAM		;CALL PARAMETER SETTER
	CLR LPRLIN		;TELL 10 IT IS DONE

; CHECK FOR EXAMINE/DEPOSIT REQUEST FROM -10

CHKEXD:	TST EXDSTS		;EXAMINE/DEPOSIT?
	BEQ CHKGLD		;NO.
	MOV EXDADR,A		;GET ADDRESS
	CMP EXDSTS,#2
	BNE 21$
	MOV EXDDAT,(A)		;DEPOSIT
21$:	MOV (A),EXDDAT		;EXAMINE
	CLR EXDSTS		;IT IS DONE

;CHECK FOR GOULD LPT OUTPUT

CHKGLD:
.IF EQ GOULDP
	CLR GLPCTR		;IF NO GOULD, FLUSH OUTPUT FOR IT
	SETOM GLPTER		;AND SAY "NOT READY"
.IFF
	TST GLPCTR		;ANY BYTES IN BUFFER?
	BEQ 1$
	CALL GLPTYO		;YES, OUTPUT THEM
1$:	MOV GLPERR,GLPTER	;COPY ERROR STATUS FROM P.I. LEVEL TO -10
.ENDC				;DONE HERE SO NO USE OF DL10 AT P.I. LEVEL
;	BR MAINX

MAINX:	JMP MAIN		;THAT'S IT
MAINE::
.ENDC ;DL10P
.IFNZ DTE20P
	.SBTTL MAIN LOOP FOR DTE20

MAIN:	BIT #%D1RUN,DIAG1	;IS KL10 RUNNING?
	BEQ TENDED		;NO, LOSE!
	BIT #%D1ERR,DIAG1	;HAS KL10 CLOCK STOPPED FOR HARDWARE ERROR?
	BNE TENDED		;YES, LOSE!
	BIT #%STINV,STATUS	;REQUEST FROM 10?
	BNE TENSER		;YES, SERVICE IT.
	BIT #%STDNI,STATUS	;TO10 XFER COMPLETE?
	BNE INPSER		;YES, SERVICE IT.
	BIT #%STNDO,STATUS	;TO11 XFER COMPLETE?
	BNE OUTSER		;YES, SERVICE IT.
	BIT #%STERI+%STERO,STATUS
	BNE LOSSAG		;BYTE TRANSFER LOST
	TST KLDCPF		;MAYBE USER WANTS TO GIVE A KLDCP COMMAND?
	BNE KLDCPR
	TSTB LKS		;60 CYCLE CLOCK TICK?
	BPL MAIN		;NO, WAIT MORE

;60-CYCLE CLOCK SERVICE

CLKSER:	TST CLKENB		;DOES 10 WANT CLOCK INTERRUPTS?
	BEQ 1$
	D10MON			;YES, GIVE ONE
	    DTECLK		;SET CLOCK FLAG IN LOW CORE
	 BCS UHUNG
	MOV #%STINX,STATUS	;AND SEND INTERRUPT
1$:	MASK 6			;NOW SIMULATE BR6 CLOCK INTERRUPT
	JSR PC,CLKBRK
	BR TENSER		;AND GO SERVICE 10 (IN CASE LOST INTERRUPT)

; HERE IF KL10 HALTS

TENDED:	SETOM NO.ITS
	CLC
	RET			;LET KLDCP PRINT THE MESSAGE

; HERE WHEN TO10 BYTE TRANSFER COMPLETE

INPSER:	.ERROR WHAT TO DO?

; HERE WHEN TO11 BYTE TRANSFER COMPLETE

OUTSER:	MOV #%STCLO,STATUS	;CLEAR FLAG
	MOV OFINI,I		;CALL FINISH HANDLER, ARG IN I
	CALL @OFINAL
	D10MON			;TURN OFF XFER IN PROGRESS FLAG
	    DTETRN
	BR MAIN
.ERROR NOTE THAT THIS DOESN'T ALLOW FULL DUPLICITY OF BYTE TRANSFERS *****

; BYTE TRANSFER ENCOUNTERED HARDWARE LOSSAGE

LOSSAG:	BPT
	BR LOSSAG

; USER WANTS TO GIVE A KLDCP COMMAND

KLDCPR:	CLR KLDCPF
	SEC
	RTS PC

;CHECK FOR COMMANDS FROM 10, STORE STATUS IN ANY STATUS WORDS
;THAT 10 HAS SET BACK TO -1

TENSER:	MOV #%STUNV,STATUS	;CLEAR 10 INTERRUPTING 11 FLAG
	JSR B,HWEXAM		;CHECK FOR A NON-TIMESHARING COMMAND
	    DTECMD
	.ERROR HOW DO WE TELL WHETHER THERE IS ONE OR NOT?

CHKOST:	JSR B,HWEXAM		;CHECK FOR 10 WANTING OUTPUT START
	    DTEOST
	BNE CHKTRN		;BRANCH IF LOCATION DTEOST IS -1
	D10MON			;HAVING PICKED IT UP, SET BACK TO -1
	    DTEOST
	MOV RH,A
	MOV #TYORNG,B
	CALL PUT

CHKTRN:	JSR B,HWEXAM		;CHECK FOR DATA TRANSFER COMMAND
	    DTETRN
	BNE CHKLSP
	MOV RH,A		;PICK UP COMMAND
	BLE 1$
	CMP A,#TRNMAX/2
	BGE 1$
	ASL A			;IT'S IN BOUNDS, DISPATCH
	CALL @TRNDSP(A)
	BR CHKLSP

1$:	BPT			;COMMAND OUT OF BOUNDS

CHKLSP:	JSR B,HWEXAM		;CHECK FOR SET LINE SPEED COMMAND
	    DTELSP
	BNE CHKTYI
	MOV RH,I		;GET LINE#
	ASL I
	CMP I,#NFTTY		;VALIDATE IT
	BLO 1$			;IGNORE IF BAD
	CMP I,#LASTTY
	BHI 1$
	JSR B,HWEXAM		;GET LPR,,BUFFERSIZE
	    DTELPR
	MOV LH,A
	MOV RH,B
	CALL SPARAM		;DO IT
1$:	D10MON			;DONE, SETOM
	    DTELSP

CHKTYI:	TST TYIRNG+RINGCT
	BEQ CHKODN		;NO TTY INPUT WAITING
	JSR B,HWEXAM
	    DTETYI
	BEQ CHKODN		;PREVIOUS CHAR NOT PICKED UP
	MOV #TYIRNG,B
	CALL GET
	MOV A,RH		;CHAR
	CALL GET
	MOV A,LH		;LINE#
	CLR SNB
	JSR B,HWDEP		;GIVE 10 LINE#,,CHAR
	    DTETYI
	MOV #%STINX,STATUS	;INTERRUPT THE 10

CHKODN:	TST TYORNG+RINGCT
	BEQ CHKHNG		;NO OUTPUT DONES WAITING
	JSR B,HWEXAM
	    DTEODN
	BEQ CHKHNG		;PREVIOUS STATUS NOT PICKED UP
	MOV #TYORNG,B
	CALL GET		;GET LINE# WITH OUTPUT DONE
	MOV A,LH
	ASL A
	MOV BUFSIZ(A),RH
	CLR SNB
	JSR B,HWDEP		;GIVE 10 LINE#,,BUFFERSIZE
	    DTEODN
	MOV #%STINX,STATUS	;INTERRUPT THE 10

CHKHNG:	TST HNGRNG+RINGCT
	BEQ MAINX		;NO HANGUPS/DIALINS WAITING
	JSR B,HWEXAM
	    DTEHNG
	BEQ MAINX		;PREVIOUS STATUS NOT PICKED UP
	MOV #HNGRNG,B
	CALL GET
	MOV A,LH
	BIC #177700,LH		;DECODE WIERD FORMAT
	MOV #6,B
1$:	ASR A
	SOB B,1$
	MOV A,RH
	BIC #177700,RH
	BIT #100,A
	BEQ 2$
	BIS #100000,RH
2$:	CLR SNB
	JSR B,HWDEP		;GIVE 10 LINE#,,SPEEDCODE+100000*DIALIN
	    DTEHNG
	MOV #%STINX,STATUS	;INTERRUPT THE 10

MAINX:	JMP MAIN
.ENDC ;DTE20P

	.SBTTL OUTPUT HANDLERS

TYOSER:
.IFNZ DTE20P
	MOV LH,I		;PICK UP LINE#
	ASL I
	CMP I,#NFTTY
	BLO 11$
	CMP I,#LASTTY
	BLOS 12$
11$:	BPT
12$:
.ENDC ;DTE20P
	MOV HDWR(I),H			;GET HARDWARE INDEX
	MOV BUFPNT(I),D			;AND ADDRESS OF TYPEOUT BUFFER
	CMP BUFSIZ(I),C			;MAKE SURE THERE IS ROOM IN BUFFER
	BHIS 2$
	 BPT				;THERE ISN'T
2$:	MOV C,B
	NEG B				;DH11 WANTS NEGATIVE BYTE COUNT
.IFNZ DL10P
	MOV #TYOPNT,A			;GET CRUFT FROM DL10
3$:	MOVB @A,(D)+			;COPY BUFFER
	SOB C,3$
.ENDC ;DL10P
.IFNZ DTE20P
	MOV D,TO11AD			;SET UP BYTE TRANSFER
	NEG C
	BIC #050000,C			;SET LAST, BYTE; CLEAR ASCIZ, 2.4
	MOV C,TO11BC			;START XFER
	MOV #TYOFIN,OFINAL		;SET UP FINALIZE ADDRESS
	MOV I,OFINI
	MOV B,OFINB
	RTS PC				;COME BACK WHEN XFER COMPLETE

TYOFIN:	MOV HDWR(I),H
	MOV OFINB,B
.ENDC ;DTE20P

;BUFFER HAS BEEN LOADED, START DEVICE

	CMP H,#CTYHWR			;SEE IF IT'S DH11 OR CTY
	BEQ CTYO
	MASK 5				;MASK DOWN TO LEVEL 5 WHILE HACKING DH11 LN# REG
	BIC DHLBIT(I),@DHBAR(H)		;IF LINE ALREADY TRANSMITTING, STOP IT
					;IT SHOULDN'T OUGHT TO BE...
	MOV DHLSEL(I),@DHSCR(H)		;HARDWARILY SELECT THIS LINE
	MOV BUFPNT(I),@DHCA(H)		;SET XMT ADDRESS
	MOV B,@DHBC(H)			;SET XMT COUNT
	BIS DHLBIT(I),@DHBAR(H)		;START TRANSMISSION HARDWARILY
	BIS DHLBIT(I),DHOAC(H)		;SOFTWARILY ALSO
	UNMASK
	RET

CTYO:	MASK 5				;START CTY
	MOV BUFPNT(I),CTYCA
	MOV B,CTYBC
	CLR TPS
	MOV #300,TPS			;CAUSE INTERRUPT
	SETOM CTYOAC
	UNMASK
	RET

.IFNZ GOULDP
.SBTTL GOULD LPT OUTPUT (M.P. LEVEL)
.IFZ DL10P, .ERROR GOULD LPT ONLY CODED FOR DL10

GLPTYO:	MOV GLPOIP,H		;GET NEXT BUFFER
	CMP GB.STA(H),#%GBMP
	BEQ 2$			;BRANCH IF M.P. ACTIVE
	BLT 1$			;BRANCH IF IDLE BUFFER AVAIL
	RET			;NO FREE BUFFERS

1$:	CALL GLPBGB		;GOBBLE A BUFFER
2$:	MOV GB.PNT(H),P
	MOV GLPCTR,C		;SET UP BYTE COUNTER
	MOV GLPGRF,GLPGF1	;COPY ARG FROM 0 FOR SPEED
	TST GLIMBF		;CHAR SAVED FROM LAST TIME?
	BEQ GLPNCL
	CLR GLIMBF		;YES, PRINT IT
	MOVB GLIMBO,A
	CALL GLPPUT
	MOVB GLIMBO+1,A		;SECOND CHAR?
	BEQ GLPNCL
	CLR GLIMBO
	CALL GLPPUT

;CHARACTER PROCESSING LOOP
;C HAS # CHARS YET TO GO, P HAS WHERE TO PUT THEM, H -> BUFFER
;A WILL HAVE CHAR

GLPNCL:	MOV GLPPTR,A		;GET NEXT CHAR
	TST GLPGF1
	BNE GLPNRM		;GRAPHIC MODE, NO CHARACTER PROCESSING
	CMP A,#177		;ESCAPE?
	BEQ GLPESC
	CMP A,#40		;CONTROL?
	BGE GLPNRM		;NO, NORMAL PRINTING
	CMP A,#14		;CHECK FOR SPECIAL CONTROLS
	BNE 10$
8$:	CLR GLPROW		;START NEW PAGE
	TST GLPCOL		;IN MIDDLE OF LINE?
	BEQ 9$			;NO, OK
	CALL GLPBWW		;OTHERWISE, HAIR
	CLR GLPFIL		;HACK HACK MAKE FF NEXT LINE
	BR GLPNB1

9$:	SETOM GB.FF(H)
	BR GLPNXC

10$:	CMP A,#12
	BNE 12$
	INC GLPROW
	CMP GLPROW,#GLPRMX
	BHIS 8$			;SKIP OVER PERFORATION
	TST GLPCOL
	BNE GLPNBF		;IF NOT A BLANK LINE, FINISH BUFFER
	INC GB.NL(H)
	BR GLPNXC

12$:	CMP A,#11
	BNE 15$
13$:	MOV #40,A		;TAB - SPACE OVER
	CALL GLPPUT
	BIT #7,GLPCOL
	BNE 13$
	BR GLPNXC

15$:	CMP A,#15
	BEQ GLPNXC		;IGNORE CR
	CMP A,#33
	BNE 16$
	MOV #'$,A		;PRINT ALTMODE AS DOLLAR
	BR GLPNRM

16$:	BIS #100,A		;RANDOM CONTROL AS UPARROW, LETTER
	MOVB A,GLIMBO+1
	MOV #'↑,A
	CALL GLPPUT
	MOVB GLIMBO+1,A
	CLR GLIMBO	
GLPNRM:	CALL GLPPUT		;HERE FOR NORMAL CHARACTER
GLPNXC:	DEC C			;HERE TO GOBBLE CHARACTER
	BGT GLPNCL		;BRANCH IF MORE CHARS TO GO
	BR GLPEND		;BUFFER EMPTIED

GLPNBF:	CALL GLPBWW		;HERE TO ADVANCE TO NEXT BUFFER
GLPNB1:	CMP GB.STA(H),#%GBIDL	;NEXT BUFFER AVAIL?
	BNE GLPEN1		;NO, STOP
	CALL GLPBGB		;YES, GOBBLE IT
	BR GLPNXC

GLPESC:	DEC C			;HERE FOR TWO CHAR ESC SEQ
	BEQ GLPEND		;-10 FORGOT 2ND CHAR, FLUSH
	MOV GLPPTR,A		;GET & DECODE 2ND CHAR
	CMP A,#105		;EOF
	BEQ GLPEOF
	BR GLPNXC		;OTHER CHARS ARE IGNORED

GLPEOF:	CLR GLPFIL
	CLR GLPROW
	CALL GLPBWW		;EOF, WRITE LAST BUFFER
GLPEN1:	DEC C			;GOBBLE A CHARACTER
GLPEND:	MOV C,GLPCTR		;HERE WHEN DONE, RELEASE 10'S BUFFER
	CMP GB.STA(H),#%GBMP	;BUFFER ACTIVE AT M.P. LEVEL?
	BNE 1$			;IF NOT, DON'T CLOBBER GB.PNT
	MOV P,GB.PNT(H)		;IF SO, REMEMBER AMT OF STUFF IN CURRENT BUFFER
1$:	RET			;RETURN TO MAIN LOOP

;OUTPUT PRINTING CHAR IN A

GLPPUT:	CMP P,GLPLIM		;LINE OVERFLOW?
	BLO 5$			;NO
	CALL GLPBWW		;YES, DONE WITH THIS BUFFER
	INC GLPROW		;OUGHT TO CHECK FOR PERFORATION, BUT...
	CMP GB.STA(H),#%GBIDL	;MORE BUFFERS?
	BNE 6$			;NO
	CALL GLPBGB
5$:	MOVB A,(P)+		;DROP CHAR IN BUFFER
	INC GLPCOL		;AND ADVANCE COLUMN
	RET

6$:	MOVB A,GLIMBO		;NO BUFFERS, SAVE CHAR BEING PRINTED
	SETOM GLIMBF		;SET FLAG SO WILL BE PRINTED NEXT TIME
	TST (SP)+		;STOP THE WORLD
	BR GLPEN1

;GOBBLE IDLE BUFFER H -> FOR M.P.  RETURNS GB.PNT(H) IN P.

GLPBGB:	MOV #%GBMP,GB.STA(H)	;ACTIVATE AT M.P. LEVEL
	CLR GB.FF(H)		;INIT THE BUFFER
	CLR GB.NL(H)
	CLR GLPCOL		;START LINE IN COLUMN 0
	MOV H,P			;INIT INSERT POINTER
	ADD #GB.DAT,P
	MOV P,GB.PNT(H)
	MOV H,GLPLIM		;SET UP MAX. VALUE OF GB.PNT
	ADD #GB.LEN,GLPLIM
	RET

;GIVE BUFFER H -> TO P.I. LEVEL

GLPBWW:	BIT #1,P		;MUST BE EVEN NUMBER OF BYTES
	BEQ 1$
	CLRB (P)+

1$:	PUSH A			;INTERFACE GETS BYTES IN WRONG ORDER
	MOV P,A			;COMPUTE NUMBER OF WORDS IN LINE
	SUB H,A
	SUB #GB.DAT,A
	ASR A
	BNE 4$
	CLR (P)+		;CAN'T HAVE ZERO-LENGTH LINE
	INC A
4$:	MOV A,GB.PNT(H)		;SAVE WORD COUNT FOR P.I. LEVEL
2$:	SWAB -(P)
	SOB A,2$
	POP A
	TST GLPFIL		;IF STARTING NEW FILE,
	BNE 5$
	SETOM GLPFIL
	SETOM GB.FF(H)		; BE SURE TO GET NEW PAGE
5$:	MOV #%GBWRT,GB.STA(H)	;QUEUE TO P.I. LEVEL
	MOV GB.NXT(H),H		;ADVANCE TO NEXT BUFFER
	MOV H,GLPOIP
	MASK 6			;STOP P.I. LEVEL (HAVE TO LOCK OUT GLPBRK & CLKBRK)
	TST GLPOAC		;PRINTER ON?
	BNE 3$			;YUP
	MOV #%GCOFF,@#GLPCSR	;NO, CLEAR OLD STUFF IN INTERFACE
	TST GLPGF1		;AND PUT IN LOW-SPEED GRAPHIC MODE IF NECC	
	BEQ 6$
	MOV #%GCGRF,@#GLPCSR
	MOV #%GCLSL,@#GLPCSR	;LOW SPEED (COME ON, THIS IS ONLY A KL10!)
6$:	MOV #%GCON,@#GLPCSR	;TURN IT ON
	MOV #%GCION,@#GLPCSR	;TURN ON INTERRUPTS
	SETOM GLPOAC
;	PUSH @#PS		;FAKE AN INTERRUPT
;	CALL GLPBRK		;IS THIS NECESSARY?
3$:	UNMASK
	RET

;GOULD LPT VARIABLES

GLPCOL:	0		;CURRENT COLUMN NUMBER
GLPROW:	0		;CURRENT ROW NUMBER
 GLPRMX==67.		;NUMBER OF LINES PER PAGE
GLPLIM:	0		;ADDRESS OF END OF CURRENT BUFFER
GLPOAC:	0		;NON-ZERO => GOULD LPT P.I. ACTIVE
GLPGF1:	0		;NON-ZERO => GOULD LPT IN GRAPHIC MODE
GLIMBO:	0		;SAVE CHAR HERE WHEN RUN OUT OF BUFFERS
GLIMBF:	0		;NON-ZERO => CHAR IN GLIMBO
GLPFIL:	0		;NON-ZERO => IN MIDDLE OF A FILE
GLPTIM:	10.		;COUNT DOWN WHEN LOSING
GLPERR:	0		;NON-ZERO => ERROR STATUS FROM P.I.
.ENDC	;GOULDP

	.SBTTL SET LINE PARAMETERS

;LINE INDEX IN I
;DH11 PARAM REG IN A
;BUFFER SIZE IN B

SPARAM:	CMP I,#NFTTY
	BGE 1$
	 BPT
1$:	CMP I,#LASTTY
	BLE 2$
	 BPT
2$:	CMP B,#1.		;MINIMUM BUFFER SIZE ONE CHARACTER
	BGE 3$
	 MOV #1.,B
3$:	CMP B,#MAXBSZ		;MAXIMUM BUFFER SIZE <MAXBSZ> CHARACTERS
	BLE 4$
	 MOV #MAXBSZ,B
4$:	MOV B,BUFSIZ(I)		;SET AMOUNT OF BUFFER TO BE USED FROM NOW ON
	MOV HDWR(I),H		;(BUT NO LONGER DO WE ATTEMPT DYNAMIC BUFFER ALLOCATION)
	CMP H,#CTYHWR
	BEQ 5$
	MASK 5			;LINE IS A DH11, HAVE TO SET LINE PARAM REG
	MOV DHLSEL(I),@DHSCR(H)	;SELECT THE LINE
	MOV A,@DHLPR(H)		;GIVE LINE-PARAMETER REG TO DH11
	UNMASK
5$:	MOV A,LPRVAL(I)		;STORE LPR IN CASE SOMEONE IS CURIOUS
	RET

	.SBTTL DH11 INPUT INTERRUPT

	.REPT NDHS
CONC DH,\.RPCNT+1,<IBK:	JSR H,DHIBK>
	  2*.RPCNT
.ENDR

DHIBK:	MOV (H),H			;PICK UP HARDWARE INDEX
	PUSH <A,B,I>
1$:	MOV @DHNRC(H),A			;RECIEVE A CHARACTER
	BPL DHIEX			;EXIT INTERRUPT IF NO MORE CHARS
	MOV A,I				;EXTRACT LINE NUMBER
	SWAB I
	BIC #177760,I
	ASL I
	ADD DHTYNO(H),I
	CALL @TTYIPC(I)			;CALL LINE HACKER
	BR 1$				;AND CHECK FOR MORE

DHIEX:	POP <I,B,A,H>
	RTI

;NORMAL DH11 INPUT

DHNRMI:	BIT #%DXPAR,A
	BEQ 1$				;IGNORE IF PARITY ERROR
10$:	 RET
1$:	BIT #%DXBRK,A			;IF BREAK,
	BEQ RCV
	TST AUTOSP(I)			;AND LINE WANTS AUTOSPEED-ON-BREAK FEATURE
	BPL 10$
ASPMD:	MOV #DHASP,TTYIPC(I)		;PUT IT IN AUTOSPEED MODE
	MOV DHLSEL(I),@DHSCR(H)		;AND SET HARDWARE TO 300 BAUD
	MOV #016703,@DHLPR(H)
	RET

;CHAR IN A RECEIVED FROM LINE IN I

RCV:	BIC #177600,A			;7-BIT CHAR RECEIVE
RCV.FW:	TST NO.ITS			;ENTER HERE FOR FULL WORD RECEIVE
	BEQ 10$
	MOV #DWNMSG,A			;ITS DOWN, GIVE MESSAGE
12$:	CALL GIVMSG
	RET

10$:	MOV #TYIRNG,B
	CMP RINGCT(B),#TYIRSZ-2
	BGT 11$
	CALL PUT			;FIRST PUT THE CHARACTER
	MOV I,A
	ASR A
	CALL PUT			;THEN THE TENNISH LINE NUMBER
	RET

11$:	MOV #IBOMSG,A			;INPUT BUFFER OVERFLOW
	BR 12$				;PROBABLY ONLY INTELLIGENT
					;TERMINALS CAN CAUSE THIS

;AUTOSPEED MODE COMES HERE WHEN CHAR RECIEVED

DHASP:	BIC #177600,A			;AUTOSPEED - SEE IF RECOGNIZE
	CMP A,#014
	BEQ 1$				;110 BAUD USUALLY GIVES THIS
	CMP A,#034
	BEQ 1$				;110 BAUD SOMETIMES GIVES THIS
	CMP A,#146
	BEQ 2$				;150 BAUD
	BIC #177770,A
	CMP A,#5
	BEQ 3$				;300 BAUD
	RET				;SOMETHING ELSE, IGNORE

1$:	MOV #006307,A			;110 IN, 110 OUT, NO PARITY, 8 BITS, EXTRA STPBT
	MOV #5,B
	MOV #12200,-(SP)
	BR 10$

2$:	MOV #012503,A			;150 IN, 150 OUT, NO PARITY, 8 BITS
	MOV #7,B
	MOV #13300,-(SP)
	BR 10$

3$:	MOV #016703,A			;300 IN, 300 OUT, NO PARITY, 8 BITS
	MOV #15.,B
	MOV #14400,-(SP)
	BR 10$

10$:	CALL SPARAM			;SET BUFFER SIZE AND HARDWARE SPEED
	MOV I,A				;SET UP SET-SPEED COMMAND TO -10
	ASR A
	BIS (SP)+,A
	MOV #HNGRNG,B
	CALL PUT
	MOV #ASPACK,A			;ACKNOWLEDGE TO USER THAT HE WON
	CALL GIVMSG
	MOV NRMIPC(I),TTYIPC(I)		;AND TAKE LINE OUT OF AUTOSPEED MODE
;	MOV #32,A			;NOW SEND IN A CONTROL/Z
;	BR RCV
; PRECEDING TWO LINES COMMENTED OUT SO ITS GREETING
; MESSAGE WON'T CANCEL -11 GREETING MESSAGE
; WHEN OPERATING AT 110 BAUD.
	RET

	.SBTTL DH11 OUTPUT INTERRUPTS

	.REPT NDHS
CONC DH,\.RPCNT+1,<OBK:	JSR H,DHOBK>
	  2*.RPCNT
.ENDR

DHOBK:	MOV (H),H			;GET HARDWARE UNIT NUMBER
	BIT #DHSNXM,@DHSCR(H)		;IS THIS INTERRUPT DUE TO NXM?
	BEQ 1$
	 BPT				;YES
1$:	BIC #DHTDON,@DHSCR(H)		;HARDWARE KLUDGE TO MAKE INTERRUPTS WIN
	PUSH <A,B,C,I>
	MOV DHOAC(H),C			;SEE WHICH BAR BITS HAVE TURNED OFF
	BIC @DHBAR(H),C
	BIC C,DHOAC(H)
	MOV DHTYNO(H),I
	ADD #15.*2,I
2$:	BIT DHLBIT(I),C
	BEQ 3$
	CALL XMTDON
3$:	SUB #2,I
	CMP I,DHTYNO(H)
	BGE 2$
DHOEX:	POP <I,C,B,A,H>
	RTI

XMTDON:	MOV I,A
	ASR A			;RETURN TENNISH LINE NUMBER
	MOV #TYORNG,B
	CALL PUT
	RET

;GIVE MESSAGE.  A -> .WORD LENGTH,MSG.  I HAS LINE NUMBER.

GIVMSG:	MOV (A)+,B		;B HAS BYTE COUNT, A HAS ADDRESS
	MASK 5
	MOV HDWR(I),H
	CMP H,#CTYHWR
	BLT 2$			;JUMP IF DH11
	TST CTYOAC
	BNE 1$			;OUTPUT ALREADY ACTIVE, CAN'T
	MOV A,CTYCA
	MOV B,CTYBC
	SETOM CTYOAC
	CLR TPS
	MOV #300,TPS		;CAUSE INTERRUPT
1$:	UNMASK
	RET

2$:	BIT DHLBIT(I),DHOAC(H)
	BNE 1$			;OUTPUT ALREADY ACTIVE, CAN'T
	MOV DHLSEL(I),@DHSCR(H)	;CAN, SO SELECT LINE
	NEG B
	MOV A,@DHCA(H)
	MOV B,@DHBC(H)
	BIS DHLBIT(I),@DHBAR(H)
;	BIS DHLBIT(I),DHOAC(H)	;COMMENTED OUT SO DON'T OVERFLOW TYORNG
	BR 1$

ASPACK:	MNAME ↑%
	MSG ↑\Connected to MCHN
\%
DWNMSG:	MSG ↑\ITS is down.
\
IBOMSG:	MSG ↑\IBO\

	.SBTTL CTY INTERRUPTS

CTYIBK:	PUSH <A,B,I,H>
	MOV #CTYHWR,H
	MOV #CTYIDX,I
	MOV TKB,A
	CALL @TTYIPC(I)
CTYEX:	POP <H,I,B,A>
CRTI:	RTI

CTYOBK:	TST CTYOAC
	BEQ CRTI		;NOT SUPPOSED TO BE TYPING OUT
	DEC CTYBC		;GOT ANY MORE CHARACTERS?
	BLT 1$			;NO, GO GIVE OUTPUT DONE
	MOVB @CTYCA,TPB		;YES, GIVE ONE
	INC CTYCA
	RTI

1$:	PUSH <A,B,I,H>		;OUTPUT DONE
	MOV #CTYHWR,H
	MOV #CTYIDX,I
	CLR CTYOAC
	CALL XMTDON
	BR CTYEX

	.SBTTL CLOCK INTERRUPT

CLKBRK:	SETOM WAKE		;WAKE UP MAIN LOOP
.IFNZ GOULDP
	PUSH @#PS		;CHECK GOULD LPT
	CALL GLPBRK		;(LOSES INTERRUPTS)
	DEC GLPTIM		;TIME TO CHECK GOULD LPT?
	BGT 13$			;NOT YET
	MOV #10.*60.,GLPTIM
	BIT #%GSNRD,@#GLPCSR	;YES, LOSING?
	BNE 14$			;PROBABLY
	CLR GLPERR		;PROBABLY NOT
	BR 13$			;(CAN'T TELL FOR SURE IF %GCON NOT DONE)

14$:	MOV @#GLPCSR,GLPERR	;LPT LOSING, TELL 10
	CALL GLPRST		;AND MAKE SURE BUFFERS DON'T CHOKE UP
.ENDC ;GOULDP
13$:
.IFNZ DL10P
	TST DLXOFF
	BNE 15$			;DON'T MESS WITH DL10
	INC DLXDWN
	CMP DLXDWN,#100.	;IF -10 MISSES THREE SLOW CLOCK BREAKS IN A ROW, IT'S DOWN
	BLE 1$
	SETOM NO.ITS		;SAY I.T.S. IS DOWN IF ANYONE ASKS
	BR 15$

1$:	CLR NO.ITS		;IT'S UP AGAIN
.ENDC ;DL10P
.IFNZ DTE20P
	JSR B,HWEXAM		;IS 10 ALIVE?
	    DTECHK
	INC RH
	CMP RH,#100.
	BLE 1$
	SETOM NO.ITS		;NO
	BR 15$

1$:	CLR NO.ITS		:IT'S UP AGAIN
.ENDC ;DTE20P
15$:	PUSH <A,B,I>		;CHECK FOR HANGUPS
	MOV #NFTTY,I
16$:	TST DIALED(I)		;HANGUP IN PROGRESS ON THIS LINE?
	BPL 17$			;NO
	INC DIALED(I)		;YES, TIMED OUT?
	BMI 17$
	CLR DIALED(I)		;YUP, LINE IS HUNG UP
	MOV I,A			;TELL -10 ABOUT IT
	ASR A
	MOV #HNGRNG,B
	CALL PUT
17$:	ADD #2,I
	CMP I,#LASTTY
	BLO 16$
	POP <I,B,A>

	ROR SWR			;LOW BIT OF SWITCHES => DDT
	BCC CLKEX
	BPT
CLKEX:	RTI
.IFNZ MDMP
	.SBTTL MODEM CONTROL

MDMBRK:	PUSH <A,B,I,H>
	MOV MDMCSR,I			;GET ASSOCIATED TTY INDEX
	BIC #177760,I
	ASL I
	MOV M2LMAP(I),I
	BEQ 90$				;EXIT IF THIS LINE NOT UNDER MODEM CONTROL
;	TST MDMCSR	.SEE MDMRNG
;	BPL 10$
;	TST DIALED(I)			;RINGING.  IS LINE DIALED UP ALREADY?
;	BNE 10$				;YES, NOT SUPPOSED TO BE RINGING
;	MOV #LINENB+LINDTR,MDMLSR	;ANSWER THE PHONE

10$:	BIT #LINCTS,MDMLSR		;DO WE HAVE CLEAR-TO-SEND?
	BEQ 20$				;NO
	TST DIALED(I)			;YES, WHAT WAS PREVIOUS STATE?
	BEQ 13$				;WAS OFF, THIS IS A DIALUP
	BPL 90$				;WAS ON, IGNORE
	NEG DIALED(I)			;WAS HANGING UP, ABORT IT
	BR 90$

13$:	INC DIALED(I)			;LINE IS NOW DIALED UP
	TST AUTOSP(I)			;IF IT HAS AUTOSPEED,
	BEQ 90$
	MOV HDWR(I),H			;HACK THAT
	CALL ASPMD
	BR 90$

20$:	TST DIALED(I)			;CTS DROPPED
	BMI 90$				;ALREADY KNOWN ABOUT, IGNORE
	MOV #-HNGDLY,DIALED(I)		;OTHERWISE START HANGUP TIMEOUT

90$:	BIC #MDMDON,MDMCSR		;RESTART SCANNER
	POP <H,I,B,A>
	RTI
.ENDC ;MDMP

.IFNZ GOULDP
.SBTTL GOULD PRINTER P.I. LEVEL

GLPBRK:	BIT #%GSBSY,@#GLPCSR
	BEQ 1$
	RTI				;LPT BUSY, WAIT

1$:	BIT #%GSDON,@#GLPCSR
	BNE 2$
	RTI				;LPT BUSY OTHER FLAVOR

2$:	PUSH <A,B,H>
	BIT #%GSERR,@#GLPCSR		;LPT LOSING?
	BEQ GLPBR1
	CALL GLPRST			;YUP, RESET THE BUFFERS
	MOV @#GLPCSR,GLPERR		;AND TELL 10

GLPOFF:	CLR GLPOAC			;HERE TO STOP P.I.
	MOV #%GCIOF,@#GLPCSR
	MOV #5000.,A			;LPT SOMETIMES BUSY FOR A WHILE
1$:	BIT #%GSBSY,@#GLPCSR		;HAVE TO WAIT SO TONER PUMPS WILL
	BEQ 2$				;REALLY TURN OFF
	SOB A,1$
2$:	MOV #%GCOFF,@#GLPCSR
GLPEX:	POP <H,B,A>
	RTI

GLPFIN:	MOV #%GBIDL,GB.STA(H)		;DONE WITH THIS BUFFER
	MOV GB.NXT(H),H			;CHECK NEXT
	MOV H,GLPOOP

GLPBR1:	MOV GLPOOP,H			;CHECK ON BUFFERS
	CMP GB.STA(H),#%GBDMA		;FINISH DMA XFER?
	BEQ GLPFIN			;YES
	CMP GB.STA(H),#%GBWRT		;QUEUED OR ALREADY ACTIVE AT P.I.?
	BLT GLPOFF			;NO, STOP
	MOV #%GBPI,GB.STA(H)		;YES, ACTIVATE IT AT P.I.
	TST GB.FF(H)			;NEED FF?
	BEQ 1$
	MOV #%GCFF,@#GLPCSR		;YES
	CLR GB.FF(H)
	BR GLPEX

1$:	TST GB.NL(H)			;NEED BLANK LINES?
	BEQ 2$
	DEC GB.NL(H)			;YES, GIVE ONE
	MOV #%GCADV,@#GLPCSR
	BR GLPEX

2$:	MOV H,B				;SET UP TEXT ADDR
	ADD #GB.DAT,B
	MOV GB.PNT(H),A			;SET UP TEXT WORD COUNT
	NEG A
	MOV A,@#GLPWC
	MOV B,@#GLPCA			;START XFER
	MOV #%GBDMA,GB.STA(H)		;FLAG BUFFER ACTIVE AT DMA LEVEL
	BR GLPEX

GLPRST:	PUSH H
	MOV #GLPBFF,H			;FLUSH ALL BUFFERS
	MOV H,GLPOOP
	MOV H,GLPOIP
3$:	CLR (H)+
	MOV (H),H
	CMP H,#GLPBFF
	BNE 3$
	MOV #60.*10.,GLPTIM		;SET TIMEOUT
	POP H
	RET

.ENDC ;GOULDP
.IFNZ DL10P
	.SBTTL TRAP HANDLING

TRAP14:	HALT			;BPT WITH NO RUG IN CORE

TRAP10:	BPT			;ILLEGAL INSTRUCTION

TRAP4:	NOP			;PATCH BPT HERE IF YOU WANT
	CMP (SP),#MAIN		;IF TRAP4 IN MAIN LOOP...
	BLO CRASH
	CMP (SP),#MAINE
	BHIS CRASH
	BIT #DLXPRT,DLXCSR	;AND DL10 PORT TURNED OFF
	BNE CRASH
	TST DLXOFF		;AND WE THOUGHT IT WAS ON
	BNE CRASH
RESTRT:	MOV #STKBAS,SP		;THEN RESTART MAIN LOOP
	CLR -(SP)		;WHICH WILL WAIT FOR DL10 PORT TO TURN ON
	MOV #MAIN,-(SP)
	RTI

CRASH:	BPT			;OTHERWISE, CRASH

PWRFAL:	HALT			;POWER FAIL
.ENDC ;DL10P

	.SBTTL INITIALIZATION

GO::
INIT:	RESET
	MOV #STKBAS,SP
	TST 14
	BNE 1$			;BPT ALREADY SET UP BY RUG
	MOV #TRAP14,14
	MOV #340,16
1$:
.IFNZ MDMP
;TURN ON DM11-BB

	MOV #MDMCLR+MDMCSN,MDMCSR	;CLEAR SCANNER MEMORY
2$:	BIT #MDMBSY,MDMCSR
	BNE 2$
	CLR I
	CLR A
3$:	TST M2LMAP(I)			;TURN ON CONNECTED MODEM CHANNELS
	BEQ 4$
	MOV A,MDMCSR
	MOV #LINENB,MDMLSR
4$:	TST (I)+
	INC A
	CMP A,#16.
	BLT 3$
	MOV #MDMSCN+MDMIEN,MDMCSR	;ENABLE SCANNER INTERRUPTS
.ENDC ;MDMP

.IFG NDHS
;TURN ON DH11'S

	MOV #2*<NDHS-1>,H
20$:	MOV #DHRENB+DHTENB,@DHSCR(H)
	SUB #2,H
	BGE 20$
.ENDC ;NDHS

;TURN ON CTY

	MOV #100,TKS
	MOV #100,TPS

;SET LINE PARAMETERS AND ALLOCATE BUFFERS

	MOV #NFTTY,I
10$:	MOV LPRVAL(I),A
	MOV BUFSIZ(I),B
	CALL SPARAM
	MOV NRMIPC(I),TTYIPC(I)
	ADD #2,I
	CMP I,#LASTTY
	BLE 10$

;TURN ON CLOCK

.IIF Z DTE20P,	MOV #100,@#LKS	;NO CLOCK INTERRUPTS IF KLDCP IS HACKING CLOCK TOO

.IIF NZ DTE20P, MOV #MAIN,SADR	;ONLY DO INIT ONCE

;GO

	JMP MAIN

;PATCH AREA

PAT: PATCH: .BLKW 200

.IF NE GOULDP
.SBTTL GOULD PRINTER BUFFERS

GLPOIP:	GLPBFF		;NEXT BUFFER IN AT M.P. LEVEL
GLPOOP:	GLPBFF		;NEXT BUFFER OUT AT P.I. LEVEL

	.REPT NGLPBF	;ASSEMBLE THE BUFFERS
	0		.SEE GB.STA
	GLPBFF		;DUE TO PALX BUG, LEAVE .SEE ON NEXT LINE
			.SEE GB.NXT
GLPBFF==.-4
	0		.SEE GB.FF
	0		.SEE GB.NL
	0		.SEE GB.PNT
	.BLKB GLPBSZ
	.ENDR
.ENDC	;GOULDP

	.SBTTL "TTYTYP" PARAMETER FILE

T LPRVAL:
	.BLKW NCT		;DH11 PARAMETER REG

BUFFRS:	;BEGIN ALLOCATING BUFFERS HERE

INFORM <BEGINNING OF BUFFERS = >,\BUFFRS
INFORM <HIGHEST LOCATION USED = >,\BUFFRS+<NCT*MAXBSZ>
	
.MACRO SPEED BAUD
ZZ==-1
.IIF IDN BAUD,OFF,  ZZ==0
.IIF IDN BAUD,50,   ZZ==1
.IIF IDN BAUD,75,   ZZ==2
.IIF IDN BAUD,110,  ZZ==3
.IIF IDN BAUD,134,  ZZ==4
.IIF IDN BAUD,150,  ZZ==5
.IIF IDN BAUD,200,  ZZ==6
.IIF IDN BAUD,300,  ZZ==7
.IIF IDN BAUD,600,  ZZ==10
.IIF IDN BAUD,1200, ZZ==11
.IIF IDN BAUD,1800, ZZ==12
.IIF IDN BAUD,2400, ZZ==13
.IIF IDN BAUD,4800, ZZ==14
.IIF IDN BAUD,9600, ZZ==15
.IIF IDN BAUD,80K, ZZ==16
.IIF IDN BAUD,40K, ZZ==17
.IIF LT ZZ, .ERROR UNRECOGNIZED SPEED "BAUD"
.ENDM

.MACRO IPARM N,IBAUD,IDFLT,OBAUD,ODFLT
.IF GE <2*N>-NFTTY
.IF LE <2*N>-LASTTY
.IIF NB IBAUD, SPEED IBAUD
.IIF B IBAUD, SPEED IDFLT
IZZ==ZZ
.IF NB OBAUD
SPEED OBAUD
.IFF
.IIF B IBAUD, SPEED ODFLT
.ENDC
; BUFFER SIZE IS 1/2 SECOND'S TYPING
; BUT WILL BE SUBJECT TO LIMIT OF MAXBSZ
.IIF LT ZZ-7, BZZ==5.
.IIF EQ ZZ-7, BZZ==15.
.IIF EQ ZZ-10, BZZ==30.
.IIF EQ ZZ-11, BZZ==60.
.IIF EQ ZZ-12, BZZ==90.
.IIF EQ ZZ-13, BZZ==120.
.IIF EQ ZZ-14, BZZ==240.
.IIF EQ ZZ-15, BZZ==480.
.IIF GT ZZ-15, BZZ==1000.
.ENDC
.=LPRVAL+<2*N>		;ASSEMBLE LINE PARAMETER WORD
.IIF NE ZZ-3, <ZZ*2000>+<IZZ*100>+3	;ISPEED, OSPEED, NO PARITY, 8 BITS, FULL DUPLEX
.IELSE <ZZ*2000>+<IZZ*100>+3+4		;110 BAUD EXTRA STOP BIT
.=BUFSIZ+<2*N>
BZZ			;ASSEMBLE BUFFER SIZE
.ENDC
.ENDC
.ENDM

;MACROS USED IN THE TTYTYP FILE:

.MACRO TTDPRT N,IBAUD,OBAUD,TT,TY
IPARM N,IBAUD,110,OBAUD,110
.ENDM

.MACRO TTDMRX N,TT,TY
IPARM N,600,,600,
.ENDM

.MACRO TTDTRM N,IBAUD,OBAUD,TT,TY
IPARM N,IBAUD,1200,OBAUD,1200
.ENDM

.MACRO TTDLPT N,TT,TY
IPARM N,LPTFOO,,LPTFOO,
.ENDM

.MACRO TTDSIPB N,IBAUD,OBAUD,TT,TY
IPARM N,IBAUD,300,OBAUD,300
.ENDM

.MACRO TTDLA36 N,TT,TY
IPARM N,300,,300,
.ENDM

.MACRO TTDIML N,IBAUD,OBAUD,VERT,TT,TY
IPARM N,IBAUD,25K,OBAUD,50K
.ENDM

.MACRO TTDIIM N,IBAUD,OBAUD,VERT,TT,TY
IPARM N,IBAUD,25K,OBAUD,50K
.ENDM

.MACRO TTDVT N,IBAUD,OBAUD
IPARM N,IBAUD,9600,OBAUD,9600
.ENDM

.MACRO TTDTEK N,IBAUD,OBAUD,TT,TY
IPARM N,IBAUD,1200,OBAUD,1200
.ENDM

.MACRO TTDDPT N,TT,TY
IPARM N,2400,,2400,
.ENDM

.MACRO TTDLSR N,TT,TY
IPARM N,2400,,2400,
.ENDM

.MACRO TTDGT40 N,IBAUD,OBAUD,VERT,TT,TY
IPARM N,IBAUD,4800,OBAUD,4800
.ENDM

.MACRO TTD11 N,IBAUD,OBAUD,TT,TY
IPARM N,IBAUD,4800,OBAUD,4800
.ENDM

.MACRO TTDTMP N,IBAUD,OBAUD,TT,TY
IPARM N,IBAUD,4800,OBAUD,4800
.ENDM

.MACRO TTDTV N,TT,TY
IPARM N,TVFOO,,TVFOO,
.ENDM

.MACRO TTD2741 N,CODE,TT,TY
IPARM N,2741FOO,,2741FOO,
.ENDM

.MACRO TTDSTY N
IPARM N,STYFOO,,STYFOO,
.ENDM

.MACRO REPEAT N,FOO
.REPT N
.ENDM

NSTTYS==0			;WE'RE NOT INTERESTED IN PSEUDO-TTYS
N11TYS==0			;NOR IN PDP11 TVS

.INSRT TTYTYP >

.END INIT