1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-05-04 07:19:10 +00:00
Files
PDP-10.stacken/files/stacken-tape-backup/dskb:10_7/anf10/dncdds.p11
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

224 lines
7.6 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.SBTTL DNCDDS - DS11 SYNCHRONOUS LINE INTERFACE 28 MAR 79
;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,1984,1988.
;ALL RIGHTS RESERVED.
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