Trailing-Edge
-
PDP-10 Archives
-
BB-D351B-SM
-
sources/kmc11.p11
There is 1 other file named kmc11.p11 in the archive. Click here to see a list.
.SBTTL KMC11/DUP11 DRIVER
;
; THIS SECTION CONTAINS SUBROUTINES TO DRIVE THE KMC11/DUP11.
; THESE ARE:
;
; DQINIT INITIALIZE THE KMC11/DUP11
; DQREAD CONDITION THE KMC11/DUP11 FOR INPUT
; DQWRIT CONDITION THE KMC11/DUP11 TO OUTPUT A DATA MESSAGE
; DQCNTL CONDITION THE KMC11/DUP11 TO OUTPUT A CONTROL MESSAGE
; DQKILL CEASE ANY KMC11/DUP11 OPERATIONS
;
; THIS SECTION ALSO CONTAINS THE INTERRUPT CODE FOR THE KMC11/DUP11,
; AND A "ONCE-PER-CLOCK-TICK" SUBROUTINE
; TO PROVIDE DELAYED MODEM CONTROL SINCE A MODEM INTERRUPT
; CANNOT BE CAUSED BY THE PROGRAM.
; IT ALSO MAINTAINS THE KEEP-ALIVE COUNTERS.
;
.REPT 0
COPYRIGHT (c) 1980, 1979
DIGITAL EQUIPMENT CORPORATION, maynard, mass.
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.
DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
.ENDR
;
;
;
; REVISION HISTORY
;
;
; 4(001) BS ADDED EDIT NUMBERS
;
;
;
VKMC11=001
;
VEDIT=VEDIT+VKMC11
;
;
;
; SPECIFY THE NUMBER OF TRAILING PADS REQUIRED ON
; DATA MESSAGES.
;
DQTRLP=1 ;TO BE SURE THE LAST CHAR MAKES IT
;
; SPECIFY THE TYPE OF LINE INTERFACE, WHICH IS REPORTED TO THE -10
;
DQTYPE=2 ;1 = DQ11, 2 = KMC11/DUP11, 3 = DUP11 ALONE
;
;
; INITIALIZATION
;
; R4 = POINTER TO LINE CONTROL BLOCK FOR THE KMC11/DUP11 TO BE
; INITIALIZED.
;
DQINIT: TRACE TRCDQF,R4 ;TRACE "DUP11 INITIALIZATION"
MOV LB.SLA(R4),R3 ;GET DUP11 LINE HARDWARE ADDRESS
MOV #UP.INI,UP.XSR(R3) ;INITIALIZE THE DUP11
11$: BIT #UP.INI,UP.XSR(R3) ;HAS IT FINISHED INITIALIZATION?
BNE 11$ ;NO, WAIT FOR IT.
MOV #UP.CCI!UP.DMD!EBCSYN,UP.PAR(R3) ;SET UP PARMS
; FOR BISYNC
MOV #UP.HDX,UP.XSR(R3) ;BLIND RECEIVER DURING TRANSMISSIONS
MOV #UP.SSY,UP.RSR(R3) ;STRIP LEADING SYNC FROM MESSAGES
MOV LB.LNU(R4),R0 ;LINE NUMBER
ASR R0 ;LINE NUMBER/4 = KMC11 NUMBER
BIC #1,R0 ;KMC11 NUMBER * 2
MOV R0,R2 ;SAVE KMC11 NUMBER * 2
ASR R2 ;COMPUTE KMC11 NUMBER
MOV #MDTBL,R1 ;COMPUTE KMC11 TABLE ADDRESS
TST R2 ; USING NO MULTIPLY INSTRUCTION
BEQ 13$ ;WE HAVE IT
12$: ADD #MDTLN,R1 ;POINT TO NEXT TABLE
SOB R2,12$ ;DECREMENT COUNTER AND TRY AGAIN.
;
; ; CONTINUED ON NEXT PAGE
;
;
; HERE TO INITIALIZE THE KMC11 WHICH OWNS THIS DUP11.
; IF THE KMC11 HAS ALREADY BEEN INITIALIZED (BY STARTING ONE
; OF ITS OTHER LINES FIRST, FOR EXAMPLE) THEN WE NEED DO NOTHING.
; OTHERWISE WE STORE THE KMC11 CONTROL BLOCK ADDRESS INTO SEL 2
; TO SIGNAL IT TO START PROCESSING AND WAIT FOR ITS "RUN" BIT.
;
; R1 = ADDRESS OF KMC11 CONTROL BLOCK
; R0 = KMC11 NUMBER * 2
; R4 = LCB POINTER
;
13$: BIT #MDFER,MDFGE(R1) ;IS PDP-11 ALREADY RUNNING?
BNE 15$ ;YES, DON'T INIT AGAIN.
MOV MDVEC(R0),R2 ;NO, POINT TO KMC11 VECTOR
BNE 14$ ;THERE IS SUCH A KMC11
STOPCD KMM ;KMC11 IS MISSING
;
14$: MOV #MDAINT,(R2)+ ;STORE POINTER TO INT. HANDLER
MOV #MD.LVL*40,(R2)+ ;STORE PRIORITY LEVEL
MOV #MDBINT,(R2)+ ;STORE OTHER INT. HANDLER POINTER
MOV #MD.LVL*40,(R2)+ ;STORE PRIORITY LEVEL
MOV #MDFER,MDFGE(R1) ;MARK PDP-11 RUNNING
MOV MDCSR(R0),R3 ;POINT TO KMC11 CSR
MOV R1,2(R3) ;POINT MICROCODE TO KMC11 TABLE
15$: MOV R1,LB.MD(R4) ;STORE POINTER TO KMC11 TABLE IN LCB
MOV LB.LNU(R4),R0 ;GET LINE NUMBER
BIC #^C3,R0 ;LINE WITHIN KMC11
ASL R0 ; *2
ADD R1,R0 ;POINT INTO KMC11 TABLE
MOV R4,MDLCB(R0) ;STORE POINTER TO LCB IN KMC11 TABLE
;
; ; CONTINUED ON NEXT PAGE
;
;
; NOW WAIT FOR THE KMC11 TO START. WE WAIT UP TO THREE SECONDS.
;
MOV R4,-(SP) ;SAVE R4
MOV #JIFSEC*3,-(SP) ;NUMBER OF JIFFIES TO WAIT
MOV #EBTIME!EBWAIT,(R5) ;WAIT ONLY FOR TIME TO PASS
MOV #1,TCTIM(R5) ;CHECK FOR "RUN" EVERY JIFFY
;
; HERE BEGINS THE LOOP THAT WAITS FOR THE KMC11 TO BEGIN RUNNING.
;
16$: MOV 2(SP),R4 ;POINT R4 TO LCB
MOV LB.MD(R4),R3 ;POINT R3 TO KMC11 CONTROL BLOCK
BIT #MDFKR,MDFGK(R3) ;IS THE KMC11 RUNNING NOW?
BNE 17$ ;YES.
JSR PC,WAIT ;NO, WAIT ONE JIFFY
DEC (SP) ;WAITED LONG ENOUGH?
BNE 16$ ;NO, CHECK AGAIN.
STOPCD KNR ;KMC11 NOT RUNNING (WAITED 3 SEC)
;
; HERE WHEN THE KMC11 HAS SET ITS "RUN" BIT.
;
17$: MOV (SP)+,R4 ;DISCARD DEPLETED COUNTER
MOV (SP)+,R4 ;GET BACK LCB POINTER
;
; EXERCISE THE KMC11 TO BE SURE IT IS WORKING
;
MOV #21,R0 ;COUNT OF TIMES TO EXERCISE
18$: JSR PC,MDACTV ;PULL ITS CHAIN
SOB R0,18$ ;DO THIS FOR A WHILE
RTS PC ;RETURN.
;
;
; START RECEIVER
;
; R4 = POINTER TO LINE CONTROL BLOCK
;
; RETURNS C BIT SET IF ERROR, CLEAR IF OK.
; (ONLY ERROR IS CHUNKS DEPLETED)
;
DQREAD: TRACE TRCDQF,R4 ;TRACE ENTRY TO "DQ READ"
MOV LB.SLA(R4),R3 ;GET HARDWARE ADDRESS
.IF NE,FT.CHK
BIT #LS.RGO!LS.RRN,(R4) ;IS DUP11 ALREADY READING?
BEQ 11$ ;NO, GOOD.
STOPCD QRN ;DUP11 SUBR WITH DUP11 RUNNING
11$: MOV LB.TC1(R4),R0 ;POINT TO BSC TASK
TST TCCHK1(R0) ;DOES IT HAVE ANY CHUNKS?
BEQ 12$ ;NO, OK
STOPCD QRN ;YES, SOMETHING'S WRONG.
12$: TST LB.CCH(R4) ;IS THERE A "CURRENT CHUNK"?
BEQ 13$ ;NO, ALL IS WELL.
STOPCD QRN ;YES, THERE SHOULD NOT BE.
13$:
.ENDC ;.IF NE,FT.CHK
MOV CHLST,R0 ;GET A CHUNK
JSR PC,GETCHK
BCS 15$ ;NO MORE CHUNKS
CLR LB.CRD(R4) ;CLEAR COUNT OF CHARACTERS READ
MOV R4,R2 ;POINT R2 TO LCB
ADD #LB.SO1,R2 ;BUILD POINTER TO FIRST SILO
JSR PC,MDSLOI ;INITIALIZE THE SILO
;
; ; CONTINUED ON NEXT PAGE
;
;
; HERE WHEN EVERYTHING IS READY.
; UNLESS WE ARE WAITING TO START A WRITE,
; WE MUST START THE RECEIVER NOW, SINCE SOME DUP11'S
; DON'T INTERRUPT ON CARRIER, AND IF WE WAIT UP TO
; 16 MILLISECONDS BEFORE STARTING THE RECEIVER AFTER
; GETTING CARRIER, WE WILL FREQUENTLY LOSE THE FIRST
; CHARACTER OF THE MESSAGE.
;
MFPS -(SP) ;SAVE CPU PRIORITY LEVEL
MTPS #BR7 ;DISABLE CPU INTERRUPTS
BIS #UP.DIE,UP.RSR(R3) ;ENABLE MODEM INTERRUPTS
BIS #LS.RGO,(R4) ;WAITING TO START RECEIVER
BIT #LS.XGO,(R4) ;IS A WRITE PENDING?
BNE 14$ ;YES, WAIT FOR IT TO START.
BIC #LS.RGO!LS.CAR,(R4) ;NO, NO READ PENDING.
BIC #UP.CAR,LB.DIP(R4) ;PROCESS CARRIER NEXT TIME WE SEE IT
BIS #LS.RRN,(R4) ;START THE READ NOW.
JSR PC,MDACTV ;ACTIVATE THE KMC11
BIS #UP.REN,UP.RSR(R3) ;ENABLE THE DUP11 FOR READING
14$: MTPS (SP)+ ;RESTORE CPU PRIORITY
CLC ;FLAG NO ERROR
RTS PC ;AND RETURN.
;
;
; HERE IF WE CANNOT GET A CHUNK TO READ INTO. THIS IS A FATAL
; READ ERROR.
;
15$: INC LB.CHD(R4) ;COUNT TIMES CHUNKS DEPLETED
; SEC ;FLAG ERROR (C ALREADY SET)
RTS PC ;GIVE ERROR RETURN.
;
;
; SUBROUTINE TO START TRANSMITTING A DATA MESSAGE FROM LB.MSG
;
; R4 = POINTER TO LINE CONTROL BLOCK
;
; RETURNS WITH C BIT SET IF ERROR, CLEAR IF NOT.
;
DQWRIT: TRACE TRCDQF,R4 ;TRACE ENTRY TO "DQ WRITE DATA"
BIC #LS.CTL,(R4) ;THIS IS A DATA, NOT A CONTROL MESSAGE
MOV LB.SLA(R4),R3 ;GET DUP11 HARDWARE ADDRESS
.IF NE,FT.CHK
BIT #LS.ACT,(R4) ;IS DUP11 STILL ACTIVE?
BEQ 11$ ;NO.
STOPCD QRN ;YES, THIS IS NOT PROPER.
11$:
.ENDC ;.IF NE,FT.CHK
MOV LB.MSG(R4),R0 ;POINT TO MESSAGE
MOV (R0),R1 ;POINT TO FIRST DATA CHUNK
MOV R1,MSGLCH(R0) ;START WITH FIRST CHUNK
ADD #CHDAT,R1 ;POINT TO DATA AREA
MOV R1,MSGPTR(R0) ;STORE POINTER TO START OF DATA
JSR PC,XMTSTR ;ARRANGE TO START TRANSMITTER
RTS PC ;RETURN.
;
;
; SUBROUTINE TO ARRANGE TO START THE TRANSMITTER
;
XMTSTR: BIS #LS.XGO,(R4) ;XMITTER WAITING FOR CTS
BIC #LS.XND,(R4) ;NOT ENDING TRANSMISSION
MFPS -(SP) ;SAVE INTERRUPT LEVEL
MTPS #BR7 ;DISABLE INTERRUPTS
BIS #UP.RTS!UP.DIE,UP.RSR(R3) ;RAISE REQUEST TO SEND
; AND ENABLE FOR CTS INTERRUPT
MOV LB.CSD(R4),LB.DEW(R4) ;WAIT A WHILE, THEN CHECK FOR CTS
; NOTE THAT MODEM INTERRUPTS ARE IGNORED
; UNTIL TIME IS UP.
BNE 11$ ;TIME IS NOT YET UP.
;
; HERE IF CLEAR-TO-SEND DELAY SPECIFIED IS ZERO.
; IF CTS IS UP, START THE TRANSMITTER. NOTE THAT
; A ZERO CLEAR-TO-SEND DELAY SHOULD BE USED ONLY WITH MODEMS
; THAT HAVE A CLEAR-TO-SEND DELAY OF LESS THAN 16 MILLISECONDS,
; SINCE A LARGER DELAY CAN BE TIMED WITHOUT LOSS OF EFFICIENCY
; AND TOO SHORT A DELAY (LESS THAN ABOUT 8 MILLISECONDS)
; DOES NOT WORK WITH SOME IBM HOSTS.
;
BIT #UP.CTS,UP.RSR(R3) ;IS CTS UP?
BEQ 11$ ;NO, WAIT FOR MODEM INTERRUPT
BIC #LS.XGO,(R4) ;NOT WAITING FOR CTS
BIS #LS.XRN,(R4) ;NOW RUNNING
BIS #UP.SND,UP.XSR(R3) ;ENABLE FOR SENDING
MOV #UP.XSM!EBCPAD,UP.XBF(R3) ;FIRST CHAR IS PAD
JSR PC,MDACTV ;ACTIVATE THE KMC11
BR 12$ ;ENABLE INTERRUPTS, CLEAR C AND RETURN.
;
; HERE IF CTS DELAY IS NON-ZERO, OR IF IT IS ZERO AND CTS IS NOT UP.
;
11$: BIC #UP.CTS,LB.DIP(R4) ;PROCESS CTS RAISING NEXT TIME WE SEE IT
12$: MTPS (SP)+ ;ENABLE INTERRUPTS
CLC ;CLEAR 'C' FLAG
RTS PC ;RETURN.
;
;
; SUBROUTINE TO START TRANSMITTING A CONTROL MESSAGE (E.G., ACK)
;
; R4 = POINTER TO LINE CONTROL BLOCK
; R0 = POINTER TO MESSAGE TO SEND
; R1 = LENGTH OF MESSAGE TO SEND
;
; ON RETURN:
;
; C SET IF ERROR, CLEAR IF NOT.
;
DQCNTL: TRACE TRCDQF,R4 ;TRACE ENTRY TO "DQ WRITE CONTROL"
MOV R0,LB.CMA(R4) ;REMEMBER CONTROL MESSAGE ADDRESS
MOV R1,LB.CMC(R4) ; AND LENGTH
BIS #LS.CTL,(R4) ;WE ARE WORKING ON A CONTROL MESSAGE
TRACE TRCDQF,R0 ; AND NOTE MESSAGE
MOV LB.SLA(R4),R3 ;GET DUP11 HARDWARE ADDRESS
.IF NE,FT.CHK
BIT #LS.ACT,(R4) ;IS DUP11 STILL ACTIVE?
BEQ 11$ ;NO.
STOPCD QRN ;YES, ERROR.
11$: TST LB.CCH(R4) ;HAS RECEIVER STILL GOT A CHUNK?
BEQ 12$ ;NO, THAT'S GOOD.
STOPCD QRN ;YES, MUST SOMEHOW BE RUNNING.
12$:
.ENDC ;.IF NE,FT.CHK
JSR PC,XMTSTR ;ARRANGE TO START TRANSMITTER
RTS PC ;RETURN.
;
;
; THIS IS THE COMMON INTERRUPT CODE FOR DUP11 RECEIVER INTERRUPTS.
; IT IS CALLED WITH PS CONTAINING THE LINE NUMBER.
; MODEM INTERRUPTS ALSO COME HERE.
;
DQAINT: JSR R4,(PC) ;SAVE R4 WITHOUT CHANGING PS
MFPS R4 ;GET PS
BIC #177760,R4 ;REMOVE ALL BUT LINE NUMBER
ASL R4 ;LINE NUMBER * 2
MOV DQLCB(R4),R4 ;GET POINTER TO LCB
MOV R3,-(SP) ;SAVE R3
MOV R1,-(SP) ;SAVE R1
MOV R0,-(SP) ;SAVE R0
.IF NE,FT.CHK
TST R4 ;HAVE WE A LINE BLOCK?
BNE 11$ ;YES.
STOPCD UQR ;UNKNOWN DUP11 RECEIVER INTERRUPT
11$:
.ENDC ;.IF NE,FT.CHK
MOV LB.SLA(R4),R3 ;GET HARDWARE ADDRESS OF DUP11
INC LB.RCT(R4) ;ONE MORE RECEIVER INTERRUPT
TRACE TRCDQF,R4 ;TRACE DUP11 "A" INTERRUPT
;
;
; HERE TO CHECK FOR A DUP11 RECEIVER INTERRUPT BIT
;
RCVTST: MOV UP.RSR(R3),R0 ;GET RECEIVER STATUS REGISTER
MOV R0,LB.RST(R4) ;STORE LAST RECEIVER STATUS
TRACE TRCDQF,R0 ;TRACE INTERRUPT STATUS
;
; HERE TO CHECK FOR DATASET INTERRUPT FLAGS, SINCE THE KMC11 TAKES
; CARE OF DATA SIGNALS.
;
11$: BIT #UP.DCA!UP.DCB,R0 ;ANY DATASET FLAGS?
BEQ 12$ ;NO, EXIT THE INTERRUPT.
JSR PC,RCVDSF ;YES, PROCESS DATASET FLAGS
;
; HERE ON NORMAL EXIT. WAKE THE BSC TASK IF REQUESTED.
;
12$: BIT #LS.CIE,(R4) ;DOES BSC TASK WANT TO BE AWAKENED?
BEQ 13$ ;NO.
BIC #LS.CIE,(R4) ;YES, CLEAR FLAG
MOV LB.TC1(R4),R0 ;POINT TO BSC TASK'S TCB
BIT #EBQCHK,(R0) ;IS BSC TASK WAITING FOR CHUNK DATA?
BEQ 13$ ;NO (UNLIKELY)
BIC #EBQCHK!EBWAIT,(R0) ;YES, UNWAIT IT.
13$:
;
; HERE TO RESTORE REGISTERS AND RETURN.
;
14$: MOV (SP)+,R0 ;RESTORE R0
MOV (SP)+,R1 ; AND R1
MOV (SP)+,R3 ; AND R3
MOV (SP)+,R4 ; AND R4
RTI ;EXIT INTERRUPT
;
;
; SUBROUTINE TO RECORD A DUP11 ERROR.
; CALLER INCREMENTS LB.SE4, LB.SE5 OR LB.SE6 BEFORE CALLING.
;
DQERRR: INC LB.SE1(R4) ;COUNT MASTER ERROR COUNTER
MOV LB.SLA(R4),R3 ;POINT TO DUP11 CSR
MOV UP.RSR(R3),LB.SE2(R4) ;RECORD STATUS REG 1
MOV UP.XSR(R3),LB.SE3(R4) ; AND STATUS REG 2
BIS #LS.ERR,(R4) ;FLAG AN ERROR
RTS PC ;RETURN TO CALLER.
;
;
; SUBROUTINE TO STOP THE RECEIVER
;
; R4 POINTS TO LCB, R3 TO CSR.
;
RCVSTP: TRACE TRCDQF,R4 ;TRACE DUP11 RECEIVER STOP
.IF NE,DEBUG
BIT #LS.RGO!LS.RRN,(R4) ;IS RECEIVER RUNNING?
BNE 11$ ;YES.
STOPCD DBG ;NO, SHOULDN'T BE HERE.
11$:
.ENDC ;.IF NE,DEBUG
BIC #UP.DIE,UP.RSR(R3) ;DISABLE MODEM INTERRUPTS
BIS #LS.KIL,(R4) ;KILL CURRENT OPERATION
JSR PC,MDACTV ;AWAKEN THE KMC11
RTS PC ;RETURN.
;
;
; HERE ON A SILO INTERRUPT FROM THE KMC11.
; DRAIN ANY NON-EMPTY SILOS WHICH HAVE THEIR "INTERRUPT ON
; NEXT CHARACTER" FLAG CLEAR, WHICH MEANS THAT THE KMC11
; MIGHT HAVE INTERRUPTED BECAUSE OF THEM. THE KMC11 WILL
; GIVE FULL AND WARNING INTERRUPTS REGARDLESS OF THE
; STATE OF THIS FLAG.
;
MDAINT: MOV R2,-(SP) ;SAVE R2
MOV R3,-(SP) ;SAVE R3
MOV R4,-(SP) ;SAVE R4
MOV R5,-(SP) ;SAVE R5
;
; HERE TO CHECK ALL LCB'S FOR A NON-EMPTY SILO
;
CLR R5 ;LINE NUMBER * 2
;
; HERE TO CHECK THE NEXT LCB
;
11$: MOV DQLCB(R5),R4 ;POINT TO LCB
BEQ 13$ ;NO LCB FOR THIS LINE
BIT #LS.XGO!LS.XRN!LS.KIL!LS.KLC,(R4)
;IS THIS LINE WRITING OR KILLED?
BNE 13$ ;YES, IGNORE ITS SILO
BIT #LS.RRN,(R4) ;NO, IS LINE DOING INPUT?
BEQ 13$ ;NO, IGNORE ITS SILO.
TRACE TRCMDF,R4 ;KMC11 INPUT INTERRUPT FOR THIS LCB
MOV LB.SLO(R4),R3 ;POINT TO SILO
BIT #MDSLFE,MDSLFG(R3) ;WILL THIS SILO INT. ON NEXT CHAR?
BNE 12$ ;YES, IGNORE IT UNTIL IT INTERRUPTS.
MOV MDSLPT(R3),R2 ;NO, GET CURRENT ADDRESS FROM SILO
SUB LB.CCD(R4),R2 ;SUBTRACT INITIAL ADDRESS
CMP R2,@LB.CCR(R4) ;HAS COUNT CHANGED?
BEQ 12$ ;NO, IGNORE THIS EMPTY SILO.
JSR PC,MDSLEM ;YES, EMPTY THE SILO
BIS #LS.RSE,(R4) ;MARK THAT THE RECEIVE SILO
; WAS EMPTIED.
.IF NE,DEBUG
BR 13$ ;DONE WITH THIS LCB
.ENDC ;.IF NE,DEBUG (NO CODE BETWEEN FINISH AND REJECT UNLESS DEBUG)
;
; ; CONTINUED ON NEXT PAGE (UNLESS DEBUG)
;
;
; HERE TO REJECT THIS LCB (R3 IS SET UP)
;
12$:
.IF NE,DEBUG
TRACE TRCMDF,R3 ;RECORD SILO POINTER
TRACE TRCMDF,(R3) ; AND ITS STATUS BITS
.ENDC ;.IF NE,DEBUG
;
; HERE WHEN WE ARE DONE WITH THIS LCB
;
13$: ADD #2,R5 ;INCREMENT LINE NUMBER * 2
CMP #<NLINES*2>,R5 ;DONE ALL THE LINES?
BNE 11$ ;NO, DO THE REST.
;
; HERE WHEN ALL THE SILOS HAVE BEEN EMPTIED.
;
MOV (SP)+,R5 ;RESTORE R5
MOV (SP)+,R4 ; AND R4
MOV (SP)+,R3 ; AND R3
MOV (SP)+,R2 ; AND R2
RTI ;EXIT THE INTERRUPT
;
;
; DUP11 TRANSMIT INTERRUPTS. SHOULD NOT HAPPEN SINCE THE KMC11
; PROCESSES ALL DATA FLAGS.
;
DQBINT: STOPCD UQX ;UNKNOWN DUP11 TRANSMIT INTERRUPT
;
;
; INTERRUPT CODE FOR KMC11 "FUNCTION DONE" AND "ERROR".
;
MDBINT: MOV R0,-(SP) ;SAVE R0
MOV R1,-(SP) ; AND R1
MOV R2,-(SP) ; AND R2
MOV R3,-(SP) ; AND R3
MOV R4,-(SP) ; AND R4
MOV R5,-(SP) ; AND R5
;
; HERE TO CHECK ALL LCB'S FOR COMPLETION OR ERROR.
;
CLR R5 ;LINE NUMBER * 2
;
; HERE TO CHECK THE NEXT LCB
;
11$: MOV DQLCB(R5),R4 ;POINT TO LCB
BEQ 18$ ;NO LCB, DO NOTHING.
TRACE TRCMDF,R4 ;NOTE OUTPUT INTERRUPT FOR THIS LCB
MOV LB.SLA(R4),R3 ;POINT TO DUP11 CSR
BIT #LS.CMP!LS.KLC,(R4) ;FUNCTION COMPLETE?
BEQ 18$ ;NO, CHECK NEXT LCB
TRACE TRCMDF,(R4) ;RECORD LCB STATUS ON INTERRUPT
BIT #LS.KLC,(R4) ;COMPLETION OF KILL REQUEST?
BEQ 12$ ;NO. CHECK FOR WRITE AND READ.
BIT #LS.MDE,(R4) ;YES, HAVE WE HAD AN ERROR?
BEQ 16$ ;NO. AWAKEN BSC TASK IF REQ.
BIC #LS.MDE,(R4) ;YES, CLEAR KMC11 ERROR FLAG
BIS #LS.ERR,(R4) ;SET SUMMARY ERROR FLAG
BR 16$ ;AWAKEN BSC TASK IF REQ.
;
;
; HERE IF NOT COMPLETION OF A KILL REQUEST
;
12$: BIT #LS.XGO!LS.XRN,(R4) ;COMPLETION OF A WRITE?
BEQ 14$ ;NO.
BIC #UP.DIE,UP.RSR(R3) ;YES, DISABLE MODEM INTERRUPTS
BIC #UP.RTS,UP.RSR(R3) ;DROP RTS
CLR LB.DEW(R4) ;NOT WAITING FOR MODEM SIGNALS
BIT #LS.MDE,(R4) ;HAVE WE HAD AN ERROR?
BEQ 13$ ;NO.
INC LB.SE5(R4) ;YES, "TRANSMITTER NOT FAST ENOUGH"
JSR PC,DQERRR ;RECORD DUP11 REGISTERS
BIC #LS.ACT!LS.MDE,(R4) ;DONT START A READ FOLLOWING WRITE
CLR LB.CCH(R4) ;THERE IS NO CURRENT CHUNK
13$: BIC #LS.XGO!LS.XRN!LS.CMP,(R4) ;CLEAR COMPLETED WRITE FLAGS
BIT #LS.ACT,(R4) ;IS DUP11 STILL ACTIVE?
BEQ 16$ ;NO, LEAVE MODEM INTS DISABLED.
BIS #UP.DIE,UP.RSR(R3) ;YES, ENABLE MODEM INTS
BR 16$ ;AWAKEN BSC TASK IF REQUESTED.
;
; HERE IF NOT COMPLETION OF KILL OR WRITE
;
14$: BIT #LS.RGO!LS.RRN,(R4) ;RECEIVER RUNNING?
BEQ 15$ ;NO.
BIC #LS.RGO!LS.RRN!LS.CMP!LS.MDE,(R4) ;YES, CLEAR THE FLAGS
BIC #UP.DIE,UP.RSR(R3) ;CLEAR MODEM INTERRUPT ENABLE
CLR LB.CCH(R4) ;THERE IS NO CURRENT CHUNK
MOV LB.SLO(R4),R0 ;POINT TO CURRENT SILO
BIT #MDSLFO,MDSLFG(R0) ;HAS IT OVERFLOWED?
BEQ 20$ ;NO.
INC LB.SE7(R4) ;YES, COUNT SILO OVERFLOWS.
20$: INC LB.SE4(R4) ;MUST BE AN ERROR...
JSR PC,DQERRR ; SINCE THAT IS ONLY REASON FOR STOPPING
BR 16$ ;AWAKEN BSC TASK IF REQUESTED
;
; HERE IF NOT COMPLETION OF KILL, WRITE OR READ.
;
15$: STOPCD KCQ ;KMC11 COMPLETE ON AN IDLE LCB
;
;
; HERE WHEN LINE HAS MADE A TRANSITION.
;
16$: MOV LB.TC1(R4),R0 ;POINT TO TCB OF BSC TASK
BIT #EBINTR,(R0) ;DOES IT WANT TO BE AWAKENED?
BEQ 17$ ;NO.
BIC #EBINTR!EBWAIT,(R0) ;YES, AWAKEN IT.
17$:
;
; HERE WHEN WE ARE DONE WITH THIS LCB.
;
18$:
.IF NE,DEBUG
TST R4 ;HAVE WE AN LCB?
BEQ 19$ ;NO, DONT TRACE
TRACE TRCMDF,(R4) ;YES, TRACE NEW STATE OF LCB
19$:
.ENDC ;.IF NE,DEBUG
ADD #2,R5 ;INCREMENT LINE NUMBER * 2
CMP #<NLINES*2>,R5 ;DONE LAST LINE?
BNE 11$ ;NO, DO THE REST.
;
; HERE WHEN WE HAVE DONE A PASS AND ALL LINES HAVE NO ACTION.
;
MOV (SP)+,R5 ;RESTORE R5
MOV (SP)+,R4 ; AND R4
MOV (SP)+,R3 ; AND R3
MOV (SP)+,R2 ; AND R2
MOV (SP)+,R1 ; AND R1
MOV (SP)+,R0 ; AND R0
RTI ;EXIT THE INTERRUPT.
;
;
; SUBROUTINE TO STOP THE TRANSMITTER
;
; R4 POINTS TO THE LCB
; R3 POINTS TO THE DUP11 CSR
;
XMTSTP: TRACE TRCDQF,R4 ;TRACE DUP11 TRANSMITTER STOP
BIC #UP.RTS,UP.RSR(R3) ;DROP REQUEST TO SEND
BIS #LS.KIL,(R4) ;TELL KMC11 TO STOP
JSR PC,MDACTV ;AWAKEN KMC11
CLR LB.DEW(R4) ;NOT WAITING TO ENABLE MODEM
CLC ;INDICATE NO ERROR
RTS PC ;RETURN.
;
;
; SUBROUTINE TO PROCESS A DATA SET FLAG.
;
; R0 = DATASET FLAGS
; R3 = DUP11 CSR
;
; ON RETURN, R3 IS DESTROYED.
;
RCVDSF: INC LB.DIC(R4) ;COUNT DATASET INTERRUPTS
MOV R0,LB.DIS(R4) ;RECORD LAST MODEM INTERRUPT STATUS
TST LB.DEW(R4) ;WAITING FOR DATASET ENABLE?
BNE 13$ ;YES, IGNORE MODEM SIGNAL.
BIT #LS.ACT,(R4) ;IS THE DUP11 ACTIVE?
BEQ 13$ ;NO, IGNORE THE MODEM SIGNALS
MOV R0,LB.DIP(R4) ;YES, RECORD LAST MODEM SIGNALS PROCESSED
BIT #LS.XGO,(R4) ;WAITING TO START XMITTER?
BEQ 11$ ;NO.
JSR PC,14$ ;YES, CHECK FOR CLEAR-TO-SEND.
11$: BIT #LS.XRN,(R4) ;RUNNING THE TRANSMITTER?
BEQ 12$ ;NO.
JSR PC,18$ ;YES, BE SURE CTS STILL UP
12$: BIT #LS.RRN,(R4) ;RUNNING RECEIVER?
BEQ 13$ ;NO.
JSR PC,20$ ;YES, WORRY ABOUT CARRIER FAILURE.
13$: RTS PC ;RETURN TO CALLER.
;
;
; THREE SUBROUTINES TO PROCESS DATA SET FLAGS. THEY ARE CALLED
; BASED ON THE CURRENT STATE OF THE DUP11.
;
; R0 = MODEM STATUS FLAGS, FROM THE DUP11.
; R3 = POINTER TO DUP11 CSR
;
; HERE IF WE ARE WAITING TO START THE TRANSMITTER
;
14$: BIT #UP.CTS,R0 ;HAVE WE CLEAR-TO-SEND?
BEQ 17$ ;NO, WAIT FOR IT.
BIC #LS.XGO,(R4) ;NO LONGER WAITING TO START TRANSMITTER
BIT #LS.RGO,(R4) ;WAITING TO START RECEIVER?
BEQ 15$ ;NO.
BIC #LS.RGO!LS.CAR,(R4) ;YES, WAITING NO LONGER.
BIC #UP.CAR,LB.DIP(R4) ;PROCESS CARRIER NEXT TIME WE SEE IT
BIS #LS.XRN!LS.RRN,(R4) ;START XMIT, FOLLOW WITH RCV
BR 16$ ;INFORM THE KMC11
;
; HERE IF THE WRITE IS NOT TO BE FOLLOWED BY A READ
;
15$: BIS #LS.XRN,(R4) ;NOW RUNNING TRANSMITTER
16$: BIS #UP.SND,UP.XSR(R3) ;ENABLE THE DUP11 FOR SENDING
MOV #UP.XSM!EBCPAD,UP.XBF(R3) ;FIRST CHAR IS PAD
JSR PC,MDACTV ;INFORM THE KMC11
17$: RTS PC ;ALL DONE.
;
; HERE IF WE ARE RUNNING THE TRANSMITTER
;
18$: BIT #UP.CTS,R0 ;IS CLEAR-TO-SEND STILL UP?
BNE 19$ ;YES, ALL OK.
INC LB.SE6(R4) ;NO, NOTE CLEAR-TO-SEND FAILURE
JSR PC,DQERRR ;NOTE ERROR
JSR PC,XMTSTP ;STOP THE TRANSMITTER
19$: RTS PC ;ALL DONE.
;
; HERE IF THE RECEIVER IS RUNNING.
;
20$: BIT #UP.CAR,R0 ;IS CARRIER UP?
BNE 21$ ;YES.
BIT #LS.CAR,(R4) ;NO, HAVE WE SEEN CARRIER YET?
BEQ 22$ ;NO, DONT WORRY ABOUT IT.
JSR PC,RCVSTP ;YES, STOP THE RECEIVER
BR 22$ ;ALL DONE.
;
; HERE IF CARRIER IS UP
;
21$: BIS #LS.CAR,(R4) ;MARK WE HAVE SEEN CARRIER
22$: RTS PC ;RETURN.
;
;
; SUBROUTINE TO SEE IF THE KMC11 HAS READ ANY CHARACTERS
; RECENTLY. ALL CHARACTERS UP TO CHLEN HAVE BEEN PROCESSED.
;
; R5 POINTS TO THE TCB, WHICH MUST HAVE EBWAIT SET.
; R4 POINTS TO THE CURRENT CHUNK.
;
; ON RETURN:
;
; C SET: SOME CHARACTERS WERE FOUND IN THE SILO.
; IF R4 UNDISTURBED, THEY ARE IN CURRENT CHUNK
; (THE LENGTH FIELD HAS BEEN UPDATED)
; IF R4 CLEAR, GET A NEW CHUNK TO PROCESS.
;
; C CLEAR: THE SILO IS EMPTY. IT IS NOW
; SET TO RESTART THE BSC TASK ON THE NEXT CHARACTER.
;
DQINWQ: MOV R0,-(SP) ;SAVE R0
MOV R3,-(SP) ; AND R3
MOV R2,-(SP) ; AND R2
MOV R4,R0 ;POINT R0 TO CURRENT CHUNK
MOV TCLCB(R5),R4 ;POINT TO LCB
11$: MFPS -(SP) ;SAVE INTERRUPT LEVEL
MTPS #MD.LVL*40 ;DISABLE KMC11 INTERRUPTS
BIT #LS.RSE,(R4) ;HAS THE RECEIVE SILO BEEN
; EMPTIED SINCE LAST CALL?
BNE 13$ ;YES, BE SURE PROCESSING IS DONE.
CMP R0,LB.CCH(R4) ;NO, IS THIS STILL THE CURRENT CHUNK?
BNE 12$ ;NO. DISCARD IT AND GET ANOTHER.
MOV DSPCLK,R3 ;YES, GET DISPATCHER CLOCK
MOV JIFCLK,R2 ; AND JIFFIE CLOCK
XOR R3,R2 ;FORM LOGICAL DIFFERENCE
BIT #177774,R2 ;HAVE MORE THAN THREE TICKS PASSED?
BNE 17$ ;YES, MAKE BSC TASK WAIT.
MOV LB.SLO(R4),R3 ;NO, POINT R3 TO SILO
MOV MDSLPT(R3),R2 ;GET CURRENT ADDRESS FROM SILO
SUB LB.CCD(R4),R2 ;SUBTRACT INITIAL ADDRESS
CMP R2,@LB.CCR(R4) ;HAS COUNT CHANGED?
BNE 14$ ;YES, PROCESS CHARACTERS
BR 16$ ;NO, TELL CALLER TO WAIT
;
;
; HERE TO ABANDON THIS CHUNK BECAUSE IT IS NO LONGER
; BEING FILLED.
;
12$: MTPS (SP)+ ;ENABLE INTERRUPTS
TRACE TRCMDF,R4 ;TRACE DECISION TO ABANDON OLD CHUNK
MOV R1,-(SP) ;SAVE R1
MOV TCIDLE,R1 ;GIVE CURRENT CHUNK TO IDLE TASK
JSR PC,QUECHK ; TO FREE.
MOV (SP)+,R1 ;RESTORE R1
CLR R0 ;NO MORE OLD CHUNK
BR 15$ ;TELL CALLER TO RECYCLE
;
; HERE TO TELL CALLER TO RECYCLE BECAUSE THE SILO HAS BEEN
; DRAINED SINCE THE LAST TIME WE CAME THROUGH HERE. IF WE
; DO NOT DO THIS, THE SILO MIGHT HAVE BEEN DRAINED BETWEEN
; THE CALLER'S LAST TEST AND OUR TESTS, SO MAKE CALLER
; DO HIS TESTS ONE MORE TIME.
;
13$: BIC #LS.RSE,(R4) ;CLEAR INTERRUPT FLAG
MTPS (SP)+ ;RESTORE INTERRUPTS
BR 15$ ;TELL CALLER TO RECYCLE
;
;
; HERE TO EMPTY THE SILO AND TELL CALLER TO PROCESS CHARS
;
14$: TRACE TRCMDF,R4 ;TRACE DECISION TO EMPTY SILO
JSR PC,MDSLEM ;EMPTY THE SILO
MTPS (SP)+ ;ENABLE INTERRUPTS
;
; HERE TO RETURN, TELLING CALLER NOT TO WAIT.
;
15$: MOV (SP)+,R2 ;RESTORE R2
MOV (SP)+,R3 ; AND R3
MOV R0,R4 ;RESTORE R4
MOV (SP)+,R0 ; AND R0
SEC ;FLAG MORE PROCESSING REQUIRED
RTS PC ;RETURN.
;
;
; HERE IF THE SILO IS STILL EMPTY. ARRANGE TO AWAKEN THIS TASK
; WHEN THE NEXT CHARACTER IS STORED.
;
16$: BIS #LS.CIE,(R4) ;SET WAKEUP FLAG
BIS #MDSLFE,MDSLFG(R3) ;MAKE THIS SILO INTERRUPT
; ON NEXT CHARACTER
;
; COME HERE TO WAIT THE TASK. FROM ABOVE, WE WILL AWAKEN
; ON THE NEXT CHARACTER. IF THE LINE IS RUNNING FAST,
; WE BYPASS THE ABOVE CODE AND JUST REQUIRE THE BSC TASK
; TO WAIT UNTIL EITHER THE CHUNK FILLS OR ITS TIMER
; EXPIRES.
;
17$: TRACE TRCMDF,R4 ;TRACE DECISION TO WAIT THE TASK.
MTPS (SP)+ ;RESTORE INTERRUPT LEVEL
MOV (SP)+,R2 ;RESTORE R2
MOV (SP)+,R3 ;RESTORE R3
MOV R0,R4 ;RESTORE R4
MOV (SP)+,R0 ;RESTORE R0
CLC ;FLAG NO CHARACTERS
RTS PC ;RETURN.
;
;
; SUBROUTINE TO EMPTY THE KMC11'S SILO.
;
; THIS SUBROUTINE IS CALLED FROM INPUT INTERRUPT
; AND IF THE BSC TASK NEEDS MORE CHARACTERS TO
; AVOID GOING IDLE.
;
; INTERRUPTS ARE MASKED OFF BY THE CALLER OF THIS SUBROUTINE.
;
; R4 = LCB POINTER
; R3 = SILO POINTER (FROM LB.SLO(R4)).
; DESTROYS R2
;
MDSLEM: TRACE TRCMDF,MDSLFG(R3) ;TRACE SILO FLAG BITS
.IF NE,DEBUG
BIT #MDSLFE,MDSLFG(R3) ;IS THIS SILO INTERRUPTABLE?
BEQ 11$ ;NO.
STOPCD DBG ;YES, WE SHOULD NOT BE PROCESSING IT.
11$: BIT #LS.RRN,(R4) ;IS LINE DOING INPUT?
BNE 12$ ;YES.
STOPCD DBG ;NO, SHOULDN'T BE HERE.
12$:
.ENDC ;.IF NE,DEBUG
MOV R0,-(SP) ;SAVE R0
MOV R1,-(SP) ; AND R1
BIT #MDSLFW,MDSLFG(R3) ;REACHED WARNING LEVEL YET?
BEQ MDSLE1 ;NO, DONT SWITCH SILOS
TRACE TRCMDF,MDSLCC(R3) ;YES, TRACE DEPARTURE OF CHUNK
MOV R4,R2 ;BUILD POINTER TO OTHER SILO
ADD #LB.SO1,R2
CMP R2,R3 ;IS THIS SILO 1?
BNE 13$ ;NO.
ADD #LB.SO2-LB.SO1,R2 ;YES, MAKE R2 POINT TO SILO 2
13$:
;
; ; CONTINUED ON NEXT PAGE
;
;
; GET A CHUNK TO HOLD NEW SILO DATA
;
MOV CHFST,R0 ;GET ANOTHER CHUNK.
CMP R0,CHLST ;IS THERE ONLY ONE CHUNK LEFT?
BEQ 14$ ;YES, WE ARE OUT OF CHUNKS
MOV (R0),R1 ;NO, GET NEXT CHUNK
BIC #1,R1 ;CLEAR "FREE" FLAG
MOV R1,CHFST ;NEXT IS NOW FIRST CHUNK
CLR (R0) ;CLEAR "FREE" BIT
CLR 2(R1) ;CLEAR NEW FIRST CHUNK'S BACK POINTER
DEC CHFREC ;ONE FEWER FREE CHUNK
TRACE TRCCNK,R0 ;TRACE CHUNK MANIPULATION
.IF NE,CHOWNR
MOV PC,R1 ;CHUNK OWNER IS HERE
JSR PC,CHOWNG ;RECORD CHUNK OWNER
.ENDC ;.IF NE,CHOWNR
JSR PC,MDSLOI ;INITIALIZE THE NEW SILO
BR MDSLE1 ;PROCESS DATA IN OLD SILO
;
; HERE IF WE RUN OUT OF CHUNKS. THIS IS NOT A FATAL ERROR IF
; THE BSC TASK SEES THE END OF THE BISYNC MESSAGE BEFORE
; NEEDING THE DATA THAT WAS LOST.
;
14$: INC LB.CHD(R4) ;RECORD EXHAUSTION OF CHUNKS
MOV LB.SLA(R4),R3 ;POINT TO DUP11 CSR
JSR PC,RCVSTP ;STOP THE RECEIVER
BR MDSLEX ;EXIT THE SUBROUTINE
;
;
; HERE TO GIVE THE CHARACTERS IN THE SILO TO THE TASK.
; THIS IS DONE BY UPDATING THE LENGTH FIELD OF THE CURRENT
; CHUNK.
;
; R3 = POINTER TO SILO. LB.SLO(R4) MAY POINT TO THE OTHER SILO.
;
MDSLE1: MOV MDSLCC(R3),R2 ;POINT TO THIS SILO'S CHUNK
MOV R2,R0 ;COPY POINTER
ADD #CHDAT,R0 ;MAKE POINTER TO DATA AREA
SUB MDSLPT(R3),R0 ;COMPUTE NEW FILL LEVEL
NEG R0 ;IN POSITIVE FORM
MOV R0,CHLEN(R2) ;STORE NEW LENGTH
TRACE TRCMDF,R0 ;TRACE NEW LENGTH
BIT #MDSLFW,MDSLFG(R3) ;ARE WE AT WARNING POINT?
BEQ 12$ ;NO, DONT RECORD STATISTIC.
MOV MDSLPT(R3),R0 ;YES, GET CURRENT FILL POINT
; (NOTE THAT THIS MAY STILL
; BE THE CURRENT SILO, BUT
; THIS IS UNLIKELY)
SUB MDSLPW(R3),R0 ;SUBTRACT WARNING POINT
CMP R0,LB.MDU(R4) ;GREATER THAN MAX NEEDED BEFORE?
BLO 12$ ;NO.
MOV R0,LB.MDU(R4) ;YES, STORE NEW MAX DEPTH
12$: CMP R3,LB.SLO(R4) ;ARE WE CHANGING SILOS?
BEQ MDSLEX ;NO.
ADD CHLEN(R2),LB.CRD(R4) ;YES, ACCUMULATE CHARS READ
CMP LB.CRD(R4),#DQRLMT ;TOO MANY CHARACTERS IN MESSAGE?
BLE MDSLEX ;NO, LOOK FOR ANOTHER CHARACTER.
MOV LB.SLA(R4),R3 ;YES, POINT TO DUP11 CSR
JSR PC,RCVSTP ;STOP THE RECEIVER
;
; CONTINUED ON NEXT PAGE
;
;
; HERE WHEN THE SILO HAS BEEN EMPTIED, OR ON AN ERROR.
;
MDSLEX: BIT #LS.CIE,(R4) ;DOES THE TASK WANT TO BE RESTARTED?
BEQ 11$ ;NO.
BIC #LS.CIE,(R4) ;YES, CLEAR FLAG
MOV LB.TC1(R4),R0 ;POINT TO BSC TCB
BIT #EBQCHK,(R0) ;WAITING FOR A CHUNK?
BEQ 11$ ;NO (UNLIKELY)
BIC #EBQCHK!EBWAIT,(R0) ;YES, UNWAIT THE TASK
11$: MOV (SP)+,R1 ;RESTORE R1
MOV (SP)+,R0 ; AND R0
RTS PC ;RETURN.
;
;
; SUBROUTINE TO INTIIALIZE A SILO.
;
; R0 = POINTER TO CHUNK TO HOLD DATA
; R2 = POINTER TO SILO.
; R4 = LCB POINTER
;
MDSLOI: MOV R0,LB.CCH(R4) ;SILO CHUNK IS NOW CURRENT
MOV LB.TC1(R4),R1 ;GET TCB OF RECEIVE CHUNK HANDLER
JSR PC,QUECHK ;SEND HIM THE CHUNK
ADD #CHLEN,R0 ;POINT TO LENGTH FIELD
MOV R0,LB.CCR(R4) ;STORE FOR NEXT INPUT INTERRUPT
ADD #CHDAT-CHLEN,R0 ;POINT TO DATA FIELD
MOV R0,LB.CCD(R4) ;STORE FOR NEXT INPUT INTERRUPT
MOV R0,MDSLPT(R2) ;STORE NEW INITIAL DATA POINTER
ADD #CHDATL,R0 ;POINT TO END OF DATA AREA
MOV R0,MDSLPL(R2) ;STORE FOR OVERFLOW CHECKING
SUB LB.MDS(R4),R0 ;BACK UP FOR LATENCY
MOV R0,MDSLPW(R2) ;STORE AS WARNING LEVEL
MOV LB.CCH(R4),MDSLCC(R2) ;COPY POINTER TO CURRENT CHUNK
CLR MDSLFG(R2) ;CLEAR SILO FLAGS
MOV R2,LB.SLO(R4) ;WE HAVE A NEW SILO
TRACE TRCMDF,LB.CCH(R4) ;TRACE NEW "CURRENT CHUNK"
RTS PC ;RETURN TO CALLER
;
;
; SUBROUTINE TO KILL ANY KMC11/DUP11 OPERATIONS.
;
; R4 = LCB POINTER
; R5 = POINTER TO BSC TCB
;
; DESTROYS R0, R1 AND R3
;
DQKILL: TRACE TRCDQF,R4 ;TRACE ENTRY TO DQKILL
MOV LB.SLA(R4),R3 ;POINT TO CSR
;
; CONSIDER STOPPING THE TRANSMITTER
;
BIT #LS.XGO!LS.XRN,(R4) ;TRANSMITTER RUNNING?
BEQ 12$ ;NO.
JSR PC,XMTSTP ;YES, BEGIN STOPPING THE TRANSMITTER
MOV #MDMXTT,R0 ;WAIT A SHORT WHILE FOR KILL
11$: BIT #LS.KLC,(R4) ;HAS THE KILL COMPLETED?
BNE 12$ ;YES.
SOB R0,11$ ;NO, WAIT A WHILE FOR IT
;
; HERE WHEN THE TRANSMITTER HAS BEEN KILLED, OR IF IT IS
; NOT RUNNING.
; CONSIDER STOPPING THE RECEIVER
;
12$: BIT #LS.RGO!LS.RRN,(R4) ;IS RECEIVER RUNNING?
BEQ 15$ ;NO.
JSR PC,RCVSTP ;MAYBE, BEGIN STOPPING THE RECEIVER
MOV #MDMXTT,R0 ;TIME TO WAIT FOR KILL
13$: BIT #LS.KLC,(R4) ;IS THE RECEIVER KILL COMPLETE?
BNE 14$ ;YES, DONT WAIT FOR IT.
SOB R0,13$ ;NO, WAIT FOR IT.
;
; HERE WHEN THE RECEIVER HAS BEEN KILLED.
;
14$: CLR LB.CCH(R4) ;THERE IS NO CURRENT CHUNK
.IF NE,DEBUG
MOV #-1,LB.SLO(R4) ;THE SILO IS GONE
.ENDC ;.IF NE,DEBUG
;
; ; CONTINUED ON NEXT PAGE
;
;
; HERE WHEN THE LINE HAS BEEN KILLED, OR WAS NOT RUNNING AT ALL.
;
15$: MFPS -(SP) ;SAVE INTERRUPT LEVEL
MTPS #BR7 ;DISABLE INTERRUPTS
BIC #UP.DIE,UP.RSR(R3) ;DISABLE DATASET INTERRUPTS
; (AVOID HARDWARE RACE CONDITION
; IN 11/34 BY DISABLING INTS)
MTPS (SP)+ ;RESTORE INTERRUPTS
16$: JSR PC,DEQCHK ;ANY CHUNKS IN RECEIVER QUEUE?
BCS 17$ ;NO.
MOV TCIDLE,R1 ;YES, FREE THEM
JSR PC,QUECHK ; BY SENDING TO BACKGROUND TASK
BR 16$ ;BE SURE WE'VE GOT THEM ALL.
;
; HERE WHEN THE KMC11/DUP11 HAS BEEN KILLED.
;
17$: BIT #LS.ACT!LS.CMP,(R4) ;WAS THE KMC11 ACTIVE?
BEQ 19$ ;NO, THIS WAS ALL FOR NOTHING.
BIT #LS.KLC,(R4) ;YES, HAS THE KILL COMPLETED?
BNE 18$ ;YES.
STOPCD KKF ;NO, KMC11 KILL FAILED.
;
; HERE WHEN THE KILL IS COMPLETE. CLEAR ALL RELEVENT LCB
; STATUS BITS.
;
18$: BIC #LS.ACT!LS.CMP!LS.KIL!LS.KLC,(R4)
;THE KMC11/DUP11 IS NO LONGER ACTIVE
19$: TRACE TRCDQF,R4 ;TRACE COMPLETION OF DQKILL
RTS PC ;RETURN.
;
;
; SUBROUTINE TO SIGNAL THE KMC11 THAT THERE IS SOME LCB
; ACTIVITY WHICH IT SHOULD NOTICE.
;
MDACTV: TRACE TRCMDF,R4 ;TRACE ENTRY TO MDACTV
TRACE TRCMDF,(R4) ;NOTE LCB STATUS
MOV R3,-(SP) ;SAVE R3
MOV LB.MD(R4),R3 ;POINT TO KMC11 TABLE
MOV R0,-(SP) ;SAVE R0
MOV R1,-(SP) ; AND R1
MOV R2,-(SP) ; AND R2
MOV #MDMXTT,R2 ;WAIT THIS LONG FOR KMC11 TO RESPOND
11$: MOV MDFGE(R3),R0 ;GET 11-FLAGS
MOV MDFGK(R3),R1 ; AND KMC FLAGS
XOR R1,R0 ;XOR 11-FLAGS WITH KMC-FLAGS
BIT #MDFEA,R0 ;IS OLD ACTIVE FLAG STILL ON?
BEQ 12$ ;NO.
SOB R2,11$ ;YES, WAIT FOR KMC11 TO FOLLOW
STOPCD KNA ;KMC11 NOT FOLLOWING ACTIVE FLAG
;
12$:
.IF NE,DEBUG
SUB #MDMXTT,R2 ;COMPUTE NUMBER OF TIMES
NEG R2 ; THROUGH THE LOOP
CMP R2,MDMUTT ;MORE THAN PREVIOUS MAX?
BLE 13$ ;NO.
MOV R2,MDMUTT ;YES, STORE NEW MAX
13$:
.ENDC ;.IF NE,DEBUG
BIT #MDFKR,MDFGK(R3) ;IS KMC11 STILL RUNNING?
BNE 14$ ;YES.
STOPCD KNR ;NO, KMC11 NOT RUNNING.
;
; HERE WHEN THE KMC11 HAS COMPLETED THE LAST OPERATION AND IS
; RUNNING.
;
14$: MOV (SP)+,R2 ;RESTORE R2
MOV (SP)+,R1 ;RESTORE R1
MOV #MDFEA,R0 ;GET BIT TO XOR
XOR R0,MDFGE(R3) ;COMPLEMENT ACTIVE FLAG
MOV (SP)+,R0 ;RESTORE R0
MOV (SP)+,R3 ; AND R3
RTS PC ;DONE.
;
;
; THREE SUBROUTINES TO INTERFACE TO THE DL10 TASK. THESE SENSE
; SET AND CLEAR THE MODEM SIGNALS DTR AND DSR.
;
; SUBROUTINE TO CLEAR DTR
;
; R0 = LCB ADDRESS
;
DQDTR0: MOV LB.SLA(R0),R0 ;POINT TO CSR
BIC #UP.DTR,UP.RSR(R0) ;CLEAR DTR
RTS PC ;RETURN.
;
; SUBROUTINE TO SET DTR
;
DQDTR1: MOV LB.SLA(R0),R0 ;POINT TO CSR
BIS #UP.DTR,UP.RSR(R0) ;SET DTR
RTS PC ;RETURN.
;
; SUBROUTINE TO RETURN VALUES OF DTR AND DSR.
;
; R0 = LCB ADDRESS
; R1 BITS 1 AND 2 ARE 0.
;
; ON RETURN:
;
; BIT 1 OF R1 = DTR
; BIT 2 OF R1 = DSR
; R1 IS OTHERWISE UNDISTURBED.
;
DQMDMS: MOV LB.SLA(R0),R0 ;POINT TO CSR
BIT #UP.DTR,UP.RSR(R0) ;IS DTR SET?
BEQ 11$ ;NO.
BIS #B1,R1 ;YES, SET FLAG IN R1
11$: BIT #UP.DSR,UP.RSR(R0) ;IS DSR SET?
BEQ 12$ ;NO.
BIS #B2,R1 ;YES, SET FLAG IN R1
12$: RTS PC ;RETURN.
;
;
; SUBROUTINE TO INTERFACE WITH THE TRAP HANDLER. ON A STOP CODE
; THIS SUBROUTINE IS CALLED TO STORE THE STATUS OF THE DUP11
; IN THE LCB FOR POST-MORTUM DEBUGGING.
;
; R5 DOES NOT POINT TO A TCB, BUT IT MUST NOT BE DESTROYED.
;
; R4 = LCB ADDRESS
;
.IF NE,DEBUG
TRAPDQ: MOV LB.SLA(R4),R3 ;GET HARDWARE ADDRESS
MOV UP.RSR(R3),LB.RG0(R4) ;STORE RECEIVER STATUS REGISTER
MOV UP.RBF(R3),LB.RG1(R4) ;STORE RECEIVER BUFFER
MOV UP.XSR(R3),LB.RG2(R4) ;STORE TRANSMIT STATUS REGISTER
MOV UP.XBF(R3),LB.RG3(R4) ;STORE TRANSMIT BUFFER
RTS PC ;RETURN.
;
.ENDC ;.IF NE,DEBUG
;
; SUBROUTINE TO STOP THE KMC11S ON A FATAL ERROR.
;
TRAPMD: CLR R1 ;KMC11 NUMBER
MOV #MDTBL,R3 ;POINTER TO KMC11 TABLE
11$: BIC #MDFER,MDFGE(R3) ;CLEAR "11-RUNNING"
ADD #MDTLN,R3 ;POINT TO NEXT KMC11 TABLE
INC R1 ;INCREMENT KMC11 NUMBER
CMP #<NLINES/4>,R1 ;DONE ALL KMC11S?
BNE 11$ ;NO, DO THE REST.
RTS PC ;RETURN TO TRAP HANDLER.
;
;
; SUBROUTINE TO CHECK ON THE DUP11S ONCE A JIFFIE
; WE MUST COUNT THE CLEAR-TO-SEND DELAY AND
; COMPENSATE FOR IMPROPER DUP11 JUMPERS WHICH
; WILL PREVENT THE CARRIER SIGNAL FROM CAUSING
; AN INTERRUPT.
;
DSPDQT: MOV R0,-(SP) ;SAVE R0
MOV R1,-(SP) ; AND R1
MOV R2,-(SP) ; AND R2
MOV R3,-(SP) ; AND R3
MOV R4,-(SP) ; AND R4
CLR R1 ;R1 IS DUP11 NUMBER
11$: MOV DQLCB(R1),R4 ;POINT TO LCB
BEQ 15$ ;NO LCB FOR THIS LINE
MFPS -(SP) ;YES, SAVE INTERRUPT LEVEL
MTPS #BR7 ;DISABLE INTERRUPTS
TST LB.DEW(R4) ;WAITING TO SET MODEM ENABLE?
BEQ 12$ ;NO.
DEC LB.DEW(R4) ;YES, WAITED LONG ENOUGH?
BNE 14$ ;NO, WAIT UNTIL NEXT TIME
12$: MOV LB.SLA(R4),R3 ;POINT TO CSR
MOV UP.RSR(R3),R0 ;GET MODEM STATUS BITS
BIT #UP.DIE,R0 ;ARE MODEM INTERRUPTS ENABLED?
BEQ 14$ ;NO, DONT CALL SUBROUTINE.
BIT #UP.DCA!UP.DCB,R0 ;ARE DATASET CHANGE FLAGS SET?
BNE 13$ ;YES, PROCESS ANY POSSIBLE CHANGES
MOV LB.DIP(R4),R2 ;GET LAST MODEM SIGNALS PROCESSED
XOR R0,R2 ;CHECK FOR ANY CHANGES IN SIGNALS
BIT #UP.CTS!UP.CAR,R2 ;ANY IMPORTANT MODEM SIGNALS CHANGED?
BEQ 14$ ;NO.
13$: JSR PC,RCVDSF ;YES, PROCESS ANY MODEM SIGNAL CHANGES
14$: MTPS (SP)+ ;RESTORE INTERRUPT LEVEL
15$: ADD #2,R1 ;INCREMENT TO NEXT LINE
CMP #NLINES*2,R1 ;DONE ALL THE LINES?
BNE 11$ ;NO, DO THE REST
;
; ; CONTINUED ON NEXT PAGE
;
;
; NOW GO THROUGH ALL THE KMC11'S.
;
CLR R1 ;KMC11 NUMBER
MOV #MDTBL,R3 ;POINT TO KMC11 TABLE
16$: BIT #MDFER,MDFGE(R3) ;IS PDP-11 RUNNING?
BEQ 18$ ;NO, THIS KMC11 NOT IN USE.
BIT #MDFKR,MDFGK(R3) ;YES, IS KMC11 RUNNING?
BEQ 18$ ;NO, NO TIMEING YET.
;
; HERE WHEN WE HAVE A RUNNING KMC11.
;
INC MDTIC(R3) ;COUNT TOWARDS ONE SECOND
CMP #JIFSEC,MDTIC(R3) ;REACHED A SECOND YET?
BNE 18$ ;NO, WAIT UNTIL NEXT TIME
CLR MDTIC(R3) ;YES, REINITIALIZE TICK COUNTER
INC MDALE(R3) ;COUNT PDP-11 ALIVE COUNTER
BIT #7,MDALE(R3) ;HAS IT BEEN EIGHT SECONDS? [2(755)]
BNE 18$ ;NO, CHECK NEXT KMC11
MOV MDALK(R3),R0 ;YES, GET KMC11 ALIVE COUNTER
CMP R0,MDALKS(R3) ;SAME AS LAST TIME?
BNE 17$ ;NO, KMC11 STILL ALIVE.
STOPCD KKS ;KMC11 KEEP-ALIVE STOPPED.
;
17$: MOV R0,MDALKS(R3) ;SAVE OLD VALUE OF KEEP-ALIVE
;
; HERE WHEN WE ARE DONE WITH THIS KMC11
;
18$: ADD #MDTLN,R3 ;POINT TO NEXT KMC11 TABLE
INC R1 ;NUMBER OF KMC11
CMP #<NLINES/4>,R1 ;DONE LAST KMC11?
BNE 16$ ;NO, DO THE REST.
;
; HERE WHEN WE ARE DONE WITH THIS "TICK".
;
MOV (SP)+,R4 ;RESTORE R4
MOV (SP)+,R3 ; AND R3
MOV (SP)+,R2 ; AND R2
MOV (SP)+,R1 ; AND R1
MOV (SP)+,R0 ; AND R0
RTS PC ;RETURN TO DISPATCHER.
;
.SBTTL CONTROL MESSAGES
;
; CONTROL MESSAGES
;
;
; ENQ MESSAGE, FOR BIDDING FOR THE LINE AND ASKING FOR A
; REPEAT OF THE LAST RESPONSE.
;
ENQMSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCENQ,EBCPAD
ENQLEN=.-ENQMSG
;
; ACK-0 MESSAGE, USED FOR POSITIVE ACKNOWLEDGMENT TO BID AND
; FOR POSITIVE ACKNOWLEDGE OF EVEN DATA BLOCKS
;
AK0MSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCDLE,EBCAK0
.BYTE EBCPAD
AK0LEN=.-AK0MSG
;
; ACK-1 MESSAGE, USED FOR POSITIVE ACKNOWLEDGMENT OF ODD DATA
; BLOCKS
;
AK1MSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCDLE,EBCAK1
.BYTE EBCPAD
AK1LEN=.-AK1MSG
;
; TTD MESSAGE, FOR SOLICITING A NAK BECAUSE DATA IS NOT
; YET READY.
;
TTDMSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCSTX,EBCENQ
.BYTE EBCPAD
TTDLEN=.-TTDMSG
;
; HASP BID SEQUENCE SOH-ENQ FOR BIDDING FOR A LINE.
;
BIDMSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCSOH,EBCENQ
.BYTE EBCPAD
BIDLEN=.-BIDMSG
;
;
; EOT MESSAGE, USED TO TERMINATE A MESSAGE SEQUENCE.
;
EOTMSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCSYN,EBCEOT
.BYTE EBCPAD,EBCPAD
EOTLEN=.-EOTMSG
;
; NAK MESSAGE, USED TO REQUEST THE RETRANSMISSION OF THE LAST
; DATA MESSAGE AND TO REFUSE A BID.
;
NAKMSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCNAK,EBCPAD
NAKLEN=.-NAKMSG
;
; WACK MESSAGE, USED TO ACKNOWLEDGE A DATA BLOCK BUT FORCE A WAIT
; BEFORE THE NEXT DATA BLOCK IS SENT.
;
WAKMSG: .BYTE EBCLPD,EBCSYN,EBCSYN
.BYTE EBCSYN,EBCDLE,EBCWAK
.BYTE EBCPAD
WAKLEN=.-WAKMSG
;
.EVEN ;BE SURE NEXT SECTION STARTS ON
; A WORD BOUNDRY.
;