Trailing-Edge
-
PDP-10 Archives
-
BB-X140B-BB_1986
-
10,7/703anf/dndte.p11
There are 3 other files named dndte.p11 in the archive. Click here to see a list.
.SBTTL DNDTE - KL10/PDP-11 INTERFACE 20 NOV 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,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
VRDTE=034 ;FILE EDIT NUMBER
;THE BULK OF THIS MODULE COMES FROM RSX-20F, SPECIFICALLY
;DMDTE.MAC,QPRDTE.MAC, AND SCOMM.MAC. THE FIRST PART OF THE FILE
;CONTAINS SUBROUTINES THAT DUPLICATE THE SUBROUTINES IN DNDL10.MAC
;
;DTE INTERRUPTS NO LONGER USED
.IIF NE DEBUG,$DBDTE=-1 ;ENABLE DTE DEBUG CODE IF WILLING TO DIE
DTE.LVL =6 ;PI LEVEL FOR DTE20
.MACRO .CRASH CODE
TRAP S..DTE
.ENDM
.SBTTL TO ELEVEN BLOCKS
BLOCK TE ;TO ELEVEN *** DO NOT CHANGE ORDER ***
X LNK,1 ;ADDRESS OF NEXT CHUNK IN MESSAGE
X QPR,1 ;# OF BYTES LEFT TO XFER IN QPR MESSAGE
X LEN,1 ;TOTAL LENGTH OF MESSAGE
XX FFW,1 ;COPY OF FIRST WORD FOR CURRENT QPR MSG
FW.MOR =1*400 ;SET WHEN THERE WILL BE ANOTHER QPR
; MESSAGE IN THIS NCL MESSAGE
XX LIN,1 ;HIGH BYTE IS LINE NUMBER, FLAGS FOR NCL
X CNK,1 ;SPACE LEFT IN CURRENT CHUNK
X QHD,1 ;QPR MESSAGE HEADER - LENGTH OF 1ST MESSAGE
X QFN,1 ;FUNCTION
X QDV,1 ;DEVICE (BETTER BE NCL)
X CMP,0 ;START OF USER DATA FOR COMPRESSION
X QSP,1 ;SPARE WORD
X ADR,1 ;ADDRESS OF WHERE TO PUT DATA OF NEXT FRAGMENT
X .SZ,0 ;SIZE OF THE TO-11 BLOCK
.IIF NE TE..SZ-CN.NCT,.PRINT; Phase error in TO-11 blocks.
.SBTTL TO TEN BLOCKS
BLOCK TT ;TO TEN *** DO NOT CHANGE ORDER ***
X FLK,1 ;FORWARD LINK
X RLK,1 ;REVERSE LINK
X ALC,1 ;*OBS* SPACE ALLOCATED FOR THIS BLOCK
X HDL,1 ;LENGTH OF HEADER
X QHD,1 ;FIRST QPR WORD, LENGTH OF HEADER
X QFN,1 ;FUNCTION
X QDV,1 ;DEVICE (NCL)
X QSP,1 ;SPARE
X QFW,1 ;FIRST WORD (LINE#, IND MSG LENGTH)
X ADR,1 ;ADDRESS OF REAL DATA
X USR,1 ;USER SUPPLIED DATA
X EFN,1 ;*OBS* EVENT FLAG NUMBER (OR SOMETHING LIKE THAT)
;ROUTINE CALLED AT STARTUP TO INITIALIZE THE DTE SOFTWARE INTERFACE
;(THE HARDWARE NEEDS NO INITIALIZATION). IT WAITS FOR THE -10 TO EXIT
;PRIMARY PROTOCOL BECAUSE THERE IS NO PRESENT MECHANISM FOR RESTARTING
;THE QUEUED PROTOCOL. IT MUST BE RESTARTED BECAUSE OTHERWISE WE WOULD
;NOT KNOW WHAT STATE WE WERE IN WHEN WE GOT RESTARTED AND THEREFORE
;CANNOT CONTINUE USING THE PRESENT INCARNATION. NOTE THAT THIS SOME
;UNPLEASANT SIDE EFFECTS - NORMALLY DTELDR RUNNING ON THE -10 WILL
;BE CALLED WHEN THE KEEP ALIVE TIMER EXPIRES AND WILL RELOAD THE-11,
;WHEN THERE REALLY IS NO NEED TO SINCE ALL THE -11 WANTED TO DO WAS
;RESTART. (THIS WILL BE A PROBLEM MAINLY WITH POWER FAULTS THAT AFFECT
;ONLY THE 87S, PRESUMABLY A RARE OCCURANCE). SYSTEM PROGRAMMERS
;TRYING TO RESTART THE -11 BY TYPING BEGIN$G TO DDT-11 WILL FIND IT
;CAUSES THE -11 TO BE RELOADED IF DTELDR IS RUNNING IN AUTOMATIC
;MODE. THE ONLY WAY TO RESTART IT IS TO GET DTELDR IN MANUAL MODE, SAY
;BEGIN$G TO DDT11 THEN /TERMINATE:N AND /INITIALIZE:N TO DTELDR. THIS IS
;KNOWN IN THE BUSINESS AS PROGRESS.
DTEINI: CLR T10QUE ;PUNT OLD MESSAGES TO THE -10
MOV #TO10Q,TO10Q ;RESET QUEUED PROTOCOL LIST
MOV #TO10Q,TO10Q+2 ;BOTH FORWARD AND BACKWARD LINKS
CLR ACKFLG ;WAIT FOR ACK BEFORE SENDING MSG
CLR TO11Q ;AND CLEAR MESSAGES SENT TO -11 BUT NOT READ
MOV .PRDTE,R0 ;GET ADDRESS OF OUR DTE
BEQ 20$ ;IF NONE (?) DON'T BOTHER
JSR R0,TRPST ;INTERCEPT NON-EX DTE
.WORD 30$ ;(JUST RETURN IF NOT THERE)
10$: CLR TNAD1(R0) ;TRY TO EXAMINE START OF COMM REGION
CLR TNAD2(R0) ; TO SEE IF QUEUED PROTOCOL IS RUNNING
JSR PC,WFED ;WAIT FOR EXAMINE
BCS 20$ ;FAILED, MUST NOT BE IN PRIMARY PROTOCOL
TST DXWD2(R0) ;NON-ZERO IF WINDOW ENABLED
BNE 10$ ;PRIMARY PROTOCOL STILL RUNNING. WAIT LONGER
20$: RTS PC ;OUT OF PRIMARY PROTOCOL, SAFE TO RESTART NOW
30$: CLR .PRDTE ;NO DTE IF IT'S NOT THERE
; TENSEC WILL SCAN FOR DTES APPEARING OUT OF
; THE DARK SO IF IT COMES BACK (MAYBE WE
; POWER FAIL RESTARTED BEFORE THE KL COULD
; GET ITS DTES GOING AGAIN) WE WILL EVEN-
; TUALLY NOTICE IT.
RTS PC ;RETURN IN ANY CASE
;ROUTINE TO REQUEST -10 TO RELOAD US. DONE SO BY SETTING THE RELOAD
;FLAG IN OUR STATUS WORD IN THE COMM AREA.
DTERLD: TST TENSCB ;ARE WE TALKING TO THE -10?
BEQ 10$ ;NO, FORGET IT
BIS #LOAD11,STSTT ;SET RELOAD REQUEST FLAG
MOV .PRADR,R3 ;GET ADDRESS OF COMM AREA DATA BLOCK
JSR R0,TRPST ;IN CASE NO -10
.WORD 10$ ; (JUST IGNORE DTE)
JSR PC,STTOIP ;CHEAT A BIT. THIS ROUTINE ONLY SENDS STSTT TO -10
MOV #TO10DB,@.PRSTA ;TELL -10 ABOUT CATASTROPHE
10$: RTS PC ;-10 SHOULD RELOAD US IMMEDIATELY
.SBTTL LOOPDT - LOOP LEVEL MESSAGE SHUFFLER
;THIS SUBROUTINE IS CALLED AT LOOP LEVEL TO DO ALL BACKGROUND TASKS:
;1) TELL NCL WHICH MESSAGES HAVE BEEN SENT TO THE -10 AND THEREFORE
; MAY NEED TO BE TIMED.
;2) PROCESS TO-11 QPR MESSAGES. ACKS MEAN THE -10 IS READY TO RECIEVE
; ANOTHER MESSAGE AND STRING DATA MESSAGES ARE TO-11 NCL MESSAGES
; IN NEED OF POSSIBLE COMPRESSION BEFORE BEING PASSED TO NCLIN0.
LOOPDT: TST TENSCB ;PRIMARY PROTOCOL RUNNING?
BEQ 99$ ;NO, CAN'T ACCESS DTE20 RETURN QUICK
JSR PC,INTLPS ;CALL "INTERRUPT" CODE
20$: MOV TO11Q,R0 ;SEE IF ANYTHING SENT FROM -10
BEQ 99$ ;NOTHING ON LIST
MOV CN.MLK(R0),TO11Q ;DELINK MSG
MOVB TE.QFN(R0),R1 ;GET MESSAGE TYPE
CMP R1,#BC.SAK ;ACKNOWLEDGE?
BEQ 40$ ;THAT MEANS WE CAN SEND ANOTHER MESSAGE
CMP R1,#BC.STR ;STRING DATA?
BEQ 35$ ;YEP, SEND IT TO NCL
TWIDDLE R1 ;SHOULDN'T GET HERE. NOTE THE OCCURANCE
JSR PC,FRECKS ;AND FORGET THE MESSAGE
BR 20$ ;LOOP ON OTHER MESSAGES
;HERE WHEN WE HAVE A DATA MESSAGE TO COMPRESS
35$: MOV TE.CMP(R0),R3 ;GET ADDRESS WHERE USER DATA STARTS
MOVB TE.LIN(R0),R4 ;GET LINE NUMBER (FLAGS) FOR THIS MESSAGE
BIC #^C6,R4 ;ISOLATE THE COMPRESSION CODE
BEQ 37$ ;NOTHING SPECIAL IF NO COMPRESSION
CLR R2 ;NOTHING WRITTEN YET
MOV R0,R1 ;CALC LENGTH OF PROTOCOL HEADER AND DATA
ADD #CN.NCT,R1 ;R1_ADDRESS OF START OF NCL
SUB R3,R1 ;R1_NEGATIVE PROTOCOL LENGTH (NCL+DAP HEADER)
ADD CN.LEN(R0),R1 ;R1_DATA LENGTH (USED IN LOOP BELOW)
SUB R1,CN.LEN(R0) ;CN.LEN_POSITIVE HEADER LENGTH (FIXED UP LATER)
MOV R0,-(P) ;SAVE POINTER TO 1ST CHUNK
MOV R3,R0 ;SETUP GETTER ADDRESS
JSR PC,@CMPDSP-2(R4) ;CALL APPROPRIATE COMPRESSER
MOV (SP)+,R0 ;GET MESSAGE ADDRESS BACK
ADD R2,CN.LEN(R0) ;ADD LENGTH OF COMPRESSED DATA TO HEADER FOR TOTAL
37$: MOV TENSCB,SNA ;THIS MESSAGE CAME FROM OUR TEN
JSR PC,NCLIN0 ;TELL NCL WE HAVE A MESSAGE FOR IT
BR 20$ ;LOOP FOR ANY MORE MESSAGES
;HERE WHEN WE GET A QPR ACK - SEND A MESSAGE TO -10
40$: JSR PC,FRECKS ;FREE THE ACK MESSAGE
TST T10QUE ;CAN WE SEND A MESSAGE RIGHT NOW?
BNE 50$ ;YES, DO SO
INC ACKFLG ;NOPE, REMEMBER WE HAVE AN OUTSTANDING REQUEST
BR 20$ ;AND SEE WHAT ELSE HAS TO BE DONE
50$: MOV T10QUE,R0 ;GET MESSAGE ADDRESS
MOV CN.MLK(R0),T10QUE ;DELINK THIS MESSAGE
JSR PC,DTEQUE ;SEND TO -10
BCC 20$ ;DO MORE
MOV R0,T10QUE ;DTEQUE FAILED (DTE KROAKED OFF)
BR 20$ ;DO SOME MORE
99$: RTS PC ;ALL FINISHED, RETURN
.SBTTL TO-11 DATA COMPRESSION ROUTINES
;THIS CODE LARGELY STOLEN FROM DNDL10 AND BEAT UPON FOR OUR PURPOSES
;WHICH ARE DIFFERENT ENOUGH TO WARRANT NOT TURNING IT INTO COMMON
;CODE. CMPDSP IS CALLED WITH R0-R3 SETUP:
;R0 ADDRESS OF NEXT DATA BYTE TO READ
;R1 # OF CHARACTERS LEFT TO COMPRESS
;R2 0 (SEE RETURNED INFO)
;R3 LIKE R0, ONLY FOR WRITING. IT CHASES R0 BUT NEVER PASSES IT
;RETURNS:
;R2 LENGTH (BYTES) OF COMPRESSED DATA.
CMPDSP: CMPRSL ;(1) LPT COMPRESSION
.IIF NE FT.ANF, COPBIN ;(2) 36 BIT MODE
.IIF EQ FT.ANF, DTERTS ;(2) BUT ONLY IF INTELLIGENCE REQUESTED
DTERTS ;(3) UNDEFINED - DO NOTHING
;ROUTINE TO PACK DATA FOR LPT. THE GENERAL SCHEME IS TO PACK THE DATA IN
;PLACE WHICH IS POSSIBLE SINCE THE COMPRESSION ALGORITHM GUARANTEES
;THAT NO MESSAGE WILL EVER BE LARGER THAN THE UNCOMPRESSED FORM.
;REGISTER USAGE
;R4 # OF OCCURANCES FOR THE PRESENT CHARACTER WE'RE COMPRESSING
;R5 THE CHARACTER WE'RE TRYING TO COMPRESS
;FORMAT OF COMPRESSED DATA:
;SINGLE OCCURANCE OF A CHARACTER 200!CHAR
;MULTIPLE SPACES (2 TO 77) 100!COUNT
;MULTIPLE ANYTHING ELSE (2 TO 37) 40!COUNT,200!CHAR
CMPRSL: MOV R3,-(P) ;SAVE POINTER TO DATA
CLR R4 ;NOTHING COMPRESSED YET
;..
;..
30$: JSR PC,AVCKR0 ;ENSURE WE'RE STILL POINTING TO DATA
TST R4 ;ANY COMPRESSED YET ?
BEQ 35$ ;IF NOT THIS IS FIRST
CMPB @R0,R5 ;IS THIS CHAR SAME AS LAST ?
BEQ 35$ ;YES SO JUST COUNT IT
JSR PC,PAKCHR ;PUT OLD CHAR INTO MSG
35$: MOVB (R0)+,R5 ;REMEMBER WHAT WE ARE COMPRRESSING
INC R4 ;COUNT IT
CMP R4,#37 ;CHECK FOR TOO MANY
BMI 39$
CMP R5,#40 ;IS CHAR A BLANK ?
BNE 38$ ;IF NOT THIS IS IT
CMP R4,#77 ;THIS IS LIMIT FOR BLANKS
BMI 39$
38$: JSR PC,PAKCHR ;MUST GO INTO MESSAGE NOW
39$: SOB R1,30$ ;LOOP FOR REST OF DATA
TST R4 ;ANY DATA COMPRESSED ?
BEQ 26$
JSR PC,PAKCHR ;PUT INTO MESSAGE
26$: MOV (P)+,R3 ;GET POINTER TO DATA OFF STACK
MOV R2,R4 ;WE HAVE TO RETURN R2
INC R4 ;COUNT FOR DAP MESSAGE TYPE BYTE FOR TOTAL
SUB #2,R3 ;POINT TO COUNT
27$: TSTB -(R3) ;GET MESSAGE TYPE
BMI 27$ ;LOOK FOR DLA
INC R3 ;BACK TO COUNT FIELD
TSTB @R3 ;CHECK FOR EXTENSIBLE
BPL 29$
MOV R4,R5 ;COPY MESSAGE LENGTH
BIS #200,R5 ;PUT EXTENSIBLE BIT ON
MOVB R5,(R3)+ ;PUT INTO MESSAGE
ASL R4
SWAB R4
29$: MOVB R4,@R3 ;PUT LENGTH INTO MESSAGE
DTERTS: RTS PC ;NOW AT LAST PASS OFF MESSAGE
;HERE TO PUT COMPRESSED LPT CHAR INTO MESSAGE
PAKCHR: CMP R4,#1 ;SINGLE OCCURANCE ?
BEQ 46$ ;IF SO JUST PUT IN AS IS
CMP #40,R5 ;IS CHARACTER A BLANK ?
BNE 44$ ;NO
BIS #100,R4 ;FLAG THIS IS BLANK COUNT
JSR PC,AVCKR3 ;ENSURE WE POINT TO DATA
MOVB R4,(R3)+ ;PUT INTO THE MESSAGE
BR 47$ ;INC LENGTH AND DONE
44$: BIS #40,R4 ;FLAG THIS IS REPITION COUNT
JSR PC,AVCKR3
MOVB R4,(R3)+ ;PUT COUNT INTO MESSAGE
INC R2 ;COUNT CHAR
46$: BIS #200,R5 ;FLAG THIS IS CHAR
JSR PC,AVCKR3
MOVB R5,(R3)+ ;PUT INTO MSG
47$: INC R2 ;COUNT CHAR INTO MESSAGE
48$: CLR R4 ;CLEAR COMPRESSION COUNT
RTS PC
;ROUTINE TO PACK BINARY DATA (36 BITS) FROM THE -10. THE UNCOMPRESSED
;FORM IS 12 BIT BYTES, 1 PER -11 WORD (3 MAKE AN ENTIRE -10 WORD).
;THIS ROUTINE TAKES PAIRS OF THESE AND PACKS THEM INTO 3 BYTES ON THE
;-11 WITH NO BYTES WASTED. THE RESULT IS A BYTE STREAM OF THE DATA
;FROM THE -10 WITH ALL THE BITS IN ORDER.
.IF NE FT.ANF
COPBIN: ASR R1 ;CONVERT # OF BYTES TO # OF WORDS
INC R0 ;MAKE SURE GETTER STARTS ON WORD BOUNDARY
BIC #1,R0 ;SINCE THAT'S WHERE THE WORD DATA WENT
32$: JSR PC,AVCKR0 ;MAKE SURE WE STILL POINT TO DATA
MOV (R0)+,R5 ;GET NEXT 12 BITS
ASL R5 ;WANT TO GET HIGH ORDER 8 BITS
ASL R5
ASL R5
ASL R5
JSR PC,40$ ;PUT HIGH ORDER BITS INTO MSG
BIC #^C170000,R5 ;STRIP EXTRA BITS
DEC R1 ;COUNT LAST 12-BITS OUT OF 10
BEQ 40$ ;IF LAST WORD, STORE LEFTOVER BITS
JSR PC,AVCKR0 ;ENSURE WE POINT TO DATA
ADD (R0)+,R5 ;GET NEXT 12 BITS
JSR PC,40$ ;PUT NEXT BYTE INTO MSG
JSR PC,40$ ;PUT NEXT BYTE INTO MSG
DEC R1 ;COUNT LAST 12 BITS OUT OF 10
BNE 32$
RTS PC
;HERE TO PUT NEXT BYTE INTO MSG
40$: SWAB R5
JSR PC,AVCKR3 ;POINT TO DATA
MOVB R5,(R3)+ ;PUT NEXT BYTE INTO MSG
INC R2 ;THAT'S ANOTHER BYTE IN FINAL MESSAGE
42$: RTS PC ;RETURN
.ENDC ; .IF NE FT.ANF
.SBTTL TENSEC - CLOCK LEVEL ROUTINE
;THE CLOCK SUPPORT FOR THE DTE INCLUDES DETERMINATION OF WHETHER OR
;NOT THE -10 IS UP. UP IS WHEN BOTH THE HEADER WORD IS NONZERO
;AND VALID EXAMINE IS SET ($DTEON DOES THE VALID EXAMINE CHECK). THE
;-10 IS DECLARED DOWN ONLY WHEN THE HEADER IS NO LONGER ACCESSIBLE (0),
;WHICH ALLOWS THE -10 TO ENTER SECONDARY PROTOCOL (E.G. EDDT) WITHOUT
;LOOSING ALL THE CONNECTIONS. WARNING:
;THIS REQUIRES THAT THIS 11 NOT BE PROCESSOR 0. SINCE TOPS-10 AND
;TOPS-20 BOTH CALL THEMSELVES PROCESSOR 0, THIS SHOULD NOT BE A PROBLEM.)
;THE SBF.IU BIT IS USED TO RECORD THE STATE OF THE -10 (IN FACT, THIS
;IS EXACTLY THE SAME WAY ANY OTHER NODE'S SBF.IU IS USED.) WHEN THE -10
;GOES OFFLINE, WE BREAK ANY OPEN CONNECTIONS AND TELL THE REST
;OF THE NETWORK IT HAPPENED. WHEN IT COMES ONLINE, WE SET UP THE
;QUEUED PROTOCOL DATA BASE AND SEND A NODEID AS THE FIRST MESSAGE.
;WHENEVER THE -10 IS FOUND TO BE UP, WE UPDATE THE KEEP ALIVE COUNTER.
;WHILE THIS MAY NOT BE THE BEST LOCATION TO DO IT, IT WILL CATCH PROBLEMS
;LIKE LOOPS, CONTINUAL INTERRUPTS, AND A KW11 THAT HAS LOST ITS
;INTERRUPT ENABLE BIT. WE ALSO MAKE SURE THE -10 SAW LAST DOORBELL.
TENSEC: MOV .PRDTE,R0 ;GET START ADDRESS OF OUR DTE20
BEQ TENSE5 ;NO DTE, MUST GO SEARCHING FOR ONE
JSR R0,TRPST ;IN CASE NO DTE (I.E., IT WENT AWAY)
.WORD TENDWD ; (NOTE -10 DOWN, REQUEUE ANY MESSAGES)
CLR TNAD1(R0) ;LOOK AT OUR HEADER WORD WHICH IS AT
CLR TNAD2(R0) ; OFFSET 0. IT WILL BE NON ZERO IF THE
JSR PC,WFED ; 10 IS TALKING TO US
BCS 10$ ;IF WE CAN'T DO IT, -10 IS DOWN
TST DXWD2(R0) ;DID WE GET OUR PROCESSOR #?
BNE TENUP ;YEP, MAKE SURE WE'RE TALKING TO -10
10$: JSR PC,TRPCL ;NO, TEN IS DOWN, CLEAR TRAP INTERCEPT
BR TENDWN ;AND FLAG NO -10
;HERE WHEN WE HAVE NO KNOWN DTE-20 (BUT WERE ASSEMBLED FOR ONE). ASSUME
;THE KL WAS POWERED OFF, OR MAYBE EVEN THAT WE WE BOOTED FROM A ROM AND
;HAVE NEVER SEEN A DTE-20 YET. WE MUST SCAN FOR ONE WHICH EXISTS
;(AND WHICH IS NOT NECESSARILY THE DTE WHICH BOOTED US).
TENSE5: MOV #TE.NNN,R0 ;NUMBER OF DTES TO TRY
MOV #TE.BAS,R1 ;BASE ADDRESS OF FIRST ONE TO TRY
;LOOP, SNIFFING AT THE DTE TO SEE IF IT IS THERE
10$: JSR R0,TRPST ;SET UP NXM INTERCEPT
.WORD 20$ ; (JUST IGNORE IT)
TST (R1) ;HELLO - ANYONE THERE?
BR 100$ ;YES!!! WE HAVE A DTE!!!
20$: ADD #TE.BNX,R1 ;NO, BUMP POINTER TO NEXT POSSIBLE DTE
SOB R0,10$ ;AND TRY AGAIN
RTS PC ;NO DTE-20 ANYWHERE
;WE NOW HAVE A DTE-20 (WHERE BEFORE WE DIDN'T)
100$: TWIDDLE ;COUNT DTE [RE]INCARNATIONS
MOV R1,.PRDTE ;SET WONDERFUL NEW DTE-20 BASE ADDRESS
ADD #TE.STW,R1 ;POINT TO DTE-20 STATUS REGISTER
MOV R1,.PRSTA ;AND SAVE ITS ADDRESS TOO
JSR PC,TRPCL ;CLEAR OUT THE TENSE5 TRAP
JSR R0,TRPST ;AND SET THE USUAL TENSEC TRAP
.WORD TENDWD ; (ZAP THE DTE AND MARK THE -10 DOWN)
BR TENUP ;NOW GO HANDLE THE -10'S COMING UP
;HERE ON NXM FROM DTE (WHICH PRESUMABLY IS NOW POWERED OFF OR THE LIKE)
TENDWD: TWIDDLE ;COUNT DTE DISAPPEARING ACTS
CLR .PRDTE ;NOTE NO MORE DTE (TENSEC MUST SCAN FOR
; ONE APPEARING OUT OF THE MISTS)
MOV #TE.BAS-1,.PRSTA ;CATCH ANYONE LOOKING AT STATUS SANS DTE
; (THIS WILL CATCH 'EM EVEN IF DTE COMES
; BACK BEFORE WE OFFICIALLY NOTICE IT)
TENDWN: MOV TENSCB,SB ;THE TEN IS DOWN, DID WE KNOW THAT?
BEQ 99$ ;YES, NOTHING MORE TO DO.
SAVE <SB> ;SAVE POINTER WHILE WE FIX UP THE QUEUES
CLR ACKFLG ;PREVENT NEW MESSAGES FROM ENTERING TO10Q
; (THEY'LL GO ON T10QUE AND TIMEOUT)
CLR TENSCB ;SAY THAT WE KNOW THE DTE IS DOWN
; CLR SB.LBA(SB) ;CLEAR ROUTING (ROUTE REALLY DOES IT)
BIS #SBF.NK,(SB) ;FORCE A NAK
BIT #SF.HID,(SB) ;DID I KNOW WHO HE WAS?
BNE 10$ ;IF SO, MAYBE THERE'S ANOTHER PATH TO HIM
CLR (SB) ;IF NOT, THEN FREE UP USLESS SCB
10$: MOV T10QUE,R0 ;NOW QUEUE ALL UNSENT MSGS ON MSGRSQ
BEQ 20$ ; THEY WILL BE RE-ROUTED NEXT JIFFY
MOV CN.MLK(R0),T10QUE ; IFF THERE IS A PATH TO THE NODE
JSR PC,MSGREQ ;REQUEUE THE MESSAGE
BR 10$ ;LOOP UNTIL ALL MSGS REQUEUED
20$: MOV TO10Q,R4 ;DISCARD MESSAGES ALREADY QUEUED
CMP R4,#TO10Q ;EMPTY RING?
BEQ 30$ ;YES, ALL DONE
JSR PC,T10DON ;PRETEND -10 GOT IT
JSR PC,..NDEL ;REMOVE CONTROL BLOCK FROM TO10Q
MOV R4,R0 ;AND DEALLOCATE IT
JSR PC,FRECNK
BR 20$ ;DO REST
30$: RESTORE <SB> ;GET THE SCB POINTER BACK AGAIN
JSR PC,ROUTE ;REMOVE UNREACHABLE NODES
JSR PC,SNDNGH ;TELL ANYONE WHO MIGHT BE INTERESTED
99$: RTS PC ;DON'T NEED TO CALL TIMDTE SINCE NO MSGS
; ARE QUEUED ANY MORE
;HERE ONCE A SECOND IF WE THINK THE DTE IS RUNNING
;STILL IN TRPST (TO TENDWD) FROM TENSEC (OR TENSE5)
TENUP: MOV TENSCB,SB ;DID WE KNOW TEN WAS UP? (GET SCB IF WE DID)
BNE 20$ ;YES, JUST UPDATE KEEP ALIVE
JSR PC,$DTEON ;NO, INITIALIZE QUEUED PROTOCOL DATA BASE
BCS 30$ ;VALID EXAMINE IS STILL OFF, LEAVE -10 DOWN
JSR PC,MAKSCB ;GET AN SCB FOR THE TEN
BCS 30$ ;NO SCB'S?
MOV SB,TENSCB ;MARK THE TEN AS UP, AND THIS SCB AS THE 10'S
MOV SB,SB.LBA(SB) ;SET UP IT'S INCESTOUS ROUTING TABLE
MOV #SBF.IU,@SB ;FLAG THAT THE DTE IS UP (WELL SORT OF...)
CLR CURMSG ;NOT BUILDING A MESSAGE
;*** DNDL10 TESTS DL10 HERE - CAN WE TEST DTE?
JSR PC,NCLRS9 ;SEND A NODEID TO -10 TO START THINGS UP
20$: INCB KPAL1 ;ALL THE KEEP ALIVE COUNTER HAS TO DO IS CHANGE
MOV .PRDTE,R0 ;SO THE -10 WILL KNOW WE'RE ALRIGHT
MOV KPAL1,DXWD3(R0) ;DON'T BOTHER WITH HIGH BITS OF WORD
MOV #DEP,TNAD1(R0) ; JUST TRANSFER IT TO THE -10
MOV #PSWW1,TNAD2(R0) ;START TRANSFER
TST DBLCNT ;HAS -10 RESPONDED TO LAST DOORBELL?
BEQ 25$ ;YEP
DEC DBLCNT ;NOT YET, COUNT DOWN TIMER
BNE 25$ ;STILL COUNTING
JSR PC,RINGDB ;TIMED OUT, TRY AGAIN
TWIDDLE ;THAT SHOULDN'T HAVE HAPPENED
25$: JSR PC,WFED ;WAIT FOR IT TO COMPLETE
30$:
TIMDTE: MOV #T10QUE-CN.MLK,R0 ;PREVENT OLD MESSAGES FROM BUILDING UP
JSR PC,TIMQUE ; IN THE QUEUE TO THE -10
.WORD 10$ ;CALL THIS FOR DISCARD OLD MESSAGES
RTS PC
10$: TWIDDLE ;COUNT THE NUMBER MESSAGES NOT SENT
JSR PC,MSGREQ ;REQUEUE THE MESSAGE NEXT TICK
RTS PC ;ALL DONE, JIFFY CODE WILL RESEND
.SBTTL MEMORY ALLOCATION
;MEMORY ALLOCATION. RSX ALLOWS FOR ALLOCATING A VARIABLE AMOUNT OF
;MEMORY PER CALL, WHEREAS THE DN87 ONLY ALLOCATES A FIXED "CHUNK"
;PER CALL. THE ROUTINE COMPROMISES AND ALLOCATES AN ENTIRE CHUNK
;NO MATTER HOW MUCH WAS REQUESTED AS LONG AS IT IS LESS THAN
;THE USABLE SPACE IN THE CHUNK.
;SUBROUTINE TO REQUEST A BLOCK OF MEMORY:
;CALL:
;R1/ LENGTH OF MEMORY REQUIRED
;RETURN:
;R0/ ADDRESS OF MEMORY
;PS/ C SET ON ERROR
;ALL OTHER REGISTERS UNMODIFIED
..ALCB: ASSERT R1 LE #CNKSIZ ;CRASH IF REQUEST IS TOO BIG
JSR PC,ERSGET ;GET A CHUNK FROM FREELIST, GOING FOR BROKE
BEQ 10$ ;NONE LEFT, RETURN ERROR
RTS PC ;RETURN CARRY CLEAR
10$: TRAP ;NO ROOM, DIE
;ROUTINE TO DEALLOCATE MEMORY ALLOCATED BY ..ALCB. SINCE WE
;ALLOCATED A SINGLE BLOCK, THE STANDARD CHUNK FREER WILL DO JUST
;FINE.
..DECB =FRECNK ;EASY DOES IT
.SBTTL QUEUED PROTOCOL INTERFACE
;ROUTINE TO SEND A MESSAGE TO QPRDTE TO SEND TO THE -10. SINCE
;THE PROTOCOL ROUTINES EXPECT THAT THE FIRST WORD OF THE DATA
;INCLUDE THE SIZE AND THE LINE NUMBER, WE HAVE TO USE
;WHAT MAY HAVE BEEN A DDCMP BCC WORD. NOWHERE ELSE IN DN87 IS
;THAT WORD USED, SO WE ARE SAFE IF USING IT.
;CALL:
;R0/ CHUNK ADDRESS
;RETURNS:
;R3,R4,R5 PRESERVED
.IIF EQ NTLINE,DDQDAT: ;NEED FOR ASYNC ONLY FRONT ENDS
DLQDAT: ASSERT NE TENSCB ;WE SHOULDN'T ROUTE HERE IF THE DTE IS DEAD
TST ACKFLG ;DID -10 REQUEST A MESSAGE?
BEQ 10$ ;NO, PUT IT ON QUEUE
JSR PC,DTEQUE ;YES, SEND IT OUT NOW
BCC 99$ ;IF SUCCEEDED JUST RETURN
; THE DTE KROAKED OFF WHILST WE WERE TRYING
; TO USE IT, QUEUE UP THE MESSAGE AND
; LET TENSEC RECOVER IT
10$: MOV #15,CN.TIM(R0) ;GIVE HIM ONLY 15 SECONDS ON THE QUEUE BEFORE
; HE TIMES OUT (SHORT, BUT DTE IS VERY FAST)
MOV #T10QUE-CN.MLK,R1 ;PUT MESSAGE ON END OF QUEUE
20$: MOV R1,R2 ;SAVE POSSIBLE LAST CHUNK
MOV CN.MLK(R1),R1 ;GET NEXT CHUNK
BNE 20$ ;THAT WASN'T LAST, TRY THIS ONE
MOV R0,CN.MLK(R2) ;EXTEND QUEUE
99$: RTS PC
;THIS ROUTINE TAKES A MULTI CHUNK MESSAGE AND SENDS IT TO THE -10.
;SINCE QPR AND THE DTE DON'T SUPPORT GATHER READ, THE DATA IN EACH
;CHUNK HAS TO BE SENT AS A SEPARATE MESSAGE AND D8SINT IN THE -10
;HAS TO PACK THEM ALL INTO A SINGLE NCL MESSAGE.
;CALL:
;R0 ADDRESS OF FIRST CHUNK OF MESSAGE
DTEQUE: CLR ACKFLG ;CAN'T SEND NEXT MESSAGE YET
MOV R0,.STUSR ;SAVE REGISTERS WE PLAN ON MANGLING
JSR R0,TRPST ;IN CASE THE DTE DOES A DISAPPEARING ACT
.WORD 100$ ; (WE WILL FLAG AN ERROR)
TST @.PRSTA ;HELLO? ANYONE THERE?
; IF -10 POWERED DOWN SUDDENLY THIS WILL TRAP
; BEFORE WE START MUNGING ON MEMORY/QUEUES/ETC.
MOV R3,-(SP) ; .STUSR REFFED BY ..STIN
MOV SB,-(SP)
MOV #100000+BC.STR,R1 ;GET STRING DATA MSG TYPE (PLUS INDIRECT BIT)
MOV #D.CNCL,R3 ;AND QPR DEVICE TYPE (NCL)
MOV CN.LEN(R0),-(SP) ;THIS WILL BE # BYTES LEFT TO SEND
MOV R0,-(SP) ;THIS WILL BE CHUNK ADDRESS CURRENTLY BEING SENT
MOV #CNKLN1,-(SP) ;FIRST CHUNK HAS UP TO THIS MUCH DATA
MOV #CN.NCT-2,-(SP) ;AND THE ACTUAL DATA STARTS HERE
10$: ADD (SP)+,R0 ;POINT TO FIRST WORD LOCATION
MOV @R0,SB ;SAVE POSSIBLE LINK WORD (IF 2ND CHUNK)
CMP 4(SP),@SP ;IS THERE MORE DATA TO SEND THAN IN CHUNK?
BLE 20$ ;NO, SEND LAST PART AND EXIT
SUB @SP,4(SP) ;THIS MUCH LESS FOR NEXT FRAGMENT
MOV (SP)+,@R0 ;AND TRANSFER THAT MUCH
BIS #FW.MOR,@R0 ;TELL -10 THERE WILL BE MORE
JSR PC,..STIN ;QUEUE UP THE MESSAGE
MOV SB,@R0 ;RESTORE POSSIBLE LINK WORD
MOV @(SP)+,R0 ;GET ADDRESS OF NEXT CHUNK IN MESSAGE
CHK NE ;THERE'D BETTER BE ONE....
MOV R0,-(SP) ;MAKE IT CURRENT
MOV #CNKLN2,-(SP) ;NOW THERE'S THIS MUCH DATA/CHUNK
MOV #CN.DT2-2,-(SP) ;SO FIRST WORD STARTS HERE
BR 10$ ;SEND MORE
20$: CMP (SP)+,(SP)+ ;RID OURSELVES OF TRASH
MOV (SP)+,@R0 ;NUMBER OF BYTES LEFT TO TRANSFER
JSR PC,..STIN ;SEND LAST FRAGMENT
MOV SB,@R0 ;FIX POSSIBLE LINK WORD
MOV (SP)+,SB ;RESTORE ALL ACS USED
MOV (SP)+,R3
CLC ;FLAG SUCCESSFUL
98$: MOV .STUSR,R0 ;RESTORE R0 (MESSAGE ADDRESS)
RTS PC ;DONE
100$: SEC ;DTE NXM'ED US, FLAG ERROR
BR 98$ ;AND RETURN NOW
;ROUTINE CALLED WHEN EACH CHUNK OF A TO-10 NCL MESSAGE REACHES THE -10.
;ONLY WHEN THE LAST CHUNK HAS BEEN SENT WILL THE MESSAGE BE
; GIVEN TO NCLODN.
;CALL:
;R4 ADDRESS OF TO-10 CONTROL BLOCK
T10DON: BIT #FW.MOR,TT.QFW(R4) ;ANYTHING MORE IN THIS NCL MESSAGE?
BNE 99$ ;YES, CAN'T GIVE IT BACK TO NCL YET
MOV R0,-(SP) ;SAVE ACS NEEDED BY TOTNDN
MOV R4,-(SP)
MOV TT.USR(R4),R0 ;GET ADDRESS OF INITIAL CHUNK
TST TENSCB ;IS THE DTE STILL UP, OR ARE WE CLEARING UNSENT
BEQ 10$ ; MSGS. IF SO, THEN REQUE THE MSG
JSR PC,NCLODN ;HAVE NCL GET RID OF IT
BR 20$ ;CLEAN STACK AND EXIT
10$: JSR PC,MSGREQ ;REQUEUE THE MESSAGE NEXT TICK
20$: MOV (SP)+,R4
MOV (SP)+,R0
99$: RTS PC
;ROUTINE CALLED WHEN QPR DOORBELL FINDS IT HAS DATA FOR NCL.
;THIS ALLOCS SPACE ALA DN87 AND SETS UP ITS INTERNAL DATA BASE.
;
;CALL:
;R0/ # OF BYTES IN MESSAGE
;RETURN:
;R0/ # OF BYTES TO XFER
;R1/ ADDRESS OF WHERE TO PUT DATA
T11DBL: MOV R0,-(SP) ;SAVE LENGTH OF QPR MESSAGE
MOV CURMSG,R5 ;ARE WE TRYING TO ADD TO ONE?
BNE 10$ ;YEP, WE HAVE ALREADY INITIALIZED STUFF
JSR PC,ERSGET ;GET FIRST CHUNK OF MESSAGE
MOV R0,R5 ;SAVE IT FOR FUTURE REFERENCING
MOV R5,CURMSG ;AND REMEMBER OVER SUBROUTINE CALLS
CLR (R0)+ ;TE.LNK SAY NOT LINKED TO ANYONE YET (ERSGET SHOULD HAVE CLEARED IT)
MOV @SP,(R0)+ ;TE.QPR SAVE LENGTH REMAINING IN FRAGMENT
MOV (SP)+,(R0)+ ;TE.LEN START COUNT LENGTH OF NCL MESSAGE
MOV TO11FW,(R0)+ ;TE.FFW REMEMBER LINE # (STATUS) FOR THIS FRAGMENT
MOV #CNKLN1,(R0)+ ;TE.CNK # BYTES LEFT IN PRESENT CHUNK
MOV #TO11HD,R1 ;COPY MESSAGE HEADER INTO CHUNK
MOV (R1)+,(R0)+ ;TE.QHD
MOV (R1)+,(R0)+ ;TE.QFN
MOV (R1)+,(R0)+ ;TE.QDV
MOV (R1)+,@R0 ;TE.QSP
ADD #CN.NCT-TE.QSP,R0 ;POINT TO FIRST DATA BYTE
MOV R0,TE.ADR(R5) ;REMEMBER NEXT BYTE TO FILL
BR CONT11 ;APPEND TO THIS CHUNK
10$: ADD @SP,TE.LEN(R5) ;THE MESSAGE IS THIS MUCH LONGER
MOV (SP)+,TE.QPR(R5) ;REMEMBER HOW MUCH WE HAVE TO TRANSFER
MOV TO11FW,TE.FFW(R5) ;REMEMBER FLAGS (LINE #) FOR THIS FRAGMENT
MOV TE.ADR(R5),TE.CMP(R5) ;HACK: WE KNOW THIS MESSAGE IS LAST AND IS USER DATA
BIT #TOBM,STATI+2 ;WILL THIS BE WORD MODE? (BINARY DATA)
BEQ EXTMSG ;NO, THAT'S A RELIEF
INC TE.ADR(R5) ;THIS WILL ROUND UP TO NEXT WORD ADDRESS
BIC #1,TE.ADR(R5)
BIC #1,TE.CNK(R5) ;AND THIS WILL ROUND DOWN TO # OF USABLE BYTES
BR EXTMSG ;TACK THIS ON AT END OF LAST ONE
;ROUTINE CALLED FROM TO-11 DONE INTERRUPT ROUTINE TO ADD NEW CHUNK
;OR PROCESS END OF FRAGMENT
;
;CALL - NO REGISTERS NEEDED
;RETURN:
;R0/ LENGTH OF NEXT FRAGMENT TO TRANSFER
;R1/ ADDRESS TO STORE DATA
;PS/ Z BIT SET IF EVERYTHING IN
T11DON: MOV CURMSG,R5 ;GET ADDRESS FOR FIRST CHUNK OF THIS MESSAGE
ASSERT NE ;T11DBL GUARANTEES IT TO BE SETUP
TST TE.QPR(R5) ;ANYTHING LEFT IN QPR MESSAGE?
BNE EXTMSG ;YES, MUST BE AT END OF CHUNK, ADD A NEW ONE
BIT #FW.MOR,TE.FFW(R5) ;IS THERE AT LEAST ANOTHER FRAGMENT?
BNE 20$ ;YES, DON'T QUEUE WHAT WE HAVE
MOV #TO11Q-CN.MLK,R0 ;PUT COMPLETED MESSAGE AT END OF LIST
10$: MOV R0,R1 ;SAVE POSSIBLE LIST END
MOV CN.MLK(R0),R0 ;GET NEXT ITEM
BNE 10$ ;THERE WAS ONE, SEE IF ANOTHER
MOV R5,CN.MLK(R1) ;PUT ON END OF LIST
CLR CN.MLK(R5) ;MARK END OF LIST
CLR CURMSG ;NO LONGER BUILDING AN NCL MESSAGE
20$: CLR R0 ;TO TELL QPR TO STOP TRANSFER
RTS PC ;BACK TO IT, Z BIT SET
EXTMSG: TST TE.CNK(R5) ;ANY SPACE LEFT IN THIS CHUNK?
BNE CONT11 ;YES, CONTINUE WITH IT
JSR PC,ERSGET ;GET ANOTHER CHUNK
MOV TE.ADR(R5),R1 ;SINCE WE'RE AT END, THIS IS START OF
MOV R0,-CNKSIZ(R1) ; NEXT CHUNK, CORRECT TO EXTEND LIST
MOV #CNKLN2,TE.CNK(R5) ;WE HAVE THIS MANY BYTES TO FILL IN THIS CHUNK
ADD #CN.DT2,R0 ;MAKE ADDRESS TO START AT
MOV R0,TE.ADR(R5) ;REMEMBER FOR AWHILE
CONT11: MOV TE.CNK(R5),R0 ;CALC NUMBER OF BYTES WE CAN TRANSFER NOW
CMP R0,TE.QPR(R5) ;WHICH IS MIN OF SPACE IN CHUNK AND QPR MESSAGE
BLE 10$ ;SPACE LEFT IN CHUNK IS SMALLER
MOV TE.QPR(R5),R0 ;SPACE IN QPR MESSAGE IS SMALLER
10$: MOV TE.ADR(R5),R1 ;WHERE TO PUT DATA
SUB R0,TE.QPR(R5) ;THIS MUCH LESS IN QPR MESSAGE
SUB R0,TE.CNK(R5) ;AND CHUNK
ADD R0,TE.ADR(R5) ;NEXT TRANSFER MAY START AT THIS ADDRESS
RTS PC ;BACK TO QPR
.SBTTL DTE20 REGISTER DEFINITIONS
; THESE LABELS ARE THOSE USED IN THE FRONT END INTERFACE SPEC
; EXCEPT STATUS WHICH CONFLICTS WITH PROTOCOL SPEC
;
; PDM# 200-200-012-00
;DTE-11 REGISTER ADDRESSES (FOR FIRST UNIT)
DLYCNT=174400 ;DELAY COUNT WORD
DEXWD3=174402 ;DEPOSIT OR EXAMINE WORD 3
DEXWD2=174404 ;DEPOSIT OR EXAMINE WORD 2
DEXWD1=174406 ;DEPOSIT OR EXAMINE WORD 1
TENAD1=174410 ;TEN ADDRESS WORD 1
TENAD2=174412 ;TEN ADDRESS WORD 2
TO10BC=174414 ;TO-10 PDP-11 MEMORY ADDRESS
TO11BC=174416 ;TO-11 BYTE COUNT
TO10AD=174420 ;TO-10 PDP-11 MEMORY ADDRESS
TO11AD=174422 ;TO-11 PDP-11 MEMORY ADDRESS
TO10DT=174424 ;TO-10 PDP-11 DATA WORD
TO11DT=174426 ;TO-11 PDP-11 DATA WORD
DIAG1=174430 ;DIAGNOSTIC WORD 1
DIAG2=174432 ;DIAGNOSTIC WORD 2
STAT=174434 ;STATUS WORD
DIAG3=174436 ;DIAGNOSTIC WORD 3
;TENAD1 DEFINITIONS
DEP=010000 ;DEPOSIT (BIT 12)
PRTOFF=004000 ;EXAMINE/DEPOSIT PROTECT OFF
PHYS=100000 ;PHYSICAL EXAMINE
;TO11BC DEFINITIONS
IFLOP=100000 ;I FLIPFLOP BIT
ZSTOP=040000 ;ZSTOP
TO11BM=020000 ;TO 11 BYTE MODE
; DIAG1 DEFINITIONS
DS04=004000 ;KL CLOCK ERROR STOP
DS05=002000 ;RUN
DS06=001000 ;HALT
DEX=000400 ;DEPOSIT OR EXAMINE MAJOR STATE
TO10=000200 ;TO 10
DFUNC=000200
TO11=000100 ;TO-11 TRANSFER MAJOR STATE
D1011=000040 ;DIAGNOSE 10/11 INTERFACE
PULSE=000020 ;SINGLE CLOCK CYCLE
DIKL10=00010 ;DIAGNOSTIC MODE SWITCH
DSEND=000004 ;SEND DATA
DCOMST=000001 ;DIAGNOSTIC COMMAND START
TO10BM=000001 ;NEED BYTE MODE IN DIAG3
;STAT DEFINITIONS (READ)
TO10DN=100000 ;TO-10 NORMAL TERMINATION
TO10ER=020000 ;TO-10 ERROR TERMINATION
RAMIS0=010000 ;RAM IS ZEROS
TO11DB=004000 ;-10 REQUESTED -11 INTERRUPT
DXWRD1=002000 ;DEXWORD 1
MPE11=001000 ;-11 MEMORY PARITY ERROR
TO10DB=000400 ;-11 REQUEST -10 INTERRUPT
TO11DN=000200 ;TO-11 TRANSFER DONE
EBSEL=000100 ;E BUFFER SELECT
NULSTP=000040 ;NULL STOP
BPARER=000020 ;EBUS PARITY ERROR
RM=000010 ;RESTRICTED MODE
DEXDON=000004 ;DEPOSIT/EXAMINE DONE
TO11ER=000002 ;TO-11 BYTE ERROR TERMINATION
INTSON=000001 ;INTERRUPTS ON
;STAT DEFINITIONS (WRITE)
DON10S=100000 ;SET TO-10 NORMAL TERMINATION (DONE)
DON10C=040000 ;CLEAR TO-10 NORMAL TERMINATION
ERR10S=020000 ;SET TO-10 ERROR TERMINATION
ERR10C=010000 ;CLEAR TO-10 ERROR TERMINATION
INT11S=004000 ;SET TO-11 DOORBELL INTERRUPT REQUEST
INT11C=002000 ;CLEAR TO-11 DOORBELL INTERRUPT REQUEST
PERCLR=001000 ;CLEAR -11 MEMORY PARITY ERROR FLAG
INT10S=000400 ;SET TO-10 DOORBELL INTERRUPT REQUEST
DON11S=000200 ;SET TO-11 NORMAL TERMINATION FLAG
DON11C=000100 ;CLEAR TO-11 NORMAL TERMINATION FLAG
INTRON=000040 ;ENABLE -11 INTERRUPT
EBUSPC=000020 ;CLEAR EBUS PARITY ERROR
INTROF=000010 ;DISABLE -11 INTERRUPT
EBUSPS=000004 ;SET EBUS PARITY ERROR
ERR11S=000002 ;SET TO-11 ERROR TERMINATION FLAG
ERR11C=000001 ;CLEAR TO-11 ERROR TERMINATION FLAG
;STATUS TO CLEAR DTE-11
DTE11C=ERR10C+PERCLR+EBUSPC+INTROF+ERR11C
;DTE20 COMMUNICATION AREA OFFSETS (WORD NAMES)
PIDENT=0 ;PROCESSOR IDENTIFICATION WORD
CHNPNT=1 ;POINTER TO COMM AREA OF NEXT PROCESSOR (CIRC LIST)
CYCLS=2 ;CLOCK CPS COUNT
TOD=3 ;TIME OF DAY
DATE=4 ;DATE
PSWW1=5 ;PROCESSOR STATUS WORD1
PSWW2=6 ;PROCESSOR STATUS WORD2
PSWW3=7 ;PROCESSOR STATUS WORD3
PSWW4=10 ;PROCESSOR STATUS WORD4
PSWW5=11 ;PROCESSOR STATUS WORD5
PSWW6=12 ;PROCESSOR STATUS WORD6
PSWW7=13 ;PROCESSOR STATUS WORD7
PSWW10=14 ;PROCESSOR STATUS WORD10
PSWW11=15 ;PROCESSOR STATUS WORD11
PSWW12=16 ;PROCESSOR STATUS WORD12
PSWW13=17 ;PROCESSOR STATUS WORD13
FORPRO=20 ;FOR PROCESSOR IDENTIFICATON WORD
PROPNT=21 ;POINTER TO COMM AREA OF THE PROCESSOR ASSOC WITH THIS BLOCK
STATUS=22 ;COMMUNICATION STATUS WORD
QSIZE=23 ;QUEUE SIZE WORD
;CTY0CW=24 ;CTY #0 COMMAND WORD
;CTY0RW=25 ;CTY #0 RESPONSE WORD
;CTY1CW=26 ;CTY #1 COMMAND WORD
;CTY1RW=27 ;CTY #1 RESPONSE WORD
;MISCW=30 ;MISCELLANEOUS COMMAND WORD FOR NON-QUEUE PROTOCOL
;MISRW=31 ;MISCELLANEOUS RESPONSE WORD
UNASG1=32 ;UNASSIGNED WORD1
UNASG2=33 ;UNASSIGNED WORD2
UNASG3=34 ;UNASSIGNED WORD3
UNASG4=35 ;UNASSIGNED WORD4
UNASG5=36 ;UNASSIGNED WORD5
UNASG6=37 ;UNASSIGNED WORD6
;EPT ADDRESSES AS DEFINED IN BOOTS FOR USE IN THE SECONDARY PROTOCOL
DTEFLG=444 ;OPERATION COMPLETE FLAG
DTEF11=450 ;PDP-10 FROM PDP-11 ARGUMENT
DTECMD=451 ;PDP-10 TO PDP-11 COMMAND WORD
DTEMTD=455 ;MONITOR TTY OUTPUT COMPLETE FLAG
DTEMTI=456 ;MONITOR TTY INPUT FLAG
;STATUS DEFINITONS
TOIT=1 ;IN PROGRESS OF PROCESSING QUEUE
TOIP=2 ;TO HIM INDIRECT IN PROGRESS
TOBM=4 ;TO HIM WORD MODE REQUESTED
LOAD11=4 ;LOAD ELEVEN
.SBTTL $DTEON -- TURN THE DTE20 ON
;
;+
;
; $DTEON -- TURN ON THE DTE20
; THIS ROUTINE WILL SET UP THE TABLES NECESSARY TO
; INITALIZE THE COMMUNICATION BETWEEN THE PDP10 AND PDP11'S
;
;
; ENTRY CONDITIONS:
;
;
; JSR PC,$DTEON
;
; EXIT CONDITIONS:
;
; R0 --1 TO INDICATE SUCCESS
; CC-C CLEAR TO INDICATE SUCCESS
;
;
; ERROR CONDITIONS:
;
; R0 -2 -- E BOX STOPPED
; CC-C SET
;
;
; REGISTERS SAVED AND RESTORED BY EMT SERVICE
;
;-
;
$DTEON: MOV R5,-(SP)
CLR DBLCNT ;NO LONGER TRYING TO SEND A MESSAGE TO THE -10
MOV .PRDTE,R0 ;FIND THE COMMON DTE20
MOV #DTE11C,STATD(R0) ;RESET DTE
CLR R1 ;SET UP TO FIND PROCESSOR NUMBER
CLR R2 ;START TRANSFER OF ABS WORD 0 OF EPT (MY PROCESSOR NUMBER
MOV #DEXTM3,R3 ;SET UP ADDRESS TO STORE WORDS
CLR R4
JSR PC,SWFED ;WAIT FOR EXAMINE/DEPOSIT
BCS 1$ ;E BOX STOP
MOV @R3,R4 ;YES --FIND OFFSET TO MY R/W AREA
MOVB @#DEXTM2+1,R2 ;FIND THE PROCESSOR NUMBER
; PROCESSOR NUMBER TO LOW ORDER BITS
BIC #177760,R2 ;MASK OFF JUNK(0.-15. LEGAL)
MOV R2,PRMEMN ;SAVE PROCESSOR NUMBER
INC R2 ;FIND COMMUNICATIONS VIRTUAL 2
MOV R2,COMBSE ;SAVE BASE OF COMMUNICATIONS AREA
ADD R4,R2 ;ADD OFFSET TO BASE OF COMM AREA
MOV R2,DEPOF ;SET CORRECT OFFSET
JSR PC,SWFED ;WAIT FOR TRANSFER
1$: BCS 80$ ;
2$: MOV @#DEXTM2,R5 ;PICK UP THE NUMBER OF 8 TM BLOCKS
BIC #177770,R5 ;FIND THE NUMBER OF 8 WORD BLOCKS IN MY AREA
SUB #2,R5 ;ACCOUNT FOR MY GENERAL SECTION
MOV R2,-(SP)
MOV R5,-(SP) ;SAVE COUNT OF BLOCKS
15$: ADD #FORPRO,2(SP) ;LOOK AT A COMMUNICATIONS AREA TO ANOTHER PROCESSOR
MOV 2(SP),R2
CLR R4
JSR PC,SWFED ;WAIT FOR TRANSFER
BCS 70$ ; E BOX STOPPED
MOV @R3,R4 ;FIND PROCESSOR NUMBER
MOV #PROTBL,R5 ;SET INITIAL POINTER
BIC #177770,R4 ;MASK OFF JUNK
BEQ 19$ ;YES -- CONTINUE
37$: ADD #5*2,R5 ;NO -- LOOK AT NEXT ENTRY
SOB R4,37$ ;TRY UNTIL ALL DONE
19$: MOV @#DEXTM2,R4 ;FIND NUMBER OF 8 WORD BLOCS
BIC #177770,R4 ;MASK OFF POSSIBLE GARBAGE
SUB R4,@SP ;UPDATE COUNT OF BLOCKS
CLR @R5 ;SET UP TO CLEAR TABLE IF NO DTE
MOV @#DEXTM1,R4 ;PICK UP DTE NUMBER
BIT #4,R4 ;DTE HERE?
BEQ 20$ ;NO -- DON'T ENTER IN TABLE
SWAB R4 ;MAKE MOD 40 (8)
ROR R4
ROR R4
ROR R4
BIC #177637,R4 ;MASKOFF JUNK
ADD #174400,R4 ;POINT TO FIRST BLOCK OF DTE'S
CMP R4,.PRDTE ;PRIMARY DTE?
BNE 40$ ;NO -- DON'T SET TABLE POINTER
MOV R5,.PRADR ;SAVE TABLE OFFSET
40$: MOV R4,@R5 ;SET DTE ADDRESS IN TABLE
MOV #37777,@R4 ;SET UP DELAY COUNTER
20$: MOV R2,EMYN(R5) ;SET THE ADDRESS OF EXAMINE MY AREA FOR N
;MAKE ADDRESS OF THE ADDRESS OF DEPOSIT MY AREA FOR N
MOV R2,DMYN(R5) ;STORE IT
SUB DEPOF,DMYN(R5) ;RESTORE SUPRESS FOR EXAMINE OF THIS BLOCK
ADD #PROPNT-FORPRO,R2 ;READ POINTER TO HIS COMM AREA
CLR R4
JSR PC,SWFED ;WAIT FOR EXAMINE/DEPOSIT
BCS 70$ ;E BOX STOPPED
MOV @R3,R2 ;FIND THE EXAMINE ADDRESS
ADD COMBSE,R2 ;ADD OFFSET TO COMMON AREA
MOV R2,EHSG(R5) ;SET EHSG ADDRESS IN TABLE
ADD #FORPRO,R2 ;POINT TO HIS FIRST TABLE FOR OTHER PROCESSORS
50$: CLR R4
JSR PC,SWFED ;WAIT FOR EXAMINE/DEPOSIT
BCS 70$
CMPB PRMEMN,@R3 ;SAME PROCESSOR NUMBER?
BEQ 60$ ;YES -- FOUND MY ENTRY
MOV @#DEXTM2,R4 ;NO -- FIND NEXT ENTRY IN LIST
BIC #177770,R4 ;IT IS IN 8 WORD INCREMENTS
ASL R4 ;SO IT MUST BE SHIFTED LEFT 3 BITS
ASL R4 ;
ASL R4 ;
ADD R4,R2 ;READ NEXT BLOCK
BR 50$ ;AND TRY AGAIN
60$: MOV R2,EHSM(R5) ;STORE EHSM ADDRESS
MOV @SP,R5 ;DONE ALL BLOCKS??
BHI 15$ ;NO -- TRY NEXT BLOCK
CLR QCOUNT ;RESET PROTOCOL COUNTERS
CLR QSTATE ;INIT STATE MECHANISM, CLEAR CARRY
70$: BIT (SP)+,(SP)+ ;CLEANUP STACK, PRESERVE C BIT
80$: MOV (SP)+,R5
RTS PC
.SBTTL SWFED -- INTERNAL SUBROUTINE START AND WAIT FOR EX/DEP
;
; SWFED -- STARTS A DEPOSIT/EXAMINE SEQUENCE AND WAITS FOR
; ITS COMPLETION. IT CHECKS TO SEE IF THE BOOTSTRAP
; PROTOCOL IS NECESSARY BY CHECKING THE EXAMINE VALID BIT
; AFTER EVERY EXAMINE/DEPOSIT. IT IS NOT NECESSARY TO
; CHECK MORE THAN ANY ONE RANDOM EXAMINE VAILD BIT
; BECAUSE IF ONE IS 0 THEN THE PROCESSOR HAS
; TO REVERT TO THE BOOTSTRAP PROTOCOL.
; IF THE EXAMINE VALID BIT IS NOT SET THEN A CALL
; TO .BTPRO MUST BE MADE TO START THE USE OF THE BOOTSTRAP
; PROTOCOL -- THIS PROTOCOL IS USED PRIMARLY IN CASES
; WHEN THE SYSTEM IS BEING BOOTSTRAPPED OR EDDT IS RUNNING.
;
; NOTE: **** THIS ROUTINE MUST BE ENTERED AT PRI6 ****
;
;
; CALLING SEQUENCE:
;
; R0 -- ADDRESS OF DTE20
; R1-- HIGH ORDER EXAMINE/DEPOSIT ADDRESS WORD (FOR TENAD1)
; R2 -- LOW ORDER EXAMINE/DEPOSIT ADDRESS WORD (FOR TENAD2)
; R3 -- ADDRESS TO XFER 3 WORD BLOCK TO OR FROM
;
; JSR PC,SWFED
;
; EXIT CONDITIONS:
;
; SUCCESS NO REGISTERS ALTERED CC-C CLEAR
;
; ERROR CONDITIONS:
;
; CC-C SET
;
;
SWFED: MOV R3,-(SP) ;SAVE REGISTERS
BIT #DEP,R1 ;CHECK FOR DEPOSIT
BNE 20$ ;YES -- GO TO DEPOSIT PART OF SUB
MOV R1,TNAD1(R0) ;SET UP ADDRESS OF XFER IN DTE
MOV R2,TNAD2(R0) ;START XFER
JSR PC,WFED ;WAIT FOR EXAMINE/DEPOSIT
BCS 40$ ;COMPLAIN ABOUT E BOX STOPPED
MOV DXWD3(R0),(R3)+ ;STORE THE WORD XFERED
MOV DXWD2(R0),(R3)+
MOV DXWD1(R0),(R3)+
10$: TST R4 ;PRIV EXAMINE/DEP?
BNE 40$ ;YES -- DON'T DO CHECKS
CLR TNAD1(R0) ;SEE IF WE CAN READ ANYTHING
CLR TNAD2(R0) ;START TRANSFER
JSR PC,WFED ;WAIT FOR XFER
BCS 40$ ;E BOX STOPPED
TST DXWD3(R0) ;VALID?
BNE 40$ ;YES -- PROCEED
BR 30$ ;DN87S - JUST SET CARRY AND RETURN
20$: MOV (R3)+,DXWD3(R0) ;TRANSFER TO 10
MOV (R3)+,DXWD2(R0) ;SET UP WORD IN DTE
MOV (R3)+,DXWD1(R0)
MOV R1,TNAD1(R0) ;SET HIGH ORDER ADDRESS
MOV R2,TNAD2(R0)
JSR PC,WFED ;WAIT FOR EXAMINE/DEPOSIT
BCC 10$ ;GO TO COMMON EXAMINE VALID BIT CHECK
;
30$: SEC ;SET CARRY TO SAY VALID EXAMINE IS OFF
40$: MOV (SP)+,R3 ;RESTORE R3
RTS PC ;RETURN TO CALLER
.SBTTL WFED -- INTERNAL SUBROUTINE WAIT FOR EXAMINE/DEPOSIT
;
; WFED -- WAITS FOR EXAMINE/DEPOSIT TRANSFERS AND
; CHECKS TO SEE THAT E BOX HAS NOT STOPPED
;
; NOTE: **** THIS ROUTINE MUST BE ENTERED AT PRI6 ****
;
;
; CALLING SEQUENCE:
; ENTRY CONDITIONS:
; R0 -- ADDRESS OF DTE20
;
; JSR PC,WFED
;
; EXIT CONDITIONS:
;
; SUCCESS NO REGISTERS ALTERED CC-C CLEAR
;
; ERROR CONDITIONS:
;
; CC-C SET
; R0 -2 -- E BOX STOPPED
;
WFED: MOV #3000,DEXST ;SET UP TIMEOUT FOR DEXDONE
10$: BIT #DEXDON,STATD(R0) ;WAIT FOR TRANSFER TO COMPLETE
BEQ 30$ ;WAIT IF NOT YET DONE
BIT #BPARER,STATD(R0) ;DONE, CHECK FOR E BUS PARITY ERROR
BNE 40$ ;LOOKS BAD
.IF NE FTKLKR ;IF PARANOID ABOUT THE KL KROAKING OFF,
BIT #DS04!DS06,DAG1(R0) ;KL IN HALT-LOOP OR CLOCK-ERROR-STOP?
BNE 39$ ;YES, THEN THE KL IS NOT RUNNING
BIT #DS05,DAG1(R0) ;IS THE KL RUN FLOP STILL SET?
BEQ 39$ ;NO, THEN THE KL IS NOT RUNNING
.ENDC;.IF NE FTKLKR
CLC ;CLEAR CC-C FOR SUCCESSFUL OPERATION
RTS PC ;RETURN TO CALLER
30$: DEC DEXST ;TIMEOUT?
BNE 10$ ;NO -- CONTINUE WAITING
39$: TWIDDLE ;COUNT THE NUMBER OF TIMES THIS HAPPENS
TWIDDLE STATD(R0) ;REMEMBER STATUS REGISTER
TWIDDLE DAG1(R0) ;REMEMBER SOME OTHER STATUS
SEC ;SET CC-C TO INDICATE FAILURE
RTS PC ;AND RETURN WITH BAD NEWS
40$: BIS #ERR11C,STATD(R0) ;CLEAR THE ERROR STATUS
BR 39$ ;AND CLAIM FAILURE
.SBTTL QUEUED PROTOCOL DATA AND SYMBOLS
TO11NP: .WORD 0 ;NODE POINTER FOR NDOE
TO11HD: .WORD 0 ;COUNT OF BYTES IN THIS QUEUE
TO11FN: .WORD 0 ;TO ELEVEN FUNCTION CODE
TO11DV: .WORD 0 ;TO ELEVEN DEVICE NUMBER
TO11SP: .WORD 0 ;SPACE
TO11FW: .WORD 0 ;FIRST WORD OF FUNCTION
.IF DF,$DBDTE
TO11GW: .WORD -1 ;GUARD WORD FOR DTE20
TO11QP: .WORD 0
TO11AS: .WORD 0 ;ADDRESS SAVE
TO11BS: .WORD 0 ;BYTE COUNT SAVE
TO10SZ: .WORD 0 ;BYTE COUNT OF XFER
TO10AS: .WORD 0
.ENDC
;
STSTT: .WORD 1,0,0 ;TO 10 STATUS
;
QCOUNT =STSTT+4 ;BOTH OF BELOW
TO10QC =STSTT+4 ;TO 10 QUEUE COUNT
TO11QC =STSTT+5 ;TO 11 QUEUE COUNT
;
BUFOV: .WORD 0 ;BUFFER OVERFLOW FLAG (NO NODES AVAILABLE
;
;
TO10Q: .WORD . ;LISTHEAD FOR TO 10 QUEUE
.WORD .-2
;
EQSZ: .WORD 0 ;ELEVEN Q SIZE
;
QSTATE: ;ZEROED AT STARTUP
TO11ST: .BLKB 1 ;STATE OF TO-11 MECHANISM
TO10ST: .BLKB 1 ;AND OF TO-10
CURMSG: .BLKW 1 ;CHUNK ADDR OF NCL MESSAGE BEING BUILT
T10QUE: .BLKW 1 ;QUEUE OF MESSAGES WAITING FOR ACKS
ACKFLG: .BLKW 1 ;NON-ZERO WHEN WE CAN SEND A MESSAGE TO -10
.STUSR: .BLKW 1 ;TEMP, SAVED BY ..STIN ON A PER MESSAGE BASIS
DBLCNT: .WORD 0 ;TIMER FOR CASES WHEN -10 MISSES DOORBELL
TO11Q: .WORD 0 ;TO 11 QUEUE
STATI: .BLKW 3 ;STATUS/SCRATCH WORD FOR EXAMINES/DEPOSITS
; DEVICE QUEUE POINTERS
;
D.CCTY =1 ;DEVICE CODE FOR CTY
D.CDL1 =2 ;DEVICE CODE FOR DL11
D.CDH1 =3 ;DEVICE CODE FOR DH11 (1)
D.CDLS =4 ;DEVICE CODE FOR DATA LINE SCANNER (1)
D.CLPT =5 ;DEVICE CODE FOR LPT
D.CCDR =6 ;DEVICE CODE FOR CDR
D.CCLK =7 ;DEVICE CODE FOR CLOCK
D.FEPD =10 ;PSEUDO DEVICE FOR FE
D.CNCL =11 ;NCL NETWORK DEVICE
;
D.CCPU =200 ;PSEUDO DEVICE PDP10 CPU
D.CKLE =201 ;KL ERROR PSEUDO DEVICE
;
;
;
; TO ELEVEN QUEUE ENTRY
;
E.FP =0 ;FORWARD POINTER
E.LS =2 ;LIST SIZE
E.FN =4 ;FUNCTION CODE
E.DV =6 ;DEVICE CODE
E.FW =10 ;FUNCTION FIRST WORD
;
; FUNCTION CODE DEFINITIONS
;
BC.RQD =1 ;REQUEST DEVICES
BC.HAD =2 ;HERE ARE DEVICES
BC.STR =3 ;STRING DATA
BC.LNC =4 ;LINE/CHARACTER DATA
BC.RDS =5 ;RETURN DEVICE STATUS
BC.SDS =6 ;SET DEVICE STATUS
BC.HDS =7 ;HERE IS DEVICE STATUS
BC.DES =10 ;DEVICE ERROR STATUS
BC.RTD =11 ;RETURN TIME OF DAY
BC.HTD =12 ;HERE IS TIME OF DAY
BC.FOD =13 ;FLUSH OUTPUT DEVICE QUEUE
BC.SNA =14 ;SEND ALL
BC.TDU =15 ;DEVICE DIAL UP
BC.THU =16 ;DEVICE HANG UP
BC.SAK =17 ;ACKNOWLEDGE DEVICE DONE
BC.XOF =20 ;X-OFF (TTY ONLY)
BC.XON =21 ;X-ON (TTY ONLY)
BC.STS =22 ;SET TTY SPEED
BC.SLA =23 ;SET LINE ALLOCATION
BC.BTP =24 ;11 REBOOT WORD
BC.AKA =25 ;ACK ALL
BC.SPT =26 ;START/STOP LINE
BC.EDR =27 ;ENABLE/DISABLE REMOTES
BC.LDR =30 ;LOAD LP RAM
BC.LDV =31 ;LOAD LP VFU
BC.D6D =32 ;DAS 60 DATA
BC.KPS =33 ;KLINIK PARAMETER STATUS
BC.FNM =34 ;1 GREATER THAN MAX FUNCTION
;DTE20 REGISTER DEFINITIONS
DAG3 =36
STATD =34
DAG2 =32
DAG1 =30
T11AD =22
T10AD =20
T11BC =16
TNAD1 =10
TNAD2 =12
DXWD1 =6
DXWD2 =4
DXWD3 =2
;QUEUED PROTOCOL STATE DEFINITIONS:
;TO-11:
TES.DB =0 ;IDLE, WAITING FOR DIRECT DOORBELL
TES.HD =2 ;WAITING FOR TO11 DONE FOR HEADER
TES.DD =4 ;WAITING FOR TO11 DONE FOR DIRECT PORTION
TES.IB =6 ;WAITING FOR INDIRECT DOORBELL
TES.ID =10 ;WAITING FOR TO11 DONE FOR INDIRECT PORTION
.IIF NDF,DBLTIM,DBLTIM=5 ;GIVE -10 5 SECONDS TO RESPOND TO A DOORBELL
.SBTTL DTE20 INTERRUPT SERVICE ROUTINES
DTEVA0: ;CHK11 USES THIS SYMBOL
.DTINT: .CRASH INT ;WE DON'T USE INTERRUPTS ANYMORE
;INTLPS - ROUTINE TO SEE IF ANY "EVENTS" HAPPENED WHILE WE WEREN'T
; LOOKING. MAIN THINGS CHECKED FOR ARE DOORBELLS AND ERRORS.
INTLPS: JSR R0,TRPST ;PREPARE FOR DTE DEATH
.WORD TENDWD ; (FLAG TEN DOWN, RE-ROUTE IF NECESSARY)
INTLP0: MOV .PRDTE,R0 ;SET UP POINTER TO THIS PROCESSOR'S DTE-20
ASSERT NE ;HAD BETTER NOT BE 0!
MOV @.PRSTA,R1 ;GET ALL OF DTE-20'S STATUS BITS
MOV .PRADR,R3 ;ADDRESS OF COMM TABLE OFFSETS
BIT #TO10DN!TO10ER!MPE11,R1 ;TO 10 DONE OR ERROR?
BNE TOTNDN ;YES -- GO CHECK IT OUT
BITB #TO11DN!TO11ER,R1 ;TO 11 DONE OR ERROR?
BEQ 4$ ;NO -- GO ON
JMP TOELDN ;YES -- SEE WHAT IS NEXT FOR 11
4$: BIT #TO11DB,R1 ;NO -- CHECK FOR DOORBELL INTERRUPT
BEQ INTLP9 ;NO -- SKIP DOORBELL STUFF
JMP DBLRNG ;YES -- GO DO DOORBELL STUFF
INTLP9: RTS PC
;THIS INTERRUPT ROUTINE DECIDES WHAT TO DO WHEN A DIRECT
;MESSAGE OR EITHER PIECE OF AN INDIRECT MESSAGE REACH THE -10. THE
;STATE VARIABLE USED IS THE FUNCTION WORD OF THE MESSAGE BEING SENT.
;ON DIRECT MESSAGES IT WILL BE POSITIVE AND AFTER THE DIRECT PORTION
;OF INDIRECT MESSAGES IT WILL BE NEGATIVE. IN THE LATTER CASE THE INDIRECT
;PORTION WILL BE SENT TO THE -10 AND THE STATE VARIABLE IS CLEARED TO
;ENTER THE STATE WHERE THE NEXT INTERRUPT MARKS THE END OF THE INDIRECT
;MESSAGE. WHEN IT OCCURS, WE CALL T10DON TO ALLOW THE NCL INTERFACE TO
;RETURN THE MESSAGE BACK TO NCL FOR DISCARD OR SAVING.
TOTNDN: BMI 10$ ;DONE?
.CRASH TET ;NO -- MUST BE EITHER MEMORY PARITY OR TO10ER
;
10$:
.IF DF,$DBDTE
MOV TO10SZ,R4
ADD TO10AS,R4
CMP R4,T10AD(R0)
BEQ 13$
MOV T10AD(R0),#0 ;SAVE THE WRONG COUNT
TRAP ;TELL SOMEONE END POINTS OF XFER DON'T MATCH
13$:
MOV #1,TO10AS ;SET NO XFER EXPECTED
.ENDC
MOV #DON10C,@.PRSTA ;CLEAR DONE FLAGS
CLR DBLCNT ;GETTING HERE MEANS THE -10 SAW THE DOORBELL
MOV TO10Q,R4 ;START NEXT ENTRY IF THERE IS ONE
TST 12(R4) ;CHECK FOR INDIRECT FUNCTION
BMI INDTTF ;YES -- START THE FUNCTION
BNE 15$ ;NO -- IF NE THEN NORMAL FUNCTION
BIC #TOIP!TOBM,STSTT+2 ;CLEAR INDIRECT IN PROGRESS
JSR PC,T10DON ;LET NCL INTERFACE KNOW ABOUT IT
15$: JSR PC,..NDEL
MOV R0,-(SP) ;SAVE R0 -- CPU NUMBER
MOV 4(R4),R1 ;FIND THE SIZE OF THIS ENTRY
MOV R4,R0 ;SET THE NODE ADDRESS
JSR PC,..DECB ;DEALLOCATE
MOV (SP)+,R0 ;RESTORE THE CPU NUMBER
MOV TO10Q,R4 ;FIND THE LISTHEAD AGAIN
CMP #TO10Q,R4 ;IS THERE ANOTHER ONE TO DO
BEQ INTLP0
JSR PC,STNTQ ;START NEXT TEN QUEUE
20$: BR INTLP0 ;CHECK THE OTHER CONDITIONS NOW
INDTTF: CLR 12(R4) ;SET INDICATOR TO INDICATE THAT THIS WAS INDIRECT
CLR DXWD1(R0) ;DEPOSIT THE WORD COUNT
CLR DXWD2(R0)
CLR R5
BISB 20(R4),R5 ;SET THE COUNT
MOV R5,DXWD3(R0)
.IF DF,$DBDTE
MOV 22(R4),TO10AS
MOV R5,TO10SZ
.ENDC
MOV 22(R4),T10AD(R0) ;SET THE TO 10 ADDRESS
MOV #QSIZE-FORPRO,R5 ;DEPOSIT THE SIZE IN 10 MEMORY
ADD DMYN(R3),R5 ;GET OFFSET
MOV #DEP,TNAD1(R0) ;SET DEPOSIT
MOV R5,TNAD2(R0) ;START XFER
JSR PC,WFED ;WAIT FOR DEPOSIT
BIS #TOIP,STSTT+2 ;SAY WE'RE DOING INDIRECT
MOV #TO10BM,DAG3(R0) ;AND TELL HARDWARE THAT WE'RE DOING
; IT IN BYTE MODE
MOV STSTT,DXWD1(R0) ;SET IN 10 MEMORY
MOV STSTT+2,DXWD2(R0)
MOV STSTT+4,DXWD3(R0)
ADD #STATUS-QSIZE,TNAD2(R0) ;DEPOSIT IN 10 MEMORY
JSR PC,WFED ;WAIT FOR DEPOSIT
JSR PC,RINGDB ;TELL -10
JMP INTLP0
;TO-11 TRANSFERS ARE CONTROLLED BY BOTH THE DONE AND DOORBELL
;INTERRUPT ROUTINES AND EVERYTHING IS SYNCHRONIZED BY THE TO11ST
;STATE VARIABLE. (SEE THE TES.?? SYMBOL DEFINITIONS FOR THE MEANINGS.)
TOELDN: BMI 10$ ;ERROR?
5$: .CRASH ETE ;YES -- TO ELEVEN ERROR FLAG UP
;
10$:
.IF DF,$DBDTE
MOV TO11BS,R1
BIS #170000,R1
NEG R1
BIT #TO11BM,TO11BS
BNE 6$
ASL R1
6$: ADD TO11AS,R1
CMP R1,T11AD(R0)
BEQ 7$
MOV T11AD(R0),#0
.CRASH DTB
7$:
.ENDC
MOV #DON11C,@.PRSTA ;CLEAR DONE FLAGS
MOVB TO11ST,R1 ;GET PRESENT TO11 STATE
JSR PC,@20$(R1) ;CALL APPROPRIATE ROUTINE
MOVB R1,TO11ST ;ENTER NEW STATE
JMP INTLP0 ;SEE WHAT ELSE TO DO
20$: DEAD11 ;IDLE
TEHDIN ;GO BRING IN THE HEADER
TEDONE ;DIRECT MESSAGE IS IN
DEAD11 ;INDIRECT DOORBELL EXPECTED
TEDONE ;INDIRECT DATA DONE
DEAD11: .CRASH PT4 ;PROTOCOL BROKEN
;
;
; DOOR BELL INTERRUPT SERVICE
;
DBLRNG: CLR TNAD1(R0) ;READ STATUS WORD
MOV #STATUS-FORPRO,R2 ;FIND THE ADDRESS OF HIS STATUS-TO ME
ADD EHSM(R3),R2
MOV R2,TNAD2(R0) ;READ THAT STATUS WORD
MOV #INT11C,@.PRSTA
JSR PC,WFED ;WAIT FOR EXAMINE
BCS 35$ ;IGNORE INTERRUPT IF NOT STARTED
MOV DXWD1(R0),STATI ;SAVE STATUS
MOV DXWD2(R0),STATI+2
MOV DXWD3(R0),STATI+4
TST STATI ;VALID EXAMINE?
BEQ 35$ ;IGNORE WHEN NOT IN PRIMARY PROTOCOL
10$: BIT #TOIP,STATI+2 ;INDIRECT IN PROGRESS
BEQ 30$ ;NO -- MUST BE NORMAL
CMPB TO11ST,#TES.IB ;WAITING FOR IND. DOORBELL?
ASSERT EQ ;BETTER BE!
JSR PC,TEINST ;YEP, START TRANSFER
BR 40$ ;SAVE NEW STATE AND CLEAN UP
;
30$: CMPB STATI+4,TO10QC ;IS THIS THE CORRECT COUNT
BEQ 35$ ;YES -- CONTINUE PROCESSING
CMPB TO11ST,#TES.DB ;WAITING FOR DIRECT DOORBELL?
ASSERT EQ
JSR PC,TEHDST ;START TRANSFER OF HEADER
40$: MOVB R1,TO11ST ;ENTER NEW STATE (TO11 DONE EXPECTED)
35$: JMP INTLP0 ;SEE IF ANYTHING NEW TO DO
;CALLED TO START THE TRANSFER OF A TO-11 MESSAGE WHICH IT DOES BY
;TRANSFERRING THE HEADER AND FIRST WORD OF DATA (ALLWAY PART OF THE
;DIRECT PACKET). WHEN THAT IS IN, MESSAGE PROCESSING CONTINUES
;AT TEHDIN.
TEHDST: BIS #TOIT,STSTT+2 ;SET QUEUE IN PROGRESS
INCB TO10QC ;INDICATE Q UPDATED
CMPB STATI+4,TO10QC ;COUNT CORRECT?
BEQ 40$ ;YES -- PROCEED
.CRASH ILQ ;NO -- DISASTER
;
40$: MOV #DEP,TNAD1(R0) ;SET UP TO DEPOSIT
MOV STSTT,DXWD1(R0) ;THE STATUS
MOV STSTT+2,DXWD2(R0)
MOV STSTT+4,DXWD3(R0)
MOV #STATUS-FORPRO,R2
ADD DMYN(R3),R2
MOV R2,TNAD2(R0)
JSR PC,WFED ;START DEPOSIT
MOV #INT11C,@.PRSTA
MOV #QSIZE-FORPRO,R2 ;FIND THE QUEUE SIZE
ADD EHSM(R3),R2 ;EXAMINE HIS FOR ME
CLR TNAD1(R0) ;CLEAR DEPOSIT BIT
MOV R2,TNAD2(R0)
JSR PC,WFED ;WAIT FOR EXAMINE/DEPOSIT
BCS 77$
MOV DXWD3(R0),EQSZ ;SET UP Q SIZE
CMP EQSZ,#100. ;LEGAL SIZE
BLO 77$ ;YES -- ALL OK
.CRASH PT4
;THIS AUTOMATICALLY SETS UP EQSZ
77$: MOV R0,R2 ;MOVE DTE ADDR TO RIGHT PLACE
MOV #12,R0 ;JUST TRANSFER THE HEADER
MOV #TO11HD,R1 ;INTO THE HEADER AREA
JSR PC,TESTRT ;START TRANSFER
30$: MOV #TES.HD,R1 ;RETURN HEADER WAIT STATE
RTS PC
;CALLED AFTER THE HEADER OF THE TO-11 MESSAGE IS SAFELY IN. THE
;REST OF THE DIRECT PORTION (IF ANY) IS TRANSFERRED INTO MEMORY SET
;UP BY THE NCL INTERFACE (T11DBL). IF THIS IS AN INDIRECT MESSAGE,
;WE WILL WAIT FOR ITS DOORBELL; IF AN ACK, IT'S ENTIRELY IN AND
;CONTROL GOES TO TEDONE TO CALL T11DON TO START PROCESSING BY LOOPDT.
TEHDIN: SWAB TO11HD ;SWAP BYTES TO CORRECT DIRECTION
SWAB TO11FN
SWAB TO11DV
SWAB TO11FW
MOV R0,R2 ;SAVE THE CPU NIMBER -ALSO RESTART HERE IF ALL FAIL
CMP #D.CNCL,TO11DV ;LEGAL DEVICE?
BEQ 42$ ;YES -- ALL OK
.CRASH PT1 ;NO -- PROTOCOL BROKEN
42$: TST TO11FN ;INDIRECT FUNCTION?
BMI 44$ ;YES -- GET OUT AND WAIT FOR REST
CMPB TO11FN,#BC.FNM ;FUNCTION MAX?
BLO 46$ ;YES -- ALL OK HERE
.CRASH PT2 ;NO -- PROTOCOL BROKEN
46$: MOV EQSZ,R0 ;GET LENGTH OF MESSAGE MINUS HEADER
JSR PC,T11DBL ;TELL NCL STUFF TO TRANSFER DIRECT MESSAGE
TST R0 ;ANYTHING TO DO?
BEQ TEDONE ;NOPE, CALL THE DONE ROUTINE
JSR PC,TESTRT ;TRANSFER THE DATA
44$: MOV R2,R0
TST TO11FN ;IS IT INDIRECT?
BPL 70$
MOV #TES.IB,R1 ;RETURN IND. DOORBELL WAIT STATE
JMP TOITDN
70$: MOV #TES.DD,R1 ;RETURN DIRECT DOORBELL WAIT STATE
RTS PC
;CALLED WHEN THE DOORBELL REQUESTING THE START OF THE INDIRECT
;DATA RINGS. T11DBL IS NOTIFIED AND RETURNS WHERE THE DATA SHOULD BE
;SENT. NOTE THAT IT NEED NOT ALLOCATE SPACE FOR THE ENTIRE MESSAGE.
TEINST: BIS #TOIT,STSTT+2 ;TELL -10 WE SHOULD BE XFERRING DATA
ADD #QSIZE-STATUS,TNAD2(R0) ;READ THE STATUS WORD
JSR PC,WFED ;WAIT FOR EXAMINE
BCS SETDNE
MOV R0,R2 ;WE NEED R0
MOV DXWD3(R2),R0 ;GET MESSAGE LENGTH
MOV R0,EQSZ ;SAVE LENGTH OF MESSAGE
JSR PC,T11DBL ;TELL NCL INTERFACE THE GOOD NEWS
JSR PC,TESTRT ;START UP THE TRANSFER
MOV R2,R0
MOV #TES.ID,R1 ;RETURN IND. DONE WAIT STATE
BR STTOIP ;STORE STATUS WORD IN COMM REGION AND DISMISS INTERRUPT
;CALLED WHEN WE FILL A CHUNK OR REACH THE END OF THE TO-11 MESSAGE.
;T11DON IS QUERIED TO DETERMINE WHETHER OR NOT IT IS TIME TO
;STOP (IT WILL PUT THE MESSAGE ON A QUEUE FOR LOOPDT TO SEE.)
TEDONE: MOV TO11NP,R1 ;ENTER THE NODE IN THE QUEUE
MOV R0,R2 ;SAVE DTE ADDRESS
JSR PC,T11DON ;TELL NCL ROUTINES DATA CAME IN
BEQ 10$ ;QUEUE IT IF THAT'S ALL THERE IS
JSR PC,TESTRT ;MORE TO RECEIVE, START IT
MOVB TO11ST,R1 ;DON'T CHANGE STATE
RTS PC
10$: MOV #TES.DB,R1 ;BACK TO INITIAL STATE
TST EQSZ ;ANY MORE TO XFER?
BEQ TOITDN ;NO -- SET DONE TO -10
TRAP ;I DON'T THINK WE CAN GET HERE!
;SERVICE ROUTINES FOR INTERRUPT CODE
TOITDN: BIC #TOIT,STSTT+2 ;CLEAR PROCESSING QUEUE STATUS
STTOIP: MOV .PRDTE,R0 ;MAKE SURE THIS IS SETUP
MOV #STATUS-FORPRO,R2 ;YES -- BETTER INDICATE THAT 11 IS FINISHED
ADD DMYN(R3),R2 ;POINT TO STATUS WORD
MOV #DEP,TNAD1(R0) ;INDICATE WRITE
MOV STSTT,DXWD1(R0) ;SET UP TO DEPOSIT
MOV STSTT+2,DXWD2(R0)
MOV STSTT+4,DXWD3(R0)
MOV R2,TNAD2(R0) ;START XFER
JSR PC,WFED ;WAIT FOR DEPOSIT
SETDNE: RTS PC ;RETURN TO TOELDN OR DBLRNG
;ROUTINE TO START A TO-11 BYTE MODE TRANSFER.
;CALL:
;R0/ # OF BYTES TO TRANSFER
;R1/ WHERE TO START DATA
TESTRT: SUB R0,EQSZ ;THIS MUCH LESS TO DO
NEG R0 ;MAKE COUNT NEGITIVE
BIC #170000,R0 ;MASK OFF COUNT
RORB R0 ;!!!WARNING THIS ASSUMES C BIT IS SET BY NEG R0!!!!^^
BIT #TOBM,STATI+2 ;WORD MODE?
BNE 25$ ;YES -- DON'T SET BYTE FLAG
ROLB R0 ;!!^^SEE ABOVE -- RESTORE TO BYTE COUNT!!
BIS #TO11BM,R0 ;SET BYTE MODE
25$: TST EQSZ ;WILL THIS FINISH MESSAGE?
BNE 30$ ;NO, DON'T INTERRUPT -10
BIS #IFLOP,R0 ;SET INTERRUPT BOTH
30$: MOV R1,T11AD(R2) ;AND START XFER
MOV R0,T11BC(R2) ;SET BYTE COUNT
.IF DF,$DBDTE
MOV R1,TO11AS
MOV R0,TO11BS
.ENDC
RTS PC
;
; STNTQ -- SUBROUTINE TO START NEXT TO TEN QUEUE
;
STNTQ: MOV R5,-(SP) ;SAVE REGISTERS
MOV R0,-(SP)
MOV .PRDTE,R0 ;SET UP ADDRESS OF DTE20
CLR DXWD1(R0)
CLR DXWD2(R0)
MOV R4,R5 ;SAVE THE NODE ADDRESS
ADD #6,R5 ;MOVE OVER LISTHEAD AND NODE SIZE
.IF DF,$DBDTE
MOV @R5,TO10SZ
.ENDC
MOV (R5)+,DXWD3(R0) ;SET THE QUEUE SIZE IN MY AREA TO HIM
MOV R5,T10AD(R0) ;SET UP THE TO10 ADDRESS
MOV #1,DAG3(R0) ;SET BYTE MODE
.IF DF,$DBDTE
MOV R5,TO10AS
.ENDC
MOV .PRADR,R5 ;FIND THE CORRECT DTE
MOV DMYN(R5),R5 ;FIND THE OFFSET INTO MY AREA
ADD #QSIZE-FORPRO,R5 ; FIND Q SIZE
MOV #DEP,TNAD1(R0) ;SET UP TO DO DEPOSIT
MOV R5,TNAD2(R0)
JSR PC,WFED
INCB TO11QC ;INCREMENT THE COUNT
MOV STSTT,DXWD1(R0)
MOV STSTT+2,DXWD2(R0)
MOV STSTT+4,DXWD3(R0)
ADD #STATUS-QSIZE,TNAD2(R0)
JSR PC,WFED ;EXAMINE/DEPOSIT
MOV (SP)+,R0
MOV (SP)+,R5 ;RESTORE REGISTERS
BR RINGDB ;DING THE -10
;RINIDB -- RING THE -10 DOORBELL
;RINGDB -- RING THE -10 DOORBELL
;
;BOTH ROUTINES RING THE -10'S DOORBELL BUT RINIDB ASSUMES THAT NXM
;TRAPPING IS NOT IN EFFECT (CALLED FROM SYSTEM STARTUP).
RINIDB: TST .PRDTE ;DO WE HAVE ANY DTE?
BEQ 99$ ;NO, THEN DON'T RING ITS DOORBELL
JSR R0,TRPST ;YES (IN THEORY), ENABLE NXM TRAPPING
.WORD 10$ ; (JUST IGNORE IT AND GO AWAY)
BR RINGDB ;GO DO IT
10$: CLR .PRDTE ;NO DTE ANYMORE
MOV #TE.BAS-1,.PRSTA;NXM ANY TURKEYS
99$: RTS PC ;SO MUCH FOR THAT IDEA
RINGDB: MOV #TO10DB,@.PRSTA ;TELL -10 TO GO
MOV #DBLTIM,DBLCNT ;START TIMER
RTS PC
.SBTTL COMMON ROUTINES AND DATA STORAGE
.PRADR: .WORD 0 ;ADDRESS OF PRIV OFFSET TABLE ENTRY
.PRSTA: .WORD 0 ;OUR DTE20 STATUS WORD ADDRESS AND
.PRDTE: .WORD 0 ;DTE20 REGISTER(S) BASE ADDRESS
; IF 0 THEN AS NEAR AS WE CAN TELL THERE
; IS NO DTE, EVEN THOUGH WE WERE ASSEMBLED
; FOR ONE (E.G., KL IS POWERED OFF)
DEXST: .WORD 0 ;DEXDONE TIMEOUT
.CRQZ: .WORD 0 ;CURRENT QUEUE SIZE
.CPFN: .WORD 0 ;CURRENT FUNCTION IN TO 10 Q
.CPDV: .WORD 0 ;CURRENT DEVICE IN TO 10 QUEUE
.CRSZ: .WORD 0 ;CURRENT SIZE OF TO10 Q
.CRPB: .WORD 0 ;CURRENT BUFFER POINTER IN TO10 Q
.CRHD: .WORD 0 ;HEAD OF CURRENT TO10Q
.CRSB: .WORD 0 ;POINTER TO CURRENT FUNCTION SIZE
;
; POINTERS TO COMMUNICATIONS AREA
;
COMBSE: .WORD 0 ;BASE OF COMMUNICATION AREA
PRMEMN: .WORD 0 ;MY PROCESSOR NUMBER
DEPOF: .WORD 0 ;DEPOSIT OFFSET FROM EXAMINE
;
;
; PROCESSOR IDENTIFICATION TABLE
;
; PROTBL FORMAT:
;
; 5 WORDS/ENTRY
; 16 ENTRYS IN THE TABLE ONE FOR EACH PROCESSOR IN COMMUNICATION
; COMMUNICATION NUMBERS ARE LIMITED TO THE RANGE 0-15.
;
; (PROCESSOR 0) PROTBL: ADDRESS OF DTE20 TO ACCESS THIS PROCESSOR
DTENM=0
; (PROCESOR 0) ADDRESS TO COMMUNICATE TO PROCESSOR 0
EMYN =2
; (PROCESSOR 0) ADDRESS TO COMMUNICATE TO PROCESSOR 0 (WRITE)
DMYN =4
; (PROCESSOR 0) ADDRESS FROM GENERAL
EHSG =6
; (PROCESSOR 0) ADDRESS FROM SPECIFIC
EHSM =10
;
; (PROCESSOR 1) ADDRESS OF DTE20 TO USE TO ACCESS THIS PROCESSOR
; ...........
;
PROTBL: .BLKW 16.*5.
;
DEXTM3: .WORD 0 ;EXAMINE WORD 3 (TEMP STORAGE) TO BE
DEXTM2: .WORD 0 ;EXAMINE WORD 2 -USED ONLY BECAUSE EXAMINE
DEXTM1: .WORD 0 ;EXAMINE WORD 1 - OR DEPOSIT MAY FAIL AND MUST BE REDONE
;
KPAL1: .WORD 0,0,0 ;11 KEEP ALIVE
.SBTTL SCOM MODULE -- ..NDEL (NODE DELETE)
;+
;
; ..NDEL -- ROUTINE TO DELETE A NODE FROM A LIST
; THIS IS A BASIC SUBROUTINE TO DELETE
; NODES FROM A LIST. IT DOES NOT DO
; ANY ACCOUNTING OR LOOKING THE NODE
; IT ASSUMES THAT THERE IS A NODE TO BE PICKED
; AND INHIBITS INTERRUPTS TO PREVENT CONFLICTS WITH
; NODES BEING ADDED TO A DEQUE.
;
;
; CALLING SEQUENCE:
; R4 -- POINTER TO NODE TO BE DELETED
; JSR PC,..NDEL
;-
;
..NDEL: MOV R1,-(SP) ;SAVE R1
MOV @R4,R1 ;PICK THE NODE
MOV R1,@2(R4) ;
MOV 2(R4),2(R1) ;
MOV (SP)+,R1 ;RESTORE R1
RTS PC ;RETURN TO CALLER
.SBTTL SCOM MODULE -- ..NADD (NODE ADD)
;+
;
;
; ..NADD -- ROUTINE TO ADD A NODE TO A DEQUEUE
; ..NADD IS THE GENERAL PICK A NODE ROUTINE
; THE ADDITION OF A NODE IS DONE WITH INTERRUPTS
; INHIBITED TO PREVENT A CONFLICT WITH
; NODE DELETION.
;
;
; CALLING SEQUENCE:
; R1 -- NODE ADDRESS
; R4 -- ADDRESS OF LISTHEAD OR PREVIOUS NODE
; JSR PC,..NADD
;-
;
;
..NADD: MOV R2,-(SP) ;SAVE R2
MOV R4,2(R1) ;SET UP BACKWARD POINTER IN NODE
MOV @R4,@R1 ;SET UP FORWARD POINTER
MOV R1,@R4 ;FORWARD POINTER FROM LIST HEAD
MOV @R1,R2 ;
MOV R1,2(R2) ;
MOV (SP)+,R2 ;RESTORE R2
RTS PC ;RETURN TO CALLER
.SBTTL SCOM MODULE -- ..STIN (START INDIRECT FUNCTION)
;
;+
;
; ..STIN -- SUBROUTINE TO START AN INDIRECT DTE20 FUNCTION
; TO THE 10
;
; ENTRY CONDITIONS:
;
; R0 -- BUFFER ADDRESS
; R1 -- FUNCTION +100000
; R2 -- EFN/BUFFER SIZE
; R3 -- DEVICE ID
;
; NOTE : THE FIRST WORD OF THE BUFFER MUST CONTAIN THE
; LINE NUMBER AND BUFFER SIZE
;
; MAY NOT BE CALLED FROM ISR
;
;
; JSR PC,..STIN
;
; EXIT CONDITIONS:
; CC-C CLEAR SUCCESS
; CC-C SET FAILURE -- PRIMARY PROTOCOL IN USE
;
;-
;
..STIN: MOV R5,-(SP) ;SAVE REGISTERS
MOV R0,-(SP)
MOV R1,-(SP)
MOV #30,R1 ;SET UP TO ALLOCATE A BUFFER
10$: JSR PC,..ALCB ;ALLOCATE BUFFER
20$: MOV R0,R5 ;MOVE BUFFER ADDRESS TO R5
CMP (R5)+,(R5)+ ;MOVE OVER THE LISTHEAD
MOV R1,(R5)+ ;STORE THE BUFFER SIZE
MOV #12,@R5 ;PUT IN THE SIZE OF THIS HEADER PACKET
MOV (R5)+,(R5)+ ;ALSO PUT IT IN FIRST WORD TO 10
MOV @SP,(R5)+ ;STORE FUNCTION CODE
MOV R3,(R5)+ ;STORE THE DEVICE I/D
CLR (R5)+ ;CLEAR THE SPARE WORD
MOV 2(SP),R1 ;RESTORE BUFFER ADDRESS
MOV (R1)+,(R5)+ ;SET BYTE COUNT/LINE NUMBER
MOV R1,(R5)+ ;SET UP BUFFER ADDRESS
MOV .STUSR,(R5)+ ;SAVE USER DATA
MOV R2,(R5)+ ;SET ADDRESS
MOV R4,-(SP) ;SAVE R4
MOV R0,R1 ;SET UP TO ENTER NODE
MOV #TO10Q,R4 ;START TO 10 Q IF NECESSARY
CMP @R4,R4 ;CHECK TO SEE IF ALREADY GOING
BNE 30$ ;YES -- JUST ENTER IN Q
MOV R1,R4 ;NO -- SET NODE ADDRESS
JSR PC,STNTQ ;START QUEUE
30$: MOV TO10Q+2,R4 ;ENTER Q
JSR PC,..NADD ;ADD NODE
MOV (SP)+,R4 ;RESTORE REGISTERS
MOV (SP)+,R1
MOV (SP)+,R0
MOV (SP)+,R5
CLC ;CLEAR C
RTS PC ;RETURN TO CALLER