Trailing-Edge
-
PDP-10 Archives
-
tops10_703a_sys_ap115_bb-ju01b-bb
-
comnet.x14
There are 3 other files named comnet.x14 in the archive. Click here to see a list.
TITLE COMNET - COMMON COMMUNICATION AREA FOR NETWORKS - V265
SUBTTL D. TODD/EJW/JBS/EGF 17 JUN 86
SEARCH F,S,NETPRM,D36PAR,MACSYM
IFN FTKL10,<SEARCH DTEPRM>
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1974,1986>
;COPYRIGHT (C) 1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
XP VCOMNET,265 ;PUT VERSION NUMBER IN GLOB AND LOADER MAP
COMNET::ENTRY COMNET ;LOAD IF IN LIBRARY SEARCH MODE
;"NORMALIZE" CERTAIN MONGEN PARAMETERS.
IFNDEF M.TTDN,<M.TTDN==:0>
IFNDEF M.XTL,<M.XTL==:0>
XP M.TLTL,M.TLTL+M.TTDN ;REDEFINE FOR RSX-20F LINES
XP M.TLTL,M.TLTL+M.XTL ;REDEFINE FOR XTC LINES
IFN M.KS10,<
XP KLILIN,M.TLTL+M.RMCR ;LINE NO. FOR KS10 KLINIK
XP M.TLTL,M.TLTL+1 ;ADD ONE FOR KLINIK LINE
>
IFNDEF M.DLP,<XP M.DLP,0> ;DEFINE NUMBER OF -20F LINE PRINTERS
IFNDEF M.DCR,<XP M.DCR,0> ;DEFINE NUMBER OF -20F CARD READERS
;COUNT NUMBER OF VARIOUS TYPES OF TAPE DRIVES (FOR CONFIG INFO)
DEFINE TDMAC(X),< ;;HELPER MACRO
XP DT'X'N,M.DT'X
M.DTXN==M.DTXN+M.DT'X
>;TDMAC
ZZ=="A"
M.DTXN==0
REPEAT M.TD10,<
TDMAC(\"ZZ)
ZZ==ZZ+1
>
IFNDEF M.TM10,<XP M.TM10,0>
IFNDEF M.TC10,<XP M.TC10,0>
IFNDEF M.TX01,<XP M.TX01,0>
IFNDEF M.TM02,<XP M.TM02,0>
IFNDEF M.DX20,<XP M.DX20,0>
XP TAPN,M.TM10+M.TC10+M.TX01+M.TM02+M.DX20+M.TM78
DEFINE MTXADD(CHN)<
IFDEF M.MT'CHN,<MTXN==MTXN+M.MT'CHN>>
MTXN==0
ZZ==-1
REPEAT TAPN,<MTXADD(\<ZZ==ZZ+1>)>
;SEE IF THE USER WANTED ANY NETWORKS AT ALL.
IFN M.NET,<
IFE FTNET,<
PRINTX FTNET MUST BE ASSEMBLED AS FTNET==-1 FOR NETWORKS
M.NET==0 ;FORCE NETWORKS OFF (DON'T LOAD NETSER)
>
>;M.NET
IFE M.NET,< ;IF NO NETWORKS, FIXUP VARIOUS SYMBOL DEFS
NTLCKJ==:CPOPJ## ;IF NO NETWORKS, THEN NO INTERLOCKS
NTCHCK==:CPOPJ## ; SO JUST MAKE THE INTERLOCK MANAGEMENT
NTLERR==:CPOPJ## ; ROUTINES BE POPJS
NETSEC==:CPOPJ## ;NO ONCE/SECOND STUFF
NTDSTP==:CPOPJ## ;NO NETWORK STOP-CODES
CLRTTY==:CPOPJ## ;NO NETWORK LDB'S TO CLEAR
NTDIDA==:CPOPJ## ;NEVER TELL MSGSER THAT INPUT'S AVAILABLE
SCNMCR==:CPOPJ1## ;SCNSER WILL NOT ECHO CHARACTERS ON NETWORK LINES
NETOPR==:CPOPJ1## ;WE DON'T NEED TO WORRY ABOUT WHICH REMOTE IS OPR
FEKINT==:CPOPJ## ;NO NETSER INTERRUPT ROUTINES
NODE.S==:CPOPJ##
VTMREC==:CPOPJ## ;NO NETWORK VIRTUAL TERMINALS
VTMDSO==:CPOPJ## ; AND HENCE NO NETWORK VIRTUAL TERMINAL
VTMDSF==:CPOPJ## ; MODEM CONTROL.
VTMENQ==:CPOPJ## ; AND NO VTM QUEUE
VTMPRL==:CPOPJ## ; AND NO PTY RELEASE CODE
VTMFRE==:CPOPJ## ; AND NO FRELDB SHANANIGANS
NDBTBL==:0 ;NO NETWORK GETTABS
NDBMXL==:0
NDBSNM==:0
TSK.==:CPOPJ## ;NO TSK. UUO
KDP.==:CPOPJ## ;NO KDP. UUO
KDPONC==:CPOPJ## ;NO D8KINT
DMRONC==:CPOPJ## ;NO D8RINT
KDPLDR==:CPOPJ## ;NO KDPLDR
TSTRDX==:CPOPJ## ;NO RDX DEVICES
TSTTSK==:CPOPJ## ;NO TSK DEVICES
TSTDDP==:CPOPJ## ;NO DDP DEVICES
NETCHN==:0 ;NO NETWORK PI-CHANNELS TO TURN
NTFCHN==:0 ; ON AND OFF
BRKFEK==:CPOPJ## ;WE DON'T NEED TO CRASH FEK'S WHEN A CPU GOES DOWN
FEKCPS==:CPOPJ## ;DON'T CRASH FEKS
FEKCPW==:CPOPJ## ;DON'T RESTART FEK'S IF NO NETWORKS
NETDEV==:CPOPJ## ;NO NETWORK DEVICES
>;M.NET
;CHECK OPTIONS FOR NETWORK DEVICES THAT HAVE THEIR OWN FEATURE TESTS.
; IF DEVICE NOT LOADED, DEFINE APPROPRIATE "DUMMY" SYMBOLS TO SATISFY LINK
IFNDEF M.RPTP,<XP M.RPTP,0> ;DEFINE NO REMOTE PAPER TAPE PUNCH
IFNDEF M.RPTR,<XP M.RPTR,0> ;DEFINE NO REMOTE PAPER TAPE READER
IFNDEF M.RPLT,<XP M.RPLT,0> ;DEFINE NO REMOTE PLOTTER
;CHECK NETMCR'S PARAMETERS
IFE M.RMCR,< XP NETDIA,NOPDNC## > ;CAN'T CONNECT TTY VIA ANF
;CHECK TSKSER'S PARAMETERS
IFE FTTSK,<
IFN M.RJOB,<
IF1,<
PRINTX ? Remote tasks will not work with FTTSK = 0.
PRINTX ? Remote task code will not be loaded in this monitor.
>;IF1
>;M.RJOB
XP M.RJOB,0 ;REMOVE REMOTE PROCESSES
>;FTTSK
;DEFINE DUMMY SYMBOLS FOR TSKSER
IFE M.RJOB,<
TSK.==:CPOPJ## ;TSK. UUO WILL GIVE "TSKSER NOT LOADED" ERROR
TSTTSK==:CPOPJ## ;TSTTSK NEVER FINDS A TASK
TSKSEC==:CPOPJ## ;NO ONCE/SECOND TSK PROCESSING
>
;CHECK RDXSER'S PARAMETERS
IFE FTRDX,<
IFN M.RDX,<
IF1,<
PRINTX ? Remote data entry will not work with FTRDX = 0.
PRINTX ? Remote data entry will not be included in this monitor.
>;IF1
>;M.RDX
XP M.RDX,0 ;NO REMOTE DATA ENTRY SERVICE
>;FTRDX
;DEFINE DUMMY SYMBOLS FOR RDXSER.
IFE M.RDX,<
TSTRDX==:CPOPJ## ;TSTRDX NEVER FINDS ONE
>
;CHECK DDPSER'S (I.E., NETDDP IN NETDEV) PARAMETERS
IFE FTDDP,<
IFN M.RDDP,<
IF1,<
PRINTX ? Remote DDCMP device service will not work with FTDDP = 0.
PRINTX ? Remote DDCMP device code will not be loaded in this monitor.
>;IF1
>;M.RDDP
XP M.RDDP,0 ;REMOVE REMOTE PROCESSES
>;FTDDP
;DEFINE DUMMY SYMBOLS FOR DDPSER
IFE M.RDDP,<
TSTDDP==:CPOPJ## ;TSTDDP NEVER FINDS A DDP DEVICE
IFN M.NET,<
ZAPDDP==:ZAPNE1## ;AND SO ALWAYS KILLS THEM OFF RIGHT AWAY
>;M.NET
IFN M.DECN,<
DDPDSP==:CPOPJ## ;DON'T LET DNADLL FIND US
>
>
;CHECK PARAMETERS FOR KMC/DUP-11 SYNCHRONOUS LINE UNITS
IFE FTKS10,< ;KMC/DUP CURRENTLY ONLY VALID ON KS-10'S
IFN M.KDUP,<
IF1,<
PRINTX ? KMC/DUP-11 will only work on a KS-10 processor.
PRINTX ? KMC/DUP-11 support will not be included in this monitor.
>;IF1
>;M.KDUP
IFN M.DMRN,<
IF1,<
PRINTX ? DMR11 will only work on a KS10 processor.
PRINTX ? DMR11 support will be excluded from this monitor.
>;IF1
>;M.DMRN
XP M.KDUP,0 ;FORCE KMC/DUP-11 LINES OFF
XP M.DMRN,0 ;FORCE DMR11 LINES OFF
>;FTKS10
IFE M.KDUP,< ;IF NO KMC/DUP-11'S
KDPONC==:CPOPJ## ;NO-OP THE INITIALIZATION CODE
KDP.==:CPOPJ## ;MAKE THE KDP. UUO GIVE "NOT IMPLEMENTED" RTN
KDPLDR==:CPOPJ##
KDPDSP==:CPOPJ## ;LET DNADLL FAIL
>
IFE M.DMRN,< ;IF NO DMR11 UNITS
DMRONC==:CPOPJ## ;NO-OP THE INITIALIZATION CODE
DMRDSP==:CPOPJ## ;LET DNADLL FAIL
>
IFE M.DECN,< ;IF NO DECNET,
D36INI::SETZM NUMTAB##+.GTDNT## ;ZERO DECNET GETTAB TABLE ENTRIES
SETZM NUMTAB##+.GTSJB## ;...
POPJ P, ;RETURN
DCNMOV==:CPOPJ##
DCNSEC==:CPOPJ##
DCNJIF==:CPOPJ##
DDIPPI==:CPOPJ##
DTIPPI==:CPOPJ##
KDIPPI==:CPOPJ##
DMIPPI==:CPOPJ##
NTMAN==:CPOPJ##
SCUUUO==:CPOPJ##
SCTPSI==:CPOPJ##
SCURST==:CPOPJ##
SCUPOP==:CPOPJ##
SCULGO==:CPOPJ##
RTRDSP==:CPOPJ##
DNET==:CPOPJ##
D36LIN==:CPOPJ##
NETDID==:NOPDNC## ;TTY CAN'T BE CONNECTED VIA NRT
DCNGTB==:0
DCNGTL==:0
DCNLOC==:MONORG
DCNAEB==:MONORG
DNCPYW==:S..NDL
DNLENG==:S..NDL
RTNSLS==:S..NDL
NOBDSP==:S..NDL
RTRHOM::
RTRADR::
RTRHIO::0
>
;THIS STOPCODE CALLED IF WE TRY TO CALL A DECNET ROUTINE WITH NO DECNET
IFE M.DECN,<
STOPCD .,STOP,NDL ;++ NO DECNET LOADED
>;END IFE M.DECN
IFE M.ENET,< ;DUMMIES FOR ETHERNET
ETHINI==:CPOPJ##
ETHSEC==:CPOPJ##
ETHNT.==:CPOPJ##
ENTRST==:CPOPJ##
ETHGTB==:0
ETHMXL==:0
ETHSER::!
DLLUNI::!
MOVEI T1,1 ;RETURN ERROR UNIFC% (ILLEGAL FUNCTION)
POPJ P, ;...
LLMPSI::!
ENTPSI::!
SETZ T2, ;RETURN DUMMY STATUS CODE
POPJ P, ;...
IFN M.KL10,<
KNIPCB==:0
KNICHN==:0
KNICFG==:CPOPJ##
KNIINI==:CPOPJ##
KNITIC==:CPOPJ##
KNISEC==:CPOPJ##
KNIMOF==:CPOPJ##
KNIMON==:CPOPJ##
KNIRMV==:CPOPJ##
KNIDED==:CPOPJ##
KNISVP==:CPOPJ##
KNILDR==:CPOPJ##
KNIDIA==:ECOD13## ;DIAG. UUO ERROR ILLEGAL FUNCTION
KNIRST==:CPOPJ##
KNIINT==:CPOPJ##
LLMINI==:CPOPJ##
LLMMIN==:CPOPJ##
> ;END IFN M.KL10
KNIBT.==:CPOPJ##
.LLMOP==:CPOPJ##
IFN FTNET,< ;DUMMIES FOR ANF/ETHERNET
D8EINI==:CPOPJ##
> ;END IFN FTNET
> ;END IFE M.ENET
IFE M.LATN,< ;DUMMIES FOR LAT
LATINI==:CPOPJ##
.LATOP==:CPOPJ##
NETDIL==:NOPDNC## ;TTY CAN'T BE CONNECTED VIA LAT
> ;END IFE M.LATN
;KONUSN - RETURN USER TYPE (DD.XXX) GIVEN USER NAME (SIXBIT/XXX/)
;CALL IS:
;
; MOVX T1,<NAM>
; PUSHJ P,KONUSN
; ERROR RETURN
; NORMAL RETURN
;
;WHERE <NAM> IS THE SIXBIT USER NAME (E.G., 'NOBODY', ETC.)
;
;ON ERROR RETURN, THE NAME IS UNKNOWN.
;
;ON NORMAL RETURN, T2 HAS THE USER TYPE (E.G., DD.NOB)
;
;USES T2.
KONUSN::MOVSI T2,-DTNAML ;LENGTH OF TABLE OF NAMES TO SEARCH
CAME T1,DTNAME(T2) ;NAME MATCH?
AOBJN T2,.-1 ;NO, SEARCH REST OF TABLE
JUMPG T2,CPOPJ## ;ERROR IF NO MATCH
ANDI T2,-1 ;RETURN ONLY POSITIVE USER TYPE
JRST CPOPJ1## ;SUCCESSFUL RETURN
;DTNAMES - LINE "USER"S
DEFINE X(NAM),<
IFN .-DTNAME-DD.'NAM,<
PRINTX ? DTNAME NAM entry out of order>
SIXBIT\NAM\
> ;END DEFINE X
DTNAME::X (NOBODY)
X (ANF)
X (DECNET)
X (PROGRA)
X (IBM)
DTNAML==.-DTNAME
;The buck stops here if there are no networks . . .
IFE M.NET,<
XP (NDAMXL,0)
XP (AOTMXL,0)
$LOW
NETZAP::EXP 0
STANAM::!
.GTNDA::
OBJTAB:: Z
XP (NETNDB,0)
END ;OF COMNET
>
SUBTTL ANF NETWORK STUFF
EXTERN NETSER ;FORCE LOADING OF NETSER
;VARIOUS AND SUNDRY PARAMETERS
;ANF ETHERNET PROTOCOL AND MULTICAST ADDRESS
;
; Note: The ANF Ethernet driver (D8EINT) will be loaded if and only if
; the symbol ANFNIP is explicitly defined (e.g., via MONGEN).
IF2,<
IFNDEF ANFNIP,< ;IF ANF ETHERNET SERVICE TO BE SUPPRESSED,
ANFNIP==:0 ;NULL ANF ETHERNET PROTOCOL
D8EINI==:CPOPJ## ;NULL D8EINT SERVICE (SYSINI DUMMY)
> ;END IFNDEF ANFNIP
IFNDEF ANFNIM,<ANFNIM==:<<ANFNIP>B15>> ;DEFAULT MULTICAST ADDRESS
> ;IF2
;MAXIMUM MESSAGE SIZE TO BE SEEN FROM THE NETWORK
ND MSGMAX,^D512 ;WHAT IT USED TO BE IN TERMS OF PCBLMX
INTERN MSGMAX ;MAKE IT GLOBAL (I.E., MONGENABLE)
MSGMAW==:<MSGMAX+3>_-2 ;MAX MESSAGE SIZE MOD -10 WORD SIZE
IFN FTENET,< ;IF ETHERNET SUPPORTED
IFG M.ENET,< ;AND IT IS LOADED
MSGMAW==:MSGMAW+2 ;ALLOW FOR 2-BYTE COUNT + 4-BYTE CRC
>> ;END IFG M.ENET + IFN FTENET
MSGMAD==:MSGMAX-20 ;MAX MESSAGE SIZE (DISCOUNTING NCL OVERHEAD)
; E.G., FOR DATA MESSAGES THIS IS HOW MUCH
; DATA CAN BE FIT IN A SINGLE MESSAGE
;MAXIMUM SIZE THE -10 WILL KNOWINGLY TRANSMIT
ND MSGXMX,MSGMAX ;MAKE AS BIG AS POSSIBLE
INTERN MSGXMX ;MAKE IT GLOBAL (I.E., MONGENABLE)
MSGXMW==:<MSGXMX+3>_-2 ;MAX TRANSMITTABLE MOD -10 WORD SIZE
IFG MSGXMX-MSGMAX,<
PRINTX ? MSGXMX greater than MSGMAX!
MSGXMX==:MSGMAX ;LIMIT MAXIMUM TRANSMITTABLE
>
IFN FTCMSR,<
IFL NETLNH-<^D36-^L<MSGMAX>>+1,<
PRINTX % NETLNH too small for MSGMAX
PRINTX % Network message length histogram table won't be accurate
>>
IFN M.KDUP,<
IFG MSGMAX-<4*KDLMMS>,<
PRINTX ? KDLMMS too small, incoming KMC/DUP messages won't fit!
>>
IFN M.DMRN,<
IFG MSGMAX-<4*DMRMMS>,<
PRINTX ? DMRMMS too small, incoming DMR messages won't fit!
>>
;ALLOCATION "GRANULARITY" (POWER OF TWO; USED FOR LSH'S)
ND MSGAGN,^D03 ;ALLOCATE BY 8-WORD BLOCKS
INTERN MSGAGN ;MAKE IT GLOBAL (I.E., MONGENABLE)
MSGAGW==:<1_MSGAGN> ;ALLOCATION GRANULARITY BY WORDS
MSGALN==:<MSGMAW+MSGAGW-1>_-MSGAGN ;ALLOCATION TABLE LENGTHS
;MAXIMUM NUMBER OF DATA-REQUESTS THAT MAY BE SENT (FOR INPUT DEVICES ONLY)
IFNDEF MAXODR,<MAXODR==:6> ;6 SEEMS LIKE ENOUGH...
;SIZE OF A "TERMINAL PCB" MUST BE A POWER OF 2, AND .LE. ^D32
IFNDEF NTTPLN,<NTTPLN==:^D32> ;SIZE OF A TERMINAL PCB
COMMENT @
PCBMRK and PCBCHK
These routines are used to manage the transfer of PCB's to and from
Front End Kontrollers in a Multi-Cpu, or Cached environment. The protocol
for using these two routines is as follows.
PCBMRK This routine should be called after the PCB is altered by
the -10. In a cached environment, it stores the Cache Sweep
Serial number so that PCBCHK can tell if cache needs to be
swept at a later date. On a non-cached, or multi-cpu machine
(free core is not cached on a SMP system) this routine is a
no-op.
PCBCHK This routine should be called with J := FEK address, and
U := PCB address. It should be immediatly before either
"FEKRDD" or "FEKWRT" is executed. If it skips, then that
implies that the FEK may access the data. If it does not
skip, then either the FEK is on the wrong CPU, or the data
is still in cache, and may not be accessed by the FEK.
@
IFN FTKL10,< ;THINGS ARE MESSY FOR KL'S
PCBMRK::CONSO APR,LP.CSB+LP.CSD ;IF THE CACHE IS ALREADY SWEEPING (BUSY)
TDZA T1,T1 ; THEN IT MAY HAVE MISSED SOME OF THE PCB
MOVEI T1,1 ; IF SO, ADD ONE TO THE SWEEP SERIAL NUMBER
ADD T1,.CPCSN## ;GET SWEEP SERIAL NUMBER (MAYBE PLUS ONE)
MOVEM T1,PCBCSN(U) ;SAVE IT FOR PCBCHK TO LOOK AT
POPJ P, ;EXIT WITH THE PCB MARKED
PCBCHK::
IFG <M.CPU-1>,< ;IF SINGLE, THEN FREECORE ALWAYS CASHED
PCBCK1: PUSHJ P,MLSCSH## ;SEE IF FRECOR IS CACHED
POPJ P, ; RETURN NOW. (NO SWEEP PROBLEMS)
>;END <M.CPU-1> ;END OF SMP ONLY CHECKS
MOVE T1,.CPCSN## ;GET THE CURRENT CSSN
CAMG T1,PCBCSN(U) ; SEE IF WE'VE SWEPT SINCE LAST ACCESS TO PCB
PUSHJ P,CSDMP## ;IF NOT, SWEEP NOW. (TOO SLOW TO WAIT)
POPJ P, ;WE'VE SWEPT, GIVE GOOD RETURN
>;END FTKL10
SUBTTL BRKFEK -- CRASH FEK'S WHEN OWNING CPU GOES DOWN
IFN M.CPU-1,< ;ONLY ASSEMBLE IF MORE THAN 1 CPU
;BRKFEK ROUTINE CALLED FROM CPNSER WHEN A CPU HAS CRASHED. THIS
; ROUTINE TELLS NETSER WHICH FRONT ENDS HAVE BECOME INACCESSABLE DUE
; TO THE CPU GOING DOWN
;CALL T1 := POINTER TO THE CDB OF THE CRASHED CPU.
;PRESERVES ALL ACS.
BRKFEK::PUSHJ P,SAVT## ;PRESERVE THE T'S
MOVSI T2,FK.CPD ;FLAG THAT SAYS "THIS FEK'S CPU DIED"
SKIPA T3,[FEKFST##] ;GET ADDRESS OF THE FIRST FEK.
BRKFE1: HRRZ T3,FEKBLK(T3) ;GET THE ADDRESS OF THE NEXT FEK.
JUMPE T3,CPOPJ## ;ZERO ADDRESS MEANS WEVE DONE THEM ALL
HLRE T4,FEKUNI(T3) ;GET THE CPU NUMBER OF THIS FEKS CPU
CAME T4,.CPCPN##-.CPCDB##(T1) ;SEE IF THIS IS THE CPU THAT DIED
JRST BRKFE1 ;NO
AOS .CPNBI##-.CPCDB##(T1) ;COUNT THE BROKEN INTERLOCK
IORM T2,FEKBLK(T3) ;IF ON JUST-DEAD CPU, SET BIT FOR 1/SECOND
JRST BRKFE1 ;GO CHECK THE NEXT FEK.
>
IFLE M.CPU-1,<BRKFEK==:CPOPJ##> ;NOT NECESSARY ON SINGLE CPU SYSTEMS
SUBTTL FEKCPS / FEKCPW - FEK ROUTINES FOR SYSTEM SLEEP
;FEKCPS ROUTINE TO CALL ALL FEK'S ON THIS CPU ON THEIR FF.CPS ENTRY
;CALL PUSHJ P,FEKCPS
;RETURN CPOPJ ;CLOBBERS NO REGISTERS
FEKCPS::PUSHJ P,SAVE1## ;SAVE P1
MOVEI P1,FF.CPS ;GET THE "CPU SLEEP" BIT
JRST FEKCPC ; AND GO TO COMMON CODE TO CALL THE FEKS
;FEKCPW ROUTINE TO CALL ALL FEK'S ON THEIR FF.CPW ENTRY
;CALL PUSHJ P,FEKCPW
;RETURN CPOPJ ;CLOBBERS NO REGISTERS
FEKCPW::PUSHJ P,SAVE1## ;SAVE P1
MOVEI P1,FF.CPW ;GET THE "CPU WAKING UP" FUNCTION CODE
; PJRST FEKCPC ;GO TO COMMON CODE
;CODE TO CALL ALL FEKS ON THIS CPU WITH THE FUNCTION CODE IN "P1"
FEKCPC: PUSHJ P,SAVT## ;SAVE ALL THE TEMPS (FOR SPRINI)
PUSH P,U ; AS WELL AS
PUSH P,F ; SUNDRY OTHER
PUSH P,W ; REGISTERS
PUSH P,J ; ..
MOVEI J,FEKFST## ;START WITH THE FIRST FEK
JUMPE J,FEKCP2 ; IF NONE AT ALL, WE'RE DONE
FEKCP1: MOVE T1,P1 ;GET THE FUNCTION CODE
IFN FTMP,<
HLRZ T2,FEKUNI(J) ;GET THE CPU THIS FEK IS ON
CAMN T2,.CPCPN## ; AND IF WE ARE ON THE RIGHT ONE.
>
XCT FEKDSP(J) ;CALL THE FEK
HRRZ J,FEKBLK(J) ;GET THE NEXT FEK
JUMPN J,FEKCP1 ; AND CALL HIM TOO.
FEKCP2: POP P,J ;RESTORE ALL
POP P,W ; THESE REGISTERS
JRST FUPOPJ## ;AND WE'RE DONE
SUBTTL NETDDB DISPATCH TABLE
JSP T4,DSPOBJ ;(-5) ON LINE CHECK
POPJ P,0 ;(-4) DEVOP. UUO
JSP T4,DSPOBJ ;(-3) RETURN BUFFER SIZE
POPJ P, ;(-2) DEVICE INITIALIZATION
JSP T4,DSPOBJ ;(-1) HUNG DEVICE
NETDSP::JSP T4,DSPOBJ ;(0) RELEASE DEVICE
JSP T4,DSPOBJ ;(1) CLOSE
JSP T4,DSPOBJ ;(2) OUTPUT
JSP T4,DSPOBJ ;(3) INPUT
JSP T4,DSPOBJ ;(4) ENTER
JSP T4,DSPOBJ ;(5) LOOKUP
JSP T4,DSPOBJ ;(6) DUMP MODE OUTPUT
JSP T4,DSPOBJ ;(7) DUMP MODE INPUT
JSP T4,DSPOBJ ;(10) USETO
JSP T4,DSPOBJ ;(11) USETI
JSP T4,DSPOBJ ;(12) UGETF UUO
JSP T4,DSPOBJ ;(13) RENAME UUO
JSP T4,DSPOBJ ;(14) CLOSE INPUT
JSP T4,DSPOBJ ;(15) UTPCLR UUO
JSP T4,DSPOBJ ;(16) MTAPE UUO
;DISPATCH ON THE OBJECT TYPE
DSPOBJ: SUBI T4,NETDSP+1 ;RELOCATE THE ENTRY
HRRES T4 ;MAKE IT A FULL WORD NUMBER
MOVSI T1,DVCNET ;GET THE NETWORK DEVICE BIT
TDNN T1,DEVCHR(F) ;IS THIS A NETWORK DEVICE?
STOPCD CPOPJ##,DEBUG,DFU,;++DEVICE UNRECOGNIZED
IFN PARANOID&P$DDB,< ;SOME CONSISTENCY CHECKING
MOVSI T1,DVLNG ;THE LONG-DISPATCH FLAG
TDNN T1,DEVMOD(F) ;CAN DEVICE HANDLE WHIZZY FUNCTIONS?
CAIG T4,DIN ;NO, WAS WHIZZY ACTION REQUESTED?
CAIA ;REASONABLE FUNCTION
PUSHJ P,NTDSTP## ;++ BAD DEVSER DISPATCH
IFN FTXMON,<
XMOVEI T1,. ;GET CURRENT PC
TLNE T1,-1 ;NETSER/NETDEV/ET AL REALLY WANT SECTION 0
PUSHJ P,NTDSTP## ;CALLED FROM NON-ZERO SECTION!
> ;IFN FTXMON
> ;IFN PARANOID&P$DDB
JUMPL T4,DSPOB1 ;DON'T INTERLOCK HUNG DEVICE CHECK ETC.
; (THEY COME IN AT LEVEL #7)
NETDBJ ;NETSER INTERLOCK FROM HERE ON..
DSPOB1: HLRZ W,DEVNET(F) ;GET THE NDT POINTER
PJRST @NDTDSP(W) ;GO TO DEVICE DEPENDENT SERVICE ROUTINE
; (NDTDSP IS @N---DP(T4))
SUBTTL NETDDB PROTOTYPE DEVICE DATA BLOCK FOR NETWORKS
DEFINE X(OFFSET,EXPR)< ;MACRO TO SET SELECTED LOCATIONS IN THE BLOCK
RELOC NETDDB+OFFSET ;GO TO THE RIGHT WORD
EXPR ;ASSEMBLE IN THE EXPRESSION
>
$LOW
NETDDB::
X DEVCHR,<XWD <6*HUNGST>+DVC2IO,0>
X DEVSER,<XWD 0,NETDSP> ;DEFINE NETWORK DISPATCH VECTOR
X DEVSTA,<XWD DEPLEN,DEPEVM> ;VARIABLE LENGTH BUFFERS, NO EVM
X DEVCPU,<EXP 707B8> ;SET DEYPCL SO WILL RUN ON ANY CPU.
X NETLEN,0 ;RESERVE ENOUGH SPACE FOR ENTIRE DDB
PURGE X ;FLUSH THE MACRO
$HIGH
SUBTTL NETNDB -- PROTOTYPE NODE DATA BLOCK
DEFINE X(OFFSET,EXPR)< ;MACRO TO SET SELECTED LOCATIONS IN THE BLOCK
RELOC NETNDB+OFFSET ;GO TO THE RIGHT WORD
EXPR ;ASSEMBLE IN THE EXPRESSION
>
$LOW
NETNDB::
X NDBNNM,<XWD OURNNM,0> ;SET OUR NODE-NUMBER
X NDBSID,<XWD SYSDAT##,CONFIG##> ;CREATION DATE,LONG-NAME
X NDBSNM,<XWD STANAM,0> ;6 CHAR STATION NAME
X NDBFLG,<XWD NDB.UP,0> ;MAKE SURE WE DON'T TRY A STARTUP SEQ
X NDBFEK,<XWD 0,NL0FEK##> ;POINT TO OUR "NULL" FEK (CPU 0)
X NDBMOM,<EXP 10> ;MAXIMUM OF 10 OUTSTANDING MSGS
X NDBDEV,<BYTE (9)1,M.TLTL,M.CDR+M.DCR,M.LPT+M.DLP,M.PTR,M.PTP,M.PLT,MTXN,M.DTXN,M.RJOB,0,M.CDP>
X NDBSN2,<SYSNDE> ;OUR SIXBIT NODE NAME
X NDBLEN,0 ;RESERVE ENOUGH SPACE FOR THE ENTIRE NDB
PURGE X ;FLUSH THE MACRO
.GTNDA::BLOCK NODMAX+1 ;GETTAB TABLE=173 INDEXED BY NODE NUMBER
NDAMXL==:<.-.GTNDA-1>_^D9 ;LENGTH OF GETTAB TABLE
$HIGH
SUBTTL BP -- NETWORK DEPENDANT BYTE POINTERS
;BYTE POINTERS INTO NETWORK DDB'S (INDEXED BY "F")
NETRSN::EXP NT%RSN ;REASON BYTE
NETSLA::EXP NT%SLA ;SOURCE LINK ADDRESS
NETDLA::EXP NT%DLA ;DESTINATION LINK ADDRESS
NETZWD::EXP NT%ZWD ;DDB LENGTH (A LA GETZWD/GIVZWD)
NETRLN::EXP NT%RLN ;LOGICAL RECORD LENGTH ("RLN" - SEE NETPRM)
NETMML::EXP NT%MML ;MAXIMUM MESSAGE LENGTH ("MML" - SEE NETPRM)
NETDVT::EXP NT%DVT ;DEVICE ATTRIBUTE BITS ("DVT" - SEE NETPRM)
NETDVU::EXP NT%DVU ;DEVICE "UNIT" TYPE ("DVU" - SEE NETPRM)
NETDVV::EXP NT%DVV ;DEVICE "CONTROLLER" TYPE ("DVV" - SEE NETPRM)
;BYTE POINTERS INTO PCB'S. INDEXED BY "U"
PCBPCV::EXP PC%PCV ;CONVERSION TYPE
PCBMSN::EXP PC%MSN ;MESSAGE NUMBER
;BYTE POINTERS INTO NDB'S (GETTAB TABLE .GTNDB==161)
NDBTBL::EXP NDBLEN ;(00) LENGTH OF NDB
EXP NB%NXT ;(01) ADDRESS OF NEXT NDB
EXP NB%NNM ;(02) NODE NUMBER
EXP NB%SNM ;(03) ADDRESS OF STATION NAME
NDBTIM::EXP NB%TIM ;(04) TIMER.
EXP NB%NGH ;(05) FIRST NEIGHBOR ENTRY
EXP NB%NGL ;(06) LAST NEIGHBOR ENTRY
EXP NB%NGN ;(07) NODE NUMBER FROM NB%NGH
EXP NB%OPR ;(10) ADDRESS OF OPR LDB
EXP NB%CTJ ;(11) JOB NUMBER OF STATION CTL
; OUTPUT MESSAGE NUMBERS
NDBLAR::EXP NB%LAR ;(12) LAST ACK RECEIVED
NDBLAP::EXP NB%LAP ;(13) LAST OUTPUT MESSAGE# ACK'ED
NDBLMS::EXP NB%LMS ;(14) LAST MESSAGE SENT
NDBLMA::EXP NB%LMA ;(15) LAST MESSAGE NUMBER ASSIGNED
NDBLAS::EXP NB%LAS ;(16) LAST ACK SENT
; INPUT MESSAGE NUMBERS
NDBLMR::EXP NB%LMR ;(17) LAST INPUT MESSAGE RECEIVED
NDBLMP::EXP NB%LMP ;(20) LAST MESSAGE PROCESSED
EXP NB%SDT ;(21) SYSTEM BUILD DATE ADDRESS
EXP NB%SID ;(22) SYSTEM ID ADDRESS
EXP NB%MOM ;(22) MAXIMUM OUTSTANDING MESSAGE COUNT
EXP NB%DEV ;(23) FIRST DEVICE
NDBMXL==:<.-NDBTBL-1>_^D9 ;LENGTH OF NDB POINTERS TABLE (GETTAB)
;POINTERS INTO A NETWORK DEVICE TABLE
NDTTYP::EXP ND%TYP ;-10 DEVTYP BYTE
NDTBFZ::EXP ND%BFZ ;-10 BUFFER SIZE
NDTSPL::EXP ND%SPL ;-10 SPOOL BITS
NDTDVT::EXP ND%DVT ;-11 DEVICE ATTRIBUTES
NDTOBJ::EXP ND%OBJ ;-11 DEVICE TYPE CODE
NDTDCM::EXP ND%DCM ;NETWORK DEVICE MODES
;POINTER TO THE "STATE" FIELD OF A LAT ENTRY (INDEXED BY T1)
LATSTA::LT%STA+NETLAT(T1) ;POINT TO THE "STATE" FIELD OF A LAT ENTRY
LATST2::LT%STA+NETLAT(T2) ;DITTO, INDEX BY T2
LATSP2::LT%STA+NETLAT(P2) ;DITTO, INDEX BY P2
LATPTR::LT%PTR+NETLAT(T1) ;POINT TO DDB/LDB ADDRESS
LATPT2::LT%PTR+NETLAT(T2) ;DITTO, INDEX BY T2
LATPP2::LT%PTR+NETLAT(P2) ;DITTO, INDEX BY P2
;POINTERS INTO THE KMC/DUP LINE BLOCKS
IFN M.KDUP,< ;ONLY DEFINE THESE IF KMC/DUP-11S EXIST
KDLSTA::EXP KD%STA ;THE KDL LINE STATE VARIABLE
KDLTIM::EXP KD%TIM ;THE KDL DDCMP TIMER
KDLXNK::EXP KD%XNK ;POINTER TO THE NAK CODE TO BE TRANSMITTED
KDLRMN::EXP KD%RMN ;POINTER TO THE RECEIVE MESSAGE COUNTER
KDLLMX::EXP KD%LMX ;POINTER TO LAST MESSAGE NUMBER ASSIGNED
KDLLMA::EXP KD%LMA ;POINTER TO LAST MESSAGE ACKED
KDLRPC::EXP KD%RPC ;POINTER TO THE REP COUNTER
>;M.KDUP
SUBTTL NDT -- NETWORK DEVICE TABLE DEFINITIONS
DEFINE NDT(XDEV,XIDEV,BUFSZ,CHR,DCM,DVT,SPL)<
NDT'XDEV:ZZ.==ZZ.+1
BYTE (18)<(SIXBIT /XDEV/)>,<(SIXBIT /XIDEV/)>
XWD CHR,XDEV'MOD
BYTE (10)DCM(8)OBJ.'XIDEV(2)0(16)DVT
BYTE (6)<.TY'XDEV/.TYEST>(12)BUFSZ(8)SPL(10)0
IFIW N'XDEV'CI##
IFIW @NDEV'XIDEV##(T4)
IFIW @'XDEV'NDP##(T1)
>
ZZ.==0 ;COUNT THE NDT'S
IFG M.RVTM,<EXTERNAL NETVTM>
IFLE M.RVTM,<
VTMREC::
VTMJIF::
VTMENQ::
VTMHST::
VTMDSF::
VTMDSO::
VTMPRL::
VTMFRE::
REPEAT 5,<POPJ P,>
TTYNDP::
REPEAT 5,<POPJ P,>
>
NDTTBL=:. ;START OF NDT TABLE
IFG M.RMCR,< ;IF "MONITOR COMMAND ROUTINE" SUPPORT
EXTERNAL NETMCR ;LOAD MCR DRIVER
OBJ.MC==OBJ.TT ;DUMMY "MCR" OBJECT TYPE TO MATCH NAMES
MCRMOD==0 ;NOT AVAILABLE AS I/O DEVICE
NDT(MCR,MC,23,<DVIN!DVOUT>,<DCM.AS!DCM.IM>,0,0)
>
IFG M.RVTM,< ;IF NETWORK VIRTUAL TERMINALS ('VTM'S)
EXTERNAL NETVTM ;LOAD VTM SERVICE
TTYMOD==1_A+1_AL+1_A8+1_PIMMOD+1_I ;VTM I/O MODES
NDT(TTY,TY,23,<DVIN!DVOUT>,<DCM.AS!DCM.IM>,0,0)
>
IFG M.RCDR,< ;IF CARD READER SUPPORT REQUESTED
EXTERNAL NETCDR ;LOAD CARD CODE, GET DISPATCH TABLE ADDR
CDRMOD==1_A+1_AL+1_I+1_IB+1_B ;LEGAL MODES FOR CDR'S
NDT(CDR,CD,34,<DVIN!DVCDR>,<DCM.DI>,0,.SPCDR) ;BUILD THE CDR NDT
>
IFG M.RLPT,< ;IF LINE PRINTER SUPPORT REQUESTED
EXTERNAL NETLPT ;LOAD LINE PRINTERS
LPTMOD==1_A+1_AL+1_A8+1_I ;LEGAL -10 MODES
NDT(LPT,LP,33,<DVOUT!DVLPT>,<DCM.CP!DCM.AS>,0,.SPLPT) ;BUILD THE NDT
>
IFG M.RPTR,< ;IF TAPE READERS REQUESTED
EXTERNAL NETPTR ;LOAD CODE
PTRMOD==1_B+1_AL+1_I+1_IB+1_A
NDT(PTR,PR,41,<DVIN!DVPTR>,<DCM.AS!DCM.IM>,0,.SPPTR) ;BUILD NDT
>
IFG M.RPTP,< ;IF TAPE PUNCHES REQUESTED
EXTERNAL NETPTP ;LOAD CODE
PTPMOD==1_B+1_AL+1_I+1_IB+1_A
NDT(PTP,PP,41,<DVOUT!DVPTP>,<DCM.AS!DCM.IM>,0,.SPPTP) ;BUILD NDT
>
IFG M.RPLT,< ;IF PLOTTERS REQUESTED
EXTERNAL NETPLT ;LOAD CODE
PLTMOD==1_B+1_AL+1_I+1_IB+1_A
NDT(PLT,PL,41,<DVOUT>,<DCM.AS!DCM.IM>,0,.SPPLT) ;BUILD NDT
>
IFG M.RJOB,< ;IF TASK'S REQUESTED
EXTERNAL NETTSK ;LOAD TSKSER
TSKMOD==1_B+1_I+1_IB+1_A+1_AL+1_BYTMOD
NDT(TSK,TK,101,<DVIN!DVOUT!DVLNG!DVDIR>,<DCM.AS!DCM.IM>,0,0) ;BUILD NDT
>
IFN M.RDX,< ;IF REMOTE DATA ENTRY TERMINALS REQUESTED
EXTERNAL NETRDX ;LOAD RDXSER
RDAMOD==1_BYTMOD+1_PIMMOD+1_A+1_AL
NDT(RDA,RD,101,<DVIN!DVOUT>,<DCM.AS>,0,0)
>
IFG M.RDDP,< ;IF NETWORK DDCMP DEVICE REQUESTED
EXTERNAL NETDDP ;LOAD DDCMP DEVICE SUPPORT
DDPMOD==1_BYTMOD ;LEGAL -10 MODES
NDT(DDP,DP,<<MSGMAD+3>/4>,<DVIN!DVOUT>,<DCM.IM>,0,0) ;BUILD THE NDT
>
NDTXWD::XWD -ZZ.,NDTTBL ;POINTER TO SEARCH THE NDT TABLE
SUBTTL OBJTAB -- TABLES INDEXED BY OBJECT TYPE
;NOW MAKE A TABLE INDEXED BY OBJECT TYPE. THE FORMAT OF THIS TABLE IS:
; BYTE (12)0 (6)TYPE (18)SIXBIT/NAME/
;
DEFINE X(A,B,C)< ;;MACRO CALLED BY OBJTYP
XWD C,SIXBIT / A/ ;;MAKE THE ENTRY
>
OBJTAB::OBJTYP ;MAKE DEVICE DESCRIPTORS
AOTMXL==:<.-OBJTAB-1>_^D9 ;LENGTH OF ANF-10 OBJECT TRANSLATION TABLE
;A BYTE POINTER TO THE TYPE FIELD IN OBJTAB.
XP OB%TYP,<POINT 6,0,17> ;POINT TO TYPE FIELD IN OBJTAB ENTRY
;A TABLE OF POINTERS INTO CONFIGURATION TABLE OF AN NDB.
; INDEXED BY W (THE STANDARD NDB POINTER)
DEFINE X(A,B,C)< ;;MACRO CALLED IN OBJTYP
POINT 9,NDBDEV+<B/4>(W),8+<<3&B>*9>
>
NETCNF::OBJTYP ;MAKE THE BYTE POINTERS
;A TABLE OF NDTS BASED ON OBJECT TYPE
;
;ENTRIES ARE ADDRESS OF NDT FOR THAT OBJECT TYPE, OR 0 IF NOT SUPPORTED
DEFINE X(A,B,C)< ;;MACRO CALLED BY OBJTYP
IFDEF NDT'A,<Z NDT'A> ;;ADDRESS OF NDT FOR THIS OBJECT TYPE
IFNDEF NDT'A,<Z> ;;OR 0 IF UNKNOWN/UNSUPPORTED
> ;END X MACRO
NDTTAB::OBJTYP ;MAKE NDT ADDRESSES
SUBTTL RANDOM -- RANDOM POINTERS TO VARIOUS THINGS OF INTEREST
$LOW
;LINK ADDRESS TABLE. ONE ENTRY FOR EACH NETWORK CONNECTION
XP LATLEN,M.CONN+1 ;LENGTH OF TABLE (MAXIMUM NUMBER OF CONNECTS
; PLUS ONE FOR NETDDB)
NETLAT::XWD 0,NETDDB ;POINT TO THE DDB (EXEC PROCESS)
BLOCK LATLEN-1 ;REST OF THE TABLE
;NETSER'S FREE-PCB MANAGEMENT LISTS (INDEXED BY BUFFER SIZE "MOD" MSGAGN)
NTFREC::BLOCK MSGALN+1 ;COUNT OF FREE PCB'S ON EACH FREE LIST
NTFREF::BLOCK MSGALN+1 ;POINTER TO FIRST FREE PCB ON EACH LIST
NTFREL::BLOCK MSGALN+1 ;POINTER TO LAST FREE PCB ON EACH LIST
;DECNET INTERLOCK WORDS
IFN M.DECN,<
D36LCK::-1 ;ACTUAL AOSED WORD
D36AID::-1 ;KEEPS TRACK OF WHICH CPU HAS THE INTERLOCK
D36PPC::-1 ;KEEPS TRACK OF WHERE WE GOT THE INTERLOCK
>;END IFN M.DECN
;FLAG WHICH INDICATES A CATASTROPHIC ERROR HAS OCCURED (PAR ERR,
;NXM, ETC.) USED BY ERRCON AND ZAPNET TO PREVENT WEM STOPCODES
NETZAP::EXP 0
$HIGH
;SIX CHARACTER STATION NAME
STANAM::SYSNDE
;POINTER TO REMOTE TERMINAL SECTION OF LINTAB
NETRTY::XWD -M.RMCR,NETOFS## ;AOBJN POINTER TO LINTAB ENTRYS
UNTERR::HRRZ T1,NRTUNN## ;NO SUCH NODE ERROR FROM NETSER
PJRST ERRMESS## ;TYPE IT OUT AS AN ERROR.
NODE.C::JSP T2,SAVCTX## ;SAVE CONTEXT, AND EXECUTE AS UUO
PUSHJ P,NODE.A## ;ASK ANF IF HE KNOWS ABOUT NODE.
IFN M.DECN,<
SKIPA ;NO SUCH NODE
POPJ P, ;DONE--ONLY REPORT ANF10
PUSHJ P,NODE.D ;TRY DECNET
>; END IFN M.DECN
JRST UNTERR ;ISSUE ERROR MESSAGE
POPJ P,
;KDP STUFF
;ETHERNET SUPPORT
;MONGENABLE PARAMETERS
IFNDEF %ETUPQ,<XP %ETUPQ,4> ;USER PORTAL JOB QUOTA
IFNDEF %ETBQT,<XP %ETBQT,<4,,10>> ;USER PORTAL DATAGRAM BUFFER QUOTAS
; (LH=TRANSMIT QUOTA, RH=RECEIVE QUOTA)
IFN M.ENET,<
EXTERN ETHSER ;FORCE LOADING OF ETHERNET SUPPORT MODULE
EXTERN ETHUUO ;FORCE LOADING OF ETHERNET UUO SERVICE
IFN M.KL10,<
EXTERN KNISER ;FORCE LOADING OF KLNI DEVICE SERVICE
EXTERN LLMINI ;AND KLNI MAINTENANCE PROTOCOL SERVICE
> ;END IFN M.KL10
IFE M.KL10,<
LLMPSI::!SETZ T2,
POPJ P,
> ;END IFE M.KL10
> ;END IFN M.ENET
IFN M.LATN,<
EXTERN LATINI ;FORCE LOADING OF LAT SERVICE ROUTINES
> ;END IFN M.LATN
;GENERAL DECNET STUFF
IFN M.DECN,<
IFE FTDECNET,<
PRINTX ? DECnet will not work with FTDECNet = 0.
PRINTX ? DECnet will not be included in this monitor
>
EXTERN D36INI,NTMAN,SCUUUO,SCTNSF,RTRINI,DNDINI,NSPINI,NRTINI ;FORCE LOADING DECNET
;SUPPORT FOR DECNET/CI
IFN FTCIDNET,<
EXTERN CIDLL ;FORCE LOADING OF SERVICE MODULE
>; END IFN FTCIDNET
IFE FTCIDNET,<
CINSEC::
CINDSP::
CININI::SETZ T1, ;RESOLVE GLOBAL REQUESTS
POPJ P,
>; END IFE FTCIDNET
SUBTTL DEFINITIONS -- DECNET MONGENABLE PARAMETERS
RADIX 10 ;NETWORK MANGLEMENT IS DECIMAL
ND %RTMXN,1023 ;MAXIMUM NODE NUMBER
ND %RTMX3,255 ;DEFAULT MAXIMUM NODE ADDRESS FOR ROUTER
ND %RTTM3,<15*1000> ;DEFAULT HELLO FREQUENCY TIMER
ND %RTTM4,<30*1000> ;DEFAULT NODE LISTENER TIMER
ND %RTITM,<1*60*1000> ;INITIALIZATION TIMER
ND %RTT3M,2 ;HELLO TIMER MULTIPLIER FOR NON-BROADCAST
ND %RTB3M,3 ;HELLO TIMER MULTIPLIER - BROADCAST ADJACENCIES
ND %RTCST,1 ;DEFAULT COST FOR CIRCUIT
ND %RTMXR,16 ;DEFAULT MAXIMUM NUMBER OF ROUTERS ON AN NI
ND %RTBRA,32 ;MAXIMUM NUMBER OF BROADCAST ROUTER ADJACENCIES
ND %RTBEA,64 ;MAXIMUM NUMBER OF END NODE ADJACENCIES
ND %RTCTO,<60*1000> ;ENDNODE CACHE TIMEOUT
ND %RTPRI,5 ;OUR PRIORITY TO BE THE DESIGNATED ROUTER
ND %RTMXC,100 ;MAXIMUM LINE COST
ND %RTMXH,16 ;MAXIMUM HOPS
ND %RTMXV,20 ;DEFAULT MAXIMUM VISITS
ND %RTTM1,<10*60*1000> ;DEFAULT MAXIMUM ROUTING MESSAGE INTERVAL (P-P)
ND %RTBT1,<40*1000> ;DEFAULT MAXIMUM ROUTING MESSAGE INTERVAL (NI)
ND %RTBSZ,576 ;PUBLISHED EXECUTOR DEFAULT BLOCK SIZE (BYTES)
IFNDEF %RTXPW,<DEFINE %RTXPW,<RTRPW <DECNET20>>> ;DEFAULT ROUTER PASSWORD
DEFINE RTRPW(PW),<
.ZZN==0
IRPC PW,<.ZZN==.ZZN+1>;;COUNT CHARS IN PWD
IFG .ZZN-RTRXPM,<PRINTX ?ROUTER PASSWORD TOO LONG>
.ZZW==<.ZZN>B7;; LEADING BYTE COUNT
.ZZC==1;; CHAR POSITION OF NEXT CHAR
IRPC PW,<.ZZW==.ZZW!<"PW">B<7+<.ZZC*8>>
IFE .ZZC-3,<EXP .ZZW
.ZZW==0
.ZZC==-1>
.ZZC==.ZZC+1>
IFN .ZZC,<EXP .ZZW>
PURGE .ZZN,.ZZW,.ZZC
>
RTRXPM==^D64 ;MAXIMUM NUMBER OF BYTES IN A VERIFICATION PSWD
RTRXPW::%RTXPW
BLOCK <<RTRXPM+1+3>/4>-<.-RTRXPW>;ALLOCATE FOR MAX
;THESE ARE LLINKS DEFAULT PARAMETER VALUES:
ND %NSDLY,<3*16> ;DELAY FACTOR
ND %NSWGT,10 ;DELAY WEIGHT
ND %NSINA,120 ;INACTIVITY TIMER
ND %NSRTH,10 ;RETRANSMISSION THRESHOLD
ND %NSFLR,1000 ;DELAY FLOOR
ND %NSRUF,10000 ;DELAY ROOF
ND %NSADL,2 ;ACK DELAY IN SECONDS
;THESE ARE SESSION CONTROL DEFAULT PARAMETER VALUES:
ND %SCINT,<30*1000> ;INCOMING TIMER VALUE
ND %SCOTT,<1*60*1000> ;OUTGOING TIMER VALUE
;THESE ARE THE DATA LINK LAYER DEFAULT PARAMETER VALUES:
ND %DLBSZ,576 ;DEFAULT MAXIMUM BUFFER SIZE (BYTES)
RADIX 8 ;LCG IS OCTAL
COMMENT ~
This novel is intended in guiding network managers who want to fine tune
their networks for performance. A word of caution before we start: The
parameters as currently defaulted, were what we had set during field
test. We know that in the majority of cases, these parameters work to
most DEC systems even though not with optimal performance. Modifying these
parameters can cause disaster, so understand what you are attempting
beforehand, and be conservative in modifying them. Be aware that DEC may
not agree with your settings, and will request them be set back to standard
values before debugging any problems in your network.
The critical timer in this case is the AVERAGE DELAY to a node. This is
kept by LLINKS by timestamping each data message it sends, and waiting
for the ACK to come back. When it has the ack, it has the delay for that
particular message, and it averages that delay into the average delay.
This delay time is used as a base in computing when to retransmit, and
when to decide that a link has gone sour, and as such is the single most
important timer as far as performance is concerned. Below is a description
of some parameters controlling how this delay is calculated.
%NSFLR - Changing this will probably only affect nodes which are relatively
close to this node. The desirable effect of lowering this is to
speed up recovery after a lost message, since the lost message will
be re-trasmitted much sooner. The undesirable effect is that links
will break if the delay changes much.
%NSRUF - Changing this will probably only affect problems involving congestion.
Lowering this will decrease the effect that congestion has on a link,
but will increase the number of messages sent, which can aggravate
the congestion. If congestion gets too bad, not enough messages get
through to keep the link alive, and it breaks.
%NSWGT - This affects how much a single delay will affect the average delay.
Increasing this causes the delay to change more slowly, lowering it
causes the delay to track reality more closely. Tremble before you
change this one - Lowering it can cause positive feedback in your
network with delay and retransmissions oscillating out of control,
while increasing it can cause links to be unable to adapt to changing
conditions.
%NSRTH - Retransmission threshold. This controls the number of times we
re-send a message before giving up. Increasing this will give the
other side a better chance of keeping your link alive, but can
aggravate congestion problems.
%NSDLY - Delay factor. This multiplied by the average delay to a node is
used as the retransmission timer. Note that this factor is kept in
1/16ths, so the default is 3 even though network management says
48.
The main theme throughout this novel is congestion. If congestion did not
exist, we would recommend lowering %NSFLR and %NSWGT, and increasing %NSRTH.
The term congestion, as used in this novel, indicates the situation where
some node, possibly an intermediate, possibly a destination, does not have
buffers for all the messages that he is receiving, and must discard some.
The destination does not receive these messages, the source does not receive
an ack for them, so must eventually retransmit them.
The reasons congestion can occurr are numerous; Some of the more common ones
are:
1) A node with a high speed line and a low speed line; Messages are coming
in the high speed line to be retransmitted on the low speed line faster
than the low speed line can handle. The messages pile up, and eventually
some of them are dropped.
2) A node with cross-traffic. Messages going from node A to node B through
node C have no trouble, until messages from node D going to node E also
through node C eat up buffers.
3) Many links to same node. Since flow control is managed on a per-link basis,
there is nothing to keep many links from transmitting their limit all at
the same time. If the source and destination are the same type of system,
often this isn't a problem since they both have the same limit on the number
of buffers. When they are of different type, and the source has more
buffers available than the destination, the destination cannot process them
all in time.
We cannot predict all situations in the field, but here are some suggested
scenarios, and suggestions as to ways of improving performance:
Scenario A: TOPS10 - DTE - DN20/MCB - DMR(56kb) - VAX
Continual file transfer activity, spurts of NRT (terminal)
activity. Occasional congestion loss caused by the spurts of
NRT activity (reason 3).
In this case, it could be possible to act as if congestion didn't
exist, and lower %NSFLR, %NSWGT, and %NSDLY. Since congestion is
fleeting, the retransmissions will occurr after the congestion
has gone away (the user has stopped banging away at his terminal)
and should not cause problems.
Scenario B: KL - DTE - DN20/MCB - DMR(56kb) - VAX
\ KDP(9600) - RSX
File transfer activity from KL to RSX and VAX. NRT activity, but
irrelevant. High congestion loss to RSX due to low speed line from
DN20 to RSX.
In this case, congestion is the dominant theme. The DN20's buffer
space is always going to be busy, since every time the RSX system
sends data requests (credits, permissions) the KL will be able to
fill the MCB before the MCB will have a chance to finish transmitting
a single message. Depending on the number of buffers in the MCB,
this will probably work fine until other network activity occurs.
When other network activity occurrs (such as file transfer to the
vax, or terminal activity), congestion loss will start up. In this
case, since the actual delay of messages isn't increasing, you want
to increase %NSWGT to avoid changing wildly every time a message is
retransmitted. You also want to set %NSRUF to provide an upper limit
on how high the delay can get. The danger here is setting it so low
that congestion hasn't been relieved by the time we retransmit, or
setting it so high that performance goes to zero.
Scenario C: TOPS10 - DTE - DN20/MCB - DMR(56kb) - DN20/MCB - TOPS20
File transfer activity from TOPS10 to TOPS20. Performance varies
wildly depending on load on TOPS20 system, including broken links
if the load gets too high on the TOPS20 system.
The dominant theme here is the fact that TOPS20 (5.1 and 6.0) will
vary the delay for message response. If the load is light, and the
job receiving messages is runnable, the turnaround will be fast. If
the job gets blocked or pages out, the acks will not be forthcoming
until the job unblocks and receives the messages, which can be a
long time. We have observed cases where the delay to a TOPS20 system
was less that 200 milliseconds, and suddenly a message didn't receive
an ack for over 20 seconds - Apparantley the job was paged out, and
there were other processes with higher priority running.
In this case, the only thing you can do is to protect yourself against
the delay changing drastically. We would suggest that you should limit
yourself to attempting to keep the link open and not worry about speed.
In this case, increase %NSFLR to something large, which will cause
retransmissions to take a long time, but will allow the link to survive
long periods with no activity. ALso increase %NSRTH, to increase even
further the odds of living through a drought of messages.
These scenarios provide idealized situations. Customers are likely to have
a combination of the above situations, or something else entirely, and
possibly the above mentioned controls are not enough. A situation where a
customer needs different controls over different nodes might occur, for
example. The routine in LLINKS is UPDELAY, and the location of interest
to anyone wanting to patch this is UPDLY1, where we have in T1 the new delay
to the node. At this point we are about to range check against NSPFLR and
NSPRUF, and then store it away. If you are attempting to insert some extra
site-dependant knowledge into this algorithm, this would be the place to
do it.
There are two tools supplied which should help you understand what is
happening in your network - DNSNUP/DNTATL and DCNSPY. DNSNUP will write out
to disk EVERY message that passes through ROUTER. This output can be later
be converted to readable form with DNTATL, so you can analyze where messages
got lost and possibly why. DCNSPY is a DPY tool which allows you to watch
links in real time. The fields displayed are defined in D36PAR, where the
convention is: Five character name, first two characters are the name of
the structure, last three characters are the name of the field. The structure
is found as "BEGSTR xx", and the field within is found as either "WORD xxx"
or "FIELD xxx", depending on its size.
There are a limited number of comments/detailed descriptions for the fields
available within DCNSPY with the COMMENT switch. Since these descriptions
are at least two years old, it may be possible to find a more up-to-date
or complete description in D36PAR itself.
END COMMENT ~
SUBTTL DECnet GETTAB tables
;The following table is for use with the TOPS-10 GETTAB UUO. It allows
;the user to find the address of certain DECnet queue headers.
DCNGTB::RTRCBQ## ;(%DNRCH) ROUTER CIRCUIT BLOCK QUEUE HEADER
NSPAPQ## ;(%DNNPH) NSP PORT BLOCK QUEUE HEADER
IFN FTKL10,ETDTAB## ;(%DNETH) DTESER ETD BLOCK TABLE
IFE FTKL10, EXP 0 ;(%DNETH) DTESER ETD BLOCK TABLE
NRTSJP## ;(%DNNSJ) NRTSER SJB POINTER
NRTCHP## ;(%DNNCH) NRTSER NRB (CHANNEL) TABLE PTR
NMXNDQ## ;(%DNNDQ) NMX'S NODE QUEUE BLOCK HEADER
0 ;(%DNLOC) OBSOLETE IN 7.03
0 ;(%DNPTR) OBSOLETE IN 7.03
CHBLKS## ;(%DNCHB) POINTER TO CH BLOCKS.
KONNAM## ;(%DNKON) POINTER TO KONTROLLER NAME TABLE
RTRNRV## ;(%DNNRV) POINTER TO ADDRESS OF ROUTER VECTOR
; INDEXED BY NODE NUMBER
RTROFS## ;(%DNOFS) POINTER TO ADDRESS OF OFFSET TO
; SECONDARY ROUTING VECTOR
RTRMXN## ;(%DNRMX) POINTER TO ADDRESS OF ROUTER MAXIMUM
; NODE NUMBER
RTNCST## ;(%DNCST) ADDRESS OF BYTE POINTER TO COST
RTNHOP## ;(%DNHOP) ADDRESS OF BYTE POINTER TO HOPS
RTNLCL## ;(%DNLCL) ADDRESS OF BYTE POINTER TO LOCAL BIT
RTNRCH## ;(%DNRCH) ADDRESS OF BYTE POINTER TO ACTIVE BIT
0 ;(%DNNDT) OBSOLETE IN 7.03
0 ;(%DNSMX) OBSOLETE IN 7.03
DCNACB## ;(%DNACB) ADDRESS OF DECNET ALLOCATION CONTROL BLOCK
DCNGTL==:<.-DCNGTB-1>B26;GETTAB UUO WANTS THIS RIDICULOUS FORMAT
;NODE.D - NODE COMMAND FOR DECNET.
; WE GET CALLED WHEN ANF HAS DECIDED THE NODE DOESN'T EXIST.
;CALL
; T2/ NODE NAME.
;RETURN
; JRST UNNERR## ;NO SUCH NODE IN DECNET
; SKIP RETURN ;SUCESS
NODE.D: PUSHJ P,SAVE4## ;FOR TEMP STORAGE
IFN FTXMON,<
SNCALL (NODED0,MS.HGH) ;GET DECNET INFORMATION INTO P ACS
>
IFE FTXMON,<
DNCALL NODED0
>
POPJ P, ;NO SUCH NODE, GIVE ERROR MESSAGE
MOVEI T1,[ASCIZ \DECnet \]
PUSHJ P,CONMES## ;TYPE OUT HEADER
MOVE T2,P4 ;GET DECNET NODE NAME
PUSHJ P,PRNAME## ;TYPE IT OUT IN SIXBIT
MOVEI T3,"(" ;PREFACE THE NUMBER
PUSHJ P,COMTYO## ;TYPE IT OUT
LDB T1,[POINTR(P1,RN%ARE)] ;GET NODE AREA
JUMPE T1,NODED1 ;JUMP IF NO ASSIGNED AREA NUMBER
PUSHJ P,RADX10## ;TYPE IT OUT IN DECIMAL
MOVEI T3,"." ;AREA SEPERATOR
PUSHJ P,COMTYO## ;...
NODED1: LDB T1,[POINTR(P1,RN%NOD)] ;GET NODE NUMBER
PUSHJ P,RADX10## ;TYPE IT OUT IN DECIMAL
MOVEI T1,[ASCIZ \) \] ;CLOSE NUMBER
PUSHJ P,CONMES## ;AND TYPE IT OUT
MOVSI T1,(ST%END) ;IS SYSTEM RUNNING AS AN ETHERNET ENDNODE?
TDNE T1,CNFST2## ;...
JRST [MOVEI T1,[ASCIZ \may be reachable via the designated router\]
PUSHJ P,CONMES## ;TELL HIM THE BAD NEWS
JRST NODED3] ;AND GO FINISH UP
JUMPE P2,[ ;IF NO LINE ID, UNREACHABLE
MOVEI T1,[ASCIZ \Unreachable\]
PUSHJ P,CONMES## ;TYPE IT OUT
JRST NODED3] ;JOIN COMMON CODE
LDB T1,[POINTR(P1,RN%ARE)] ;GET AREA NUMBER
CAMN T1,RTRHOM## ;IS THIS NODE IN OUR AREA?
JRST NODED2 ;YES, CONTINUE ALONG
MOVEI T1,[ASCIZ \may be reachable via the area router\]
PUSHJ P,CONMES## ;TELL HIM NODE MAY BE REACHABLE
JRST NODED3 ;AND FINISH UP
NODED2: LDB T1,[POINTR(P1,RN%NOD)] ;GET JUST NODE NUMBER
CAMN T1,RTRADR## ;IS THIS OURSELVES?
JRST NODED3 ;YES, THAT'S ALL FOLKS.
MOVEI T1,[ASCIZ \Hops:\]
PUSHJ P,CONMES## ;TYPE OUT MORE HEADERS
HLRZ T1,P3 ;GET HOPS FROM SAVED LOCATION
PUSHJ P,RADX10## ;TYPE IT OUT IN DECIMAL
MOVEI T1,[ASCIZ \ Cost:\]
PUSHJ P,CONMES## ;TYPE IT OUT
HRRZ T1,P3 ;GET COST FROM SAVED LOCATION
PUSHJ P,RADX10## ;PRINT OUT IN DECIMAL
MOVEI T1,[ASCIZ \ via \] ;MORE HEADER INFO
PUSHJ P,CONMES## ;TYPE IT OUT
LOAD T2,LIDEV,+P2 ;GET THE DEVICE TYPE
HRRZI T1,KONNAM##(T2) ;GET LOCAL POINTER TO KONTROLLER DEVICE NAME
PUSHJ P,CONMES## ;TYPE IT OUT AS AN ASCIZ STRING
MOVEI T3,"-" ;SEPERATOR
PUSHJ P,COMTYO ;TYPE OUT
LOAD T1,LIKON,+P2 ;GET THE LINE/CPU NUMBER
PUSHJ P,PRTDIG## ;TYPE IT OUT IN DECIMAL
LOAD T1,LIDEV,+P2 ;GET DEVICE TYPE AGAIN
CAIN T1,LD.ETH ;IS IT AN ETHERNET?
JRST NODED3 ;YES, WE'RE DONE
MOVEI T3,"-" ;SEPERATOR
PUSHJ P,COMTYO ;TYPE OUT THE DASH
LOAD T1,LIUNI,+P2 ;GET THE UNIT NUMBER
PUSHJ P,PRTDIG## ;TYPE IT OUT
NODED3: PUSHJ P,PCRLF## ;AND RETURN
JRST CPOPJ1##
;GET DECNET INFO. RETURNS INFO IN P ACS:
;CALL
;T2/ NODE NAME
;RETURN
;P1/ NODE NUMBER
;P2/ LINE ID (0 IF UNREACHABLE)
;P3/ HOPS,,COST
;P4/ NODE NAME
NODED0: SE1ENT ;DECNET IS SECTION 1
MOVE T1,T2 ;PUT NODE NAME WHERE SESSION CONTROL EXPECTS
PUSHJ P,SCTN2A## ;ASK SESSION CONTROL ABOUT IT
POPJ P,
MOVE P1,T1 ;SAVE NODE ADDRESS
PUSHJ P,SCTA2N## ;CONVERT IT TO A NAME
MOVE T1,['?!?!?!'] ;CAN'T HAPPEN, BUT DON'T LET IT BOTHER US
MOVE P4,T1 ;SAVE FOR LATER
MOVE T1,P1 ;GET ADDRESS AGAIN.
PUSHJ P,RTNLID## ;ASK IF REACHABLE
JRST [ SETZ P2, ;INDICATE UNREACHABLE
JRST CPOPJ1##] ;AND RETURN
MOVE P2,T1 ;SAVE LINE ID FOR LATER
LDB T1,[POINTR(P1,RN%ARE)] ;GET AREA NUMBER
CAME T1,RTRHOM## ;IS NODE IN OUR AREA?
JRST CPOPJ1## ;NO, ALL DONE, RETURN
LDB T2,[POINTR(P1,RN%NOD)] ;GET NODE NUMBER
ADD T2,RTRNRV## ;AND POINT TO THE ROUTER DATA WORD.
LDB T1,RTNHOP## ;GET HOPS TO NODE.
HRL P3,T1 ;SAVE FOR LATER USE
LDB T1,RTNCST## ;GET COST TO NODE
HRR P3,T1 ;SAVE FOR LATER USE
JRST CPOPJ1## ;AND RETURN
;D36PIN and D36PIF - Take and release the DECnet interlock.
;Call
; CX/ Return address
;Return
; With/without the interlock
;Preserves all ACs except CX
;Note - CX is a DECnet scratch AC which is hardwired to be R
CX==R
D36PIF::
CONO PI,NETPIF## ;MAKE SURE NOONE ON THIS CPU INTERRUPTS US
SKIPGE D36LCK ;GIVE OTHER CPUS A CHANCE
AOSE D36LCK ;MAKE SURE NOONE ON ANOTHER CPU GETS US
JRST .-2 ;WAIT
APRID D36AID ;RECORD WHO HAS THE INTERLOCK
MOVEM CX,D36PPC ;SAVE CALLING PC FOR TRACKING PURPOSES
JRST (CX) ;RETURN TO CALLER WITH INTERLOCK SET
D36PIN::
SETZM D36AID ;WE NO LONGER OWN THE INTERLOCK
SETOM D36LCK ;ALLOW OTHER CPU IN
CONO PI,NETPIN## ;ALLOW PENDING INTERRUPTS ON THIS CPU IN
JRST (CX) ;RETURN
PURGE CX
;STILL UNDER IFN M.DECN
;ROUTINES TO INITIALIZE LINES, AND ASK ROUTER TO INTIALIZE DECNET LINES
DEFINE DEFLIN,<
IFN FTKS10,<
DEFKS
>
IFN FTKL10,<
CPUNN=0
REPEAT M.CPU,<
IFN FTKL10,DEFKL(\CPUNN)
CPUNN==CPUNN+1
> ;END OF REPEAT M.CPU
> ;END OF IFN FTKL10
> ;END OF DEFINE DEFLIN
DEFINE DEFKL(CPU),<
DTENN==0
REPEAT M'CPU'DTEN,<
DEFDTE(CPU,\DTENN)
DTENN==DTENN+1
>
> ;END OF DEFINE DEFKL
DEFINE DEFKS,<
KDPNN==0
REPEAT M.KDUP,<
DEFKDP(\KDPNN)
KDPNN==KDPNN+1
>
DMRNN==0
REPEAT M.DMRN,<
DEFDMR(\DMRNN)
DMRNN==DMRNN+1
>
> ;END OF DEFINE DEFKS
DEFINE DEFDTE(CPU,DTENO),<
IFE M'CPU'DTENO'DTE-DT.DNT,<
HRRZ F,ETDTAB##+CPU ;;GET ETD TABLE ADDRESS FOR THIS CPU
ADDI F,DTENO ;;OFFSET TO CORRECT DTE
MOVE F,(F) ;;PICK UP ETD ADDRESS
MOVEI T1,DD.DEC ;;SET LINE USER OF DECNET
MOVEM T1,ETDUSR(F) ;;...
MOVEI T1,DI.ICB ;;FUNCTION INITIATIZE CIRCUIT BLOCK
SETZ T2, ;;NO DNADLL ID
MOVE T3,[1B0+<LD.DTE_9+CPU,,DTENO'_9+0>] ;;GET CURRENT LINE ID
SNCALL (DTIPPI##,MS.HGH) ;;TELL DNADLL ABOUT THIS LINE
JFCL ;;IGNORE ERROR
>
> ;END DEFINITION OF DEFDTE
DEFINE DEFKDP(KDPNO),<
IFE M.'KDPNO'KDP-DD.DEC,<
MOVEI T1,DC.IOC ;;FUNCTION INITIATIZE CIRCUIT BLOCK
SETZ T2, ;;NO DNADLL ID
MOVE T3,[1B0+<LD.KDP_9+0,,KDPNO_9+0>] ;;GET CURRENT LINE ID
SNCALL (KDIPPI##,MS.HGH) ;;TELL DNADLL ABOUT THIS LINE
JFCL ;;IGNORE ERROR
>
> ;END DEFINITION OF DEFKDP
DEFINE DEFDMR(DMRNO),<
IFE M.'DMRNO'DMR-DD.DEC,<
MOVEI T1,DC.IOC ;;FUNCTION INITIATIZE CIRCUIT BLOCK
SETZ T2, ;;NO DNADLL ID
MOVSI T3,(1B0+<LD.DMR_9+DMRNO,,0>) ;;GET CURRENT LINE ID
SNCALL (DMIPPI##,MS.HGH) ;;TELL DNADLL ABOUT THIS LINE
JFCL ;;IGNORE ERROR
>
> ;END DEFINITION OF DEFDMR
D36LIN::DEFLIN ;DEFAULT THE LINES WHICH HAVE TO BE
POPJ P, ;RETURN
;NOBDSP - THE "NOBODY" KONTROLLER
;
;NOBDSP SERVES BASICALLY AS A PLACE-HOLDER FOR THE VARIOUS LINE
;DRIVERS TO DISPATCH TO FOR USER "NOBODY".
NOBDSP::
NOBSTP: STOPCD CPOPJ##,DEBUG,NOB, ;++ "NOBODY" KONTROLLER DISPATCH GOT CALLED
>;END OF IFN M.DECN
XLIST ;DON'T LIST THE LITERALS
$LIT
LIST
CNTEND::END