Trailing-Edge
-
PDP-10 Archives
-
custsupcuspmar86_bb-x130b-sb
-
dncdds.p11
There are 10 other files named dncdds.p11 in the archive. Click here to see a list.
.SBTTL DNCDDS - DS11 SYNCHRONOUS LINE INTERFACE 28 MAR 79
;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 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
VRCDDS=006 ;FILE EDIT NUMBER
.IF NE DSN ;.IF SYNCHRONOUS LINES PRESENT, AND THEY HAVE DS11S
.IF NE FTDS11
;NOTES ON THE TRANSMIT AND RECEIVE INTERRUPT SERVICE ROUTINES
;DATA INTERRUPTS REALLY CONSIST OF 2 PHASES, SUPPLYING THE NEXT
;CHARACTER AND SETTING UP THE NEXT BUFFER. SINCE THE LATTER MAY TAKE
;SO MUCH TIME THAT DATA INTERRUPTS ARE LOCKED OUT, BOTH THESE ISR'S
;EMPLOY A TECHNIQUE TO GET AROUND THESE PROBLEMS. ONLY THE TRANSMITTER
;IS DESCRIBED HERE AS THE RECEIVER IS ESSETIALLY IDENTICAL.
;THE FIRST THING THE TRANSMIT INTERRUPT ROUTINE DOES IS TO SUPPLY
;THE HARDWARE WITH THE NEXT CHARACTER TO OUTPUT. IF THERE ARE MORE
;CHARACTERS WAITING IN THE STRING THE INTERRUPT IS DISMISSED.
;HOWEVER, IF THE STRING IS EXHAUSTED, THE DDCMP TRANSMIT COROUTINE
;MUST BE CALLED VIA @LB.XDN(J) TO GET THE NEXT STRING. SINCE THIS
;MAY TAKE A LONG TIME (THE RECEIVER CHECKS THE BCC), THE PRIORITY
;LEVEL IN THE PS IS DECREMENTED TO ALLOW DATA INTERRUPTS FROM THE
;RECEIVER OR OTHER LINES TO BE PROCESSED. ONCE THE COROUTINE IS DONE,
;WE INCREMENT THE PS, STORE THE POINTER TO THE NEXT STRING, AND
;FINALLY DISMISS THE INTERRUPT.
;THERE ARE A COUPLE OF RACE CONDITIONS TO KEEP IN MIND. FIRST, IF A
;DATA INTERRUPT FOR A DIFFERENT LINE OCCURS WHILE IN THE COROUTINE
;AND IT DECIDES IT HAS TO CALL ITS COROUTINE, IT WILL DO SO, GET AN
;ANSWER AND EXIT BEFORE THE FIRST INTERRUPT FINISHES BEING PROCESSED!
;THEREFORE, WHILE THIS SCHEME SHORTENS RESPONSE TIME TO DATA INTERRUPTS,
;IT MAY DOUBLE (OR TRIPLE...) RESPONSE TO REQUESTS FOR A NEW STRING.
;IT DOESN'T HAPPEN OFTEN, BUT IT DOES HAPPEN.
;SECOND, THERE ARE TIMES WHEN RESPONSE IS SO SLOW THAT A DATA INTERRUPT
;WILL OCCUR FOR A LINE ALREADY IN ITS COROUTINE. IF ITS PRESENT
;STRING STILL HAS DATA, THE LINE WILL GET ITS CHARACTER AND EVERYTHING
;KEEPS PLODDING ALONG. HOWEVER, IT CAN OCCUR THAT THE CURRENT
;STRING IS EXHAUSTED. IN THIS CASE LB.SXR+6 WILL BE 0, A FLAG
;THAT SAYS WE ARE STILL INSIDE THE COROUTINE. IN THIS CASE (AND IT
;DOES HAPPEN!) ABOUT THE ONLY THING WE CAN DO IS CALL DSXABT TO
;STOP THE TRANSMITTER AND LET THE DDCMP LOOP LEVEL CODE FIGURE
;OUT WHAT HAPPENED AND RESTART THE TRANSMITTER.
;DSDINI IS CALLED TO INITIALIZE A DS11 LINE
DSDINI: MOV #DS.IVA,DS.AUX ;SET VECTORS AGAIN
MOV #DS.DTR,DS.RST(DQ) ;SET ONLY DATA TERM. READY
MOV #DS.DTR,DS.XST(DQ) ;IN BOTH STATUS REGISTERS
RTS PC
;DSXBEG IS USED TO START UP AN IDLE DS11 LINE
DSXBEG: MOV LB.SLA(J),DQ ;BE CONSISTENT
TRACE DS ;SO YOU CAN SEE WHAT GOES ON
BIS #LS..XG,(J) ;SET RUN BIT SO NO 2ND CALL
MOV #SYNCHS,LB.SXR(J) ;START WITH SYNCS
MOV #-FTNSYN,LB.SXR+2(J)
JSR PC,@LB.XDN(J) ;GET MORE
MOV R0,LB.SXR+4(J) ;SET SECONDARY BUFFER
MOV R1,LB.SXR+6(J) ;AND COUNT
MOV #DS.XGO,DS.XST(DQ) ;BEFORE STARTING DS11
MOVB #SYN,DS.XDR(DQ) ;PRIME IT WITH A SYNCH
RTS PC
.MACRO X Q
DSVC'Q:
DSC.'Q: SAVE <J>
MOV #FLBDS+<LB.SIZ*'Q>,J
.ENDM X
Z=DSN-1
.REPT DSN
X \Z
.IIF NE Z, BR DSXINT ;NOW TO GENERAL XMINT ROUTINE
Z=Z-1
.ENDR
;DSXINT COME HERE FOR A DATA TRANSMIT INTERRUPT
DSXINT: SAVE <DQ> ;SAVE REGISTERS AS NECESSARY
MOV LB.SLA(J),DQ ;GET ADDRESS OF DEVICE REGISTERS
MOVB @LB.SXR(J),DS.XDR(DQ) ;SEND NEXT CHARACTER
INC LB.SXR(J) ;AND UPDATE THE ADDRESS
INC LB.SXR+2(J) ;COUNT THE BYTE
BNE DSXDIS ;THAT'S ALL
MOV LB.SXR+6(J),LB.SXR+2(J) ;COPY COUNT
BEQ DSXABT ;ABORT IF WE OVERRAN LOW LEVEL
CLR LB.SXR+6(J) ;MARK THIS STRING INVALID
MOV LB.SXR+4(J),LB.SXR(J) ;COPY ADDRESS
SUB #40,PS ;ENTER LOW LEVEL
SAVE <R0,R1,R2>
JSR PC,@LB.XDN(J) ;MORE TO DO?
MOV R0,LB.SXR+4(J) ;STORE THE ADDRESS
ADD #40,PS ;BACK TO HIGH LEVEL
MOV R1,LB.SXR+6(J) ;AND THE DATA COUNT
BNE 40$
MOV #DS.DTR,DS.XST(DQ) ;MAKE IT IDLE
BIC #LS..XG,(J) ;NO MORE BUSY
QUEPUT QO 39$
40$: RESTORE <R2,R1,R0>
DSXDIS: RESTORE <DQ,J>
RTI
.MACRO X Q
DSVD'Q:
DSD.'Q: SAVE <J>
MOV #FLBDS+<LB.SIZ*'Q>,J
.ENDM X
Z=DSN-1
.REPT DSN
X \Z
.IIF NE Z, BR DSXSIN ;NOW TO GENERAL XMT STATUS ROUTINE
Z=Z-1
.ENDR
;DSXSIN IS CALLED FOR XMIT STATUS INTERRUPTS
DSXSIN: SAVE <DQ>
MOV LB.SLA(J),DQ ;GET HARDWARE ADR
DSXABT: ;HERE IF DATA OVERRUNS XMIT COROUTINE
.IIF EQ FT.SLB, INC LB.SLE(J) ;COUNT ERROR INTERRUPTS
.IIF EQ FT.SLB, MOV DS.XST(DQ),LB.SLE+2(J) ;SAVE ERROR STATUS
MOV #DS.ZAP+DS.DTR,DS.XST(DQ) ;CLEAR THE LINE
BIT #LS..XG!LS.XDT!LS.XCT,@J ;ARE WE ACCOUNTED AS BUSY
BEQ DSXDIS ;IF NOT ACTIVE DONE
QUEPUT QO 19$ ;SOLVE THE RIDDLE
BIC #LS.XDT!LS.XCT!LS..XG,@J ;TRANSMITTER IS NO LONGER RUNNING
BR DSXDIS ;DISMISS INTERRUPT
;DSRBEG IS CALLED TO START LISTENING TO A LINE
DSRBEG: BIS #LS..RG,(J) ;RECEIVER GOING AND STRIPPING
MOV LB.SLA(J),DQ ;GET HDW VALUE
MOV #SYN,DS.RDR(DQ) ;TELL DS11 WHAT SYNCH IS
TRACE DS ;AND TRACE IT
MOV LB.IPT(J),R0 ;GET INPUT BUFFER
ADD J,R0 ;ADDRESS
MOV R0,LB.SRR(J) ;STORE THE ADDRESS
MOV #-4,LB.SRR+2(J) ;ZAP THE COUNT
ADD #4,R0 ;NEXT SEGMENT
MOV R0,LB.SRR+4(J) ;ADDRESS GOES HERE
MOV #-4,LB.SRR+6(J) ;THIS IS THE COUNT
MOV #DDRJNK,LB.RDN(J) ;HERE FOR A RECEIVE
MOV #DS.RGO,DS.RST(DQ) ;LET THE LINE RUN
BIC #LS.SSY,(J) ;RESET REQUEST STRIP SYNCH FLAG
RTS PC ;AND WAIT
.MACRO X Q
DSVA'Q:
DSA.'Q: SAVE <J>
MOV #FLBDS+<LB.SIZ*'Q>,J
.ENDM X
Z=DSN-1
.REPT DSN
X \Z
.IIF NE Z, BR DSRINT ;NOW TO GENERAL RECEIVE ROUTINE
Z=Z-1
.ENDR
;DSRINT RECEIVE INTERRUPTS FOR THE DS 11 COME HERE
;WHEN THE LINE IS SKIPPING BLANKS LB.SRR IS ZERO
DSRINT: SAVE <DQ> ;SAVE REGISTERS
MOV LB.SLA(J),DQ ;GET ADR OF LINE REGISTERS
MOVB DS.RDR(DQ),@LB.SRR(J) ;GET DATA BYTE
INC LB.SRR(J) ;ADVANCE POINTER
INC LB.SRR+2(J) ;COUNT THE BYTE
BNE DSRDIS ;AND THAT'S ALL NEARLY
BIT #LS.SSY,@J ;WANT TO START STRIPPING SYNC ?
BEQ 20$
BIC #LS.SSY,@J
MOV #SYN,DS.RDR(DQ) ;TELL DS WHAT TO LOOK FOR
MOV #DS.RGO,DS.RST(DQ) ;RESTART RECEIVER IN SYNC SEARCH
20$: SAVE <R0,R1,R2>
MOV LB.SRR+6(J),LB.SRR+2(J) ;SECONDARY IS FIRST NOW
BEQ 50$ ;STOP LINE IF WE OVERRUN LOW LEVEL
CLR LB.SRR+6(J) ;MARK FRAGMENT AS INVALID
MOV LB.SRR+4(J),LB.SRR(J) ;NEXT ONE
SUB #40,PS ; IN CASE WE TAKE A VERY LONG TIME
JSR PC,@LB.RDN(J) ;RECEIVE WSA DONE
MOV R0,LB.SRR+4(J) ;STORE NEXT ADDRESS AND COUNT
ADD #40,PS ;LOCKOUT INTERRUPTS AGAIN
MOV R1,LB.SRR+6(J) ;IF ANY
BNE 60$ ;TRY TO GET ANOTHER BUFFER
;HERE TO STOP THE RECEIVER
50$: MOV #DS.ZAP+DS.DTR,DS.RST(DQ);SILENCE THE LINE
BIC #LS..RG,@J ;CLEAR RECEIVER RUNS FLAG
QUEPUT QI 49$
JSR PC,DDCIGO ;NOW RESTART IT SO WE DON'T LOSE
;SOMETHING VALUABLE
60$: RESTORE <R2,R1,R0> ;RESTORE REGISTERS
DSRDIS: RESTORE <DQ,J>
RTI ;DISMISS INTERRUPT
;HERE FOR A RECEIVER STATUS INTERRUPT
.MACRO X Q
DSVB'Q:
DSB.'Q: SAVE <J>
MOV #FLBDS+<LB.SIZ*'Q>,J
.ENDM X
Z=DSN-1
.REPT DSN
X \Z
.IIF NE Z, BR DSRSIN ;NOW TO GENERAL RECEIVE ROUTINE
Z=Z-1
.ENDR
DSRSIN: SAVE <DQ>
MOV LB.SLA(J),DQ ;GET HDW ADR FOR DS11 LINE
BIT #170000,@DQ ;WAS THIS A SYNC TYPE INT
BEQ DSRDIS
.IIF EQ FT.SLB, INC LB.SLE(J) ;COUNT ERROR INTERRUPTS
.IIF EQ FT.SLB, MOV @DQ,LB.SLE+2(J) ;SAVE STATUS
MOV #DS.ZAP+DS.DTR,@DQ ;IDLE THE RECEIVER
BIT #LS..RG,(J) ;BUSY ACCORDING TO THE BOOKS
BEQ DSRDIS ;IF NOT GOING IGNORE
BIC #LS..RG,(J) ;CLEAR THE FLAG
QUEPUT QI 89$ ;PUT IT IN Q
BR DSRDIS ;DISMISS INTERRUPT
.ENDC;.IF NE FTDS11
.ENDC ; .IF NE DSN