Trailing-Edge
-
PDP-10 Archives
-
BB-X140B-BB_1986
-
10,7/703anf/dndh11.p11
There are 3 other files named dndh11.p11 in the archive. Click here to see a list.
.SBTTL DNDH11 - DH11 ASYNCHRONOUS LINE INTERFACE 11 DEC 84
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
; COPYRIGHT (C) 1976,1977,1978,1979,1980,1981,1982,1983,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
VRDH11=034 ;FILE EDIT NUMBER
.IF NE FTDH11
.SBTTL SET DH11 LINE SPEED
; CALL JSR PC,DHSPD
; R0/ DH11 STATUS REG ADDRESS
; R1/ NEW LINE SPEED
; R2/ LINE NO.
DHSPD: PIOFF ; DON'T WANT ANYONE ALTERING THE DH LINE
MOV R1,-(P) ; SAVE SPEEDS
BIC #17,(R0) ; CLEAR LINE SELECT
BISB R2,(R0) ; SELECT THE LINE
BIC #^C37,R1 ; GET LOW SPEEDS
ASL R1 ; MAKE IT A WORD INDEX
MOV DHSPDT(R1),R2 ; GET RIGHT BITS
BMI 98$ ; BAD SPEED, IGNORE
ASL R2 ; SHIFT UP FOR DH XMIT LOCATION
ASL R2 ; TWICE
ASL R2 ; THRICE
ASL R2 ; FOUR BITS WORTH
MOV (P),R1 ; GET BACK SPEED
SWAB R1
BIC #^C37,R1
ASL R1 ; MAKE IT A WORD INDEX
BIS DHSPDT(R1),R2 ; ADD IN OTHER SPEED
BMI 98$ ; BAD SPEED
SWAB R2 ; POSITION BITS
ROR R2
ROR R2
BIS #7,R2 ; TWO STOP BITS AND 8 BIT CHARS
BIC #140070,R2 ; STRIP EXTRA BITS
.IF EQ FT2BIT
CMP R2,#006307 ; IF HIGHER THAN 110 BAUD
BLOS .+6
BIC #4,R2 ; MAKE THAT ONE STOP BIT
.ENDC; .IF EQ FT2BIT
CMP #B.134,(P) ; IS THIS THE SPEED OF A 2741
BNE 10$ ; IF NOT, JUST SKIP
BIC #77,R2 ; IF IT'S A 2741 THEN WE WANT
BIS #61,R2 ; 6 BIT CHARS, ODD PARITY AND 1 STOP BIT
10$: MOV R2,DH.LPR(R0) ; SET THE LINE SPEED
97$: MOV (P)+,R1 ; RETURN VALID SPEED IN R1
PION ; RESTORE PI LEVEL
CLC ; INDICATE GOOD RETURN
RTS PC
98$: TST (P)+ ; POP BOGUS SPEED VALUE
PION ; RESTORE PI LEVEL
SEC ; FLAG ERROR
RTS PC
DHSPDT: 0 ; 0 BAUD
1 ; 50 BAUD
2 ; 75 BAUD
3 ; 110 BAUD
4 ; 134.5 BAUD
5 ; 150 BAUD
6 ; 200 BAUD
7 ; 300 BAUD
10 ; 600 BAUD
11 ; 1200 BAUD
12 ; 1800 BAUD
-1 ; 2000 BAUD
13 ; 2400 BAUD
-1 ; 3600 BAUD
14 ; 4800 BAUD
-1 ; 7200 BAUD
15 ; 9600 BAUD
-1 ; 19000 BAUD
16 ; EXT 1.
17 ; EXT 2.
;DH-11 BREAK CONTROL (REACHED FROM DEVBK? DISPATCH TABLE)
DHBKON: SAVE <R3> ; SET XMIT BREAK ON A LINE
MOV @DB.DHB(J),R3 ; GET THE DH-11 HARDWARE BASE ADDRESS
BIS DB.BIT(J),DH.BRK(R3) ; SET THE XMIT-BREAK BIT
RESTORE <R3> ; WE ARE DONE WITH R3
RTS PC
DHBKOF: SAVE <R3> ; CLEAR XMIT BREAK ON A LINE
MOV @DB.DHB(J),R3 ; GET THE DH-11 HARDWARE BASE ADDRESS
BIC DB.BIT(J),DH.BRK(R3) ; CLEAR XMIT BREAK
RESTORE <R3> ; WE ARE DONE WITH R3
RTS PC
.SBTTL DH11 CODE
; HERE TO INIT A DH11 LINE
DH.INI:
SAVE <R4>
MOV (R3),R4 ; FETCH ADDRESS OF THE DH HDW
BIT #DH.RIE!DH.TIE,(R4) ; IF INTERRUPTS NOT ENABLED
BNE 10$
CLR DHBBAR(R3) ; SET ALL LINES INACTIVE
MOV #FTSILO,DH.SSR(R4) ; SET SILO ALARM LEVEL
BIS #DH.RIE!DH.TIE,(R4) ; ENABLE INTERRUPTS
10$: MOV 4(P),R4 ; FETCH THE LCB ADDRESS
TST DHB.DM(R3) ; IF THERE IS A DM11BB FOR THE DH
BNE 17$ ; THEN ALLOW IT TO BE A DATASET LINE
BIC #LCB.DS,(R4) ; ELSE NO DATASET
17$: MOV LC.SPD(R4),R1 ; GET THE LINE SPEED
BIT #LCB.AB,(R4) ; IF THIS IS AN AUTO BAUD LINE
BEQ 20$
BIC #LCB.LS,(R4) ; CLEAR LOW SPEED
MOV #B.HSPD,R1 ; ASSUME AUTO BAUD
20$:
.IF NE TTYDHN ; IF NO TTYS DON'T TELL -10
CMP 6(P),#TTDHIN ; IF TTY LINE
BNE 25$
MOV R1,-(P) ; SET THE LINE SPEED
JSR PC,SETSPD
TST (P)+
BR 30$
.ENDC; .IF NE TTYDHN
25$:
MOV (R3),R0 ; GET THE DH HDW ADDRESS
JSR PC,DHSPD ; SET THE SPEED
30$: MOV J,LC.BLK(R4)
MOV 6(P),LC.INS(R4) ; SET THE INTERRUPT SERVICE PROCS
MOV 10(P),LC.OUS(R4) ; FOR THE LINE
RESTORE <R4>
RTS PC
;BLOCKS FOR EACH DH11
;FIRST WORD IS HDW ADR OF DH11
; IF HDW IS NOT PRESENT WILL BE ZERO
DHBBAR=2 ;ACTIVE LINES(SOFTWARE BAR)
DHB.BN=4 ;FIRST LINE # IN GROUP
DHB.DM=6 ;ADR OF DM11BB IF PRESENT, ELSE 0
DHB.VC=10 ;DH11 VECTOR ADDRESS
DHB.LC=12 ;START OF THE LINE CONTROL BLOCKS
DHB.SZ=12+<20*LC..SZ> ;SIZE OF A DH11 BLOCK
.MACRO XX
.MACRO XXX NNN
.IF NDF DHS'NNN
.IIF EQ DHL'NNN, DHS'NNN=0
.IIF EQ DHL'NNN-1, DHS'NNN=B.HSPD
.IIF EQ DHL'NNN-2, DHS'NNN=AL.SPD
.IIF EQ DHL'NNN-3, DHS'NNN=MP.SPD
.IIF EQ DHL'NNN-4, DHS'NNN=MP.SPD
.IIF EQ DHL'NNN-5,DHS'NNN=RP.SPD
.IIF EQ DHL'NNN-6,DHS'NNN=RA.SPD
.IIF GE DHL'NNN-7,DHS'NNN=B.LSPD
.ENDC
.IF NDF DHC'NNN
.IF EQ DHL'NNN-1
DHC'NNN=LCB.AB
.IFF
DHC'NNN=0
.ENDC
.ENDC
LCB'NNN:.WORD DHC'NNN ;LC.CAR
.IIF NDF DHZ'NNN,DHZ'NNN=0
.BYTE DHZ'NNN ;LC.STA
.BYTE ;LC.MOD
.WORD DHS'NNN ;LC.SPD
.WORD DHS'NNN ;LC.PSP
.WORD 0 ;LC.BLK
.WORD 0 ;LC.INS
.WORD 0 ;LC.OUS
.IF NE NDZ11
.WORD 0 ;LC.CNT
.WORD 0 ;LC.BUF
.ENDC
.ENDM
.MACRO X A
.IIF LT DH.MAX-NDH11,.ERROR 200;# DH11S REQUIRED EXCEEDS # CONFIGURED
DH'A'BLK: 0
0 ;DHBBAR
A*20 ;DHB.BN
0 ;DHB.DM
0 ;DHB.VC
Q=A*20
.REPT 20
XXX \Q
Q=Q+1
.ENDR
.ENDM X
Z=0
;BUILD A DH11 BLOCK FOR EACH DH11
.REPT DH.MAX
X \Z
Z=Z+1
.ENDR
.ENDM
XX
DHBLIM:
.SBTTL DH11 RECEIVE INTERRUPT SERVICE
.MACRO X A
DHI'A'IN:
MOV R0,-(P)
MOV #DH'A'BLK,R0
.ENDM X
Z=DH.MAX-1
.REPT DH.MAX
X \Z
.IIF NE Z,BR DHIINT
Z=Z-1
.ENDR
DHIINT: SAVE <R1,R2,R3,R4,J> ;SAVE REGISTERS
MOV (R0),-(P) ;SET DH11 ADDRESS FOR CHAR LOOP
ADD #DHB.LC,R0 ;BASE OF THE LINE CONTROL BLOCKS
MOV R0,-(P) ;SET LCB BASE FOR PER-CHAR LOOP
;LOOP EMPTYING THE DH INPUT SILO
10$: MOV 2(P),R3 ;RESTORE THE HARDWARE ADR
MOV 2(R3),R1 ;GET NEXT CHAR FROM SILO
BPL 99$ ;DISMISS INTERRUPT WHEN NO MORE
MOV R1,J ;COPY WORD
SWAB J ;SWAP HALVES
BIC #^C17,J ;LEAVE ONLY RELATIVE LINE#
ASL J ;WORD INDEX
MOV LCBIDX(J),J ;GET LCB OFFSET
ADD (P),J ;PLUS BASE ADDRESS OF LCB'S
MOV LC.INS(J),R2 ;GET THE SERVICE PROC
BEQ 10$ ;PROCESS THE NEXT CHAR IF THERE IS NONE
MOV LC.BLK(J),J ;GET THE CONTROL BLOCK
BEQ 10$ ;PROCESS THE NEXT CHAR IF THERE IS NONE
JSR PC,(R2) ;PROCESS THE CHAR
BR 10$ ;AND PROCESS THE NEXT CHAR
99$: ADD #4,P ;POP OFF SAVED ADDRESSES
RESTORE <J,R4,R3,R2,R1,R0>
RTI
.SBTTL DH11 TRANSMIT INTERRUPT SERVICE
.MACRO X A
DHO'A'IN: MOV R0,-(P)
MOV #DH'A'BLK,R0
.ENDM X
Z=DH.MAX-1
.REPT DH.MAX
X \Z
.IIF NE Z,BR DHOINT
Z=Z-1
.ENDR
DHOINT: SAVE <R1,R2,R3,R4,J> ;SAVE REG'S
MOV @R0,R1 ;GET DH11 HDW ADDRESS
BIT #DH.NXM,@R1 ;DID THE DH GET A NXM?
BEQ 10$ ;NO, NORMAL INTERRUPT
.IF EQ DGUTS
TRAP
.IFF
TWIDDLE ;COUNT THE NXM ERRORS
BIS #DH.CNX,(R1) ;CLEAR THE ERROR
.ENDC ; .IF EQ DGUTS
10$: BIC #DH..TI,@R1 ;CLEAR TRANSMIT-INTERRUPT FLAG
MOV R0,J ;GET ADDRESS OF THE BLOCK'S END
ADD #DHB.SZ,J
MOV DHBBAR(R0),R2 ;GET SOFTWARE STATUS REGISTER
BIC 12(R1),R2 ;CLEAR BITS FOR LINES STILL ACTIVE
BEQ 99$ ;BRANCH IF NO LINES
BIC R2,DHBBAR(R0) ;CLEAR SOFTWARE BAR BITS
30$: SUB #LC..SZ,J ;BACK UP TO THE PREVIOUS LCB
ASL R2 ; AND CHECK THIS LINE'S XMITTER
BLO 32$ ;FOUND A NEWLY INACTIVE LINE SO FIX IT
BNE 30$ ; NO CHANGE,SO TRY NEXT LINE
; NOTHING LEFT TO CHECK
99$: RESTORE <J,R4,R3,R2,R1,R0> ;RESTORE AC'S
RTI
32$: MOV R2,-(P) ;SAVE COMBINED STATUS
MOV J,-(P) ;SAVE LINE NUMBER
MOV LC.OUS(J),R3 ;GET THE OUTPUT SERVICE PROC
BEQ 33$ ;AND TRY NEXT LINE IF NONE
MOV LC.BLK(J),J ;GET THE CONTROL BLOCK
BEQ 33$ ;AND TRY THE NEXT LINE IF NONE
JSR PC,(R3) ;DO SOMETHING FOR THE XMITTER.
33$: MOV (P)+,J ;GET BACK LINE CONTROL BLOCK
MOV (P)+,R2 ;GET BITS AGAIN
BR 30$ ;AND FIND REST
.SBTTL TTY OUTPUT INTERRUPT SERVICE
.IF NE TTYDHN+RDADHN
;HERE TO TYPE ON A DH11 LINE
; CALL MOV <CHAR>,R0
; JSR PC,DHTYPE
DHTYPE: MOVB R0,DB.BUF(J) ;SAVE CHAR TO TYPE
MOV #-1,R0 ;GET COUNT
MOV J,R1 ;COPY DEVICE BLOCK ADR
ADD #DB.BUF,R1 ;MAKE POINTER TO BUFFER
;HERE TO TYPE A STRING OF CHARS ON A DH11 LINE
; CALL MOV <ADR>,R1
; MOV <-COUNT>,R0
; JSR PC,DHIMTY
DHIMTY: MOV DB.DHB(J),R2 ;GET ADR OF DH11 BLOCK
MOV @R2,R3 ;GET HDW ADR OF DH11
BIC #17,@R3 ;CLEAN LINE SELECT
BISB DB..LN(J),@R3 ;SELECT OUR LINE
BIC DB.BIT(J),14(R3) ;STOP SENDING BREAK
MOV R1,6(R3) ;TELL DH11 WHERE DATA IS
MOV R0,10(R3) ;TELL DH11 HOW MANY BYTES
BIS DB.BIT(J),DHBBAR(R2) ;FLAG LINE IS GOING
ASR R0
ASR R0
DEC R0 ; MAKE SURE WE TIME FOR AT LEAST 1 SECOND
; IF CLOCK IS ABOUT TO TICK, AND
; WE USE A MINUS 1, WE WILL TIME
; ONLY FOR ABOUT 1 JIFFY, AND LOSE
MOVB R0,DB.TIM(J) ;SET OUTPUT TIMER (ABOUT .2 PER CHAR)
BIS DB.BIT(J),12(R3) ;START LINE
RTS PC
.ENDC ; .IF NE TTYDHN+RDADHN
.SBTTL DH11/DM11 MODEM CONTROL ROUTINES 4 NOV 83
;HERE TO WAIT FOR DM11 TO SETTLE
.IF NE FTDM11
DH=R3
; DM.TIM IS THE MAX. SETTLING TIME FOR THE DM11 IN MEMORY CYCLES
; THE PROCEDURE DMWAIT DELAYS FOR AT LEAST THIS TIME
ND DM.TIM,<^D40> ;SPEC FOR DM WAIT TIME IS 20 CORE
; OR 40 MOS CYCLES
.MACRO DMPEEK QADR,QLINE
.IF DF PEEKDM
.IIF NB <QADR>, CMP #'QADR,DH
.IIF B <QADR>, CMP #170500,DH
DMPK.A=.-2
BNE 102$
MOV (DH),R1
BIC #^C17,R1
.IIF NB <QLINE>, CMP #'QLINE,R1
.IIF B <QLINE>, CMP #0,R1
DMPK.L=.-2
BNE 102$
MOV (DH),#0
DMPKDS=.-2
MOV 2(DH),#0
DMPKLS=.-2
102$:
.ENDC; .IF DF PEEKDM
.ENDM DMPEEK
DMWAIT: TST (R0)+ ; PREPARE SUCCESS RETURN
SAVE <R1>
MOV #<<DM.TIM+5>/5>,R1 ; LOOP TILL THE DM11 SETTLES
; (8E-6 SEC TYP,16E-6 SEC MAX)
100$: BIT #DM.BSY,(DH) ; CHECK IF THE DM11 IS CYCLING
BEQ 101$ ; AND BRANCH IF DM11 HAS SETTLED
SOB R1,100$
TWIDDLE ; IF DM11 IS BROKEN
TST -(R0) ; SET UP FAILURE RETURN
101$: DMPEEK 170500,0
RESTORE <R1>
RTS R0
; THIS IS THE DM-11BB SCAN CODE. IT MUST BE CALLED EVERY 1/6 OF A SECOND
; TO KEEP TRACK OF CHANGES TO THE DM'S. THIS CODE IS ALL DONE AT LOOP LEVEL.
; NONE OF THE DM-11 SUPPORT IS INTERRUPT DRIVEN.
DMSCN: MOV #DH0BLK,-(P) ; PUSH/SAVE LOC OF FIRST DH-11
;JUMP TO HERE TO CHECK THE NEXT DH-11
DMS.00: CMP #DHBLIM,(P) ; HAVE WE DONE ALL THE DH-11'S?
BHI 10$ ; IF NOT THEN SKIP,
TST (P)+ ; ELSE RESTORE P AND
RTS PC ; RETURN
;START CHECKING OUT THIS DH-11'S LINES
10$: MOV (P),J ; GET THE ADDRESS OF THE DH AND
ADD #DHB.SZ,(P) ; INCR @P FOR NEXT TIME.
MOV DHB.DM(J),R3 ; GET ADDRESS OF THE DM-11
BEQ DMS.00 ; BUT IF NONE, THEN DO NEXT DH.
ADD #DHB.LC,J ; BUMP J TO POINT TO FIRST LCB
BIS #DM.SCN,(R3) ; AND CLEAR THE DM-11 SCANNER.
BR DMS.11 ; NOW JUMP INTO MIDDLE OF CHECK LOOP.
; JUMP HERE TO CHECK NEXT LINE OF CURRENT DM-11.
DMS.10: ADD #LC..SZ,J ; STEP TO THE NEXT LCB
CMP J,(P) ; HAVE WE STEPPED TO NEXT DH-11?
BHIS DMS.00 ; IF SO THEN GO DOIT.
BIS #DM.STP,(R3) ; ELSE STEP TO NEXT LINE
;ENTER HERE TO RE-EVALUATE THE CURRENT LINE
DMS.11: JSR R0,DMWAIT ; WAIT FOR DM TO SETTLE
TRAP ; QUIT IF THE DM IS BROKEN
BIT #LCB.DS,LC.CAR(J) ; IF THIS ISN'T A DATA-SET LINE-
BEQ DMS.10 ; THEN GO DO THE NEXT ONE.
MOV R3,R1 ; GET LINE
TST (R1)+ ; STATUS REG (DMBASE+1)
BIS #DM.LE,(R1) ; INDICATE THAT WE WANT TO READ IT,
MOV (R1),R0 ; GET STATUS BITS FROM THE DM
MOV LC.BLK(J),R4 ; GET THE ADDR OF THE DDB.
BEQ DMS.12 ; IF NO DDB THEN RESET LCB
.IF EQ TTYN
BR DMS.13 ; IF IT'S NOT A TTY, SET DTR
.IFF
CMP #TTDHIN,LC.INS(J) ; IF IT'S NOT A TTY LINE
BNE DMS.13 ; THEN SET DTR
.ENDC;.IF EQ,TTYN
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
; AT THE TIME OF DISPATCH THE REGISTERS CONTAIN
; R0 <-> CONTAINS THE DM STATUS
; R1 <-> POINTER TO STATUS
; R2 <-> CONTAINS THE DM-11 STATE BITS
; R3 <-> DM BASE ADDRESS
; R4 <-> POINTER TO DDB
; J <-> POINTER TO THE LCB
MOVB LC.STA(J),R2 ; GET THE STATE OF THE LCB
ASSERT R2 GE #0 ; ASSURE OURSELVES THAT IT IS -
ASSERT R2 LE #LCS.MX ; INDEED A VALID STATE.
JMP @10$(R2) ; AND JUMP OFF TO PROPER ROUTINE.
;DATASET STATE DISPATCH TABLE
10$: DMSVIR ; (00) VIRGIN STATE
DMSRNG ; (02) RINGING STATE
DMSCDT ; (04) CARRIER DETECT STATE
DMSCDS ; (06) CARRIER DETECT SATISFIED.
DMSABD ; (08) AUTO BAUD DETECT STATE
DMSOKU ; (10) RUNNING NOT CONNECTED
DMSOKW ; (12) RUNNING IN 3 SEC WAIT STATE
DMSOKC ; (14) RUNNING CONNECTED TO -10
DMSLOC ; (16) LOST CARRIER STATE
DMS.15 ; (18) SOMEONE WANTS US TO HANG UP
DMSHNG ; (20) HANG UP STATE
.IF NE FTDN11
DMSDIA ; (22) DIALER RUNNING STATE
DMSDSU ; (24) DIALOUT SUCCEEDED
DMSDFA ; (26) DIALOUT FAILED HANG UP PHONE
.ENDC;.IF NE FTDN11
.IIF NE .-10$-2-LCS.MX,.ERROR <.-10$-2> ;DISPATCH STATE PHASE ERROR IN DNDM11
; UTILITY ROUTINES FOR MODEM SUPPORT.
; RESET A LINE CONTROL BLOCK
DMS.12: MOVB #LCS.VG,LC.STA(J) ; RESTORE VIRGINITY
BIC #LCB.TM,LC.CAR(J) ; CLEAR THE TIMER
CLR (R1) ; CLEAR RTS,DTR
TST R4 ; IS THERE ANY DDB?
BEQ DMS.10 ; NO, TO THE NEXT LINE
BR DMS.16 ; GO CLEAR THE DDB'S BITS
;ASSERT DATA TERMINAL READY (ASSUMES R3 -> DM-11)
DMS.13: BIS #DM.LE!DM.DTR!DM.RTS,(R1) ; SET DTR
BR DMS.10 ; AND GO DO NEXT LINE
; HERE TO CHECK IF STATUS HAS CHANGED, AND IF SO SEND NEW STATUS
; TO THE -10. (R4 -> DDB, R2 HAS NEW STATUS)
DMS.14: CMP R2,DB.DCS(R4) ; HAS IT CHANGED?
BEQ DMS.10 ; IF NOT, THEN DO NEXT LINE
MOV R2,DB.DCS(R4) ; SET NEW STATUS,
SAVE <J> ; NOW FUDGE 'J' AND
MOV R4,J ; QUEUE
JSR PC,QUEXDS ; THE DDB FOR SERVICE.
RESTORE <J> ; CLEAN UP, AND
BR DMS.10 ; GO DO NEXT LINE
; HERE TO HANG UP A LINE. R4 -> DDB, J -> LCB, R1 -> DM STATUS REGISTER
DMS.15:
.IF NE FTDN11
BITB #DNDIAL,DB.DNS(R4) ; CONTROLLED BY DN11/801?
BEQ 30$ ; NO
;SINCE THE DATASET LINE IS BEING CONTROLLED BY A DN11/801 (I.E.,
;SOMEONE DIALED OUT ON THE LINE RATHER THAN CALLING IN ON IT) WE
;MUST CLEAR THE DN11/801 TO RELEASE CONTROL OF THE PHONE LINE.
SAVE <J,R1> ; YES, SAVE SOME ACS
MOV R4,J ; SETUP J WITH DDB ADDRESS
JSR PC,DNCLR ; ZAP THE DN11/801
RESTOR <R1,J> ; GET BACK OUR ACS
.ENDC;.IF NE FTDN11
30$: BIC #DM.DTR!DM.RTS,(R1) ; CLEAR RTS, DTR
MOVB #LCS.HG,LC.STA(J) ; SET HANG UP STATE
BIC #LCB.TM,LC.CAR(J) ; FIRST CLEAR OUT THE TIMER,
BIS #MDMHDT*6,LC.CAR(J) ; NOW SET MODEM HOLD DOWN TIME.
; HERE TO CLEAR OUT THE DDB.
DMS.16: MOV DB.DCS(R4),R2 ; GET DDB CHARACTERISTICS
BIC #TS.DTR!TS.CAR,R2 ; RESET THESE
BR DMS.14 ; TELL THE -10 THE NEWS
; HERE TO PUT A LINE IN THE RUNNING STATE
DMS.17: BIS #DM.RTS!DM.DTR!DM.LE,(R1); SET RTS AND DTR IN THE DM-11
MOVB #LCS.RU,LC.STA(J) ; ASSUME WE ARE IN UNCONNECTED STATE
; (WE WILL CHECK LATER)
BIC #LCB.TM,LC.CAR(J) ; CLEAR ANY TIMERS.
DMS.18: MOV DB.DCS(R4),R2 ; GET LINE CHARACTERISTICS
BIS #TS.DTR!TS.CAR,R2 ; SET THESE BITS
BR DMS.14 ; NOW TELL THE -10
;THE DATASET "STATE" MACHINE, SUCH AS IT IS
;(00) VIRGIN STATE, WAIT FOR RING
DMSVIR: MOV DB.DCS(R4),R2 ; KEEP COPY OF DB.DCS IN R2
BIT #DM.RNG!DM.CAR,R0 ; IS RING OR CARRIER SET?
BEQ DMS.16 ; NO, CLEAR THE BITS IN THE DDB
BIS #TS.RNG,R2 ; YES, SET THE FACT THAT RING IS UP.
BIC #TS.DTR,R2 ; CLEAR CARRIER AND DTR
MOVB #LCS.RG,LC.STA(J) ; SET STATE TO RINGING
BR DMS.14 ; TELL THE -10 AND DO NEXT LINE.
;(02) DATASET PHONE IS RINGING
DMSRNG: BIS #DM.RTS!DM.DTR!DM.LE,(R1); SET DTR, RQS
MOVB #LCS.CD,LC.STA(J) ; SET CARRIER DETECT STATE
BIS #30.*6,LC.CAR(J) ; SET TIMER TO RUN FOR 30 SEC
BR DMSJ11 ; AND CHECK THE LINE AGAIN.
;(04) WE HAVE ANSWERED THE PHONE, NOW WAIT FOR CARRIER TO APPEAR
DMSCDT: BIT #DM.CAR,R0 ; DID THE CARRIER COME UP?
BEQ 40$ ; BRANCH IF NOT.
CLR DB.STR(R4) ; CLEAR THE STRING POINTER
CLRB DB.ASP(R4) ; SO WE DO NOT OUTPUT
CLRB DB.HLD(R4) ; BOGUS MESSAGES WHEN PEOPLE
; DIAL IN
BIT #LCB.AB,LC.CAR(J) ; IS THIS AN AUTO-BAUD LINE?
BEQ 30$ ; IF NOT THEN LEAVE SPEED ALONE
.IF NE FTDN11
BITB #DNDIAL,DB.DNS(R4) ;AUTOBAUD DATASET - BUT IF DIALING OUT
BNE 20$ ; THEN ASSUME USER SPEED IS CORRECT
.ENDC ;FTDN11
BIC #LCB.LS,LC.CAR(J) ; CLEAR LOW SPEED BIT
SAVE <J,#B.HSPD> ; SAVE LCB POINTER, PUSH SPEED.
10$: MOV LC.BLK(J),J ; GET POINTER TO DDB FOR SETSPD.
JSR PC,SETSPD ; SET SPEED TO AUTO-BAUD SPEED
RESTORE <J,J> ; GET POINTER TO LCB BACK.
20$: MOVB #LCS.CS,LC.STA(J) ; SET WAIT STATE.
BIC #LCB.TM,LC.CAR(J) ; AND SET THE TIMER TO RUN FOR
BIS #1.*6,LC.CAR(J) ; ANOTHER SECOND
BR DMSJ10 ; AND WE ARE DONE WITH THIS FOR NOW.
; HERE IF DATA SET BUT NOT AUTOBAUD TO RESET SPEED
30$: SAVE <J,LC.PSP(J)> ; GET PERM SPEED
BR 10$ ; SET SPEED
; HERE TO CHECK FOR TIME OUT DURING CARRIER DETECT
40$: BIT #LCB.TM,LC.CAR(J) ; HAS THE TIMER RUN OUT?
BEQ DMSJ15 ; YES, HANG UP THE PHONE
DEC LC.CAR(J) ; OTHERWISE COUNT DOWN TIMER
BR DMSJ10 ; AND DO THE NEXT LINE
;(06) CARRIER DETECTED, WAIT A MOMENT FOR THINGS TO SETTLE DOWN. THIS IS
; SO WE IGNORE THE RANDOM GARBAGE ON THE LINE CAUSED BY INSERTING THE
; PHONE IN THE ACOUSTIC COUPLER.
DMSCDS: BIT #LCB.TM,LC.CAR(J) ; HAS THE TIMER RUN OUT?
BEQ 10$ ; YES, MAKE SURE WE STILL HAVE CARRIER
DEC LC.CAR(J) ; COUNT DOWN ANOTHER TICK
BR DMSJ10 ; AND GO DO THE NEXT LINE
10$: BIT #DM.CAR,R0 ; IS CARRIER STILL UP?
BEQ 20$ ; TAKE REMEDIAL ACTION IF NOT.
BIT #LCB.AB,LC.CAR(J) ; IF THIS IS NOT AN AUTO-BAUD LINE -
BEQ DMS.17 ; THEN BRING IT ON LINE NOW.
MOVB #LCS.AB,LC.STA(J) ; IF IT IS, THEN GO TO AUTO-BAUD STATE
BIS #30.*6,LC.CAR(J) ; AND SET FOR A 30 SEC TIME OUT
BR DMS.18 ; GO MARK TERMINAL UP (SET DTR)
20$: MOVB #LCS.CD,LC.STA(J) ; IF CARRIER WENT AWAY, GO BACK TO
BIS #28.*6,LC.CAR(J) ; CARRIER DETECT AND A 28 SEC TIME OUT.
BR DMSJ10 ; NOW GO DO NEXT LINE
;(08) WAITING FOR USER TO AUTOBAUD (TYPE <CR>)
DMSABD:
.IF NE FTDN11
BITB #DNDIAL,DB.DNS(R4) ; DIALING OUT?
BNE DMS.17 ; YES, ALL SET
.ENDC ;FTDN11
BIT #DM.CAR,R0 ; CARRIER STILL THERE ?
BEQ DMSJ15 ; NO, HANG IT UP
BIT #LCB.TM,LC.CAR(J) ; OTHERWISE SEE IF HE HAS TIMED OUT.
BEQ DMSJ15 ; IF HE HAS THEN HANG HIM UP
DEC LC.CAR(J) ; OTHERWISE DECREMENT TIMER, AND
BR DMSJ10 ; GO DO THE NEXT LINE
;CONVENIENT JUMPS
DMSJ10: JMP DMS.10 ; CHECK NEXT DATASET LINE
DMSJ11: JMP DMS.11 ; RECHECK CURRENT DATASET LINE
DMSJ12: JMP DMS.12 ; RESET THE LINE
DMSJ14: JMP DMS.14 ; SEND STATUS TO -10 IF CHANGED
DMSJ15: JMP DMS.15 ; HANG UP THE PHONE
DMSJ17: JMP DMS.17 ; SET TERMINAL TO RUNNING STATE
;(10) WE ARE RUNNING BUT NOT CONNECTED
DMSOKU: TST @R4 ; HAVE WE BEEN CONNECTED YET?
BGE DMSAOK ; IF NOT, JUST CHECK CARRIER
BIC #LCB.TM,LC.CAR(J) ; IF WE HAVE, RESET THE TIMER
BIS #3*6,LC.CAR(J) ; AND SET IT FOR 3 SEC
MOVB #LCS.RW,LC.STA(J) ; AND GO TO CONNECT WAIT STATE.
BR DMSAOK ; (ALSO CHECK CARRIER)
;(12) IN THIS STATE WE ARE WAITING FOR A CONNECT TO THE -10 TO SETTLE
; DOWN. THE REASON THIS STATE IS NECESSARY IS THAT THE -10 SENDS A LOT
; OF STATUS MESSAGES THAT IT DOESN'T REALLY MEAN DURING THE INITAL STARTUP.
; IF ONE OF THESE STATUS MESSAGES HAPPENS TO CLEAR DTR THE PHONE WILL
; HANG UP... (SIGH)
DMSOKW: BIT #LCB.TM,LC.CAR(J) ; HAS THE TIMER RUN OUT YET?
BEQ 10$ ; IF IT HAS, GO CHANGE STATE
DEC LC.CAR(J) ; OTHERWISE COUNT OFF NEXT TICK
BR DMSAOK ; AND CHECK THE CARRIER BIT
10$: MOVB #LCS.RC,LC.STA(J) ; GO TO CONNECTED STATE
BR DMSAOK ; AND CHECK CARRIER
;(14) WE ARE UP AND RUNNING, CONNECTED TO A -10
DMSOKC: TST @R4 ; ARE WE STILL CONNECTED
BLT DMSAOK ; YES, CHECK CARRIER
MOVB #LCS.RU,LC.STA(J) ; NO, CHANGE STATE
; BR DMSAOK ; AND CHECK CARRIER
;MAKE SURE CARRIER IS STILL PRESENT
DMSAOK: BIT #DM.CAR,R0 ; IS CARRIER STILL UP?
BNE DMSJ10 ; YES, LINE IS OK, CHECK NEXT ONE
MOVB #LCS.LC,LC.STA(J) ; NO, SET TO CARRIER LOST STATE
BIC #LCB.TM,LC.CAR(J) ; CLEAR AND
BIS #5*6,LC.CAR(J) ; SET THE 5 SEC TIMER
BR DMSJ10 ; AND GO DO THE NEXT LINE
;(16) WE HAVE LOST CARRIER, GIVE IT A FEW SECONDS TO REAPPEAR BEFORE
; HANGING UP IN CASE IT IS JUST A MOMENTARY LINE OUTAGE.
DMSLOC: BIS #DM.DTR!DM.RTS!DM.LE,(R1); KEEP RQS AND DTR UP!
BIT #DM.RNG,R0 ; GOT A NEW CALL TRYING TO GET IN?
BNE DMSJ15 ; YES, THEN HANG UP THE OLD ONE FIRST
; (SO THE -10 DETACHES OLD JOB, ETC)
BIT #DM.CAR,R0 ; IS CARRIER BACK??
BNE DMSJ17 ; IF SO, TELL THE -10
BIT #LCB.TM,LC.CAR(J) ; HAVE WE TIMED OUT YET?
BEQ DMSJ15 ; IF SO, THEN HANG IT UP
DEC LC.CAR(J) ; OTHERWISE COUNT OFF THE TIME
BR DMSJ10 ; AND GO DO THE NEXT LINE
;(20) THE LINE IS HUNG UP. WAIT FOR PHONE TO SETTLE DOWN BEFORE RE-ENABLING
; IT FOR ANOTHER INCOMING CALL.
DMSHNG: BIT #LCB.TM,LC.CAR(J) ; TIMED OUT?
BEQ DMSJ12 ; IF SO, THEN RESET LINE
DEC LC.CAR(J) ; OTHERWISE COUNT TIME
BR DMSJ10 ; AND DO THE NEXT LINE
.IF NE FTDN11
;(22) THIS LINE HAS INITIATED A DIALOUT REQUEST. WAIT FOR SUCCESS/FAILURE
DMSDIA: BIS #DM.LE!DM.RTS!DM.DTR,(R1) ; MAKE SURE MODEM ENABLED
BR DMSJ10 ; AND CHECK THE NEXT LINE
;(24) THE DIALOUT HAS SUCCEEDED, TELL THE -10
DMSDSU: BIT #DS.XDS,@R4 ; ROOM FOR NEW DEVICE CONTROL STATUS?
BNE DMSDIA ; NO, WAIT LONGER THEN
JMP DMSRNG ; YES, WAIT FOR CARRIER CONFIRM
;(26) THE DIALOUT FAILED, TELL THE -10
DMSDFA: BIT #DS.XDS,@R4 ; ROOM FOR NEW STATUS YET?
BNE DMSDIA ; NO, WAIT LONGER THEN
BR DMSJ15 ; YES, GO HANG UP THE LINE
.ENDC;.IF NE FTDN11
.ENDC;.IF NE FTDM11
.SBTTL DH11 ROUTINE FOR DDCMP 28 MAR 79
DH=%3
.IF NE NDHMPT!NADHLN!NDHTRB!RDPDHN!FT.MPT ;++DH11++ DEPENDENCE FOR FT.MPT ASSUMED IN THIS TEST ;--
;INITIALIZE A DDCMP LINE
DHDINI: MOVB LB..LN(J),R2 ;GET THE DH LINE #
.IIF NE FT.RDM!FT.RDP, MOV J,-(P) ;SAVE THE LINE BLOCK ADR
MOV #DDDHOU,-(P) ;GET THE OUTPUT INTERRUPT SERVICE PROC
MOV #DDDHIN,-(P) ;GET THE INPUT INTERRUPT SERVICE PROC
MOV LB.LCB(J),-(P) ;GET THE LINE CONTROL BLOCK ADDRESS
.IF NE FT.RDM
BIT #LS.MPT,(J) ;IF MULTIPOINT
BEQ 11$
TST LB.MPL(J) ;AND NOT A TRIBUTARY
BEQ 11$
CLR J ;MUSTN'T SAVE THE BLOCK ADR IN
;THE LCB BECAUSE ITS OFFLINE
11$:
.ENDC ;.IF NE FT.RDM
JSR PC,DH.INI ;INIT THE DH LINE
ADD #6,P ; POP THE ARGS
.IIF NE FT.RDM!FT.RDP, MOV (P)+,J ;RESTORE THE LINE BLOCK ADR
RTS PC
;ENABLE RECEIVER
DHRBEG: BIS #LS..RG,(J) ;FLAG RECEIVER GOING
MOV LB.IPT(J),-(P) ;GET BUFFER ADR
ADD J,(P)
MOV (P),LB.SRR(J) ;SET RECEIVER BUFFER
MOV #-1,LB.SRR+2(J) ;AND LENGTH
INC (P) ;SAME FOR SECONDARY BUFFER
MOV (P)+,LB.SRR+4(J)
MOV #-1,LB.SRR+6(J)
MOV #DHRSYN,LB.RDN(J) ;AND SET MESSAGE SEG PROC
RTS PC
;CHUCK GARBAGE TILL DDCMP HEADER STARTS
DHRSYN: MOV LB.SRR(J),R0 ;GET ADDRESS OF NEXT CHAR IN BUFFER
CMPB #ENQ,R1 ;IF <ENQ>
BEQ 09$
CMPB #SOH,R1 ;OR IF <SOH>
BEQ 09$
CMPB #DLE,R1 ;OR IF <DLE>
BNE 11$
09$:
.IF NE FT.MPT
BITB #MP.OFF,LB.MPS(J) ;IF MULTIPOINT OFFLINE CONDITION
BEQ 10$ ;WE MAY HAVE A PROBLEM
TST LB.MPL(J) ;IF ITS NOT A TRIBUTARY
BNE 11$ ;FORGET THIS BYTE
BIS #LS..RG,(J) ;ELSE SET RECEIVER GOING
;(SO WE DON'T LOSE THIS BYTE)
JSR PC,SELNXT ;PUT STATION BACK ONLINE
CLRB LB.MPT(J) ;BUT CLEAR THE TIMER BECAUSE THIS
;IS ONLY PRETEND
BICB #MP.SEL,LB.MPS(J) ;AND ALSO THE SELECTED FLAG
.ENDC ;.IF NE FT.MPT
;MAKE THE NEXT BUFFER THE SECOND HALF OF THE HEADER
10$: ADD #3,R0
SUB #2,LB.SRR+2(J) ;AND FIX THE COUNT FOR THE FIRST HALF
MOV #-4,R1 ;SET COUNT FOR SECOND HALF
MOV #DDRJNK,LB.RDN(J) ;AND SET MESSAGE SEG PROC
RTS PC
11$: DEC LB.SRR(J) ;ELSE BACK UP TO THE BUFFER'S START
MOV #-1,R1
RTS PC
;ENABLE XMITTER
DHXBEG:
.IF NE FTTRIB
BIT #LS.MPT,(J) ;IF NOT MULTIPOINT
BNE DHXBG2
.ENDC
DHXBG0: JSR PC,@LB.XDN(J) ;GET THE FIRST BUFFER LOAD
MOV R0,LB.SXR(J)
MOV R1,LB.SXR+2(J)
BNE DHXBG3 ;IF BUFFER EMPTY, EXIT
BIC #LS..XG!LS.XDT!LS.XCT,(J) ;SIGNAL XMITTER STOPPED
RTS PC
DHXBG1: MOV LB.SXR+4(J),LB.SXR(J) ;SET 2ND BUFFER AS FIRST
MOV LB.SXR+6(J),LB.SXR+2(J)
BNE DHXBG3
BR DHXBG0 ;IF ITS EMPTY FILL IT
.IF NE FTTRIB
DHXBG2: BITB #MP.CMS,LB.MPS+1(J) ;IF ALTER MODEM STATE ENABLED WHILE
BEQ DHXBG0 ;REQUEST TO SEND IS DISABLED
BITB #MP.RTS,LB.MPS+1(J)
BEQ DHXBG0
JSR R0,DMSTAT ;FIX THE DM11 LINE STATUS
.BYTE 0,MP.RTS
BICB #MP.RTS,LB.MPS+1(J) ;REQUEST TO SEND IS NOW ENABLED
MOV #DHFILL,LB.SXR(J) ;SEND SYNC SEQ TO TIME MODEM TRANSITION
MOV #-FTASYN,LB.SXR+2(J)
.ENDC
DHXBG3: JSR PC,@LB.XDN(J) ;REFIL THE 2ND BUFFER
MOV R0,LB.SXR+4(J)
MOV R1,LB.SXR+6(J)
BIS #LS..XG,(J) ;SIGNAL XMITTER GOING
DHSXMT: PIOFF
MOV LB.DHB(J),DH ;GET THE DH BLOCK ADR
BIS LB.BIT(J),DHBBAR(DH) ;AND SET THE XMITTER AS STARTED
MOV (DH),DH ; GET HARDWARE ADR
BIC #17,(DH) ;SET UP THE LINE IN THE DH
BISB LB..LN(J),(DH)
MOV LB.SXR(J),6(DH) ;SET THE XMIT BUFFER ADR
MOV LB.SXR+2(J),10(DH) ;SET THE XMIT COUNT
BIC LB.BIT(J),14(DH) ;BE SURE WE'RE NOT SENDING BREAK
BIS LB.BIT(J),12(DH) ;START THE XMITTER
PION
RTS PC
;INPUT INTERRUPT SERVICE
DDDHIN:
DDHINS: BIT #LS..RG,(J) ;IF THE RECEIVER IS RUNNING
BEQ 80$
MOVB R1,@LB.SRR(J) ;SAVE CHAR IN BUFFER
INC LB.SRR(J) ;ADVANCE THE BUFFER INDEX
INC LB.SRR+2(J) ;AND THE COUNT
BNE 80$
MOV LB.SRR+4(J),LB.SRR(J) ;IF FULL, SET 2ND BUF AS FIRST
MOV LB.SRR+6(J),LB.SRR+2(J)
BIC #LS.SSY,(J) ;DON'T NEED TO STRIP SYNC ON A DH
JSR PC,@LB.RDN(J) ;SEND THE MSG SEG TO DDCMP
MOV R0,LB.SRR+4(J) ;SET THE NEW 2ND BUFFER
MOV R1,LB.SRR+6(J)
TST LB.SRR+2(J) ;IF NO BUFFER
BNE 80$
BIC #LS..RG,(J) ;CLEAR THE RECEIVER GOING
QUEPUT QI 79$
80$: RTS PC
;OUTPUT INTERRUPT SERVICE
DDDHOU:
DDHOUS: JSR PC,DHXBG1 ;START THE XMITTER
TST LB.SXR+2(J) ;IF NO BUFFER
BNE 99$
.IF NE FT.MPT
BIT #LS.MPT,(J) ;IF MULTIPOINT
BEQ 95$
BITB #MP.SEL,LB.MPS(J) ;AND IF NOT SELECTED
BNE 95$
.IF NE FTTRIB
TST LB.MPL(J) ;AND THIS IS A TRIBUTARY
BNE 90$
BIS #LS..XG,(J) ;SET XMITTER GOING FOR FILL
MOV #DHFILL,LB.SXR(J)
MOV #-FTASYN,LB.SXR+2(J) ;WE MUST SHUT OFF THE XMITTER
MOV LB.LCB(J),DH ;BUT FIRST TIME THE LAST TWO
MOV #DDHSTP,LC.OUS(DH) ;CHARS THAT THE HWD BUFFERED
MOV #DHSXMT,-(P)
.ENDC ;.IF NE FTTRIB
90$: JSR PC,DESLCT ;DESELECT THE STATION
.ENDC ;.IF NE FT.MPT
95$: QUEPUT QO 89$
99$: RTS PC
.IF NE FTTRIB
;SEND BREAK TO HALT THE XMITTER
DDHSTP: JSR R0,DMSTAT ;AND FIX DM11 LINE STATUS IF REQUIRED
.BYTE MP.RTS,0
BISB #MP.RTS,LB.MPS+1(J) ;REQUEST TO SEND IS NOW DISABLED
MOV LB.LCB(J),DH ;RETURN TO ORDINARY INTERRUPT SERVICE
MOV #DDHOUS,LC.OUS(DH)
BIC #LS..XG,(J) ;SET XMITTER AS STOPPED
CLR LB.SXR+2(J)
RTS PC
DHFILL: ; FILL CHARACTERS FOR DH TIMING
.REPT FTASYN
.BYTE -1
.ENDR
.EVEN
DMSTAT: MOV LB.DHB(J),DH ;GET THE DM11 HARDWARE ADR
MOV DHB.DM(DH),DH
BEQ 30$ ;IF NONE EXIT
BIT #LS.MPT,(J) ;IF MULTIPOINT
BEQ 30$
BITB #MP.CMS,LB.MPS+1(J) ;AND IF CHANGE OF MODEM STATE ENABLED
BEQ 30$
BIS #DM.SCN,(DH) ;CLEAR THE DM11 SCAN
JSR R0,DMWAIT ;AND WAIT FOR IT TO SETTLE
TRAP ;DM11 BROKEN
BISB LB..LN(J),(DH) ;SET THE LINE NUMBER
JSR R0,DMWAIT ;AND WAIT AGAIN
TRAP ;DM11 BROKEN
TST (DH)+ ;GET THE ADDRESS OF THE LINE STATUS REGISTER
BICB (R0)+,(DH) ;CLEAR THE BITS
BISB (R0)+,(DH) ;AND SET THE BITS
RTS R0
30$: TST (R0)+ ;DO NOTHING AT ALL
RTS R0
.ENDC ;.IF NE FTTRIB
.ENDC ;.IF NE NDHMPT!NADHLN!NDHTRB!RDPDHN!FT.MPT
.ENDC ;.IF NE FTDH11 FROM BEGINING OF DNDH11.P11