Trailing-Edge
-
PDP-10 Archives
-
bb-d868c-bm_tops20_v4_2020_distr
-
language-sources/qsrnet.mac
There are 36 other files named qsrnet.mac in the archive. Click here to see a list.
TITLE QSRNET - NETWORK DATA BASE MANAGER
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979
; DIGITAL EQUIPMENT CORPORATION
;
; 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.
SEARCH QSRMAC,ORNMAC,GLXMAC
PROLOG (QSRNET)
SUBTTL LOCAL STORAGE
NETPAG: BLOCK 1 ;SAVE AREA FOR THE NODE UUO/JSYS DATA PAGE
NETADR: BLOCK 1 ;SAVE AREA FOR THE ADDR OF THE NODE BLK ADDRESS
NETDUP: BLOCK 1 ;FLAG FOR DUPLICATE NODE DB ENTRIES
NWAMSG: $BUILD .OHDRS+ARG.DA+OBJ.SZ
$SET(.MSTYP,MS.CNT,.OHDRS+ARG.DA+OBJ.SZ)
$SET(.MSTYP,MS.TYP,.QONWA)
$SET(.OARGC,,1)
$SET(.OHDRS+ARG.HD,AR.LEN,OBJ.SZ+1)
$SET(.OHDRS+ARG.HD,AR.TYP,.OROBJ)
$EOB
MSGPDB: $BUILD IPCHSZ
$SET(.IPCFP,LHMASK,.OHDRS+ARG.DA+OBJ.SZ)
$SET(.IPCFP,RHMASK,NWAMSG)
$EOB
ONOFF: [ASCIZ/Online /]
[ASCIZ/Offline /]
INTERN N$INIT ;NETWORK INITIALIZATION
INTERN N$NODE ;CHECK FOR NODE ONLINE/OFFLINE STATUS
INTERN N$INTR ;ADD A NODE TO THE DATA BASE
INTERN N$INT ;NETWORK CHANGE INTERRUPT PROCESSOR.
INTERN N$NRTE ;NETWORK ROUTING ROUTINE
INTERN N$CSTN ;PERFORM STATION RE-ROUTING
INTERN N$LOCL ;VALIDATE A LOCAL NODE NAME/NUMBER
INTERN N$MTCH ;SEE IF 2 NODE NAME/NUMBERS ARE EQUIVALENT
INTERN N$NONL ;IBM NODE ONLINE PROCESSOR
INTERN N$NOFF ;IBM NODE OFFLINE PROCESSOR
SUBTTL N$INIT - ROUTINE TO INITIALIZE THE NETWORK DATA BASE MANAGER.
N$INIT: MOVEI H,HDRNET## ;GET ADDR OF NETWORK DB HEADER
PUSHJ P,M$GFRE## ;GET A FREE CELL
PUSHJ P,I%HOST ;GET THE HOST IDS
MOVEM S1,G$LNAM## ;SAVE THE LOCAL NODE NAME
MOVEM S2,G$LNBR## ;SAVE THE LOCAL NODE NUMBER
MOVEM S1,NETNAM(AP) ;SAVE THE NAME
MOVEM S2,NETNBR(AP) ;SAVE THE NUMBER
MOVX S1,NETNSV+NETONL ;GET VALID STATUS+ONLINE
MOVEM S1,NETSTS(AP) ;SAVE IT
$TEXT (<-1,,NETASC(AP)>,<^N/NETCOL(AP)/^0>) ;GEN NAME(NBR)
PUSHJ P,M$FLNK## ;LINK IT IN AT THE BEGINNING.
PUSHJ P,I$NINT## ;GO SETUP FOR NETWORK INTERRUPTS
SETOM G$CNET## ;FAKE A NETWORK CHANGE INTERRUPT
$RETT ;RETURN
SUBTTL N$INT - ROUTINE TO PROCESS NETWORK TOPOLOGY CHANGES
N$INT: $BGINT 1,
SETOM G$CNET## ;INDICATE A NETWORK CHANGE OCCURED
$DEBRK ;LEAVE INTERRUPT LEVEL
SUBTTL N$INTR - ROUTINE TO ANALYZE THE NETWORK CHANGES
;CALL: PUSHJ P,N$INTR
; TRUE ALWAYS
N$INTR: PUSHJ P,.SAVE2 ;SAVE P1 AND P2
SETZM G$CNET## ;CLEAR THE INTERRUPT FLAG
DOSCHD ;FORCE A SCHEDULING PASS ON NETWORK INTERRUPTS
MOVEI H,HDRNET## ;GET THE NETWORK DB HEADER ADDRESS
LOAD AP,.QHLNK(H),QH.PTF ;GET THE FIRST ENTRY
LOAD AP,.QELNK(AP),QE.PTN ;SKIP THE CENTRAL SITE
MOVX S1,NETNSV ;GET THE NETWORK-STATUS-VALID BITS
;CLEAR THE NETWORK-STATUS-VALID BITS FOR ALL NETWORK ENTRIES
INTR.1: JUMPE AP,INTR.2 ;NO MORE,,CONTINUE PROCESSING
ANDCAM S1,NETSTS(AP) ;CLEAR THE STATUS BIT
LOAD AP,.QELNK(AP),QE.PTN ;GET THE NEXT ENTRY ADDRESS
JRST INTR.1 ;AND GO PROCESS IT
;DO NECESSARY PROCESSING FOR ON-LINE NODES
INTR.2: PUSHJ P,GET.NETWORK.TOPOLOGY ;READ THE NETWORK TOPOLOGY
JUMPF INTR.3 ;NO MORE,,GO PROCESS OFF-LINE NODES
PUSHJ P,FINDNODE ;FIND THE NODE IN OUR DATA BASE
MOVE S1,NETSTS(AP) ;PICK UP THE NODE STATUS
TXNN S1,NETONL+NETADD ;WAS IT ONLINE or JUST ADDED ???
PUSHJ P,PURGE.DUP.OBJS ;NO,,THE SCAN OBJ QUEUE FOR DUP OBJS
MOVE S1,NETSTS(AP) ;PICK UP THE NODE'S STATUS BITS
TXZE S1,NETADD ;IF IT WAS JUST ADDED,,GEN THE NODE NAME
$TEXT (<-1,,NETASC(AP)>,<^N/NETCOL(AP)/^0>) ;GEN THE NAME
TXNN S1,NETONL ;IS IT WAS OFFLINE,,THEN TELL THE OPR
$WTO (< Network Node ^T/NETASC(AP)/ is Online >,,,$WTFLG(WT.SJI))
TXO S1,NETNSV+NETONL ;ADD VALID STATUS+ONLINE
MOVEM S1,NETSTS(AP) ;SAVE IT
JRST INTR.2 ;AND GO GET ANOTHER NODE
;NOW DO SOME PROCESSING FOR THE OFF-LINE NODES
INTR.3: LOAD AP,.QHLNK(H),QH.PTF ;GET THE FIRST DB ENTRY
SKIPA ;SKIP THE FIRST TIME THROUGH
INTR.4: LOAD AP,.QELNK(AP),QE.PTN ;GET THE NEXT NODE DB ENTRY
JUMPE AP,.RETT ;NO MORE,,WE ARE FINALLY DONE
MOVE S1,NETSTS(AP) ;GET THIS NODES STATUS BITS
TXC S1,NETONL ;FLIP THE ONLINE BIT
TXNE S1,NETNSV+NETONL+NETIBM;MUST BE STATUS INVALID+ONLINE+NOT IBM
JRST INTR.4 ;NO,,GET THE NEXT ENTRY
MOVX S1,NETONL ;GET THE ONLINE BIT
ANDCAM S1,NETSTS(AP) ;TURN IT OFF (MAKE IT OFFLINE)
$WTO (< Network Node ^T/NETASC(AP)/ is Offline >,,,$WTFLG(WT.SJI))
MOVE S1,NETCOL(AP) ;GET THE NODE NAME/NUMBER
MOVEM S1,NWAMSG+.OHDRS+ARG.DA+OBJ.ND ;SAVE THE NODE NAME/NUMBER
PUSH P,AP ;SAVE THIS ADDR SINCE IT GETS TRASHED
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
;LOOP THROUGH THE OBJECT QUEUE LOOKING FOR OBJECTS STARTED AND
;SETUP FOR THE NODE WHICH WENT DOWN
LOAD P1,HDROBJ##+.QHLNK,QH.PTF ;GET THE FIRST ENTRY
SKIPA ;SKIP THE FIRST TIME THROUGH
INTR.5: LOAD P1,.QELNK(P1),QE.PTN ;POINT TO THE NEXT OBJECT
MOVE S1,NWAMSG+.OHDRS+ARG.DA+OBJ.ND ;RESTORE THE NODE NAME/NUMBER
JUMPE P1,INTR.6 ;NO MORE,,FINISH UP
CAME S1,OBJNOD(P1) ;IS THIS A REMOTE OBJECT ???
JRST INTR.5 ;NO,,SKIP THIS
LOAD S1,OBJSCH(P1) ;GET THE SCHEDULING BITS
TXC S1,OBSSTA+OBSSUP ;MUST BE STARTED+SETUP !!!
TXNE S1,OBSSTA+OBSSUP ;IS IT ???
JRST INTR.5 ;NO,,SKIP THIS
HRLI S1,OBJTYP(P1) ;GET THE SOURCE OBJECT ADDRESS
HRRI S1,NWAMSG+.OHDRS+ARG.DA+OBJ.TY ;GET THE DESTINATION ADDRESS
BLT S1,NWAMSG+.OHDRS+ARG.DA+OBJ.SZ-1 ;COPY IT OVER
MOVE S1,OBJPID(P1) ;GET THE PID TO SEND TO.
MOVEM S1,MSGPDB+.IPCFR ;SAVE AS THE RECIEVERS PID
MOVEI AP,MSGPDB ;GET THE PDB ADDRESS
PUSHJ P,C$SEND## ;SEND THE MESSAGE OFF
JRST INTR.5 ;AND GO SEE IF THERE ARE ANY MORE
INTR.6: POP P,AP ;RESTORE AP
PUSHJ P,SNDORN ;SEND THE MESSAGE OFF TO ORION
JRST INTR.4 ;AND GO CHECK THE NEXT NODE
SUBTTL N$NODE - ROUTINE TO VERIFY THAT THE NODE IS ONLINE.
;CALL: S1/A SIXBIT NODE NAME OR A NODE NUMBER
;
;RET: TRUE IF ONLINE, FALSE IF OFFLINE.
; S1/ THE NODE NBR(-10), NODE NAME(-20)
; S2/ THE ENTRY ADDRESS
N$NODE: $SAVE AP ;SAVE AP FOR A MINUTE
LOAD AP,HDRNET##+.QHLNK,QH.PTF ;GET THE FIRST LINK
NODE.1: JUMPE AP,NODE.2 ;NONE THERE,,ADD IT TO THE LIST.
CAME S1,NETNBR(AP) ;DO WE MATCH AS A NUMBER ???
CAMN S1,NETNAM(AP) ;OR DO WE MATCH AS NAMES ???
JRST NODE.3 ;YES TO EITHER,,CONTINUE ON.
LOAD AP,.QELNK(AP),QE.PTN ;GET THE POINTER TO THE NEXT NODE.
JRST NODE.1 ;AND TRY IT.
NODE.2: PUSHJ P,N$ANET ;ADD THIS NODE TO THE DATA BASE
NODE.3: MOVE S1,NETCOL(AP) ;GET THE NODE ID IN S1
MOVE S2,AP ;GET THE ENTRY ADDRESS
MOVE AP,NETSTS(AP) ;GET THE STATUS BITS
TXNE AP,NETONL ;IS IT ONLINE ???
$RETT ;ONLINE !!
$RETF ;OFFLINE !!!
SUBTTL N$ANET - ROUTINE TO ADD A NODE TO THE DATA BASE.
;CALL: S1/ THE NODE NAME OR NUMBER TO ADD
;
;RET: TRUE ALWAYS
N$ANET: $SAVE H ;ALSO H
MOVEI H,HDRNET## ;GET OUR HEADER ADDRESS
PUSH P,S1 ;SAVE S1 FOR A MINUTE
PUSHJ P,M$GFRE## ;GET A FREE CELL
POP P,S1 ;RESTORE S1.
MOVEM S1,NETNAM(AP) ;SAVE THE NODE NAME
MOVEM S1,NETNBR(AP) ;SAVE THE NODE NUMBER
$TEXT (<-1,,NETASC(AP)>,<^N/NETCOL(AP)/^0>) ;GEN THE NAME STRING
PUSHJ P,M$ELNK## ;LINK IT IN AT THE END
$RETT ;AND RETURN
SUBTTL N$NRTE - ROUTINE TO PERFORM NETWORK ROUTING
;CALL: S1/SOURCE NODE NAME OR NUMBER
; S2/DESTINATION NAME OR NUMBER
;
;RET: TRUE ALWAYS
N$NRTE: PUSHJ P,.SAVE2 ;SAVE P1, P2
DMOVE P1,S1 ;SAVE SOURCE, DESTINATION NODES
PUSHJ P,N$NODE ;FIND THE SOURCE NODE
MOVEM P2,NETRTE(S2) ;ROUTE SOURCE TO DESTINATION
MOVE S1,P2 ;GET THE DESTINATION NODE
MOVE P2,S2 ;SAVE THE SOURCE ENTRY ADDRESS
PUSHJ P,N$NODE ;FIND THE DESTINATION
$ACK (<Node ^T/NETASC(P2)/ Routed to ^T/NETASC(S2)/>,,,.MSCOD(M))
CAMN S2,P2 ;IS THE NODE THE SAME ???
SETZM NETRTE(S2) ;YES,,RESET IT TO ZERO
$RETT ;RETURN
SUBTTL N$CSTN - ROUTINE TO PERFORM STARTION RE-ROUTING
;CALL: S1/NODE WE WANT TO CHECK
;
;RET: S1/THE NODE NBR(-10), THE NODE NAME(-20)
; S2/THE ENTRY ADDRESS
N$CSTN: PUSHJ P,N$NODE ;FIND THE NODE
SKIPN NETRTE(S2) ;GET ITS ROUTING NODE
$RETT ;NONE THERE,,RETURN
MOVE S1,NETRTE(S2) ;GET THE NODE ITS ROUTED TO.
PUSHJ P,N$NODE ;FIND IT.....
$RETT ;AND RETURN
SUBTTL N$LOCL - ROUTINE TO VERIFY THAT A NODE NAME/NUMBER IS LOCAL
;CALL: S1/NODE NAME or NODE NUMBER
;
;RET: TRUE if S1 contains a local node name or number
; FALSE if s1 is not local
N$LOCL: CAME S1,G$LNAM## ;IS IT THE LOCAL NODE NAME ???
CAMN S1,G$LNBR## ;OR IS IT THE LOCAL NODE NUMBER ???
$RETT ;YES TO EITHER,,RETURN TRUE
$RETF ;ELSE RETURN FALSE
SUBTTL N$MTCH - SEE IF 2 REMOTE STATION ID'S ARE EQUIVALENT
;CALL: S1/ First node name/number
; S2/ Second node name/number
;
;RET: True if they match
; False otherwise
N$MTCH: CAMN S1,S2 ;YOU NEVER KNOW,,WE MIGHT GET LUCKY !!
$RETT ;THEY'RE EQUAL,,WE WIN BIG !!!
PUSH P,S2 ;SAVE THIS NODE NAME FOR A MINUTE
PUSHJ P,N$NODE ;FIND THE FIRST NAME IN OUR DATA BASE
POP P,S1 ;RESTORE SECOND NODE NAME TO S1
CAME S1,NETNAM(S2) ;S2 POINTS TO FIRST NAME'S DB ENTRY
CAMN S1,NETNBR(S2) ;DO WE MATCH EITHER THE NODE NAME
$RETT ;OR THE NODE NUMBER .. IF SO WE WIN !!
$RETF ;ELSE NO MATCH .
SUBTTL N$NONL / N$NOFF - IBM ONLINE/OFFLINE PROCESSING ROUTINES
;CALL: S1/ The Node DB Entry Address
; S2/ The Object Block Address
;
;RET: True Always
N$NONL: TDZA TF,TF ;INDICATE 'ONLINE' ENTRY POINT
N$NOFF: MOVEI TF,1 ;INDICATE 'OFFLINE' ENTRY POINT
MOVE S2,OBJTYP(S2) ;GET THE OBJECT TYPE
CAXE S2,.OTRDR ;IS IT THE CARD READER
CAXN S2,.OTBAT ; OR IS IT THE EMULATION SPOOLER ???
SKIPA ;YES,,CONTINUE
$RETT ;NO,,RETURN NOW
MOVE S2,TF ;SAVE THE ENTRY POINT INDICATOR
MOVX TF,NETONL ;GET THE NODE ONLINE BIT
JUMPN S2,NOFF.1 ;OFFLINE,,GO PROCESS IT
;Here if we are Online
TDNE TF,NETSTS(S1) ;ARE WE ONLINE ALREADY ???
$RETT ;YES,,JUST RETURN
IORM TF,NETSTS(S1) ;NO,,LITE THE NODE ONLINE BIT
JRST NOFF.2 ;MEET AT THE PASS
;Here if we are Offline
NOFF.1: TDNN TF,NETSTS(S1) ;ARE WE ALREADY OFFLINE ???
$RETT ;YES,,JUST RETURN
ANDCAM TF,NETSTS(S1) ;NO,,CLEAR NODE ONLINE BIT
;Here we tell the OPR whats happening and tell ORION also.
NOFF.2: $WTO(< Network Node ^T/NETASC(S1)/ is ^T/@ONOFF(S2)/>,,,<$WTFLG(WT.SJI)>)
LOAD TF,NETSTS(S1),NT.MOD ;GET THE NODES MODE OF OPERATION
CAXE TF,DF.TRM ;IS IT TERMINATION ???
$RETT ;NO,,JUST RETURN
MOVE TF,NETPTL(S1) ;YES,,GET THE NODES PORT,,LINE NUMBER
MOVEM TF,NWAMSG+.OFLAG ;SAVE IT IN THE MESSAGE
MOVX TF,%ONLINE ;DEFAULT TO NODE ONLINE
SKIPN S2 ;UNLESS ITS OFFLINE
MOVEM TF,NWAMSG+.MSFLG ;ONLINE,,LITE THE NODE ONLINE BIT
MOVE TF,NETCOL(S1) ;GET THE NODES NAME/NUMBER
MOVEM TF,NWAMSG+.OHDRS+ARG.DA+OBJ.ND ;SAVE IT IN THE MESSAGE
PUSHJ P,SNDORN ;SEND THE MSG OFF TO ORION
SETZM NWAMSG+.MSFLG ;DONE,,CLEAR THE FLAG WORD
SETZM NWAMSG+.OFLAG ; AND THIS ONE TOO
$RETT ;RETURN
SUBTTL SNDORN - ROUTINE TO SEND A NODE WENT AWAY MSG OFF TO ORION
SNDORN: $SAVE AP ;SAVE AP ACROSS THE CALL
MOVE S1,G$OPR## ;GET ORION'S PID
MOVEM S1,MSGPDB+.IPCFR ;SAVE AS THE RECIEVERS PID
MOVX S1,.OTOPR ;GET THE OPR OBJECT TYPE
STORE S1,NWAMSG+.OHDRS+ARG.DA+OBJ.TY ;SAVE IT
SETZM NWAMSG+.OHDRS+ARG.DA+OBJ.UN ;ZAP ANY UNIT NUMBER
MOVEI AP,MSGPDB ;GET THE MESSAGE PDB ADDRESS
PUSHJ P,C$SEND## ;SEND IT OFF
$RETT ;AND RETURN
SUBTTL GET.NETWORK.TOPOLOGY - ROUTINE TO GET THE NETWORK TOPOLOGY
;CALL: PUSHJ P,GET.NETWORK.TOPOLOGY
;
;RET: S1/SIXBIT NODE NAME
; S2/NODE NUMBER OR NODE NAME IF -20
; T1/-1 IF ONLINE, 0 IF OFFLINE
; FALSE IF NO MORE NODES IN THE SYSTEM DATA BASE
GET.NETWORK.TOPOLOGY:
TOPS20 <
SKIPE S1,NETPAG ;HAVE WE READ THE TOPOLOGY YET ???
JRST GET.1 ;YES,,GET NEXT AND RETURN
PUSHJ P,M%GPAG ;GET A PAGE FOR THE DATA
MOVEM S1,NETPAG ;SAVE THE PAGE ADDRESS
MOVEI S2,776 ;GET THE BLOCK LENGTH
MOVEM S2,.NDNND(S1) ;SAVE IT IN THE DATA BLOCK
MOVX S1,.NDGNT ;GET NETWRK TOPOLOGY INFO FUNCTION
MOVE S2,NETPAG ;GET THE ARGUMENT BLOCK ADDRESS IN S2
NODE ;GET THE NETWORK TOPOLOGY
ERJMP GET.2 ;NO GOOD,,RELEASE THE PAGE & RETURN
MOVE S1,NETPAG ;GET THE DATA ADDRESS
HLRZ S2,.NDNND(S1) ;GET THE NODE COUNT
JUMPE S2,GET.2 ;NONE THERE,,RELEASE DATA PAGE & RETURN
MOVEM S2,.NDNND(S1) ;SAVE THE TOTAL COUNT
MOVEI S2,.NDBK1-1(S1) ;POINT TO THE FIRST NODE BLK POINTER
MOVEM S2,NETADR ;SAVE THE ADDRESS FOR LATER
GET.1: SOSGE .NDNND(S1) ;SUBTRACT 1 FRON NODE COUNT
JRST GET.2 ;IF NO MORE,,RELEASE THE DATA PAGE
AOS S2,NETADR ;POINT TO THE NEXT NODE BLK ADDRESS
MOVE S1,0(S2) ;GET THE POINTER TO THE NODE BLOCK
MOVE S1,.NDNAM(S1) ;GET THE BYTE PTR TO THE NODE NAME
PUSHJ P,S%SIXB ;CONVERT IT TO SIXBIT
MOVE S1,S2 ;GET THE NODE NAME IN S1
$RETT ;RETURN
GET.2: MOVE S1,NETPAG ;GET THE DATA PAGE
PUSHJ P,M%RPAG ;RELEASE IT
SETZM NETPAG ;CLEAR THE DATA PAGE FLAG
$RETF ;AND RETRUN
> ;END TOPS20 CONDITIONAL
TOPS10 <
SKIPE S1,NETPAG ;HAVE WE READ THE TOPOLOGY YET ???
JRST GET.1 ;YES,,GET NEXT AND RETURN
PUSHJ P,M%GPAG ;GET A PAGE FOR THE DATA
MOVEM S1,NETPAG ;SAVE THE PAGE ADDRESS
MOVEM S1,NETADR ;SAVE THE DATA ADDRESS
MOVEI S2,776 ;GET THE DATA BLOCK LENGTH
MOVEM S2,0(S1) ;SAVE THE NODE. PARAMETER
HRLI S1,12 ;GET THE NODE. TOPOLOGY FUNCTION
NODE. S1, ;GET THE NETWORK TOPOLOGY
JRST GET.4 ;CANT DO IT,,NO NETWORK HERE
MOVEM S1,@NETPAG ;SAVE THE NODE COUNT
MOVE S1,NETPAG ;GET THE NODE. BLOCK ADDRESS
GET.1: SOSGE 0(S1) ;COUNT DOWN THE NODE COUNT
JRST GET.4 ;NO MORE,,FINISH UP AND RETURN
AOS S2,NETADR ;BUMP DATA ARG COUNT BY 1
MOVE S2,0(S2) ;GET A NODE NUMBER
LOAD AP,HDRNET##+.QHLNK,QH.PTF ;POINT TO THE FIRST NETWORK ENTRY
SKIPA ;SKIP THE FIRST TIME THROUGH
GET.2: LOAD AP,.QELNK(AP),QE.PTN ;GET THE NEXT NETWORK ENTRY
JUMPE AP,GET.3 ;NOT THERE,,GET THE NAME
CAME S2,NETNBR(AP) ;HAVE WE FOUND IT ???
JRST GET.2 ;NO,,TRY NEXT ENTRY
MOVE S1,NETNAM(AP) ;GET THE NODE NAME
MOVE AP,NETSTS(AP) ;GET THE NETWORK STATUS
TXNE AP,NETONL ;WAS IT ALREADY ONLINE ???
$RETT ;YES,,JUST RETURN
GET.3: MOVEI S1,2 ;BLOCK LENGTH OF 2
MOVE TF,[2,,1] ;GET PARAMETER LIST (WANT NODE NAME)
NODE. TF, ;GET THE NODE NAME (GIVEN NODE NBR)
MOVE TF,S2 ;SHOULD NOT HAPPEN !!!
MOVE S1,TF ;GET THE NODE NAME IN S1
$RETT ;AND RETURN
GET.4: MOVE S1,NETPAG ;GET THE DATA PAGE ADDRESS
PUSHJ P,M%RPAG ;RELEASE THE PAGE
SETZM NETPAG ;CLEAR THE DATA PAGE FLAG
$RETF ;AND RETURN
> ;END TOPS10 CONDITIONAL
SUBTTL FINDNODE - ROUTINE TO FIND A NODE IN OUR DATA BASE
;CALL: S1/ The Sixbit Node Name
; S2/ The Node Number
;
;RET: AP/ The DB Entry Address
FINDNOD: DMOVE P1,S1 ;SAVE THE NODE NAME AND NUMBER
LOAD AP,HDRNET##+.QHLNK,QH.PTF ;GET THE FIRST ENTRY IN THE NODE DB
SKIPA ;SKIP THE FIRST TIME THROUGH
FIND.1: LOAD AP,.QELNK(AP),QE.PTN ;GET THE NEXT ENTRY IN THE DATA BASE
JUMPE AP,FIND.4 ;NOT FOUND,,ADD IT
CAME P1,NETNAM(AP) ;DO THE NAMES MATCH ???
CAMN P2,NETNBR(AP) ;OR THE NUMBERS ???
SKIPA ;YES,,CONTINUE
JRST FIND.1 ;NO,,GO CHECK THE NEXT ENTRY
MOVEM P1,NETNAM(AP) ;SAVE THE NAME
MOVEM P2,NETNBR(AP) ;SAVE THE NUMBER
PUSH P,AP ;SAVE AP FOR A MINUTE
FIND.2: LOAD AP,.QELNK(AP),QE.PTN ;GET THE NEXT ENTRY ADDRESS
JUMPE AP,FIND.3 ;NO MORE,,JUST RETURN
CAME P1,NETNAM(AP) ;DO THE NAMES MATCH ???
CAMN P2,NETNBR(AP) ;OR THE NUMBERS ???
SKIPA ;YES,,DELETE THE DUPLICATE ENTRY
JRST FIND.2 ;NO,,GO CHECK THE NEXT ENTRY
PUSHJ P,M$DLNK## ;DE-LINK THIS ENTRY
FIND.3: POP P,AP ;RESTORE THE OLD ENTRY ADDRESS
$RETT ;AND RETURN
FIND.4: PUSHJ P,M$GFRE## ;GET A FREE CELL FOR THE ENTRY
MOVEM P1,NETNAM(AP) ;SAVE THE NODE NAME
MOVEM P2,NETNBR(AP) ;SAVE THE NODE NUMBER
MOVX S1,NETADD ;GET THE ADDED BITS
MOVEM S1,NETSTS(AP) ;SET IT (AVOID THE OBJ QUEUE SEARCH)
PUSHJ P,M$ELNK## ;LINK IT IN
$RETT ;AND RETURN
SUBTTL PURGE.DUP.OBJS - ROUTINE TO PURGE DUPLICATE OBJECTS
;This routine is called because it is possible to start the same
;device at the same node using both the node name and node number.
;This works only if the node is offline, since QUASAR cannot
;validate the Node. For example, if an operator said:
;Start Pr 0/Node:MUMBLE and Start Pr 0/Node:10 and node MUMBLE
;and node 10 are the same node, then you have a problem when
;the node comes online. This routine is called when a node comes
;online and it schedules a shutdown for the duplicate node.
;CALL: AP/ Node DB Address of Node which came online
;
;RET: True Always
PURGE.D: LOAD T1,HDROBJ##+.QHLNK,QH.PTF ;GET THE FIRST OBJECT ADDRESS
SKIPA ;SKIP THE FIRST TIME THROUGH
PURG.1: LOAD T1,.QELNK(T1),QE.PTN ;GET THE NEXT OBJECT ENTRY ADDRESS
JUMPE T1,.RETT ;DONE,,COMPLETE NODE ONLINE PROCESSING
MOVE S1,OBJNOD(T1) ;GET THE OBJECTS NODE NAME/NUMBER
CAME S1,NETNAM(AP) ;LETS SEE IF WE MATCH
CAMN S1,NETNBR(AP) ;MUST TRY BOTH VALUES
SKIPA ;YES,,CONTINUE ON
JRST PURG.1 ;NO,,TRY NEXT OBJECT
MOVE S1,NETCOL(AP) ;SYSTEM'IZE THE NODE FIELD
MOVEM S1,OBJNOD(T1) ; OF THE OBJECT BLOCK
MOVX S1,OBSIGN ;GET THE IGNORE BIT
ANDCAM S1,OBJSCH(T1) ;CLEAR IT UNCONDITIONALLY
MOVE T2,T1 ;GET THE OBJECT ADDRESS
;HAVING FOUND 1 OBJECT STARTED FOR THIS NODE,,ARE THERE ANY MORE ???
PURG.2: LOAD T2,.QELNK(T2),QE.PTN ;POINT TO THE NEXT OBJECT ENTRY
JUMPE T2,PURG.1 ;NO MORE,,CONTINUE ON
MOVE S1,OBJNOD(T2) ;GET THIS OBJECTS NAME/NUMBER
CAME S1,NETNAM(AP) ;DO WE MATCH BY NAME
CAMN S1,NETNBR(AP) ;OR BY NUMBER ???
SKIPA ;YES,,CHECK REST OF BLOCK
JRST PURG.2 ;NO,,GO CHECK THE NEXT OBJECT BLOCK
;WE FOUND ANOTHER OBJECT STARTED FOR THIS NODE,,ARE THEY FOR
;THE SAME DEVICE ??? IF SO, THATS A NO-NO
MOVE S1,OBJTYP(T1) ;GET THE FIRST OBJ'S TYPE
CAME S1,OBJTYP(T2) ;DO WE MATCH ???
JRST PURG.2 ;NO,,WE'RE OK SO FAR
MOVE S1,OBJUNI(T1) ;GET THE FIRST OBJ'S UNIT
CAME S1,OBJUNI(T2) ;DO WE MATCH ???
JRST PURG.2 ;NO,,THATS OK TOO !!!
MOVE S1,T2 ;GET THE DUPLICATES ADDRESS
PUSH P,AP ;SAVE THE NODE ENTRY ADDRESS
PUSHJ P,S$SHUT## ;GO SHUT IT DOWN
POP P,AP ;RESTORE NODE ENTRY ADDRESS
$RETT ;CANT HAVE MORE THEN 2 DUPLICATE OBJECTS
;SO JUST RETURN NOW !!!
END