Trailing-Edge
-
PDP-10 Archives
-
BB-BT99V-BB_1990
-
10,7/anf10/dntty.p11
There are 5 other files named dntty.p11 in the archive. Click here to see a list.
.SBTTL DNTTY - TERMINAL ROUTINES 02-AUG-89
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1976,1977,1978,1979,1980,1981,1982,1983,1984,1987,1988,1990.
;ALL RIGHTS RESERVED.
VRTTY=123 ;FILE EDIT NUMBER
.IF NE <FT.CTY+TTYN+RDAN>
;DB.DCS STATUS BITS FOR TTY SERVICE
TS.DFE=1 ;DEFERED ECHO MODE
TS..LC=2 ;TRANSLATE LOWER CASE TO UPPER
TS.FRZ=4 ;OUTPUT HAS BEEN FROZEN BY TYPEIN OF XOF
TS.IMI=10 ;IMAGE MODE INPUT
TS.IMO=20 ;IMAGE MODE OUTPUT
TS.PAG=40 ;TTY PAGE IN EFFECT
TS.TAP=100 ;TTY TAPE FEATURE(IMPLIES SUPPRESS NORMAL CR HANDLING)
TS.TAB=200 ;TTY HAS HDW TAB
TS.FRM=400 ;TTY HAS HDW FORM FEED
TS.8BI=1000 ;8-BIT INPUT MODE
; =2000 ;FREE BIT
TS.CRL=4000 ;NO AUTO CR/LF ON LINE OVERFLOW
TS.DTR=10000 ;DATA TERMINAL READY
TS.RNG=20000 ;RING
TS.CAR=20000 ;CARRIER
; =40000 ;FREE BIT
; =100000 ;FREE BIT
TS.RCN=TS..LC!TS.PAG!TS.TAB!TS.FRM!TS.CRL!TS.DTR!TS.RNG!TS.CAR ;BITS TO PRESERVE ON A RECONNECT
;DB.DVT DEVICE-TYPE BITS FOR TTY SERVICE
TT.DSL=B0 ;DATASET LINE
TT.ABD=B1 ;AUTOBAUD THIS LINE
TT.CSB=B2 ;CAN SET BAUD RATE
; =B3 ;FREE BIT
; =B4 ;FREE BIT
TT.801=B5 ;AUTO-DIAL LINE
TT.CSH=B6 ;CAN SET HOST
TT.RIC=B7 ;RUN INITIA CUSP (IGNORED BY -10)
TT.ABR=B8 ;AUTOBAUD REQUESTABLE
TT.8BL=B9 ;8-BIT LINE (BY DEFAULT)
.IIF NDF,ESCF,ESCF=176 ;NOTE, ESCF CANNOT BE > 177
;MACRO TO MAKE DEVICE DEPENDENT PORTION OF DEVICE BLOCK FOR TTY'S
.MACRO SETLCB QLCB
.WORD LCB'QLCB ;DB.LCB
.ENDM
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
ZZZ=1
.REPT NXTDH&17
ZZZ=ZZZ*2
.ENDR
.WORD ZZZ ;DB.BIT
.BYTE 17&NXTDH ;DB..LN
Z=0
.IF NDF DV'XZZ'XS
.IIF DF DEV'XS,DV'XZZ'XS=DEV'XS
.ENDC
.IF NDF DV'XZZ'XS
Z=LCB.AB ;AUTO BAUD LINE
ZZXS=R.HSPD ;SCAN AT 2400 BAUD
.IFF
ZZXS=DV'XZZ'XS
.IIF NE ZZXS-R.HSPD,DV'XZZ'ABD=0 ;NO AUTOBAUD AT WRONG SPEED
.IIF DF DV'XZZ'ABD,.IIF NE DV'XZZ'ABD, Z=LCB.AB
.ENDC
.IF NDF DV'XZZ'RS
.IIF DF DEV'RS,DV'XZZ'RS=DEV'RS
.ENDC
.IIF NDF DV'XZZ'RS,ZZRS=ZZXS
.IIF DF DV'XZZ'RS,ZZRS=DV'XZZ'RS
.IF NE ZZRS-R.HSPD
Z=Z&<^C<LCB.AB>>
DV'XZZ'ABD=0
.ENDC
.MACRO DHSSET LINE
ZZS=0
.IIF DF DV'XZZ'XS,ZZS=1
.IIF DF DV'XZZ'RS,ZZS=1
.IF NE ZZS
SPD ZZXS,ZZRS ;CALCULATE LINE SPEED
DHS'LINE=QQ
.ENDC
.ENDM DHSSET
DHSSET \NXTDH
.IIF DF DV'XZZ'DSL,.IIF NE DV'XZZ'DSL, Z=Z!LCB.DS
.MACRO DHCSET LINE
DHC'LINE=Z
.ENDM DHCSET
.MACRO DHZSET LINE
DHZ'LINE=LCS.VG
.IF EQ Z&LCB.DS
DHZ'LINE=LCS.AB
.IF EQ Z&LCB.AB
DHZ'LINE=LCS.RU
.ENDC
.ENDC
.ENDM
DHCSET \NXTDH
DHZSET \NXTDH
.BYTE 12,12,20,12,12,12 ;DB.FIL
.BYTE 0 ;DB.EPL
SETLCB \NXTDH ;DB.LCB
DHINDX=DHINDX+1
.IF NE FTDN11
Z=0
.IF DF DV'XZZ'801
Z=DV'XZZ'801
.ENDC
.BYTE Z ;DB.DNS (DN11 STATUS)
.BYTE 0 ;DB.DNT (DN11 TIMER)
.ENDC;.IF NE FTDN11
.WORD 0 ;DB.TTS (TTY STATUS WORD)
.BLKB <DB.TSZ-DB.TZR>
.EVEN
.ENDM DDXGEN
NXTDZ=-1 ;
NXTDH=-1 ;LOCATE FIRST TTY LINE
DRESET=0
ASYDEV=ASY.DH ;BUILD DH LINES FIRST
DDBGEN TTY,T,TTYDHN,TTYDRQ,<DS.TTY!DS.OUT> ;MAKE DEVICE BLOCKS FOR TTYS
ASYDEV=ASY.DZ ;NOW DZ LINES
DRESET=1 ;DONT BUILD NEW SYMBOLS
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
ZZZ=1
.REPT NXTDZ&7
ZZZ=ZZZ*2
.ENDR
.WORD ZZZ ;DB.BIT
.BYTE 7&NXTDZ ;DB..LN
Z=0
.IF NDF DV'XZZ'XS
.IIF DF DEV'XS,DV'XZZ'XS=DEV'XS
.ENDC
.IF NDF DV'XZZ'XS
Z=LCB.AB ;AUTO BAUD LINE
ZZXS=R.HSPD ;SCAN AT 2400 BAUD
.IFF
ZZXS=DV'XZZ'XS
.IIF NE ZZXS-R.HSPD,DV'XZZ'ABD=0 ;NO AUTOBAUD AT WRONG SPEED
.IIF DF DV'XZZ'ABD,.IIF NE DV'XZZ'ABD, Z=LCB.AB
.ENDC
.IF NDF DV'XZZ'RS
.IIF DF DEV'RS,DV'XZZ'RS=DEV'RS
.ENDC
.IIF NDF DV'XZZ'RS,ZZRS=ZZXS
.IIF DF DV'XZZ'RS,ZZRS=DV'XZZ'RS
.IF NE ZZRS-R.HSPD
Z=Z&<^C<LCB.AB>>
DV'XZZ'ABD=0
.ENDC
.MACRO DZSSET LINE
ZZS=0
.IIF DF DV'XZZ'XS,ZZS=1
.IIF DF DV'XZZ'RS,ZZS=1
.IF NE ZZS
SPD ZZXS,ZZRS ;CALCULATE LINE SPEED
DZS'LINE=QQ
.ENDC
.ENDM DZSSET
DZSSET \NXTDZ
.IIF DF DV'XZZ'DSL,.IIF NE DV'XZZ'DSL, Z=Z!LCB.DS
.MACRO DZCSET LINE
DZC'LINE=Z
.ENDM DZCSET
.MACRO DZZSET LINE
DZZ'LINE=LCS.VG
.IF EQ Z&LCB.DS
DZZ'LINE=LCS.AB
.IF EQ Z&LCB.AB
DZZ'LINE=LCS.RU
.ENDC
.ENDC
.ENDM
DZCSET \NXTDZ
DZZSET \NXTDZ
.BYTE 12,12,20,12,12,12 ;DB.FIL
.BYTE 0 ;DB.EPL
SETLCB \<NXTDZ+<NDH11*20>> ;DB.LCB
DZINDX=DZINDX+1
.IF NE FTDN11
Z=0
.IF DF DV'XZZ'801
Z=DV'XZZ'801
.ENDC
.BYTE Z ;DB.DNS (DN11 STATUS)
.BYTE 0 ;DB.DNT (DN11 TIMER)
.ENDC;.IF NE FTDN11
.WORD 0 ;DB.TTS (TTY STATUS WORD)
.BLKB <DB.TSZ-DB.TZR>
.EVEN
.ENDM DDXGEN
DDBGEN TTY,T,TTYDZN,TTYDRQ,<DS.TTY!DS.OUT>
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
ZZZ=1
.REPT NXTDH&17
ZZZ=ZZZ*2
.ENDR
.WORD ZZZ ;DB.BIT
.BYTE 17&NXTDH ;DB..LN
Z=0
.BYTE 12,12,20,12,12,12 ;DB.FIL
.BYTE 0 ;DB.EPL
.WORD CT0LDB ;DUMMY LINE CONTROL BLOCK
.IF NE FTDN11
Z=0
.IF DF DV'XZZ'801
Z=DV'XZZ'801
.ENDC
.BYTE Z ;DB.DNS (DN11 STATUS)
.BYTE 0 ;DB.DNT (DN11 TIMER)
.WORD CT'XZZ'DDB+DB.TSZ ;CTY HAS NO DATASET FUNCTION
.ENDC
.WORD 0 ;DB.TTS (TTY STATUS WORD)
.BLKB <DB.TSZ-DB.TZR>
.EVEN
.ENDM DDXGEN
.IF NE FT.CTY
DRESET=0
NXTDH=0 ;CTY ISN'T A DH DEV SO FAKE IT
.IF NDF CTYRNN
.IIF DF TTYRNN,CTYRNN=TTYRNN ;SAME RESTRICTIONS AS TTYS
.ENDC
DDBGEN CTY,CT,1,TTYDRQ,<DS.OUT!DS.TTY> ;MAKE A DEVICE BLOCK FOR THE CTY
.ENDC
.IF NE FT.RDA ; IF WE HAVE IT, IT IS THE SAME
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
ZZZ=1
.REPT NXTDH&17
ZZZ=ZZZ*2
.ENDR
.WORD ZZZ ;DB.BIT
.BYTE 17&NXTDH ;DB..LN
Z=0
.IF NDF DV'XZZ'XS
.IIF DF DEV'XS,DV'XZZ'XS=DEV'XS
.ENDC
.IF NDF DV'XZZ'XS
ZZXS=R.HSPD ;SCAN AT 2400 BAUD
.IFF
ZZXS=DV'XZZ'XS
.ENDC
.IF NDF DV'XZZ'RS
.IIF DF DEV'RS,DV'XZZ'RS=DEV'RS
.ENDC
.IIF NDF DV'XZZ'RS,ZZRS=ZZXS
.IIF DF DV'XZZ'RS,ZZRS=DV'XZZ'RS
.MACRO DHSSET LINE
ZZS=0
.IIF DF DV'XZZ'XS,ZZS=1
.IIF DF DV'XZZ'RS,ZZS=1
.IF NE ZZS
SPD ZZXS,ZZRS ;CALCULATE LINE SPEED
DHS'LINE=QQ
.ENDC
.ENDM DHSSET
DHSSET \NXTDH
.IIF DF DV'XZZ'DSL, .IIF NE DV'XZZ'DSL, Z=Z!LCB.DS
.MACRO DHCSET LINE
DHC'LINE=Z
.ENDM DHCSET
.MACRO DHZSET LINE
DHZ'LINE=LCS.VG
.IF EQ Z&LCB.DS
DHZ'LINE=LCS.AB
.IF EQ Z&LCB.AB
DHZ'LINE=LCS.RU
.ENDC
.ENDC
.ENDM
DHCSET \NXTDH
DHZSET \NXTDH
.BYTE 0,0,0,0,0,0 ;DB.FIL
.BYTE 0 ;DB.EPL
SETLCB \NXTDH ;DB.LCB
DHINDX=DHINDX+1
.IF NE FTDN11
Z=0
.IF DF DV'XZZ'801
Z=DV'XZZ'801
.ENDC
.BYTE Z ;DB.DNS (DN11 STATUS)
.BYTE 0 ;DB.DNT (DN11 TIMER)
.ENDC
.WORD 0 ;DB.TTS (STATUS)
.BLKB <DB.TSZ-DB.TZR>
.EVEN
.ENDM DDXGEN
ASYDEV=ASY.DH
DRESET=0
NXTDH=-1 ; START WITH RIGHT LINE NUMBER
DDBGEN RDA,D,RDADHN,RDADRQ,<DS.OUT>
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
ZZZ=1
.REPT NXTDZ&7
ZZZ=ZZZ*2
.ENDR
.WORD ZZZ ;DB.BIT
.BYTE 7&NXTDZ ;DB..LN
Z=0
.IF NDF DV'XZZ'XS
.IIF DF DEV'XS,DV'XZZ'XS=DEV'XS
.ENDC
.IF NDF DV'XZZ'XS
ZZXS=R.HSPD ;SCAN AT 2400 BAUD
.IFF
ZZXS=DV'XZZ'XS
.ENDC
.IF NDF DV'XZZ'RS
.IIF DF DEV'RS,DV'XZZ'RS=DEV'RS
.ENDC
.IIF NDF DV'XZZ'RS,ZZRS=ZZXS
.IIF DF DV'XZZ'RS,ZZRS=DV'XZZ'RS
.MACRO DZSSET LINE
ZZS=0
.IIF DF DV'XZZ'XS,ZZS=1
.IIF DF DV'XZZ'RS,ZZS=1
.IF NE ZZS
SPD ZZXS,ZZRS ;CALCULATE LINE SPEED
DZS'LINE=QQ
.ENDC
.ENDM DZSSET
DZSSET \NXTDZ
.IIF DF DV'XZZ'DSL, .IIF NE DV'XZZ'DSL, Z=Z!LCB.DS
.MACRO DZCSET LINE
DZC'LINE=Z
.ENDM DZCSET
.MACRO DZZSET LINE
DZZ'LINE=LCS.VG
.IF EQ Z&LCB.DS
DZZ'LINE=LCS.AB
.IF EQ Z&LCB.AB
DZZ'LINE=LCS.RU
.ENDC
.ENDC
.ENDM
DZCSET \NXTDZ
DZZSET \NXTDZ
.BYTE 0,0,0,0,0,0 ;DB.FIL
.BYTE 0 ;DB.EPL
SETLCB \<NXTDZ+<NDH11*20>> ;DB.LCB
DZINDX=DZINDX+1
.IF NE FTDN11
Z=0
.IF DF DV'XZZ'801
Z=DV'XZZ'801
.ENDC
.BYTE Z ;DB.DNS (DN11 STATUS)
.BYTE 0 ;DB.DNT (DN11 TIMER)
.ENDC
.WORD 0 ;DB.TTS (STATUS)
.BLKB <DB.TSZ-DB.TZR>
.EVEN
.ENDM DDXGEN
ASYDEV=ASY.DZ
DRESET=1
NXTDZ=-1
DDBGEN RDA,D,RDADZN,RDADRQ,<DS.OUT>
.ENDC; .IF NE FT.RDA
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ ;REDEFINE FOR NEXT DEVICE
.ENDM DDXGEN
.IF NE FT.TSK
.IIF NE FT.CTY, .WORD CTYDDB ;ADDRESS OF DEVICE BLOCK FOR CTY IS ENTRY "-1"
TTYTAB:
.MACRO X ART,ARG,ARX,ARY
.IF EQ D'ART'L'ARG'-1
.WORD T'ARX'DDB
ZTTY=ZTTY+1
.IFF
.IF EQ D'ART'L'ARG'-6
.WORD D'ARY'DDB
ZRDA=ZRDA+1
.IFF
.WORD 0
.ENDC
.ENDC
.ENDM
ZTTY=0 ;START WITH TTY0 DDB
ZRDA=0 ;START WITH RDA0 DDB
Z=0 ;INITIALIZE INDEX FOR DH11
.REPT DHLINE
X H,\Z,\ZTTY,\ZRDA
Z=Z+1
.ENDR
Z=0 ;RESET DZ11 LINE INDEX
.REPT DZLINE
X Z,\Z,\ZTTY,\ZRDA
Z=Z+1
.ENDR
.ENDC ;.IF NE FT.TSK
.IF NE FT.CTY
CT0LDB: .WORD 0 ;LC.CAR DUMMY LDB FOR CTY
.BYTE LCS.RU ;LC.STA LINE IS RUNNING
.BYTE 0 ;LC.MOD
.WORD B.300 ;LC.SPD 300 BAUD
.WORD B.300 ;LC.PSP 300 BAUD
.WORD CT0DDB ;LC.BLK
.WORD CTIINT ;LC.INS
.WORD CTOINT ;LC.OUS
.IF NE NDZ11
.WORD 0 ;LC.CNT
.WORD 0 ;LC.BUF
.ENDC
.ENDC
CTYSER:
TTYSER: CMP #TTYMML,DB.MML(J) ;DID HANDLER GIVE REASONABLE SIZE MSG ?
BPL 10$ ;IF SO USE IT
MOV #TTYMML,DB.MML(J) ;USE OUR SIZE CAUZ IT'S SMALLER
10$: MOVB #DCM.AS,DB.DCM(J) ;SET DATA CODE AND MODE
MOVB DB.TYP(J),R0 ;GET ASYNC CONTROLLER TYPE
ASR R0 ;MAKE INTO DIRECT VALUE (NOT INDEX)
.IF NE FT.CTY
CMP #CT0DDB,J ;IS THIS THE CTY?
BEQ 11$ ;YES,
.ENDC ;.IF NE FT.CTY
INCB R0 ;NO,
11$: INCB R0 ;CTY = 1; DH-11 = 2; DZ-11 = 3
MOVB R0,DB.DVV(J) ;SET CONTROLLER TYPE
JSR PC,DVCCFM ;SEND CONNECT CONFIRM
BIT #DS.CON,@J ;CONNECTED ?
BNE 20$
RTS PC
20$: JSR PC,DVXDRQ ;SEND SOME DATA REQUESTS
TST DB.OBF(J) ;DID 10 SEND DATA ?
BNE TOGMSG
JMP TTYICK
;HERE TO OUTPUT THE "ESCAPE FUNCTION" CHARACTER
TOGESC: JSR PC,QTECHR ;QUEUE TWO OF 'EM SO THAT ONE
BR TOGMSG ;WILL ACTUALLY GET PRINTED
;START OF SUBMESSAGE, DISPATCH BASED ON MESSAGE TYPE
TOGMS1: CMP R0,#4 ;MESSAGE MUST BE IN 0..4
BHI TOGBAD ;IF NOT, WE COMPLAIN (ACTUALLY 1..4)
ASL R0 ;WORD INDEX
JMP @10$(R0) ;DISPATCH ON MESSAGE TYPE
10$: TOGBAD ;00 - INVALID MESSAGE
TOGMSG ;01 - DATA WITHOUT EOM
TOGMSG ;02 - DATA WITH EOM
TOGSTS ;03 - STATUS
TOGCTL ;04 - CONTROL
;HERE WHEN WIN A DATA CHAR
TOGCHR: CMP R0,#ESCF ;IS THIS FUNCTION FLAG?
BEQ TOGESC ;YES, SPECIAL PROCESSING
JSR PC,QTYCHR ;QUEUE CHAR TO BE TYPED
TOGMSG: JSR PC,DVGBYT ;GET NEXT BYTE FROM THE NCL MESSAGE
BR TOGCHR ;WON A DATA CHARACTER
BR TOGMS1 ;WON A MESSAGE TYPE
JMP TOGDON ;ALL OUT OF MESSAGE
;HERE ON BAD MESSAGE TYPE OR FORMAT
TOGBAD:
.IF EQ DGUTS
TRAP ;ILLEGAL MSG TYPE
.IFF
CTYMSG NCL
32$: JSR PC,DVGBYT ;GET NEXT BYTE OF MSG
BR 32$ ;EAT BAD MSG
BR TOGMS1 ;TRY AGAIN WITH NEXT MSG
JMP TOGDON ;ALL DONE
.ENDC
;HERE WHEN WE RECEIVE A STATUS MESSAGE
TOGSTS: JSR PC,DVGDBY ;GET CODE IN STATUS MSG
10$: MOV R0,-(P) ;SAVE CODE
JSR PC,DVGEXF ;GET BITS TO SET/CLEAR
ASSERT EQ DB.OCN(J) ;MAKE SURE NOTHING LEFT OVER
MOV (P)+,R1 ;GET CODE AGAIN
MOV DB.DCS(J),-(P) ;SAVE CURRENT STATUS
BIT #TS.DTR,R0 ;IF IT'S DTR
BEQ 40$ ; AND
CMP #2,R1 ;HE WANTS IT CLEAR
BNE 40$ ; SKIP IF NOT "CLEAR"
SAVE <R1> ;GET A TEMP FOR A BIT
BIT #TS.FRZ,R0 ;IS TEN CLEARING XOFF
BEQ 15$ ;NO,ONWARD
SAVE <R0,R2,R3,R4,R5> ;YES,SAVE SOME ACS
JSR PC,BEGXMT ;START OUTPUT
RESTORE <R5,R4,R3,R2,R0> ;RESTORE ACS
15$: MOV DB.LCB(J),R1 ;GET POINTER TO THE LCB
BEQ 35$ ;GET OUT IF NO LCB
ADD #LC.STA,R1 ;POINT TO DATASET STATE BYTE
CMPB #LCS.RC,@R1 ;RUNNING NORMALLY?
.IF NE FTDN11
BEQ 27$ ;YES, -10 WANTS US TO HANG UP
CMPB #LCS.DL,@R1 ;NO, DIALING OUT?
BEQ 27$ ;YES, -10 APPARENTLY WANTS TO ABORT
CMPB #LCS.DS,@R1 ;DIALING OUT SUCCESSFUL?
.ENDC;.IF NE FTDN11
BNE 35$ ;YES, -10 STILL WANTS TO ABORT
27$: MOVB #LCS.HA,@R1 ;FORCE DATASET TO HANG UP
35$: RESTORE <R1> ;GET SET/CLEAR BACK (IT'S CLEAR)
40$: BIC #TS.DTR!TS.CAR,R0 ;IGNORE -10'S OPINION OTHERWISE
42$: BIT #TS.ESC,R0 ;SET OR CLEAR IMAGE OUTPUT?
BEQ 60$ ;NO, ACT NORMALLY
SAVE R0 ;SAVE BITS TO SET/CLEAR
SAVE R1 ;PRESERVE ORIGINAL SET/CLEAR CODE
DEC R1 ;MAKE SET=0 AND CLEAR=1
SAVE R1 ;PRESERVE THAT AS WELL
MOV R0,R1 ;COPY THE BITS TO TEST
MOV #MAXESC,R0 ;START WITH THE MAXIMUM VALID INDEX
44$: BIT R1,ESCTAB(R0) ;CHECK IF THIS BIT IS TO BE TWEAKED
BEQ 45$ ;SKIP THIS NONSENSE IF NOT
ADD @P,R0 ;YES, MAKE SURE OF THE FUNCTION CODE
JSR PC,QTECHR ;PUT IT INTO THE OUTPUT STREAM
SUB @P,R0 ;RESTORE THE TABLE INDEX
45$: SUB #2,R0 ;INDEXING THE TABLE TWO AT A TIME
BPL 44$ ;UNTIL OFF THE TOP
TST (SP)+ ;POP JUNK
RESTOR R1 ;RETRIEVE SET/CLEAR CODE
RESTOR R0 ;GET BITS TO SET/CLEAR BACK
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;DO "SET" BITS IF REQUESTED
60$: CMP #1,R1 ;DOES HE WANT A SET BITS ?
BNE 70$
BIS R0,DB.DCS(J) ;SET BITS
BR 90$ ;AND NOW DONE
;DO "CLEAR" BITS IF REQUESTED
70$: CMP #2,R1 ;WANT TO CLEAR BITS ?
BNE 80$
BIC R0,DB.DCS(J) ;CLEAR THE BITS LIKE BEFORE
BR 90$ ;NOW DONE
;NOT "SET" OR "CLEAR" BITS
80$:
.IF EQ DGUTS
TRAP
.IFF
TST (P)+ ;GET STACK BACK INTO SYNC
CTYMSG NCL ;LOG BAD NCL MSG ERROR
RTS PC ;AND EXIT
.ENDC ;.IF EQ DGUTS
;SEE IF ANYTHING CHANGED, TELL THE -10 IF NEEDED
90$: TRACE DV
MOV DB.DCS(J),R0 ;COPY OF NEW STATUS
BIC #TS.DTR!TS.CAR,(P) ;IGNORE DTR AND CAR (THIS IS TO AVOID
BIC #TS.DTR!TS.CAR,R0 ; A STATUS MESSAGE WAR WITH THE -10)
CMP R0,(P)+ ;DID DEVICE CONTROL STATUS CHANGE?
BEQ 95$ ;NO, ALL SET
BIS #DS.XDS,@J ;YES, SEND -10 OUR NEW STATUS
95$: BR TOGMSG
;HERE WHEN WE RECEIVE A CONTROL MESSAGE
TOGCTL: JSR PC,DVGDBY ;GET DCT BYTE
52$: CMP R0,#5 ;DCT ALSO CAN'T BE TOO BIG
BHI TOGBAD ;DCT MUST BE IN RANGE 0..5
ASL R0 ;WORD INDEX
JSR PC,@54$(R0) ;DISPATCH ON DCT CODE
BR TOGMSG ;FIRE UP ANOTHER MESSAGE
54$: TOGC00 ;00 - ECHO PIPELINE MARKER
TOGC01 ;01 - CHARACTER GOBBLER
TOGC02 ;02 - TTY CHARACTERISTICS
TOGC03 ;03 - AUTO DIAL
TOGC04 ;04 - XOFF REQUEST
TOGC05 ;05 - AUTOBAUD REQUEST
;HERE WHEN RECEIVE A DIAL-OUT REQUEST
TOGC03:
.IF NE FTDN11
JSR PC,DNSTRT ;START DIALING
RTS PC ;NOTHING MORE HERE
.IFF
TST (P)+ ;POP RETURN ADDRESS
BR TOGBAD ;BUMMER
.ENDC
;HERE WHEN RECEIVE AN ECHO-PIPELINE MARKER
TOGC00: JSR PC,DVGDBY ;GO GET MARKER
TST DB.IBF(J) ;MORE STUFF PENDING ?
BNE 99$ ;IF SO CAN'T GO TO LOCAL ECHO
CMPB R0,DB.EPL(J) ;DOES IT MATCH LAST I SENT ?
BNE 99$ ;IF NOT IGNORE IT
BIC #TS.DFE,DB.DCS(J) ;BACK INTO LOCAL ECHO MODE
BIS #DS.XDS,(J) ;SEND NEW STATUS TO HOST
99$: RTS PC ;ALL DONE HERE
;HERE TO SEND AN XOFF MSG ASAP
TOGC04: JSR PC,SNDXOF ;SEND XOFF RIGHT AWAY
BIC #DS.IST,@J ;LET THE -10 GENERATE THE XON
RTS PC ;AND KEEP WORKING
;HERE WHEN RECEIVE A CHARACTER GOBBLER
TOGC01: PIOFF ;DISABLE INTERRUPTS FOR A WHILE
MOV DB.TOB(J),R0 ;GET POINTER TO OUTPUT CHARS
MOV DB.TOB+2(J),R1 ;SAVE END POINTER ALSO
CLR DB.TOC(J) ;ZERO OUTPUT COUNT
CLR DB.TOB(J) ;NO OUTPUT TAKER
CLR DB.TOB+2(J) ;AND NO TAKER
PION ;REENABLE INTERRUPTS
BIC #TS.FRZ,DB.DCS(J) ;START OUTPUT IF STOPPED
MOV R1,-(SP) ;MOVE TO A MORE CONVENIENT PLACE
TST R0
BEQ 40$
10$: CMP R0,(P) ;WAS THAT LAST CHARACTER TO THROW AWAY?
BEQ 30$ ;YES, WE'RE DONE
ADVCNK R0,FREE ;ADVANCE A FREE CHUNK (IF NECESSARY)
MOVB (R0)+,R1 ;GET NEXT CHARACTER
CMP R1,#ESCF ;IS IT FUNCTION ESCAPE CHARACTER?
BNE 10$ ;NO, KEEP FLUSHING
ADVCNK R0,FREE ;ADVANCE CHUCKS, IF NEEDED
MOVB (R0)+,R1 ;GET FUNCTION CODE
JSR PC,DOESCF ;PERFORM FUNCTION
BR 10$ ;AND CONTINUE FLUSHING
30$: DEC R0 ;ENSURE WE HAVEN'T RUN OFF CHUNK
BIC #CNKSIZ-1,R0 ;FREE REST OF LIST
JSR PC,FRECKS ;FRECK IT!
40$: TSTB (P)+ ;CLEAN UP STACK
RTS PC ;BACK FOR MORE MESSAGES
;HERE WHEN RECEIVE A CHARACTERISTICS MESSAGE
TOGC02: MOV J,R2 ;COPY DEVICE BLOCK POINTER
ADD #DB.FIL,R2 ;POINT TO FILLER SECTION
MOV #6,R3 ;COUNTER
66$: JSR PC,DVGEXF ;GET AN EXTENSIBLE FIELD
CLC ;NEED LOGICAL SHIFT (DIVIDE BY 2)
ROR R0 ;GET FILL TIME AS SEC/500
BEQ 67$ ;IF 0 JUST USE IT
ASR R0 ;GET FILL TIME AS SEC/250
ADD #4,R0 ;FOR ROUND OFF
BIT #37000,R0 ;IS TIME TOO LARGE FOR TICK TIMER
BEQ 68$
NEG R0
SWAB R0 ;GET FILL TIME IN SEC
BR 67$
68$: ASR R0 ;GET FILL TIME IN SEC/125
ASR R0 ;GET FILL TIME IN SEC/62.5
67$: MOVB R0,(R2)+ ;SAVE FILLER
SOB R3,66$ ;LOOP BACK FOR REST OF FILLER
;NOW GET SPEED FROM CHARACTERISTICS MESSAGE
JSR PC,DVGEXF ;GET RECEIVE SPEED
.IF NE TTYN
JSR PC,75$ ;CONVERT RECEIVE SPEED TO A DH11 CODE
MOV DB.LCB(J),R2 ;POINT TO LINE CONTROL BLOCK
MOV LC.SPD(R2),R2 ;GET INITIAL GUESS FOR SPEED
MOV R2,-(P)
TST R1 ;CHECK SPEED TABLE INDEX FROM 75$
BLT 72$ ;IF DIDN'T FIND SPEED
BIC #^C377,R2 ;MASK OUT JUNK
SWAB R1 ;POSITION RECEIVE CODE IN "LH"
BIS R1,R2 ;SET NEW RECEIVE SPEED IN OUR COPY
.ENDC
72$: JSR PC,DVGEXF ;GET TRANSMIT SPEED
.IF NE TTYN
JSR PC,75$ ;CONVERT THAT TO A DH11 CODE
TST R1
BLT 74$ ;IF DIDN'T FIND SPEED
BIC #377,R2 ;MASK OUT JUNK
BIS R1,R2 ;PUT NEW SPEED IN OUR COPY
74$: CMP R2,(P)+ ;SAME AS LAST SPEED ?
BEQ TYSR60 ;IF SO IGNORE
PIOFF
MOV R2,-(P) ;SAVE SPEED
MOV DB.LCB(J),R2 ;POINT TO LCB
CMPB #LCS.AB,LC.STA(R2) ; AUTO BAUD ?
BNE 73$ ; NO
MOVB #LCS.RU,LC.STA(R2) ;SET TO RUN STATE
BIC #LCB.TM,LC.CAR(R2) ;CLEAR TIMER
73$: JSR PC,SETSPD ;SET NEW SPEED
TST (P)+ ;POP THE SPEED
PION
BR TYSR60
;HERE TO SEARCH SPEED TABLE FOR DH11 CODE
75$: MOV #SPDLIM-SPDTAB,R1 ;MAKE SPEED TABLE INDEX
76$: CMP R0,SPDTAB(R1) ;CHECK FOR MATCH
BEQ 78$
SUB #2,R1 ;LOWER INDEX TO SPDTAB
BPL 76$
78$: ASR R1 ; FORM TRUE INDEX
RTS PC
.ENDC
TYSR60: JSR PC,DVGEXF ;GET WIDTH
MOVB R0,DB.WID(J)
JSR PC,DVGEXF ;GET AUTO CAR RETURN POSITION
MOVB R0,DB.ACR(J)
JSR PC,DVGEXF ;GET ELEMENT NUMBER
86$: JSR PC,DVGEXF ;GET 2741 BITS
MOV R0,DB.TTS(J) ;STUFF INTO DDB
BIT #TT.DFT,R0 ;FORMS TYPE PRESENT?
BEQ 99$ ;NO, DON'T PROCESS IT
TST DB.OCN(J) ;ANY MORE IN THIS SUBMESSAGE?
BEQ 99$ ;NO--IT'S NOT REALLY THERE
MOV #DB.DFT,R2 ;YES, GET ITS OFFSET
ADD J,R2 ;THEN ITS ADDRESS
MOV #6,R3 ;AND LIMIT OF CHARACTERS
91$: JSR PC,DVGDBY ;GET NEXT BYTE
DEC R3 ;TEST AGAINST STORAGE LIMIT
BMI 92$ ;SKIP STORAGE IF RAN OUT
MOVB R0,(R2)+ ;SAVE CHARACTER
92$: TSTB R0 ;CHECK SIGN BIT
BMI 91$ ;LOOP OVER EXTENSIBLE ASCII
BICB #200,-(R2) ;MAKE SURE PROPERLY TERMINATED
99$: ASSERT EQ DB.OCN(J) ;COUNT SHOULD BE 0 NOW
RTS PC ;BACK FOR MORE [SUB]MESSAGES
;HERE WHEN WE RECEIVE AN AUTOBAUD REQUEST
TOGC05:
.IF NE TTYN
ASSERT EQ DB.OCN(J) ;COUNT SHOULD BE 0 NOW
BIT #TT.ABR,DB.DVT(J) ;CHECK FOR LEGALITY OF REQUEST
BEQ 99$ ;ILLEGAL--SEND SPEED BACK TO TEN NOW
MOV DB.LCB(J),R2 ;GET LCB ADDRESS
JSR PC,SET.AB ;SETUP TO DO AUTOBAUD
BIC #DS.XCH,@J ;DON'T SEND CHARACTERISTICS YET
RTS PC ;BACK FOR MORE [SUB]MESSAGES
99$: BIS #DS.XCH,@J ;SEND CHARACTERISTICS TO TEN IF NO A/B
.ENDC ;.IF NE TTYN
RTS PC ;BACK FOR MORE [SUB]MESSAGES
TOGDON: BIT #DS.XDS,(J) ;SEND STATUS IF REQUIRED
BEQ 20$
JSR PC,DVPDCS
20$:
.IF NE FT.TSK
JSR PC,TK0WAK ;WAKE 'GET PRINTER' TASK IF ANY
MOV J,R3 ;COPY DDB ADDRESS
24$: MOV DB.TSK+6(J),J ;GET ADDRESS OF 'PUT KEYBOARD' TASK
BEQ 26$
JSR PC,TSKWAK
26$: MOV R3,J ;RESTORE DDB ADDRESS
.ENDC
JSR PC,BEGXMT ;START TYPING
;HERE TO CHECK FOR INPUT TO GO TO THE 10
TTYICK: BIT #DS.ACT,@J ;UNLESS ACTIVE
BNE 10$
BIT #DS.DIE!DS.DSC,(J) ;ARE WE DONE WITH THE CONNECTION
BEQ 10$ ;IF NOT, SEE IF THERE IS INPUT
JMP DVCCFM ;NO LONGER CONNECTED. SEND
; DISCONNECT CONFIRM AND CLEAN DDB
10$:
.IF NE DN11N
.IF NE FT.RDA&FT.TSK
TST DB.RDT(J) ; CHECK FOR RDA DEVICE
BEQ 17$ ; NO
JSR PC,DNSTTJ ; CHECK FOR AUTO DIAL ON DEVICE
JSR PC,RDXSTA ; CHECK STATUS
17$:
.ENDC
.ENDC
BIT #DS.IQU,@J ;IS NCL ALREADY SENDING OUR INPUT ?
BEQ 16$
12$:; JMP TYICK9 ;IF SO HOLD REST
RTS PC ;SAVE 2 BYTES
;NOW SHIP THE CHARACTERS
16$: BIT #DS.IST,(J) ;DID WE STOP INPUT?
BEQ 15$ ;NO, BRANCH
JSR PC,SNDXON ;YES, SEND AN XON
BIC #DS.IST,(J) ;AND CLEAR XOFF FLAG
15$:
.IF NE FT.TSK
CMP DB.ICC(J),#TTYMIC ;HOW MANY CHARS IN MSG?
BHIS 18$ ;IF FULL SEND IT
BIT #DS.PAU,(J) ;CHECK WHETHER WE SHOULD HOLD
BNE 12$
.ENDC
18$:
.IF NE FT.RDA
TST DB.RDT(J) ; RDA DEVICE ??
BEQ 19$ ; NO, KEEP GOING
TST DB.IDR(J) ; INPUT DATA REQUESTS ??
BNE 11$ ; SEND DATA
RTS PC ; NO, GO BACK
11$: JMP RDACN0
19$:
.ENDC
BIT #DS.EPL,@J ;NEED TO SEND AN ECHO PIPELINE MARKER ?
BEQ 20$ ;IF NOT DON'T BOTHER
MOV #4,R0 ;CODE THIS IS A CONTROL MSG
JSR PC,DVPBSM ;BEGIN CONTROL SUBMESSAGE
BCS TYICK3 ;IF WE CAN'T SEND MSG,
;PRETEND WE DIDN'T WANT TO
CLR R0 ;CODE IS ECHO-PIPELINE-MARKER
JSR PC,DVPDAT
BCS 20$ ;ERROR RETURN
MOVB DB.EPL(J),R0 ;SERIAL # FOR MARKER
INC R0 ;INCREMENT SERIAL NUMBER
JSR PC,DVPDAT
BCS 20$ ;ERROR RETURN
BIC #DS.EPL,@J ;FLAG WE HAVE DONE IT NOW
INCB DB.EPL(J) ;INCREMENT SERIAL NUMBER FOR REAL
;HERE TO CONSIDER SENDING CHARACTERISTICS
20$: BIT #DS.XCH,@J ;NEED TO SEND CHARACTERISTICS ?
BEQ TYICK3
MOV #4,R0 ;CHARACTERISTICS IS CONTROL SUBMSG
JSR PC,DVPBSM ;BEGIN SUBMESSAGE
BCS TYICK3 ;IF WE CAN'T SEND MSG,
;PRETEND WE DIDN'T WANT TO
MOV #2,R0 ;CODE IS 2 FOR CHARACTERISTICS
JSR PC,DVPDAT
BCS TYICK3 ;ERROR RETURN
MOV #6,R2 ;ESTABLISH COUNTER FOR FILLS
MOV J,R4 ;COPY DEVICE BLOCK ADDRESS
ADD #DB.FIL,R4 ;POINT TO FILLERS
22$: MOVB (R4)+,R0 ;GET NEXT FILLER
BIC #^C377,R0 ;STRIP EXTRA BITS
ASL R0
ASL R0
ASL R0
ASL R0
JSR PC,DVPEXD ;PUT EXTENSIBLE FIELD IN SUBMESSAGE
SOB R2,22$ ;LOOP BACK FOR REST OF FILLERS
.IF NE TTYN
MOV DB.LCB(J),R0 ;POINT TO LINE CONTROL BLOCK
MOV LC.SPD(R0),R0 ;GET SPEED
MOV R0,-(P)
SWAB R0
ASL R0 ;MAKE INTO INDEX
JSR PC,24$
MOV (P)+,R0
ASL R0
JSR PC,24$
BR 26$
24$: BIC #^C76,R0 ;STRIP EXTRA BITS
MOV SPDTAB(R0),R0 ;TRANSLATE TO BAUD
JMP DVPEXD
26$:
.IFF
MOV #^D110,R0 ;DEFAULT IS 110 BAUD
JSR PC,DVPEXD ;PUT INTO SUBMSG
MOV #^D110,R0 ;DEFAULT IS 110 BAUD
JSR PC,DVPEXD
.ENDC
MOVB DB.WID(J),R0 ;WIDTH
JSR PC,DVPEXA
MOVB DB.ACR(J),R0 ;AUTO CRLF POSITION
JSR PC,DVPEXA
CLR R0 ;FOR NON 2741 80'S SEND ZIP
JSR PC,DVPEXD ; (ELEMENT NUMBER)
MOV DB.TTS(J),R0 ;GET THE "2741" BITS
JSR PC,DVPEXD
TSTB DB.DFT(J) ;CHECK AGAIN
BEQ 50$ ;DON'T SEND A NULL TYPE
MOV J,R4 ;DDB ADDRESS
ADD #DB.DFT,R4 ;FORMS TYPE
BICB #200,5(R4) ;MAKE SURE OF TERMINATION
40$: MOVB (R4),R0 ;GET NEXT BYTE OF TTY TYPE
JSR PC,DVPDAT ;SEND AS DATA
TSTB (R4)+ ;CHECK WHAT WE SENT
BMI 40$ ;LOOP OVER EXTENSIBLE BYTES
50$: BIC #DS.XCH,@J ;HAVE SENT THEM NOW
TYICK3:
.IF NE FT.TSK
BIT #DS.Q10,(J) ;IS THERE STUFF IN THIS ?
BEQ 24$
BIC #DS.Q10,(J) ;NOT ANY LONGER
BR 26$
.ENDC
24$: BIT #DS.XDS,@J ;NEED TO SEND DEVICE STATUS ?
BEQ 40$
26$:
JSR PC,DVPDCS ;PUT DEVICE STATUS INTO THE MESSAGE
40$:
RDACN0: MOV DB.IBF(J),R0 ;GET MESSAGE POINTER
BEQ TYICK9 ;IF NO CORE
.IF NE FT.RDA
TST DB.RDT(J) ;RDX DEVICE ?
BEQ 45$ ; NO
BPL 39$ ;NO BREAK SEEN
BIC #RDEBRK,DB.RDT(J) ;CLEAR BREAK SEEN
38$: DECB DB.IDR(J) ;COUNT REQUEST OFF
BR 45$
39$: CMP DB.ICC(J),#TTYMIC ;DO WE HAVE TO SHIP IT ?
BHIS 38$ ; YES
BR TYICK9 ;RETURN TO USER
45$:
.ENDC
TST DB.ICN(J) ;UNFINISHED SUBMESSAGE ?
BEQ 46$
JSR PC,DVPSBM ;CLOSE OFF SUBMESSAGE
46$: MOV J,CN.DDB(R0) ;SAVE DEVICE BLOCK ADDRESS
BIS #DS.IQU,@J ;SO WE DON'T SEND MORE FOR WHILE
CLR DB.ICC(J) ;NO LONGER HOLDING TTY CHARS
JSR PC,NCLIN1 ;GET RID OF MESSAGE
CLR DB.IBF(J) ;FORGET BUFFER
CLR DB.IAD(J) ;FORGET BYTE POINTER
;
; Here after we have cleared our count of input
; characters that gets maintained at interupt level.
; NOTE that we moved the XON code from higher up to down
; here, since we want to make sure all is idle before we
; let the terminal start up again
;
.IF NE FT.RDA
TST DB.RDT(J) ;IS THIS AN RDA
BNE TYICK9 ;YES, SKIP THIS
.ENDC
BIT #DS.IST,(J) ;DID WE STOP INPUT?
BEQ TYICK9 ;NO, BRANCH
JSR PC,SNDXON ;YES, GO SEND AN XON
BIC #DS.IST,(J) ;AND CLEAR XOFF FLAG
TYICK9: RTS PC
SPDTAB: .WORD ^D0
.WORD ^D50
.WORD ^D75
.WORD ^D110
.WORD ^D134
.WORD ^D150
.WORD ^D200
.WORD ^D300
.WORD ^D600
.WORD ^D1200
.WORD ^D1800
.WORD ^D2000
.WORD ^D2400
.WORD ^D3600
.WORD ^D4800
.WORD ^D7200
.WORD ^D9600
.WORD ^D19200
.WORD ^D1
SPDLIM: .WORD ^D2
.MACRO X Q ;MACRO TO MAKE IT EASY TO DEFINE DISPATCH ENTRYS
.IF DF Q
.WORD Q
.IFF
.WORD TRPINT
.ENDC
.ENDM
DEVTYP: ;DISPATCH FOR TYPE OF DEVICE TO TYPE ON
X DHTYPE
X DZTYPE
DEVSPD: ;DISPATCH FOR TYPE OF DEVICE TO SET SPEED ON
X DHSPD
X DZSPD
DEVBKN: ;DISPATCH TO TURN ON XMIT-BREAK
X DHBKON
X DZBKON
DEVBKF: ;DISPATCH TO TURN OFF XMIT-BREAK
X DHBKOF
X DZBKOF
;DEVICE TIMER (USED FOR IRMA CATCHER)
RDATIM:
CTYTIM:
TTYTIM:
JMP @10$(R0) ;DISPATCH ON TIMER CODE
10$: TCLK00 ;(TCLK00) FILLER
30$ ;(TCLK02)
30$ ;(TCLK04)
30$ ;(TCLK06)
30$ ;(TCLK10)
30$ ;(TCLK12)
30$: RTS PC ;HERE TO JUST RETURN
TCLK00: PIOFF
BIT #DS.ACT,@J ;BE SURE IS ACTIVE
BEQ 90$ ;THIS IS A RACE CONDITION
JSR PC,XMTINT ;FAKE TRANSMIT DONE INTERRUPT
90$: PION
100$: RTS PC
TYPHIA: MOV #HIAMSG,R1 ; GET "HOST IS AVAILABLE"
BR TTYMSG ; AND PRINT IT ON THE TTY
TYPNHA: MOV #NHAMSG,R1 ;GET "NO HOST AVAILABLE"
BR TTYMSG ; AND GIVE IT TO THE USER
TYPWCC: MOV #WCCMSG,R1 ;GET "WAITING FOR CONNECT CONFIRM"
BR TTYMSG
TYPHSD: MOV #HSDMSG,R1 ;GET "HOST SENT DISCONNECT"
BR TTYMSG
TYPHWA: MOV #HWAMSG,R1 ;GET "HOST WENT AWAY"
BR TTYMSG
TYPIBF: MOV #IBFMSG,R1 ;GET "INPUT BUFFER FULL"
; BR TTYMSG
;TTYMSG ROUTINE TO START A TTY TYPING A FIXED STRING. (WON'T
; TYPE STRING IF AN RDA LINE, OR IF ONE IS ALREADY TYPING.)
;ENTER WITH
; R1/ ADDRESS OF STRING TO TYPE
TTYMSG: TST DB.STR(J) ;DON'T FORCE THE MSG IF
BNE 99$ ;ONE IS ALREADY TYPING OUT
.IF NE FT.RDA
TST DB.RDT(J) ;RDA ??
BNE 99$ ;YES, DON'T SEND HIM GARBAGE.
.ENDC
MOV R1,DB.STR(J)
; CLRB DB.TIM(J) ;CLEAR TIMER SO OUTPUT SURE TO START.
; ; (THIS IS NECESSARY BECAUSE IF WE
; ; ARE PRINTING A DISCONNECT MSG,
; ; CLRDDB WILL CLEAR TIMER AND STOP US)
JSR PC,BEGXMT ;START THE TTY TYPING
99$: RTS PC
TYMSG1: RTS PC
;HERE FROM LOOP WITH INPUT CHAR IN R0, DEVICE BLOCK ADR IN J
RECINT: BIT #DS.DIE!DS.DSC,@J ;DID TEN DIE ?
BNE TYMSG1 ;TOSS CHAR AND LET DISCONNECT
; CODE TELL USER WHAT'S GOING ON
.IF NE FTHOST!FT.RDA
BIT #DS.CON,@J ;IS TTY CONNECTED ?
BNE RECIN0
.ENDC
.IF NE FT.RDA
TST DB.RDT(J) ; IS THIS RDA DEV ??
BNE TYMSG1 ; YES, DUMP IT
.ENDC
.IF NE FTHOST
JSR PC,FNDPFH ;TRY TO CONNECT TO HOST
BEQ TYPNHA ;IF NO HOST AVAILABLE, TELL THE USER
JSR PC,SNDCON ;TRY TO CONNECT TO THE HOST
BR TYPWCC ;TELL THE GUY WE SENT A CONNECT FOR HIM
.ENDC
;HERE TO PROCESS THE CHARACTER
RECIN0:
.IF NE FTHOST
TST DB.RLA(J) ;ARE WE HALF WAY THERE
BEQ TYPWCC ;IF SO, SAY "WAITING FOR CONFIRM"
.ENDC
.IF NE FT.TSK
BIT #DS.PAU,(J) ;DID THIS COME FROM A TASK
BEQ 14$ ;NO, INTERUPT LEVEL CHECKS BUFFER FULL
CMP #TTYMIC,DB.ICC(J) ;HOW MANY CHARS ALREADY WAITING ?
BMI TYPIBF ;TELL USER THAT INPUT BUFFER IS FULL
.ENDC
14$: BIC #^C377,R0 ;STRIP EXTRA BITS
MOV R0,R1 ;COPY CHARACTER
BIT #TT.8BT,DB.TTS(J) ;IS THIS AN 8-BIT TERMINAL?
BNE 13$ ;YES, DON'T TRIM TO 7-BIT
BIC #^C177,R1 ;NO, STRIP EXTRA BITS
13$: CMPB R1,#21 ;IS THIS AN "XON"
BNE 15$ ;NO, MOVE ALONG
SAVE <R0,R1> ;SAVE CHARACTER
JSR PC,BEGXMT ;YES, START TYPING
RESTORE <R1,R0> ;GET BACK CHARACTER
15$: BIT #DS.XDS,(J) ;SEND NEW STATUS TO HOST?
BEQ 16$ ;NO, KEEP GOING
SAVE <R0,R1> ;PROTECT OUR CHAR FROM DNDEV
JSR PC,DVPDCS ;SEND STATUS TO THE -10
RESTORE <R1,R0> ;GET THE CHARACTER BACK
16$: BIT #TS.IMI,DB.DCS(J) ;CHECK FOR IMAGE INPUT MODE
BNE RECIN1 ;IN WHICH WHICH CASE NO EDITING
CMP R1,#40 ;SPACE?
BNE 20$ ;NOPE, DON'T DO AUTO CRLF CHECK
MOVB DB.ACR(J),R2 ;GET ACR POSITION
BEQ 20$ ;0 SAYS WE DON'T DO IT
CMPB R2,DB.COL(J) ;HAVE WE REACHED THAT POINT?
BHI 20$ ;NOT YET, KEEP GOING
MOV #15,R0 ;CHANGE SPACE INTO CR
MOV #15,R1 ;IN BOTH PLACES
20$: BITB #CF..LC,CHRTAB(R1) ;IS CHARACTER LOWER CASE ?
BEQ RECIN1
BIT #TS..LC,DB.DCS(J) ;DO WE WANT TO CONVERT LC TO UPPER ?
BEQ RECIN1
BICB #40,R0 ;CONVERT TO UPPER CASE
RECIN1:
.IF NE FT.RDA
TST DB.RDT(J) ; RDA ??
BNE 99$ ; YES, CHECK FOR BREAK
.ENDC
42$: BIT #TS.DFE,DB.DCS(J) ;IN DEFERED ECHO MODE ?
BNE 55$ ;SEND IT WITH A NEW ECHOPIPELINE MARKER
BIT #DS.ACT,@J ;IS LINE ALREADY TYPING ?
BNE 50$ ;IF SO GO INTO DEFERRED ECHO MODE
BIT #<TS.TAP!TS.IMI>,DB.DCS(J) ;TAPE OR IMAGE MODE?
BNE 43$ ;IF SO, THEN <CR> NOT SPECIAL
CMPB #15,R1 ;IS CHAR A CARRIAGE RETURN ?
BEQ 48$ ;IF SO SPECIAL ACTION
43$: BITB #CHRDEF,CHRTAB(R1) ;DOES THIS CHAR PUT US INTO DEFERRED ECHO MODE ?
BNE 50$
TSTB R0 ;CHECK FOR 8-BIT CHARACTER
BPL 41$ ;NO, IT'S DEFINITELY NORMAL
BIT #TS.8BI,DB.DCS(J) ;YES, TEST FOR 8-BIT INPUT MODE
BEQ 50$ ;NO, WE NEED DEFERRED ECHO AFTER ALL
41$: MOV R0,-(P) ;SAVE CHAR
.IF NE FT.TSK
JSR PC,TK0WAK ;WAKE UP THE 'GET PRINTER' TASK
BEQ 46$ ;IF NONE, JUST ECHO
JSR PC,QTYCHR ;USE NCL ENTRY
BR 49$
.ENDC
46$: TSTB DB.HLD(J) ;IF ALREADY HOLDING A CHAR BETTER FORCE IT OUT
BEQ 44$
47$: JSR PC,BEGXMT ;ECHO IT
MOVB (P),DB.HLD(J) ;SAVE CHAR
BR 45$
44$: MOVB R0,DB.HLD(J) ;SAVE CHAR
49$: JSR PC,BEGXMT ;ECHO IT
45$: MOV (P)+,R0 ;GET CHAR BACK
.IF NE FT.HLD ;IF WE ARE HOLDING CHARACTERS
CMP #<TTYMIC/2>,DB.ICC(J) ;DO WE HAVE PLENTY OF CHARACTERS?
BMI 60$ ;YES, SEND THE MESSAGE NOW
TWIDDLE ;FOR THISE WHO WATCH
TWIDDLE DB.ICC(J) ;SEE HOW MANY CHARS IN THE MESSAGE
JSR PC,DVPDAT ;PUT BYTE INTO THE MESSAGE
BR 70$ ;GO RETURN
.IFF
BR 60$ ;PUT CHAR IN INPUT QUEUE
.ENDC;.IF NE FT.HLD ;IF WE ARE HOLDING CHARACTERS
;HERE WHEN USER TYPES A CARRIAGE RETURN WHILE IN LOCAL ECHO MODE
48$:
.IF NE FT.TSK
JSR PC,TK0WAK ;WAKE UP 'GET PRINTER' TASK
BEQ 51$
MOV R0,-(P) ;SAVE CHARACTER <CR>
JSR PC,QTYCHR ;ECHO THE <CR>
MOV #12,R0 ;AND APPEND A <LF>
JSR PC,QTYCHR
MOV (P)+,R0 ;GET THE <CR> BACK
BR 52$ ;NOW SEND THE <CR> TO THE HOST
.ENDC
51$: MOV #CRLMSG,DB.STR(J) ;TYPE A CR/LF
52$: JSR PC,55$ ;PUT CARRIAGE RETURN INTO MSG
BIS #TS.DFE,DB.DCS(J) ;SET DEFERED ECHO MODE
JSR PC,BEGXMT
JMP DVPDCS ;SEND NEW STATUS TO 10
;IF RDA, CHECK FOR BREAK
.IF NE FT.RDA
99$: CMP #RDABRK,R1 ;BREAK ??
BNE 60$ ; NO
BIS #RDEBRK,DB.RDT(J) ;SET IT SEEN
BR 60$
.ENDC
;HERE TO GO INTO DEFERRED ECHO MODE
50$: BIS #TS.DFE,DB.DCS(J) ;SET DEFERED ECHO FLAG
MOV R0,-(P) ;SAVE INPUT CHAR
JSR PC,DVPDCS ;PUT STATUS INTO MESSAGE
MOV (P)+,R0 ;GET CHAR BACK
55$: BIS #DS.EPL,@J ;NEED TO SEND A NEW ECHO PIPELINE MARKER
60$: JSR PC,DVPDAT ;PUT BYTE INTO THE MESSAGE
98$: JSR PC,QUEDEV ;WAKE SERVICE ROUTINE
70$:
.IF NE FT.RDA!FT.TSK
.IF NE FT.RDA
TST DB.RDT(J) ;IS THIS AN RDA DEVICE?
BNE 75$ ;YES, NEED TO COUNT CHAR
.ENDC
.IF NE FT.TSK
BIT #DS.PAU,(J) ;DID THIS COME FROM A TASK?
BEQ RECINX ;NO, DON'T COUNT, INTERUPT LEVEL HAS
.ENDC
75$: INC DB.ICC(J) ;COUNT CHAR INTO THE MESSAGE
.ENDC ; .IF NE FT.RDA!FT.TSK
RECINX: RTS PC
;HERE TO SEND XON
SNDXON: MOVB #21,R0 ;GET XON
BR SNDNOW ;GO SEND IT
;HERE TO SEND XOFF
SNDXOF: MOVB #23,R0 ;GET XOFF
BIT #TT.8BT,DB.TTS(J) ;IS THIS AN 8-BIT TTY?
BNE SNDNOW ;YES, SEND AS IS
BIT #TT.8BL,DB.DVT(J) ;NO, IS IT AN 8-BIT LINE?
BNE SNDNOW ;YES, LEAVE IT ALONE ANYWAY
BIS #200,R0 ;NO, MUST SEND WITH PARITY
SNDNOW: PIOFF ;INTERUPTS OFF
BIT #DS.ACT,@J ;ARE WE ALREADY OUTPUTING?
BEQ 10$ ;NO, START OUTPUT
MOVB R0,DB.ASP(J) ;YES, WE'LL CATCH IT AT NEXT XMT INT
BR 20$ ;TURN ON INTERRUPTS AND EXIT
10$: BIS #DS.ACT,@J ;SAY WE ARE TYPING
JSR PC,TYPE90 ;GO SEND IT
20$: PION ;INTERUPTS BACK ON
RTS PC ;RETURN
BEGXMT: PIOFF ;DISABLE INTERRUPTS
BIT #DS.ACT,@J ;ARE WE ALREADY TYPING ?
BNE 20$ ;IN CASE ALREADY TYPING
BIS #DS.ACT,@J ;SET ACTIVE FLAG
TSTB DB.TIM(J) ;IF TIMER IS RUNNING,EXIT
BNE 20$
JSR PC,XMTINT
20$: PION ;REENABLE INTERRUPTS
RTS PC
;HERE WHEN NO OUTPUT LEFT AND MAY WANT TO RELEASE OUTPUT CHUNK
XMT.80: TST DB.OBF(J)
BNE XMT.90
DEC R0 ;BACK UP TAKER
BIC #CNKSIZ-1,R0 ;MAKE INTO A CHUNK ADR
JSR PC,FRECNK ;RELEASE CHUNK
CLR DB.TOB(J) ;CLEAR POINTER
CLR DB.TOB+2(J) ;AND PUTTER
;HERE WHEN NOTHING MORE TO TYPE
XMT.90: JSR PC,QUEDEV ;SEND DATA REQUESTS MAYBE
BIC #DS.ACT,@J ;CLEAR ACTIVE FLAG
.IF NE FT.TSK
MOV J,-(P) ;SAVE DDB ADR
MOV DB.TSK+4(J),J ;GET TASK BLOCK ADR
BEQ 12$ ;IF NONE WE ARE DONE
JSR PC,TSKWAK ;WAKE UP THE TASK
12$: MOV (P)+,J ;RESTORE DDB ADR
.ENDC
20$: RTS PC
;HERE AT INTERRUPT LEVEL TO SEE IF THERE ARE MORE CHARS TO TYPE
TTDZOU:
TTDHOU:
XMTINT: MOVB DB.ASP(J),R0 ;DO WE WANT TO SEND A CHARACTER FAST?
BEQ 1$ ;NO
CLRB DB.ASP(J) ;YES, CLEAR OUT THE CHAR
JMP TYPE90 ;AND SEND IT
1$: CMP #20,JIFFLG ;IF CLOCK LEVEL HAS RUN RECENTLY
BGE XMT.0 ; THEN IT'S OK TO RUN TERMINALS NOW
MOVB #3,DB.TIM(J) ;IF WE'VE BEEN TYING UP THE MACHINE
BIS #DS.ACT,@J ;FLAG THE LINE AS "ACTIVE"
5$: RTS PC ;BUT OTHERWISE SHUT IT DOWN
; (LETTING IRMA RESTART IT LATER)
XMT.0: CLR DB.TIM(J) ;CLEAR THE TIMER
.IF NE FT.RDA
TST DB.RDT(J) ;RDA DEVICE ??
BNE 33$ ; YES
.ENDC
MOV DB.LCB(J),R1 ;POINT TO LCB OF LINE
BIT #LCB.DS,@R1 ;IS THIS A DATA SET LINE?
BEQ 2$ ; NO, SO GO AHEAD
CMPB #LCS.CD,LC.STA(R1) ;SEE IF WE ARE AUTOBAUDING (OR ABOUT TO)
BGT 2$ ; STATE < LCS.CD
CMPB #LCS.AB,LC.STA(R1) ;MAX STATE TO HOLD ON
BLT 2$ ; STATE > LCS.AB
MOVB #-6,DB.TIM(J) ;WAIT FOR LATER TO CHECK FOR OUTPUT
RTS PC
2$:
10$: MOV DB.FTM(J),DB.TIM(J) ;SET IRMA TIMER WAITING IN WINGS
BEQ 20$ ;IF NONE FIND NEXT CHAR TO TYPE
CLR DB.FTM(J)
RTS PC ;WAIT FOR TIMER TO GO OFF
20$: TST DB.STR(J) ;IS THERE A MESSAGE TO TYPE ?
BEQ 30$
MOVB @DB.STR(J),R1 ;GET NEXT CHAR IN STRING
BNE 22$
CLR DB.STR(J) ;HAVE EXHAUSTED STRING
BR 30$
22$: INC DB.STR(J) ;ADVANCE STRING POINTER
BR 38$
30$: MOVB DB.HLD(J),R1 ;HOLDING A CHARACTER ?
BEQ 32$ ; FROM FREE CR/LF ?
CLRB DB.HLD(J) ;DON'T TYPE IT TWICE
BR 38$ ;BUT GO TYPE IT NOW
32$: BIT #TS.FRZ,DB.DCS(J) ;IS OUTPUT STOPPED WITH XOF ?
BNE XMT.90 ;IF SO STOP TYPING
33$:
.IF NE FT.TSK
MOV DB.PTK(J),R0 ;GET PRINTER TAKER (TASK)
BEQ 50$ ;IF NON, TRY FOR STUFF FROM NCL
DEC DB.PCN(J) ;ADJUST COUNT
ASSERT PL
JSR PC,XMTGET ;POINT TO NEXT CHARACTER IN CHUNKS
MOVB (R0)+,R1 ;GET NEXT BYTE
CMP R0,DB.PPT(J) ;WAS THAT THE LAST
BNE 46$
DEC R0
BIC #CNKSIZ-1,R0 ;RESTORE CHUNK POINTER
JSR PC,FRECNK ;RELEASE CHUNK
CLR DB.PPT(J) ;CLEAR PUTTER
CLR R0
46$: MOV R0,DB.PTK(J) ;SAVE UPDATED PUTTER
BR 38$
50$: TST DB.TSK(J) ;IS THERE A 'GET PRINTER' TASK
BNE XMT.90 ;IF SO STOP THE XMITTER
.ENDC
36$: MOV DB.TOB(J),R0 ;GET POINTER TO OUTPUT CHARS
BEQ XMT.90 ;IF NONE WE ARE DONE
CMP R0,DB.TOB+2(J) ;SAME AS PUTTER ?
BEQ XMT.80
JSR PC,XMTGET ;POINT TO NEXT BYTE
MOVB (R0)+,R1 ;GET NEXT BYTE
MOV R0,DB.TOB(J)
DEC DB.TOC(J) ;COUNT CHAR OUT OF CHUNKS
CMP R1,#ESCF ;IS IT ESCAPE FUNCTION CHARACTER?
BNE 38$ ;NO, CONTINUE NORMALLY
JSR PC,XMTGET ;POINT TO NEXT CHARACTER
MOVB (R0)+,R1 ;GET FUNCTION
MOV R0,DB.TOB(J) ;UPDATE TAKER
DEC DB.TOC(J) ;AND ACCOUNT FOR CHARACTER
CMP R1,#ESCF ;ANOTHER ESCAPE?
BEQ 38$ ;YES, PASS IT ON AS DATA
JSR PC,DOESCF ;NO, DO FUNCTION
BR 36$ ;LOOK FOR ANOTHER CHARACTER
38$: MOVB #-2,DB.TIM(J) ;RESET IRMA CATCHER
BIT #TS.IMO,DB.TTC(J) ;IMAGE MODE?
BEQ 39$ ;NO,
MOV R1,R0 ;YES, COPY CHARACTER
JMP TYPE90 ; NO EDITING
39$: CMPB #11,R1 ;IS THIS A TAB?
BEQ 40$ ; IF SO, GO DO FILL
BIT #TT.8BT,DB.TTS(J) ;IS THIS AN 8-BIT TTY?
BNE TYPEIT ;YES, GO DO IT
CMPB #211,R1 ;NO, IS THE OTHER FLAVOR OF TAB ?
BNE TYPEIT
40$: MOVB DB.COL(J),R2 ;GET CURRENT COLUMN
ADD #10,R2 ;WHERE WE WILL BE WHEN DONE
BIC #7,R2
BIT #TS.CRL,DB.TTC(J) ;EVER DO FREE CR/LF
BNE 62$
CMPB R2,DB.WID(J) ;IS THAT INSIDE BOUNDRY ?
BLOS 62$
MOV R1,R0 ;PUT CH WHERE IT IS EXPECTED
JMP TYPE85 ;IF NOT TYPE CR FIRST
62$: BIT #TS.TAB,DB.TTC(J) ;DOES TTY HAVE HARDEWARE TAB ?
BNE XMT.2
INCB DB.COL(J) ;ADVANCE COLUMN POINTER
BITB #7,DB.COL(J) ;WAS THAT LAST ?
BEQ XMT.1
MOVB R1,DB.HLD(J) ;SAVE TAB FOR LATER
XMT.1: MOV #40,R1
DECB DB.COL(J) ;SPACES WILL INC LATER
BR TYPEIT
XMT.2: MOVB R2,DB.COL(J) ;SAVE COLUMN
BR TYPEIT ;GO TYPE CHARACTER
;SUBROUTINE TO ADVANCE CHUNKS AND CAUSE DATA REG UNITS TO BE SENT
;CALL MOV <CHUNK ADDRESS<,R0
XMTGET: BIT #CNKSIZ-1,R0 ;ARE WE PAST END OF CURRENT CHUNK?
BNE 10$ ;NO, NOTHING SPECIAL
JSR PC,QUEDEV ;YES, WAKE SERVICE ROUTINE AT LOOP LEVEL
10$: ADVCNK R0,FREE ;POINT TO NEXT BYTE
RTS PC ;RETURN TO CALLER
;SUBROUTINE TO DO ESCAPE FUNCTION
; CALL MOV <FNC>,R1
; JSR PC,DOESCF ;GET FUNCTION IN REGISTER
DOESCF: CMP R1,#ESCF ;IS IT A SECOND ESCAPE CHARACTER?
BEQ 10$ ;IF SO, RETURN IMMEDIATELY
CMP R1,#MAXESC+1 ;CHECK RANGE
ASSERT LE
.IF NE DGUTS
BHI 10$ ;SIGH
.ENDC
MOV R1,-(SP) ;SAVE SET/CLEAR STATUS
BIC #1,R1 ;REDUCE TO VALID INDEX
MOV ESCTAB(R1),R1 ;GET BIT TO TWEAK
BIT #1,(SP)+ ;TEST FOR SET VS. CLEAR
BNE 5$ ;CLEAR
BIS R1,DB.TTC(J) ;SET
BR 10$ ;DONE SETTING
5$: BIC R1,DB.TTC(J) ;CLEAR THE BIT
10$: RTS PC
TS.ESC=0 ;START OUT WITH NO SYNCHRONOUS FUNCTIONS
.MACRO X BIT ;DISPATCHING MACRO
.WORD TS.'BIT ;THE BIT TO TEST AGAINST
TS.ESC=TS.ESC!TS.'BIT ;INCLUDE IT IN THE MASK
.ENDM
ESCTAB: ;ESCAPE FUNCTION TABLE
X IMO ;IMAGE OUTPUT
X TAB ;HARDWARE TABS
X FRM ;HARDWARE FORM FEED
X CRL ;NO FREE CRLF
MAXESC=.-ESCTAB-2 ;MAXIMUM LEGAL INDEX
TS.ESC=TS.ESC ;BITS TO HANDLE SYNCHRONOUSLY
;HERE TYPE A CHAR
; CALL JSR PC,TYPEIT ;WITH J SET UP AND CHAR IN R1
TYPEIT:
TYPE40: MOV R1,R0 ;COPY CHARACTER
BIT #TS.IMO,DB.TTC(J) ;IMAGE MODE OUTPUT ?
BNE TYPE90 ;IF SO NO EDITING
BIT #TT.8BT,DB.TTS(J) ;8-BIT TTY?
BNE 30$ ;YES, AVOID PARITY
BIC #^C177,R1 ;STRIP PARITY BIT
MOV R1,R0 ;COPY JUST IN CASE
BIT #TT.8BL,DB.DVT(J) ;8-BIT LINE?
BNE 30$ ;YES, AVOID PARITY
MOVB PARTAB(R1),R0 ;PUT PARITY ON CHARACTER
30$: BITB #CHRHMO,CHRTAB(R1) ;IS THIS A NORMAL ASCII CHARACTER ?
BNE TYPE82 ;IF SO JUST ADJUST COUNT
BITB #CHRFLL,CHRTAB(R1) ;DOES CHAR REQUIRE FILLERS ?
BEQ 61$
MOV R1,R2 ;COPY 7 BIT CHAR
ADD #DB.FIL-10,R2
ADD J,R2
MOVB @R2,DB.FTM(J) ;SET FILL TIMER FOR LATER USE
61$: CMPB #10,R1 ;IS CHAR A BACKSPACE ?
BEQ TYPE81 ;BACKUP COLUMN POINTER
CMPB #11,R1 ;IS CHAR HORIZONTAL TAB ?
BEQ TYPE90 ;IF SO DB.COL ALREADY COUNTED
CMPB #204,R1 ;IS THIS A NEW-LINE?
BEQ 62$ ;TREAT LIKE CR
CMPB #15,R1 ;IS THIS A CARRIAGE RETURN ?
BNE TYPE90
62$: CLRB DB.COL(J) ;BACK IN COLUMN 0 !
BR TYPE90
;HERE WHEN TYPING A BACKSPACE
TYPE81: DECB DB.COL(J) ;BACK UP COLUMN COUNTER
BGE TYPE90 ;IF STILL POSITIVE TYPE IT
CLRB DB.COL(J) ;ELSE BACK TO COLUMN ZERO
BR TYPE90 ;THEN TYPE IT
;HERE FOR USUAL PRINTING CHARACTERS
TYPE82: INCB DB.COL(J) ;COUNT COLUMNS
TYPE83: CMPB DB.COL(J),DB.WID(J) ;WAS THIS ALREADY ON RH MARGIN ?
BLOS TYPE90 ;IF OK CONTINUE
BIT #TS.CRL,DB.TTC(J) ;EVER DO FREE CR/LF
BNE TYPE90 ;IF NOT DON'T DO ONE NOW
TYPE85: MOVB R0,DB.HLD(J) ;SAVE CHARACTER FOR LATER
MOV #CRLMSG,DB.STR(J) ;DO A CR/LF FIRST
JMP XMTINT ;AND START OVER
;HERE WHEN HAVE SET FILLERS ETC.
TYPE90:
.IF NE TTYN+RDAN+FT.CTY
.IF NE FT.CTY
CMP J,#CTYDDB ;IS THIS FOR THE CTY ?
BNE 33$
JMP CTYTYP ;IF SO DO IT
33$:
.ENDC
MOV DB.LCB(J),R1 ;POINT TO LCB
CMPB #LCS.RU,LC.STA(R1) ;LINE OK?
BGT 95$ ; NO, DONT PRINT IT
CMPB #LCS.RC,LC.STA(R1) ;LINE OK?
BLT 95$ ; NO, DONT PRINT IT
JINDEX JMP,DB.TYP(J),R2,DEVTYP
95$: MOVB #-1,DB.TIM(J) ;SIMULATE 600 BAUD
RTS PC ;IRMA WILL CATCH THIS LATER
.ENDC
.IIF EQ TTYN, BR CTYTYP
.SBTTL TABLES FOR AUTO BAUD UP TO 9600 BAUD (LOW BIT IS MASKED OFF)
HSPMSK=376 ;MASK FOR UNWANTED BITS (HIGH SPEED AUTOBAUD)
HSPCHR=377 ;CHAR TO SWITCH TO HIGH SPEED DETECT
LSPCHR=000 ;CHAR TO SWITCH TO LOW SPEED DETECT
LSPTAB: .BYTE 174 ;110 BAUD ^C
.BYTE 214 ;110 BAUD CR
.BYTE 234 ;110 BAUD CR
.BYTE 346 ;150 BAUD CR
.BYTE 036 ;150 BAUD ^C
.BYTE 215 ;300 BAUD CR
.BYTE 015 ;300 BAUD CR, ODD
.BYTE 003 ;300 BAUD ^C
.BYTE 203 ;300 BAUD ^C, ODD
.BYTE 376 ;1200 BAUD ^C, EVEN
LSPEND: ;END OF TABLE
;TABLE OF LOW SPEED INDEX'S
LSP.IG=200 ;THROW AWAY NEXT CHAR AFTER AB CHAR (SIGN BIT)
LSP.SP=017 ;MASK FOR SPEED INDEX
LSPSPD: .BYTE 00 ;110 BAUD ^C
.BYTE LSP.IG!00 ;110 BAUD CR
.BYTE LSP.IG!00 ;110 BAUD CR
.BYTE LSP.IG!01 ;150 BAUD CR
.BYTE 01 ;150 BAUD ^C
.BYTE 02 ;300 BAUD CR
.BYTE 02 ;300 BAUD CR, ODD
.BYTE 02 ;300 BAUD ^C
.BYTE 02 ;300 BAUD ^C, ODD
.BYTE 04 ;1200 BAUD ^C, EVEN
.EVEN
;HIGH SPEED TABLE (NOTE THAT HSPMSK MASKS CHARACTERS BEFORE COMPARE)
HSPTAB: .BYTE 200 ;300 BAUD CR OR ^C, ODD OR EVEN
.BYTE 036 ;1200 BAUD ^C, ODD OR EVEN
.BYTE 346 ;1200 BAUD CR, ODD OR EVEN
.BYTE 006 ;1800 BAUD ^C, ODD OR EVEN
.BYTE 072 ;1800 BAUD CR, ODD OR EVEN
.BYTE 002 ;2400 BAUD ^C, EVEN
.BYTE 202 ;2400 BAUD ^C, ODD
.BYTE 214 ;2400 BAUD CR, EVEN
.BYTE 014 ;2400 BAUD CR, ODD
.BYTE 370 ;4800 BAUD ^C, ODD
.BYTE 360 ;4800 BAUD ^C, EVEN
.BYTE 374 ;4800 BAUD ^C, EVEN
.BYTE 376 ;9600 BAUD ^C OR CR, ODD OR EVEN
HSPEND: ;END OF TABLE
;TABLE OF HIGH SPEED INDEX'S
HSPSPD: .BYTE LSP.IG!2 ;300 BAUD CR OR ^C
.BYTE LSP.IG!04 ;1200 BAUD ^C
.BYTE LSP.IG!04 ;1200 BAUD CR
.BYTE 05 ;1800 BAUD ^C
.BYTE 05 ;1800 BAUD CR
.BYTE 06 ;2400 BAUD ^C
.BYTE 06 ;2400 BAUD ^C
.BYTE 06 ;2400 BAUD CR
.BYTE 06 ;2400 BAUD CR
.BYTE 07 ;4800 BAUD ^C
.BYTE 07 ;4800 BAUD ^C
.BYTE 07 ;4800 BAUD ^C
.BYTE 10 ;9600 BAUD ^C, CR
.EVEN
;DH11 HARDWARE SPEEDS
SPDPAR: .WORD B.110 ;00
.WORD B.150 ;01
.WORD B.300 ;02
.WORD B.600 ;03
.WORD B.1200 ;04
.WORD B.1800 ;05
.WORD B.2400 ;06
.WORD B.4800 ;07
.WORD B.9600 ;10
.SBTTL TTY INPUT INTERRUPT SERVICE
.IF NE TTYN
ABCHAR: .WORD 0 ;STORE THE AUTOBAUD CHARACTER HERE
;HERE ON A DH11 OR DZ11 CHARACTER INTERUPT
TTDZIN:
TTDHIN:
MOV DB.LCB(J),R2 ;POINT TO LCB
BIT #LCB.IG,LC.CAR(R2) ;ARE WE IGNORING THIS LINE FOR 1 CHAR
BEQ 10$ ;NO
BIC #LCB.IG,LC.CAR(R2) ;YES, SKIP THIS CHAR AND GRAB NEXT
BR LRTS
10$: CMPB #LCS.AB,LC.STA(R2) ;AUTO BAUD?
BEQ REC.AB ; YES
CMPB #LCS.RU,LC.STA(R2) ;LINE OK?
BGT LRTS ; IF IT ISN'T, PUNT THE CHAR
CMPB #LCS.RC,LC.STA(R2) ;LINE OK?
BLT LRTS ; IF IT ISN'T, PUNT THE CHAR
BIT #DHRFER,R1 ;CHECK FOR A FRAMING ERROR
BEQ REC.00 ;BRANCH IF NORMAL CHARACTER
;HERE TO HANDLE A FRAMING ERROR - PROBABLY A BREAK
BIT #LCB.BK,LC.CAR(R2) ;WAS LAST CHAR A BREAK?
BNE 30$ ;YES, WE HAVE GOTTEN TWO IN A ROW
BIS #LCB.BK,LC.CAR(R2) ;NO, FLAG THIS ONE
BR LRTS ;AND IGNORE IT
30$: BIT #LCB.AB,LC.CAR(R2) ;IF THIS ISN'T AN AUTO-BAUD
BEQ LRTS ;LINE, THEN DON'T RESET SPEED
SET.AB: MOVB #LCS.AB,LC.STA(R2) ;RESET STATE TO AUTO-BAUD
BIS #LCB.TM,LC.CAR(R2) ;GIVE HIM FOREVER TO RESPOND
BIC #LCB.LS,LC.CAR(R2) ;USE HIGH SPEED TABLE
MOV #B.HSPD,-(P) ;PUSH A SPEED OF 2400 BAUD,
JSR PC,SETSPD ;AND SET THE LINE TO IT.
TST (P)+ ;CLEAN UP THE STACK
LRTS: RTS PC ;AND GO HOME
REC.AB: MOVB R1,ABCHAR ;SAVE CHAR
BIT #LCB.LS,LC.CAR(R2) ;USING LOW SPEED TABLE?
BEQ 15$ ;NO, USE HIGH SPEED
CMPB #HSPCHR,R1 ;IS THIS A HIGH SPEED CHARACTER?
BEQ 60$ ;YES, SET HIGH SPEED AND TRY AGAIN
MOV #LSPTAB,R0 ;GET START OF TABLE
10$: CMP R0,#LSPEND ;AT END OF TABLE
BEQ 60$ ;BRANCH IF END OF TABLE
CMPB R1,(R0)+ ;DOES CHAR MATCH
BNE 10$ ;LOOP IF NOT
MOVB LSPSPD-LSPTAB-1(R0),R0 ;GET CHAR STATUS
BR 30$ ;GO TO COMMON CODE
15$: MOV #HSPTAB,R0 ;GET START OF TABLE
BICB #^C<HSPMSK>,R1 ;STRIP OFF UNWANTED BITS
CMPB #LSPCHR,R1 ;IS THIS A LOW SPEED CHARACTER?
BEQ 20$ ;YES, GO SEARCH LOW SPEEDS
20$: CMP R0,#HSPEND ;AT END OF TABLE
BEQ 50$ ;BRANCH IF END OF TABLE
CMPB R1,(R0)+ ;DOES CHAR MATCH
BNE 20$ ;LOOP IF NOT
MOVB HSPSPD-HSPTAB-1(R0),R0 ;GET CHAR STATUS
30$: BPL 40$ ;BRANCH IF NOT IGNORING NEXT CHAR
BIS #LCB.IG,LC.CAR(R2) ;IGNORE THE NEXT CHAR ON THIS LINE
40$: MOV R0,R2 ;MAKE COPY
BIC #^C<LSP.SP>,R2 ;GET INDEX BITS
ASL R2 ;MAKE IT A WORD
MOV SPDPAR(R2),-(P) ;GET THE DH11 SPEED BITS
JSR PC,SETSPD ;GO SET NEW SPEED
TST (P)+ ;NOW POP OFF USED SPEED BITS
MOV DB.LCB(J),R1 ;GET POINTER TO LCB
MOVB #LCS.RU,LC.STA(R1) ;GO TO RUNNING STATE
BIC #LCB.TM,LC.CAR(R1) ;STOP ANY TIMERS
BIS #DS.XDS,@J ;ALSO TELL THE -10
MOVB #1,DB.TIM(J) ;KICK THE IRMA TIMER
BIT #TT.8BL,DB.DVT(J) ;CHECK FOR 8-BIT LINE
BNE 44$ ;GO IF WANT 8-BIT
BIC #TT.8BT,DB.TTS(J) ;MAKE SURE WE START IN 7-BIT
MOV #215,R1 ;A CR
BR 46$ ;MAKE IT LOOK LIKE THE USER TYPED IT
44$: BIS #TT.8BT,DB.TTS(J) ;MAKE SURE WE START IN 8-BIT
MOV #015,R1 ;A CR
46$: JMP TTYINP ;LOOKS LIKE THE USER TYPED IT
50$: BIS #LCB.IG,LC.CAR(R2) ;IGNORE THE NEXT CHARACTER
MOV #B.LSPD,-(P) ;PUSH A SPEED OF 300 BAUD
BIS #LCB.LS,LC.CAR(R2) ;USE LOW SPEED TABLE
BR 70$ ;GO TO COMMON CODE
60$: MOV #B.HSPD,-(P) ;PUSH A SPEED OF 2400 BAUD,
BIC #LCB.LS,LC.CAR(R2) ;USE HIGH SPEED TABLE
70$: JSR PC,SETSPD ;AND SET THE DETECTION SPEED
TST (P)+ ;CLEAN UP THE STACK
RTS PC ;DON'T DO ANYTHING WITH THE CHAR
REC.00: BIC #LCB.BK,LC.CAR(R2) ;CLEAR BREAK CHAR FLAG
JMP TTYINP ;PASS INPUT TO QUEUE
.ENDC;NE TTYN
;CTY INPUT INTERRUPT
.IF NE FT.CTY
CTIINT: SAVE <J>
MOV #CTYDDB,J ;GET DEVICE BLOCK FOR CTY
SAVE <R0,R1>
TSTB CTISTS ;CHECK IT WAS DATA INTERRUPT
BGE CTIIN9 ;TRASH INTERRUPT
SPL 7 ;LOCK OUT EVERYTHING ELSE
MOV CTICHR,R1 ;GET KEYBOARD DATA & CLEAR FLAG
.IF NE FT.DDT
CMP #204,R1 ;DID I TYPE A CTRL/D?
BNE CD1 ;NOPE, IGNORE
CD: BR CTIIN9 ;PUT BREAKPOINT HERE
CD1:
.ENDC
JSR PC,TTYINP ;HAVE TTY INPUT
CTIIN9: RESTORE <R1,R0>
RESTORE <J>
RTI ;DISMISS INTERRUPT
;CTY OUTPUT INTERRUPT
CTOINT: SAVE <R0,R1,R2,R3,J>
MOV #CTYDDB,J ;LOAD DEVICE BLOCK ADDRESS
CLR CTOSTS ;DISABLE INTERRUPTS
JSR PC,XMTINT ;GO SEE WHAT WE CAN DO NEXT
RESTORE <J,R3,R2,R1,R0>
RTI
CTYTYP: MOVB R0,CTOCHR ;TYPE NEXT CHAR
MOVB #100,CTOSTS ;ENABLE INTERUPTS
RTS PC
.ENDC
;HERE TO QUEUE A CHAR TO TYPED
; CALL: LOAD J WITH TTY DEVICE BLOCK ADDRESS
; MOV <CHR>,R0
; JSR PC,QTYCHR
QTYCHR: MOV R0,R3 ;COPY BYTE
PIOFF
JSR PC,QTYCH ;QUEUE THE CHARACTER
PION
RTS PC
;SUBROUTINE TO QUEUE ESCAPE CHARACTER + FUNCTION CODE
; CALL MOV <FNC>,R0 ;PUT FUNCTION IN R0
; JSR PC,QTECHR ;ASSUMES J CONTAINS DDB ADDRESS
QTECHR: PIOFF
MOV R0,-(P) ;SAVE FUNCTION CODE
MOV #ESCF,R3 ;GET ESCAPE CHARACTER
JSR PC,QTYCH ;QUEUE IT
MOV (P),R3 ;RETRIEVE FUNCTION
JSR PC,QTYCH ;QUEUE IT ALSO
MOV (P)+,R0 ;RETURN R0 INTACT
PION
RTS PC
QTYCH: MOV DB.TOB+2(J),R0 ;GET POINTER TO LAST DATA CHAR
BNE 14$
JSR PC,ERSGET ;TAKE FROM EMERGENCY STORE
TST (R0)+ ;SKIP LINK WORD
MOV R0,DB.TOB+2(J) ;SET LIMIT WORD
MOV R0,DB.TOB(J) ;SET 1ST BYTE POINTER
14$: ADVCNK R0 EXTEND ;ADVANCE TO NEXT CHARACTER
; ;ALLOCATING A NEW CHUNK IF REQUIRED
16$: MOVB R3,(R0)+ ;PUT BYTE INTO CHUNK
MOV R0,DB.TOB+2(J) ;RESET LIMIT BYTE POINTER
INC DB.TOC(J) ;COUNT CHAR INTO THE CHUNKS
RTS PC
;HERE TO PASS TTY INPUT CHAR TO TASK OF NCL
; CALL WITH J POINTING TO LINE BLOCK
; AND INPUT CHAR IN R1
TTYINP:
.IF NE FT.TSK
MOV DB.TSK+2(J),R0 ;GET TASK BLOCK THAT WANTS INPUT
BEQ TYPIN0
SAVE <J>
MOV R0,J
JSR PC,TSKWAK ;WAKE THE TASK
RESTORE <J>
MOV DB.KPT(J),R0 ;GET KEYBOARD PUTTER
ADD J,R0 ;MAKE ADR ABSOLUTE
MOV R1,(R0)+ ;PUT CHAR INTO BUFFER
SUB J,R0 ;MAKE ADR RELATIVE AGAIN
CMP R0,#DB.KQU+TQS+TQS ;DID WE HIT END OF QUEUE ?
BNE 20$
MOV #DB.KQU,R0 ;YES SO POINT TO START
20$: CMP R0,DB.KTK(J) ;WOULD THIS OVERTAKE TAKER ?
BEQ 90$ ;IF SO DON'T DO IT
MOV R0,DB.KPT(J) ;NO SO FREEZE IT
90$: RTS PC
.ENDC
TYPIN0: CMP #TTYMIC,DB.ICC(J) ;HOW MANY CHARS ALREADY WAITING ?
BPL 5$ ;STILL OK
JMP TYPIBF ;TELL USER THAT INPUT BUFFER IS FULL
5$: MOV R1,R0 ;COPY THE CHARACTER
BIT #TT.8BT,DB.TTS(J) ;CHECK FOR 8-BIT TTY
BNE 10$ ;YES, DON'T STRIP "PARITY"
BIC #^C177,R0 ;NO, CLEAR PARITY IN THE COPY
10$: BIT #TS.PAG,DB.DCS(J) ;ARE WE IN PAGE MODE?
BEQ 20$ ;NO, DON'T CHECK XON/XOFF
CMPB #23,R0 ;WAS THE CHAR ^S (XOFF)?
BNE 12$ ;NO, CHECK ^Q
BIS #TS.FRZ,DB.DCS(J) ;YES, STOP OUTPUT
BR 20$ ;QUEUE THE XOFF
12$: CMPB #21,R0 ;WAS THE CHAR A ^Q (XON)?
BNE 20$ ;NO, NORMAL CHAR
BIC #TS.FRZ,DB.DCS(J) ;YES, START OUTPUT
20$: QUEPUT TI ;PUT THE CHAR IN THE INPUT QUEUE
;
; Stop input from a terminal at interupt level, thereby
; avoiding any problems with loop level begin unable
; to keep up with TTY input.
;
.IF NE FT.RDA
TST DB.RDT(J) ;Is this an RDA device?
BNE 35$ ;Yes, skip this
.ENDC
BIT #DS.IST,(J) ;Have we already sent XOFF
BNE 35$ ;Yes, don't bother with another
INC DB.ICC(J) ;Count this character
CMP #TTYMIC-^D20,DB.ICC(J) ;Are we in danger of overrunning?
BHI 35$ ;No, all is well
JSR PC,SNDXOF ;Yes, ship an XOFF now
BIS #DS.IST,(J) ;Signal that we sent an XOFF
35$: RTS PC ;Let loop level worry about the char.
PARTAB: .BYTE 000,201,202,003,204,005,006,207
.BYTE 210,011,012,213,014,215,216,017
.BYTE 220,021,022,223,024,225,226,027
.BYTE 030,231,232,033,234,035,036,237
.BYTE 240,041,042,243,044,245,246,047
.BYTE 050,251,252,053,254,055,056,257
.BYTE 060,261,262,063,264,065,066,267
.BYTE 270,071,072,273,074,275,276,077
.BYTE 300,101,102,303,104,305,306,107
.BYTE 110,311,312,113,314,115,116,317
.BYTE 120,321,322,123,324,125,126,327
.BYTE 330,131,132,333,134,335,336,137
.BYTE 140,341,342,143,344,145,146,347
.BYTE 350,151,152,353,154,355,356,157
.BYTE 360,161,162,363,164,365,366,167
.BYTE 170,371,372,173,374,175,176,377
; HERE TO SET LINE SPEED
.IF NE TTYN
; CALL: JSR PC,SETSPD ; WITH J SETUP
; RETURN ; USES R0 & R1
SETSPD:
SAVE <R2,R3>
.IF NE FT.CTY
CMP J,#CTYDDB ; IS THIS FOR THE CTY ?
BEQ 99$ ; CAUSE CTY NOT DH11
.ENDC
BIS #DS.XCH,@J ; SO WE SEND CHARACTERISTICS TO 10
MOV @DB.DHB(J),R0 ; GET DH11 HDW ADDRESS
MOV 6(P),R1 ; GET NEW LINE SPEED
MOVB DB..LN(J),R2 ; FETCH THE DH11 LINE #
JINDEX JSR,DB.TYP(J),R3,DEVSPD
BCS 98$ ; CARRY SET IS ERROR
MOV DB.LCB(J),R2 ; SUCCESS, GET ADDRESS OF LCB
MOV R1,LC.SPD(R2) ; AND PUT NEW ACTUAL SPEED IN LCB
98$:
99$: RESTORE <R3,R2>
RTS PC
.IFF
SETSPD: RTS PC
.ENDC
.ENDC