;TITLE DNADLL - DLL use interface for DECnet-36 V016 SUBTTL Marty Palmieri 14 JAN 86 SEARCH ETHPRM,D36PAR,MACSYM SALL ENTRY DNDINI ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ;COPYRIGHT (C) 1983,1984,1986 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; XP DNADLL,016 IFN FTOPS20,< SEARCH PROLOG TTITLE DNADLL,,< - DLL interface for DECnet-36> > IFN FTOPS10,< SEARCH F,S TITLE DNADLL - DLL interface for DECnet-36 .CPYRT<1983,1986> >;END OF IFN FTOPS10 D36SYM ;SET UP D36 SPECIFIC PARAMETERS IFN FTOPS10,<$RELOC> XRESCD ;RELOC TO HIGHSEG (RSCOD PSECT ON TOPS-20) SUBTTL Table of Contents SUBTTL Definitions -- External References ;These are the external references to the D36COM library of routines. EXT DNGMSG ;GET DECNET-36 MESSAGE BLOCK EXT DNFMSG ;FREE MESSAGE BLOCK EXT DNGEMS ;GET EMERGENCY MESSAGE BLOCK EXT DNLENG ;GET MESSAGE LENGTH EXT DNGWDS ;GET SOME WORDS EXT DNGWDZ ;GET SOME ZEROED WORDS EXT DNFWDS ;FREE SOME WORDS EXT DNSWDS ;SMEAR SOME WORDS IFN FTRTST,< EXT UPDTCK ; Updated DNGTIM > EXT DNGTIM ;RETURN CURRENT UPTIME (IN MS) EXT NMXEVT ;NTMAN event processor EXT NTPARM ;Common parameter routine EXT NTCTRS ;Common counter routine ;These are the external references to D36COM data cells EXT RTRHOM ;OUR HOME AREA EXT RTRADR ;OUR NODE NUMBER EXT RTRLOO ; Low order of DECnet address (string) EXT MXLBSZ ;Maximum receive block size for a line EXT IBBLK ;DECnet-36 initialization block ;These are the external references to ROUTER EXT RTRPRO ;ROUTER'S PROTOCOL TYPE EXT RTRHIO ;HI PART OF THE NI ADDRESS EXT RTRDLE ; Entry into ROUTER from dnadll EXT RTRCOP EXT TSTBLK ;These are some default parameters EXT %RTRMA ;MULTICAST ID "ALL ROUTERS" EXT %RTEMA ;Multicast ID "All endnodes" EXT %RTEHS ;Size in bytes of Ethernet header ;Other external references EXT RTN ;NON-SKIP RETURN EXT RSKP ;SKIP RETURN SUBTTL Definitions -- Accumulators ;Internal feature tests IFN FTOPS10,< FTCI==0 ;Don't support CI20 circuits FTDDP==FTNET ;Support DDP (ANF-10) circuits FTDTE==FTKL10 ;Support DTE circuits on KL10 FTNI==FTKL10 ;Support Ethernet circuits on KL10 FTKDP==FTKS10 ;Support DMR-11 circuits on KS10 FTDMR==FTKS10 ;Support DMR-11 circuits on KS10 >; END IFN FTOPS10 IFN FTOPS20,< FTCI==-1 ;Support CI20 circuits FTDDP==0 ;Don't support DDP (ANF-10) circuits FTDTE==-1 ;Support DTE circuits FTDMR==0 ;Don't support DMR-11 circuits FTKDP==0 ;Don't support KDP-11 circuits FTNI==-1 ;Support ethernet circuits >; END IFN FTOPS20 ;These are some local AC defintions for DNADLL DL=FREE1 ;DL usually points to the data link block LN=FREE2 ;LN contains pointer to line data entry UN=MS ;UN is the NI user block PURGE FREE1 ; Lose this symbol PURGE FREE2 ; and this one ;Some local symbols NOSET==PANST ;From BEGSTR in D36PAR NOCLR==PANCL BEX==PABEX DN.NDR==1B0 ; Is not processed by specific DLL DN.NMF==1B1 ; Network management function SUBTTL Definitions -- BEGSTRs BEGSTR QB WORD NXT, ; Pointer to next request in queue HWORD FCN, ; Function requested WORD DA1, ; Function specific data WORD DA2, ; Additional data WORD DLB ; Associated data link block address ENDSTR ;Line data block structure BEGSTR LN WORD NXT ; Address of next LN block WORD LID ; Line ID WORD PID ; Line's portal id WORD FLG,0 ; Flags FIELD CAD,1 ; Channel address is DECnet (Ethernet only) FIELD STA,1 ; State of line FIELD CON,2 ; Controller (normal/loopback) FIELD PRO,6 ; Protocol type FIELD CTY,6 ; Circuit type FIELD DBF,6 ; Default number of buffers FIELD BSZ,12 ; Maximum receive buffer size on this line HWORD BNO ; Number of buffers to post HWORD NBP ; Number of buffers posted ENDSTR SUBTTL Definitions -- $BUILD, $SET, and $EOB Macros ;Following page is from GLXMAC... ; - Build pre-formed data blocks ;Many components have a need to build simple and complex blocks which ; contain pre-formatted data, such as FOBs,IBs and other blocks ; which are made up of several words, each containing from 1 to several ; fields. Since data structures change, these blocks should not be ; just created using EXP or whatever. These macros will take values ; and install them in the right field and word of a structure. ; Start off a structure, argument is the size of the structure. DEFINE $BUILD(SIZE)< IFDEF ..BSIZ, ..BSIZ==0 ;;START COUNTER ..BLOC==. ;;REMEMBER OUR STARTING ADDRESS REPEAT SIZE,< ;;FOR EACH WORD IN THE BLOCK BLD0.(\..BSIZ,0) ;;ZERO OUT IT'S ACCUMULATOR ..BSIZ==..BSIZ+1> ;;AND STEP TO NEXT >;END OF $BUILD DEFINITION ; For each value installed somewhere in the structure, set it into the block ; Arguments are word offset,field in word (optional) and value to set. DEFINE $SET(STR,VALUE,OFFSET),< IFNDEF ..BSIZ, IFNB ,< IFB ,<..STR0 (..SET,,STR)> IFNB ,<..STR0 (..SET,,STR,OFFSET)>> IFB ,< IFB ,<..STR0 (..SET,,FWMASK)> IFNB ,<..STR0 (..SET,,FWMASK,OFFSET)>> > ; END OF $SET DEFINITION DEFINE ..SET (VALUE,LOC,MSK) < IFGE <<&777777>-..BSIZ>,< PRINTX ?WORD offset greater than $BUILD size parameter> SET0. (\,MSK,) > ;END ..SET DEFINITION ; After all values are declared, the block must be closed to do its actual ; creation. DEFINE $EOB,< IFNDEF ..BSIZ, IFN <.-..BLOC>, XLIST ;;DON'T SHOW THE BLOCK ..T==0 REPEAT ..BSIZ,< BLD0.(\..T,1) ;;STORE EACH WORD ..T==..T+1 > PURGE ..BSIZ,..T,..BLOC ;;REMOVE SYMBOLS LIST >; END OF $EOB DEFINITION DEFINE BLD0.(N,WHAT),< IFE WHAT,<..T'N==0> IFN WHAT, > ;END OF BLD0. DEFINITION DEFINE SET0.(LOC,MSK,VALUE),< IFN <<..T'LOC>&MSK>, ..TVAL== ..TMSK== ..T'LOC==..T'LOC! PURGE ..TVAL,..TMSK >;END OF SET0. DEFINITION SUBTTL DNADLL - Generic data link layer -- DNDCCR - Compute Core Requirements ;DNDCCR computes DNADLL's core requirements. ;Call: ; PUSHJ P,DNDCCR ;Returns: ; T1/ Size of DNADLL core IFN FTOPS10,< DNDCCR::SETZ T1, ;NO ADDITIONAL REQUIREMENTS RET ;AND RETURN >; END IFN FTOPS10 SUBTTL DNADLL - Generic data link layer -- DNDINI - Initialization ;DNDINI - Initialize common DLL interface for Router ; ; Call: ; with nothing ; ; Return: ; RET ;Only return ; ; Uses: T1-T3 ; ;This routine gets called at system initialization. RESCD INTERNAL DNDINI DNDINI: TSTS6 TOXSWAPCD ife ftki10,< TRACE DND, >;ki10 SAVEAC LOAD T1,IBRTR,+IBBLK ; Get Router type desired MOVEM T1,DNDRNT ; Save as Router's node type ;Get and initialize an EC (Event Communication) block MOVX T1,EV.GEC ;Function code "get EC block" CALL NMXEVT IFSKP. MOVEM T1,DNDECP ;Save pointer MOVX T2,4 ;DNADLL may queue 4 event blocks STOR T2,ECMAX,(T1) ENDIF. ;Now try to initialize all of the lines MOVSI P1,-LD.MAX ; Get AOBJN pointer to INITBL table DNDIN1: CALL @INITBL(P1) ; Initialize next line type CAI ; Ignore error return AOBJN P1,DNDIN1 ; Loop back for all table entries RET INITBL: IFIW ; Test bed driver (obsolete) IFIW ; DTE line driver IFIW ; KDP line driver IFIW ; DDP (ANF-10) line driver IFIW ; CI-20 SCA line driver IFIW ; NIA-20 Ethernet line driver IFIW ; DMR-11 line driver IF1,>,> XRESCD SUBTTL DNADLL - Generic data link layer -- DNDJIF - Once a jiffy code INTERNAL DNDJIF XRENT DNDJIF SAVEAC DNDJF1: SYSPIF ; Interrupts off DEQUE P1,DNDINQ,QB.NXT,DNDNOQ ; Get a function block from the queue SYSPIN LOAD DL,QBDLB,(P1) ; DLB pointer LOAD T1,QBFCN,(P1) ; Function LOAD T2,DLUID,(DL) ; Get DNADLL users ID LOAD T3,QBDA1,(P1) ; Data for function LOAD T4,QBDA2,(P1) ; Additional data CALL RTRDLE ; Call the ROUTER TRN OPSTR , DLUID,(DL) ; Do we have a circuit block? STOR T1,DLUID,(DL) ; Then save expected circuit block MOVE T1,DNDQBL ; Get the length of the QB block queue CAIG T1,^D12 ; Is it greater than the desired IFSKP. ; maximum? MOVE T1,P1 ; Yes, the free the block CALL DNFWDS ELSE. SYSPIF ; No interrupts please MOVE T1,DNDQBQ ; No, get the queue head MOVEM T1,(P1) ; and put this one at the head MOVEM P1,DNDQBQ AOS DNDQBL ; Add it into the count SYSPIN ENDIF. JRST DNDJF1 ; Get next function block on queue DNDNOQ: SYSPIN ; Queue is now empty RET ; No more function blocks queued SUBTTL DNDALL - Generic data link layer -- DNDSEC - Once a second code RESCD INTERNAL DNDSEC DNDSEC: TSTS6 TOXRESCD SAVEAC ; Check all data link blocks SKIPA DL,DLBQUE DNDSE1: LOAD DL,DLNXT,(DL) JUMPE DL,RTN LOAD LN,DLLNB,(DL) ; Get line data block address LOAD T1,DLDID,(DL) ; Get line ID LOAD T1,LIDEV,+T1 ; Get device type MOVE T1,SECTBL(T1) ; Get dispatch address CALL (T1) ; Do devices once/second JRST DNDSE1 SECTBL: IFIW ; Test bed driver (obsolete) IFIW ; DTE line driver IFIW ; KDP line driver IFIW ; DDP (ANF-10) line driver IFIW ; CI-20 SCA line driver IFIW ; NIA-20 Ethernet line driver IFIW ; DMR-11 line driver IF1,>,> SUBTTL DNADLL - Generic data link layer -- DNDQUE - Queue once a jiffy request ;DNDQUE - Queue up interrupt level requests to scheduler level ; ; Call: ; T1 - Function to call ROUTER with (ie: DI.xxx) ; T3 - Function specific data (Usually MB address) ; T4 - Additional function specific data (usually status) ; ; CALL DNDQUE ; only return ; ; Uses T1-T4. ; DNDQUE: SAVEAC ; Get a spare AC MOVE P1,T1 ; Save function for a moment MOVE P2,T3 ; MOVE P3,T4 SYSPIF SKIPN T1,DNDQBQ ; Any free block on the QB queue? IFSKP. MOVE T2,(T1) ; Yes, then get one from it MOVEM T2,DNDQBQ SOS DNDQBL ; Account for it SYSPIN ELSE. SYSPIN MOVX T1,QB.LEN ; Get length of user NI block CALL DNGWDZ ; Try to get the words IFNSK. ; Couldn't MOVE T1,P2 ; Get address of possible message CAIE P1,DI.ODN ; Is this a function for which we CAIN P1,DI.INC ; expect a message block CALL DNFMSG ; Yes, then free it RET ; Return ENDIF. ENDIF. STOR P1,QBFCN,(T1) ; Store function STOR DL,QBDLB,(T1) ; Save DLB pointer STOR P2,QBDA1,(T1) ; Store the data STOR P3,QBDA2,(T1) SYSPIF ENDQUE T1,DNDINQ,QB.NXT,T2 ; Queue the data link block SYSPIN RET SUBTTL DNDALL - Generic data link layer -- DNDDSP - ROUTER function dispatch ;DNDDSP - Dispatch for calls to DNADLL from ROUTER ; ; Call: ; T1 - Function (DF.xxx) ; T2 - Address of DLB block ; T3 - Function specific data ; T4 - Additional function specific data ; ; Return: ; RET on error ; RETSKP on success RESCD INTERNAL DNDDSP DNDDSP: TSTS6 TOXRESCD SAVEAC SKIPE DL,T2 ; Get address of DLB block LOAD LN,DLLNB,(DL) ; and address of line data block CAXL T1,DF.OPN ; Range check the CAXLE T1,DF.MAX ; function code BUG.(CHK,DNDIRF,DNADLL,SOFT,,,< Cause: DNADLL was called with a bad function by ROUTER >,RTN) LOAD CX,DLDID,(T2) ; Get the line ID DLLDSP: LOAD CX,LIDEV,+CX ; Get the device type CAILE CX,LD.MAX ; Legal type? RET ; BUGCHK ********************************** MOVE CX,DSPTBL(CX) ; Get dispatch table address CALLRET (CX) ; Call the DLL DSPTBL: IFIW ; Test bed driver (obsolete) IFIW ; DTE line driver IFIW ; KDP line driver IFIW ; DDP (ANF-10) line driver IFIW ; CI-20 SCA line driver IFIW ; NIA-20 Ethernet line driver IFIW ; DMR-11 line driver IF1,>,> SUBTTL DNDALL - Generic data link layer -- DNDNMX - NTMAN function dispatch ;DNDNMX - Dispatch for calls to DNADLL from NTMAN ; ; Call: ; T1 - Function code (NF.xxx) ; T2 - Address of NF function block ; ; Return: ; RET on error with NTMAN error code in T1 ; RETSKP on success RESCD INTERNAL DNDNMX DNDNMX: TSTS6 TOXRESCD SAVEAC CAXL T1,NF.SET ; Range check the CAXLE T1,NF.CET ; function code BUG.(CHK,DNDINF,DNADLL,SOFT,,,< Cause: DNADLL was called with a bad frunction by NTMAN >,RTN) MOVE T1,NXFTBL(T1) ; Convert to internal function code TXZE T1,DN.NDR ; Should we process this ourselves CALLRET DNDNMF ; Yes, then do not dispatch to DLL LOAD CX,NFETY,(T2) ; Get entity type CAIE CX,.NTNOD ; Is the entity node? IFSKP. MOVEI CX,LD.ETH ; Yes, then assume Ethernet (presently the STOR CX,LIDEV,+CX ; only node entity is the NI physical address) ELSE. ; LOAD CX,NFEID,(T2) ; Get the entity ID ENDIF. CALLRET DLLDSP ; Dispatch to DLL and return NXFTBL: DN.NMF!DF.SET ;NTMAN - Set parameter DN.NMF!DF.CLR ;NTMAN - Clear parameter DN.NMF!DF.RED ;NTMAN - Read parameter DN.NMF!DF.SHC ;NTMAN - Show counters DN.NMF!DF.SZC ;NTMAN - Show and zero counters DN.NDR!DF.RET ;NTMAN - Return list (e.g. show known lines) DN.NDR!DF.A2N ;NTMAN - Map node address to name DN.NDR!DF.N2A ;NTMAN - Map node name to address DN.NDR!DF.CET ;NTMAN - Check entity IF1,>,> SUBTTL DNADLL - Generic data link layer -- DNDNMF - Network management functions ;DNDNMF - Process non DLL specific network management functions ; ; Call: ; T1 - NTMAN function code (NF.xxx) ; T2 - Address of NF block ; ; Returns: ; RET on error with NTMAN error code in T1 ; RETSKP on success XSWAPCD DNDNMF: SAVEAC MOVE P1,T2 ; Save address of NF block HRRZ T1,T1 ; Clear any flags CAIN T1,DF.CET ; Requested to check entity? JRST NMXCET ; Yes, then be NML's humble servant CAIE T1,DF.RET ; Is request for return list? RNMXER (NF.MPE) ; We only do the two we just checked TMNN NFBFF,(P1) ; Buffer present? RNMXER (NF.MPE) ; Must have one for this stuff LOAD T1,NFETY,(P1) ; Get entity type CAIE T1,.NTLIN ; Is the entity line? IFSKP. LOADE T1,NFSEL,(P1) ; Get the selector type CAXL T1,.NTSGN ; Range check the selection criteria CAXLE T1,.NTKNO ; If not between SIGNIFICANT & KNOW RNMXER (NF.MPE) ; we don't do it CALLRET <-.NTSGN>+@[ IFIW ; SIGNIFICANT lines not supported IFIW ; ADJACENT lines IFIW ; LOOP line IFIW ; ACTIVE lines IFIW ](T1) ; KNOWN lines ELSE. RNMXER (NF.FNS) ; We don't do any others ENDIF. NMXILS: RNMXER (NF.MPE) ; NTMAN is confused XRESCD SUBTTL DNADLL - Generic data link layer -- NMXSAL - Show active lines SUBTTL DNADLL - Generic data link layer -- NMXSKL - Show known lines ;NMXSAL - Called by DNDNMF to process SHOW ACTIVE LINES ;NMLSKL - Called by DNDNMF to process SHOW KNOWN LINES ; ; Call: ; P1 - Address of NF block ; ; T2 - Address of NF block ; ; Returns: ; RET on error with NTMAN error code in T1 ; RETSKP on success XSWAPCD NMXSKL: SKIPA T1,[-1] ; "Show known lines" NMXSAL: SETZ T1, ; "Show active lines" SAVEAC STKVAR MOVEM T1,FUNC SETZ P2, ; Initialize the count LOAD T2,NFBLN,(P1) ; Get length of buffer LOAD T4,NFBUF,(P1) ; Get buffer address ADD T2,T4 ; Compute end of buffer SKIPA LN,LNBQUE ; Get first line block NMXSA1: LOAD LN,LNNXT,(LN) ; Get next line block JUMPE LN,NMXSA2 ; Exit loop at end of list LOAD T1,LNSTA,(LN) ; Get line state CAIE T1,LS.ON ; Is circuit active? SKIPGE FUNC ; No, is function "known" TRNA ; Yes, include this line JRST NMXSA1 ; No, skip this line LOAD T1,LNLID,(LN) ; Get the line's ID CAML T4,T2 ; Check to be sure we don't run off end RNMXER (NF.MPE) ; NTMAN error if not enough room MOVEM T1,(T4) ; Save into buffer AOJ P2, ; Count it AOJA T4,NMXSA1 ; Advance buffer NMXSA2: STOR P2,NFBLN,(P1) ; Tell NTMAN number written RETSKP XRESCD SUBTTL DNADLL - Generic data link layer -- NMXCET - Check entity ;NMXCET - Build data link blocks and circuit blocks if needed ; ; Call: ; P1 - Address of NF block ; ; Return: ; RET ;Only return ; ; Uses: T1-T3 ; ;This routine is called by network management to cause DNADLL data link blocks ;and Router circuit blocks to be built. XSWAPCD NMXCET: LOAD T1,NFEID,(P1) ; Get entity ID TMNE LILXC,+T1 ; Is it a circuit? IFSKP. CALL DNDFDL ; (T1) No, see if we have a data link block TRNA ; No, see if we should make one RETSKP ; Got it, tell NTMAN o.k. LOAD T1,NFEID,(P1) ; Get entity ID TXO T1,LILXC ; Make this circuit entity into a line entity ENDIF. TXZ T1,LIDRP ; and clear any multi-drop numbers CALL DNDFLN ; (T1) Get the line data block for this line RNMXER (NF.URC) TMNE LILXC,+NF.EID(P1) ; Was the entity a line? RETSKP ; Yes, return success LOAD T1,NFEID,(P1) ; Entity ID CALLRET DNDCDL ; Create a DLB and tell ROUTER SUBTTL DNADLL - Generic data link layer -- DNDCDL - Create data link block ;DNDCDL - Create a data link block if needed ; ;Call: ; T1/ Circuit id ; LN/ Address of line block ; ;Returns: ; RET on error with NTMAN error code in T1 ; RETSKP on success with address of data link block in DL XRESCD DNDCDL: SAVEAC ; Save P1 MOVE P1,T1 ; Save circuit id CALL DNDFDL ; Try to find circuit in circuit block queue SKIPA ; Not there, create a new circuit block RETSKP ; Found it, return with address in DL MOVEI T1,DL.LEN ; Length of data link block CALL DNGWDZ ; (T1) Allocate space RNMXER (NF.RES) ; Error MOVE DL,T1 ; Hold on to this address STOR P1,DLDID,(DL) ; Device ID STOR LN,DLLNB,(DL) ; Line data block address LOAD T1,LNDBF,(LN) ; Get default number of buffers STOR T1,LNBNO,(LN) ; Number of buffers MOVEI T1,DI.ICB ; Ask Router to initialize a circuit block MOVE T2,DL ; Get DLB address in correct place MOVE T3,P1 ; Get circuit id LOAD T4,LNBSZ,(LN) ; Tell the maximum block size for this line CALL RTRDLE ; (T1,T2,T3,T4) Call Router now SKIPE T1 ; T1 contains Router callback ID if successful IFSKP. ; else 0 MOVE T1,DL CALL DNFWDS ; Return the block RNMXER (NF.URC) ENDIF. STOR T1,DLUID,(DL) ; Save circuit block address ENDQUE DL,DLBQUE,DL.NXT,T2 ; Queue the data link block RETSKP SUBTTL DNADLL - Generic data link layer -- DNDFDL - Find data link block ;DNDFDL - Search the queue for a Data Link Block ; ; Call: ; T1/ Line (device) ID ; ; Return: ; RET ;No Data Link Block for given ID ; RETSKP ;With DL = Data Link Block ; ; and LN = Line Block ; ; Uses: T1-T2 ; ;This routine is used for calls from Network Management XSWAPCD DNDFDL: SETZRO LILXC,+T1 ; Clear "this is a line" indicator SKIPN DL,DLBQUE ;Start looking at first data link block RET ;None there, just return DNDGL1: LOAD T2,DLDID,(DL) ;Get its' line ID CAMN T1,T2 ;Is it the one we're looking for? JRST DNDGL2 ;Yes, exit loop LOAD DL,DLNXT,(DL) ;Get the next data link block JUMPN DL,DNDGL1 ;Go check it out RET ;Couldn't find it DNDGL2: LOAD LN,DLLNB,(DL) ;Get address of line block RETSKP ;And return XRESCD SUBTTL DNADLL - Generic data link layer -- DNDCLN - Create line block ;DNDCLN - Create a link block as needed ; ;Call: ; T1/ Line id ; T2/ Address of prototype line block ; ;Returns: ; RET on error ; RETSKP on success with address of line block in LN DNDCLN: SAVEAC ; Save P1 and P2 DMOVE P1,T1 ; Save line id and address of prototype CALL DNDFLN ; Try to find line in data base SKIPA ; Not there, create it RETSKP ; Return with line block address in LN MOVEI T1,LN.LEN ; Get length of line block CALL DNGWDZ ; Allocate core for block RET ; Can't, return MOVE LN,T1 ; Remember address of line block MOVEI T1,LN.LEN ; Get length of line block MOVE T2,P2 ; Get address of prototype line block MOVE T3,LN ; And address of new line block PUSHJ P,XBLTA## ; Copy prototype into new line block STOR P1,LNLID,(LN) ; Store line id into LN block LOAD T1,LIDEV,+P1 ; Get device type MOVE T1,MXLBSZ(T1) ; Get default receive buffer size OPSTR ,IBBSZ,+IBBLK ; Is request for less? LOAD T1,IBBSZ,+IBBLK ; Yes, then use that STOR T1,LNBSZ,(LN) ; Store into line block SYSPIF ; Interlock queue access ENDQUE LN,LNBQUE,LN.NXT,T1 ; Add line block to data base SYSPIN ; Release interlock RETSKP ; And return SUBTTL DNADLL - Generic data link layer -- DNDFLN - Find line block ;DNDFLN - Search the queue for a line data block ; ; Call: ; T1/ Line id ; ; Return: ; RET ;Line not configuered into monitor ; RETSKP ;With LN = Line Data Block ; ; Uses: T1-T2 ; ;This routine is used for calls from Network Management XSWAPCD DNDFLN: SKIPN LN,LNBQUE ;Start looking at first line data block RET ;None there, just return DNDGN1: LOAD T2,LNLID,(LN) ; Get its' line ID CAMN T1,T2 ;Is it the one we're looking for? RETSKP ;Good return LOAD LN,LNNXT,(LN) ;Get the next line data block JUMPN LN,DNDGN1 ;Go check it out RET ;Couldn't find it XRESCD SUBTTL CIDLL - CI20 data link layer -- Dummy Routines ;Dummy routines if CI20 circuits not supported IFE FTCI,< CIDINI: CIDSEC: CIDDSP: RET >; END IFE FTCI SUBTTL CIDLL - CI20 data link layer -- CIDINI - Initialize lines IFN FTCI,< ;Call: ; CALL CIDINI ;Returns: ; RET Always CIDINI: RET ;Still in IFN FTCI SUBTTL CIDLL - CI20 data link layer -- CIDSEC - Once a second code ;Still in IFN FTCI ;Call: ; DL/ Address of data link block ; LN/ Address of line data block ; CALL CIDSEC ;Returns: ; RET always CIDSEC: RET ;Still in IFN FTCI SUBTTL CIDLL - CI20 data link layer -- CIDDSP - Function dispatch ;Still in IFN FTCI ;Call: (for non-network management functions) ; T1/ Function code (DF.xxx) ; T3-T4/ Function specific data ; DL/ Address of data link block ; LN/ Address of link table block ; CALL CIDDSP ;Call: (for network management functions) ; T1/ Function code (DF.xxx) ; T2/ Address of NF block ; CALL CIDDSP CIDDSP: STKVAR MOVEM T1,FUNC TXZE T1,DN.NMF ; Is this from network management? JRST DCIDS2 ; Yes, just do the dispatch CAIE T1,DF.OPN ; Is this an open circuit call? JRST DCIDS1 ; No, not special MOVE T3,T2 ; Callback ID goes into T3 LOAD T2,DLDID,(T2) ; Get the line identifier for this circuit TRNA DCIDS1: LOAD T2,LNPID,(LN) ; Get the portal ID to talk to CIDLL DCIDS2: CALL CINDSP ; Call CIDLL RET ; Pass on the error HRRZ T2,FUNC CAIE T2,DF.OPN ; Was this an open request? RETSKP ; No, just return success STOR T1,LNPID,(LN) ; T1 should contain the Port ID RETSKP >; END IFN FTCI SUBTTL DDPDLL - DDP (ANF-10) data link layer -- Dummy Routines ;Dummy routines if DDP (ANF-10) circuits not supported IFE FTDDP,< DDDINI: DDDSEC: DDDDSP: DDIPPI::RET ;$ >; END IFE FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDINI - Initialize lines IFN FTDDP,< ;Call: ; CALL DDDINI ;Returns: ; RET always ;Side effects: ; Creates LN blocks for any existing DDP lines DDDINI: RET ; DDPs initialize via DDIPPI DI.ICB call ; Prototype DDP line block DDDPLN: $BUILD (LN.LEN) $SET (LNSTA,LS.ON) ; Default line state of on $SET (LNPRO,0) ; Protocol type = DDCMP-Point $SET (LNCTY,0) ; Circuit type = DDCMP-Point $SET (LNDBF,1) ; Default number of receive buffers = 1 $EOB ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDSEC - Once a second code ;Still in IFN FTDDP ;Call: ; DL/ Address of data link block ; LN/ Address of line data block ; CALL DDDSEC ;Returns: ; RET always DDDSEC: LOAD T1,LNSTA,(LN) ; Get line's state TMNE DLLIU,(DL) ; Is DECnet using the data link? CAIE T1,LS.ON ; Yes, is line running? RET ; No, return CALLRET DDIPRB ; Try to post some buffers ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDDSP - Function dispatch ;Still in IFN FTDDP ;Call: (for non-network management functions) ; T1/ Function code (DF.xxx) ; T3-T4/ Function specific data ; DL/ Address of data link block ; LN/ Address of link table block ; CALL DDDDSP ;Call: (for network management functions) ; T1/ Function code (DF.xxx) ; T2/ Address of NF block ; CALL DDDDSP DDDDSP: MOVE CX,DDDDTB(T1) ; Get dispatch address CALLRET (CX) DDDDTB: IFIW ; Open a portal/circuit IFIW ; Close a portal/circuit IFIW ; Transmit a packet IFIW ; Set a parameter IFIW ; Clear a parameter IFIW ; Read paramater IFIW ; Show counters IFIW ; Show and zero counters IFIW ; Return list IFIW ; Map Node Address to Name IFIW ; Map Node Name to Address IFIW ; Check Entity Id IF1,>,> DDDILL: RET ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDOPN - Open portal ;Still in IFN FTDDP ;DDDOPN - Open a data link layer port ; ; Call: ; T1/ Function (DF.OPN) ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;ON RESOURCE FAILURE ; RETSKP ;On success with T1 = Line state ; ; Uses: T1-T3 DDDOPN: MOVX T1,DD.OPN ; Get function LOAD T2,LNLID,(LN) ; Get line id SETONE DLLIU,(DL) ; Indicate circuit is using the line MOVE T3,DL ; Callback ID (DL block) CALL DLLDDP ; Call NETDEV JRST DDDOP1 ; Error STOR T1,LNPID,(LN) ; Store portal id CALL DDIPRB ; Try posting receive buffers LOAD T1,LNSTA,(LN) ; Get current line state RETSKP ; Return DDDOP1: SETZRO DLLIU,(DL) ; Clear the line in use indicator RET ; Give error return ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDCLS - Close portal SUBTTL DDPDLL - DDP data link layer -- DDP Parameters ;Still in IFN FTDDP XSWAPCD DDDLPT: PARAMETER (^D0,,,,,,,,< Line state>) PARAMETER (^D1105,,^D20,^D5,^D10,,,< STOR T2,LNBNO,(LN)>,) PARAMETER(^D1110,,,,,,,,< Controller>) PARAMETER(^D1112,,,,,,,,< Protocol>) PARAMETER(^D2500,,,,,,,,< Receive buffer size>) DDDLPL==.-DDDLPT DDDCPT: PARAMETER (^D1112,,,,,,,,< Circuit type>) DDDCPL==.-DDDCPT XRESCD ;Still in IFN FTDDP SUBTTL DDDDLL - DDP data link layer -- DDP Counters ;Still in IFN FTDDP XSWAPCD ;Circuit counters maintained by the line DDDCCT: COUNTER (^D1000,^D32,,,,< Bytes received>) COUNTER (^D1001,^D32,,,,) COUNTER (^D1010,^D32,,,,< Data blocks received>) COUNTER (^D1011,^D32,,,,< Data blocks sent>) COUNTER (^D1065,^D16,,,,< User buffer unavailable>) DDDCCL==.-DDDCCT XRESCD ;Still in IFN FTDDP ;DDDCLS - Close a circuit on a DDP line ; ; Call: ; DL/ Data link block address ; LN/ Line tabel block address ; ; Return: ; RET ;On error ; RETSKP ;On success ; DDDCLS: MOVX T1,DD.CLS ; Get DDP driver function LOAD T2,LNPID,(LN) ; Get DDP portal id CALL DLLDDP ; Ask driver to terminate RET ; Error SETZRO DLLIU,(DL) ; Clear the line in use indicator MOVX T2,LS.OFF ; Save new line state as off STOR T2,LNSTA,(LN) ; ... JUMPE T1,RSKP ; If we got an MB return it DECR LNNBP,(LN) ; No longer posted CALL DNFMSG ; Return it to the free pool RETSKP ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDXMT - Transmit packet ;Still in IFN FTDDP ;DDDXMT - Send a packet to DDP driver ; ; Call: ; T3/ Message block ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;On error from driver ; RETSKP ;On success DDDXMT: MOVX T1,DD.QUE ; Get function LOAD T2,LNPID,(LN) ; Get DDP portal id CALLRET DLLDDP ; ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDRED - Read parameter SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDSET - Set parameter SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDCLR - Clear parameter ;Still in IFN FTDDP XSWAPCD DDDRED: MOVEI T3,NF.RED ; Funtion will be in T3 CALLRET DDDCPF ; Call common parameter routine DDDSET: MOVEI T3,NF.SET CALLRET DDDCPF ; Call common parameter routine DDDCLR: MOVEI T3,NF.CLR ; CALLRET DDDCPF ; Call common parameter routine DDDCPF: STKVAR MOVEM T3,FUNC ; Save function (read,set,clear) MOVE P1,T2 ; Save NTMAN function block LOAD T1,NFETY,(P1) ; Get the entity type CAIE T1,.NTCKT ; Is it circuit? IFSKP. LOAD T1,NFEID,(P1) ; Yes, get the entity ID again CALL DNDFDL ; Find the data link block RNMXND ; Don't know of this link-Return succes/no data LOAD LN,DLLNB,(DL) ; Address of line data block XMOVEI T1,DDDCPT ; Use the circuit parameter table MOVEI T2,DDDCPL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity type line? IFSKP. LOAD T1,NFEID,(P1) ; Get the entity ID CALL DNDFLN ; Get the line data block for this line RNMXER (NF.MPE) ; We don't support this device XMOVEI T1,DDDLPT ; Get parameter table address MOVEI T2,DDDLPL ; and its length ELSE. RNMXER (NF.MPE) ; We don't support any others ENDIF. ENDIF. MOVE T3,FUNC ; Recover requested function CALLRET NTPARM ; Call the common parameter processer ; T1/ table ; T2/ table's length ; T3/ function ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDSHC - Show counters SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDSZC - Show and zero counters ;Still in IFN FTDDP XSWAPCD DDDSHC: SKIPA T3,[NF.COU] ;Load function code and skip DDDSZC: MOVX T3,NF.SZC ;Load function code STKVAR MOVEM T3,FUNC ;T3 will be used later MOVE P1,T2 ;Move NF pointer to where it should be LOAD T1,NFETY,(P1) ;Get the entity type CAIE T1,.NTCKT ;Is it a circuit IFSKP. LOAD T1,NFEID,(P1) ;Get circuit identifier CALL DNDFDL ;Get the data link block block RNMXND XMOVEI T1,DDDCCT ;Address of circuit counter table MOVEI T2,DDDCCL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity a line? IFSKP. RNMXND ; Return with no data ELSE. RNMXER (NF.OPF) ; We don't do any others ENDIF. ENDIF. ;Call NTCTRS to do the real work MOVE T3,FUNC ;Get function to do CALLRET NTCTRS ;Read the counters and return ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDRTL - Return list SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDDCET - Check entity ;Still in IFN FTDDP DDDRTL: DDDCET: RNMXER (NF.MPE) ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DLLDDP - Call DDP driver ;Still in IFN FTDDP DLLDDP: MOVX T4,DD.DEC ; Say we are DECnet user SNCALL (DDPDSP##,MCSEC1) RET RETSKP ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDIPPI - DDP driver callback ;Still in IFN FTDDP ;DDIPPI - Interrupt from NETDDP ; ;Call: ; T1/ Function code (DI.xxx) ; T2/ Address of data link block ; T3/ Function specific data DDIPPI::CAXL T1,DI.ODN CAXLE T1,DI.ICB BUG. (CHK,DDIIFD,DNADLL,SOFT,,,< This BUG is not documented yet. >,RTN) SAVEAC ; Save DL and LN SKIPE DL,T2 ; Get address of data link block LOAD LN,DLLNB,(DL) ; and line data block address MOVE T1,DDIDLI(T1) ; Get address of function specific routine CALLRET (T1) ; Dispatch to routine and return DDIDLI: IFIW ; Unused IFIW ; Output done IFIW ; Input complete IFIW ; Line state change IFIW ; Initialize circuit block IF1,>,> DDIILL: RET ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDIODN - Transmit done ;Still in IFN FTDDP ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address DDIODN: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYS,(DL) ; Update bytes sent INCR DLDBS,(DL) ; Another packet sent MOVEI T1,DI.ODN ; Function is Output Done CALLRET DNDQUE ; Queue message up and return ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDIINC - Receive done ;Still in IFN FTDDP ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address DDIINC: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYR,(DL) ; Update bytes received INCR DLDBR,(DL) ; Another packet received DECR LNNBP,(LN) ; Account for buffer received MOVEI T1,DI.INC ; Function is input complete CALL DNDQUE ; Queue message up CALLRET DDIPRB ; Post a buffer for driver ;Special entry [krock] for the DDP to release posted buffer(s). ; ;This should be a call-back entry (e.g., DI.INE), but is just coded ;inline for minimal impact on other driver types. The call mimics an ;entry via DDIPPI . . . ; ; T1/ Ignored ; T2/ Data link block address ; T3/ MB address DDIINE::SAVEAC ; Save the usual ACs SKIPN DL,T2 ; Must have the data link block address PUSHJ P,NTDSTP## ; Otherwise something confused LOAD LN,DLLNB,(DL) ; Get associated LN block DECR LNNBP,(LN) ; Decrement count of outstanding buffers ; (count should be 0 now) MOVE T1,T3 ; Position MB address in T1 CALLRET DNFMSG ; Pitch useless message buffer ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDILSC - Line state change ;Still in IFN FTDDP ;Call: ; T3/ New state ; DL/ Data link block address ; LN/ line data block address DDILSC: STOR T3,LNSTA,(LN) ; Save the new state TMNN DLLIU,(DL) ; Is Router using this line? IFSKP. MOVEI T1,DI.LSC ; Yes, notify ROUTER CALL DNDQUE ENDIF. LOAD T1,LNSTA,(LN) ; Get state again CAIN T1,LS.ON ; Is new state = on? CALL DDIPRB ; Yes, post a buffer RET ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDIICB - Initialize circuit block ;Still in IFN FTDDP ;DDIICB - Create DDP line and circuit blocks ; ;Call: ; T3/ Line id ; ;Returns: ; RET on error ; RETSKP on success DDIICB: SAVEAC ; Save DL and LN MOVE T1,T3 ; Get line id XMOVEI T2,DDDPLN ; Get address of prototype DDP line block CALL DNDCLN ; Create line block if needed RET ; Can't, give error return LOAD T1,LNLID,(LN) ; Get line id TXZ T1,LILXC ; Make into circuit id CALL DNDCDL ; Create circuit block if needed RET ; Can't, give error return MOVE T1,DL ; Give the DL block to our user RETSKP ; Return ;Still in IFN FTDDP SUBTTL DDPDLL - DDP (ANF-10) data link layer -- DDIPRB - Post receive buffer ;Still in IFN FTDDP ; Call: ; DL/ Data link block address ; LN/ line data block address ; ; Uses: T1-T3 DDIPRB: SAVEAC LOAD T1,LNNBP,(LN) ; Get number posted OPSTR ,LNBNO,(LN) ; Enough posted? RET LOAD T1,LNBSZ,(LN) ; Get the size to post for this link CALL DNGMSG ; Request a message block RET ; None available, return MOVE MB,T1 ; Save address of block XMOVEI T2,IN.MSD(MB) ; Point to the input MSD STOR T2,MBFMS,(MB) ; Store in forst MSD slot MOVE T3,MB ; Get MSD address for DDP driver MOVEI T1,DD.PRB ; Function is post receive buffer LOAD T2,LNPID,(LN) ; Get DDP portal id CALL DLLDDP ; Attempt to post the buffer JRST [MOVE T1,MB ; Get message block address CALL DNFMSG ; Free message block we couldn't post RET] ; and return INCR LNNBP,(LN) ; Account for buffer posted RET ; And return >; END IFN FTDDP SUBTTL DMRDLL - DMR data link layer -- Dummy Routines ;Dummy routines if DMR circuits not supported IFE FTDMR,< DMDINI: DMDSEC: DMDDSP: RET >; END IFE FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDINI - Initialize lines IFN FTDMR,< ;Call: ; CALL DMDINI ;Returns: ; RET always ;Side effects: ; Creates LN blocks for any existing DMR lines DMDINI: RET ; DMRs initialize from DMIPPI ;Prototype DMR line block DMDPLN: $BUILD (LN.LEN) $SET (LNSTA,LS.ON) ; Default line state = ON $SET (LNPRO,0) ; Default protocol type = DDCMP-POINT $SET (LNCTY,0) ; Default circuit type = DDCMP-POINT $SET (LNDBF,0) ; Default number of receive buffers = 0 $EOB ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDSEC - Once a second code ;Still in IFN FTDMR ;Call: ; DL/ Address of data link block ; LN/ Address of line data block ; CALL DMDSEC ;Returns: ; RET always DMDSEC: REPEAT 0,< LOAD T1,LNSTA,(LN) ; Get line's state TMNE DLLIU,(DL) ; Is DECnet using the data link? CAIE T1,LS.ON ; Yes, is line running? RET ; No, return CALLRET DMIPRB ; Try to post some buffers >;We'll ask when we want one RET ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDDSP - Function dispatch ;Still in IFN FTDMR ;Call: (for non-network management functions) ; T1/ Function code (DF.xxx) ; T3-T4/ Function specific data ; DL/ Address of data link block ; LN/ Address of link table block ; CALL DMDDSP ;Call: (for network management functions) ; T1/ Function code (DF.xxx) ; T2/ Address of NF block ; CALL DMDDSP DMDDSP: MOVE CX,DMDDTB(T1) ; Get dispatch address CALLRET (CX) DMDDTB: IFIW ; Open a portal/circuit IFIW ; Close a portal/circuit IFIW ; Transmit a packet IFIW ; Set a parameter IFIW ; Clear a parameter IFIW ; Read paramater IFIW ; Show counters IFIW ; Show and zero counters IFIW ; Return list IFIW ; Map Node Address to Name IFIW ; Map Node Name to Address IFIW ; Check Entity Id IF1,>,> DMDILL: RET ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDOPN - Open portal ;Still in IFN FTDMR ;DMDOPN - Open a data link layer port ; ; Call: ; T1/ Function (DF.OPN) ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;ON RESOURCE FAILURE ; RETSKP ;On success with T1 = Line state ; ; Uses: T1-T3 DMDOPN: MOVX T1,DC.FAL ; Get function (Assign line) LOAD T2,LNLID,(LN) ; Get line id MOVE T3,DL ; Callback ID (DL block) CALL DLLDMR ; Call DMRINT RET ; Error SETONE DLLIU,(DL) ; Indicate circuit is using the line STOR T1,LNPID,(LN) ; Store portal id MOVX T1,DC.FIL ; Get function (Initialize protocol) LOAD T2,LNPID,(LN) ; Get portal id MOVE T3,DL ; Callback ID (DL block) CALL DLLDMR ; Call DMRINT RET ; Error LOAD T1,LNSTA,(LN) ; Get current line state RETSKP ; Return ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDCLS - Close portal ;Still in IFN FTDMR ;DMDCLS - Close a circuit on a DMR line ; ; Call: ; DL/ Data link block address ; LN/ Line tabel block address ; ; Return: ; RET ;On error ; RETSKP ;On success ; DMDCLS: MOVX T1,DC.FHL ; Get DMR driver function LOAD T2,LNPID,(LN) ; Get DMR portal id CALL DLLDMR ; Ask driver to terminate RET ; Error SETZRO DLLIU,(DL) ; Clear the line in use indicator MOVX T2,LS.OFF ; Save new line state as off STOR T2,LNSTA,(LN) ; ... RETSKP ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDXMT - Transmit packet ;Still in IFN FTDMR ;DMDXMT - Send a packet to DMR driver ; ; Call: ; T3/ Message block ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;On error from driver ; RETSKP ;On success DMDXMT: MOVX T1,DC.FQB ; Get function LOAD T2,LNPID,(LN) ; Get DMR portal id CALLRET DLLDMR ; ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDRED - Read parameter SUBTTL DMRDLL - DMR data link layer -- DMDSET - Set parameter SUBTTL DMRDLL - DMR data link layer -- DMDCLR - Clear parameter ;Still in IFN FTDMR XSWAPCD DMDRED: MOVEI T3,NF.RED ; Funtion will be in T3 CALLRET DMDCPF ; Call common parameter routine DMDSET: MOVEI T3,NF.SET CALLRET DMDCPF ; Call common parameter routine DMDCLR: MOVEI T3,NF.CLR ; CALLRET DMDCPF ; Call common parameter routine DMDCPF: STKVAR MOVEM T3,FUNC ; Save function (read,set,clear) MOVE P1,T2 ; Save NTMAN function block LOAD T1,NFETY,(P1) ; Get the entity type CAIE T1,.NTCKT ; Is it circuit? IFSKP. LOAD T1,NFEID,(P1) ; Yes, get the entity ID again CALL DNDFDL ; Find the data link block RNMXND ; Don't know of this link-Return succes/no data LOAD LN,DLLNB,(DL) ; Address of line data block XMOVEI T1,DMDCPT ; Use the circuit parameter table MOVEI T2,DMDCPL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity type line? IFSKP. LOAD T1,NFEID,(P1) ; Get the entity ID CALL DNDFLN ; Get the line data block for this line RNMXER (NF.MPE) ; We don't support this device XMOVEI T1,DMDLPT ; Get parameter table address MOVEI T2,DMDLPL ; and its length ELSE. RNMXER (NF.MPE) ; We don't support any others ENDIF. ENDIF. MOVE T3,FUNC ; Recover requested function CALLRET NTPARM ; Call the common parameter processer ; T1/ table ; T2/ table's length ; T3/ function ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDSHC - Show counters SUBTTL DMRDLL - DMR data link layer -- DMDSZC - Show and zero counters ;Still in IFN FTDMR XSWAPCD DMDSHC: SKIPA T3,[NF.COU] ;Load function code and skip DMDSZC: MOVX T3,NF.SZC ;Load function code STKVAR MOVEM T3,FUNC ;T3 will be used later MOVE P1,T2 ;Move NF pointer to where it should be LOAD T1,NFETY,(P1) ;Get the entity type CAIE T1,.NTCKT ;Is it a circuit IFSKP. LOAD T1,NFEID,(P1) ;Get circuit identifier CALL DNDFDL ;Get the data link block block RNMXND XMOVEI T1,DMDCCT ;Address of circuit counter table MOVEI T2,DMDCCL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity a line? IFSKP. RNMXND ; Return with no data ELSE. RNMXER (NF.OPF) ; We don't do any others ENDIF. ENDIF. ;Call NTCTRS to do the real work MOVE T3,FUNC ;Get function to do CALLRET NTCTRS ;Read the counters and return ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMR Parameters ;Still in IFN FTDMR XSWAPCD DMDLPT: PARAMETER (^D0,,,,,,,,) PARAMETER(^D1110,,,,,,,,< Controller>) ;PARAMETER(^D1111,,,,,,,,< ; Duplex>) PARAMETER(^D1112,,,,,,,,< Protocol>) DMDLPL==.-DMDLPT DMDCPT: PARAMETER (^D1112,,,,,,,,< Circuit type>) DMDCPL==.-DMDCPT XRESCD ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMR Counters ;Still in IFN FTDMR XSWAPCD ;Circuit counters maintained by the line DMDCCT: COUNTER (^D1000,^D32,,,,< Bytes received>) COUNTER (^D1001,^D32,,,,) COUNTER (^D1010,^D32,,,,< Data blocks received>) COUNTER (^D1011,^D32,,,,< Data blocks sent>) DMDCCL==.-DMDCCT XRESCD ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMDRTL - Return list SUBTTL DMRDLL - DMR data link layer -- DMDCET - Check entity ;Still in IFN FTDMR DMDRTL: DMDCET: RNMXER (NF.MPE) ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DLLDMR - Call DMR driver ;Still in IFN FTDMR DLLDMR==DMRDSP## ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMIPPI - DMR driver callback ;Still in IFN FTDMR ;DMIPPI - Interrupt from DMRINT ; ;Call: ; T1/ Function code (DC.Ixx) ; T2/ Address of data link block ; T3/ Function specific data INTERNAL DMIPPI XRENT DMIPPI CAXL T1,DC.IPU CAXLE T1,DC.ICC BUG. (CHK,DMIIFD,DNADLL,SOFT,,,< This BUG is not documented yet. >,RTN) SAVEAC ; Save DL and LN SKIPE DL,T2 ; Get address of data link block LOAD LN,DLLNB,(DL) ; and line data block address MOVE T1,DMIDLI(T1) ; Get address of function specific routine CALLRET (T1) ; Dispatch to routine and return DMIDLI: IFIW ; Protocol up IFIW ; Protocol down IFIW ; Maint msg received IFIW ; Start received IFIW ; Output done IFIW ; Output not done IFIW ; Input complete IFIW ; Get buffer IFIW ; Initialize circuit block IFIW ; Destroy circuit block IF1,>,> DMIDCB: DMIILL: RET ; Still FTDMR SUBTTL DMRDLL - DMR data link layer -- DMILSC - Line state change DMISTR: DMIPRU: SKIPA T3,[LS.ON] ; Protocol is now up DMIPRD: MOVEI T3,LS.OFF ; Protocol is down JRST DMILSC ; Line state changed DMIMAI: MOVEI T3,LS.SRV ; Service ; JRST DMILSC ; We changed DMILSC: STOR T3,LNSTA,(LN) ; Save new state TMNN DLLIU,(DL) ; In use by router? IFSKP. MOVEI T1,DI.LSC ; Yes, notify ROUTER CALL DNDQUE ENDIF. RET ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMIODN - Transmit done ;Still in IFN FTDMR ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address DMIOND: ; Output not done, who cares? DMIODN: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYS,(DL) ; Update bytes sent INCR DLDBS,(DL) ; Another packet sent MOVEI T1,DI.ODN ; Function is Output Done CALLRET DNDQUE ; Queue message up and return ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMIINC - Receive done ;Still in IFN FTDMR ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address DMIINC: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYR,(DL) ; Update bytes received INCR DLDBR,(DL) ; Another packet received MOVEI T1,DI.INC ; Function is input complete CALL DNDQUE ; Queue message up RET ; OK, done ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMIICB - Initialize circuit block ;Still in IFN FTDMR ;DMIICB - Create DMR line and circuit blocks ; ;Call: ; T3/ Line id ; ;Returns: ; RET on error ; RETSKP on success DMIICB: SAVEAC ; Save DL and LN MOVE T1,T3 ; Get line id XMOVEI T2,DMDPLN ; Get address of prototype DMR line block CALL DNDCLN ; Create line block if needed RET ; Can't, give error return LOAD T1,LNLID,(LN) ; Get line id TXZ T1,LILXC ; Make into circuit id CALL DNDCDL ; Create circuit block if needed RET ; Can't, give error return RETSKP ; Return ;Still in IFN FTDMR SUBTTL DMRDLL - DMR data link layer -- DMIBFR - Provide receive buffer ;Still in IFN FTDMR ; Call: ; DL/ Data link block address ; LN/ line data block address ; ; Uses: T1-T3 DMIBFR: MOVE T1,T3 ; Get the size to get for this link CALL DNGMSG ; Request a message block JRST [SETZ T1, RET] XMOVEI T2,IN.MSD(T1) ;POINT SERVICE AT THE BUFFER MOVEM T2,MB.FMS(T1) ;SO WE AREN'T CONFUSED LATER RET ; And return >; END IFN FTDMR SUBTTL DTEDLL - DTE data link layer -- Dummy Routines ;Dummy routines if DTE circuits not supported IFE FTDTE,< DTDINI: DTDSEC: DTDDSP: RET >; END IFE FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDINI - Initialize lines IFN FTDTE,< ;Call: ; CALL DTDINI ;Returns: ; RET always ;Side effects: ; Creates LN blocks for any existing DTE lines DTDINI: SAVEAC ; Save P1 and P2 MOVSI P1,-CPUN## ; Set up CPU AOBJN counter DTDIN1: MOVE P2,[-3,,1] ; Set up DTE AOBJN counter DTDIN2: MOVEI T1,DD.CKE ; Ask DTE driver to check its existance HRLZ T2,P1 ; Get CPU number HRR T2,P2 ; And DTE number CALL DLLDTE ; Does this DTE exist? JRST DTDIN3 ; No, skip it MOVX T1,LILXC!FLD(LD.DTE,LIDEV) ; Build a line id for this DTE STOR P1,LIKON,+T1 ; Store CPU number STOR P2,LIUNI,+T1 ; And DTE number XMOVEI T2,DTDPLN ; Get address of prototype DTE line block CALL DNDCLN ; Create line block if needed JRST DTDIN3 ; Can't, skip this DTE LOAD T1,LNLID,(LN) ; Get line id TXZ T1,LILXC ; Make into circuit id CALL DNDCDL ; Create circuit block if needed JFCL ; Error DTDIN3: AOBJN P2,DTDIN2 ; Loop back for all possible DTEs AOBJN P1,DTDIN1 ; Loop back for all possible CPUs RETSKP ; Return ; Prototype DTE line block DTDPLN: $BUILD (LN.LEN) $SET (LNSTA,LS.OFF) ; Default line state of off $SET (LNPRO,8) ; Protocol type = QP2 $SET (LNCTY,8) ; Circuit type = QP2 $SET (LNDBF,1) ; Default number of receive buffers = 1 $EOB ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDSEC - Once a second code ;Still in IFN FTDTE ;Call: ; DL/ Address of data link block ; LN/ Address of line data block ; CALL DTDSEC ;Returns: ; RET always DTDSEC: LOAD T1,LNSTA,(LN) ; Get line's state TMNE DLLIU,(DL) ; Is DECnet using the data link? CAIE T1,LS.ON ; Yes, is line running? RET ; No, then don't attempt to post buffers CALLRET DTIPRB ; Try to post a buffer ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDDSP - Function dispatch ;Still in IFN FTDTE ;Call: (for non-network management functions) ; T1/ Function code (DF.xxx) ; T3-T4/ Function specific data ; DL/ Address of data link block ; LN/ Address of link table block ; CALL DTDDSP ;Call: (for network management functions) ; T1/ Function code (DF.xxx) ; T2/ Address of NF block ; CALL DTDDSP DTDDSP: MOVE CX,DTDDTB(T1) ; Get dispatch address CALLRET (CX) DTDDTB: IFIW ; Open a portal/circuit IFIW ; Close a portal/circuit IFIW ; Transmit a packet IFIW ; Set a parameter IFIW ; Clear a parameter IFIW ; Read paramater IFIW ; Show counters IFIW ; Show and zero counters IFIW ; Return list IFIW ; Map Node Address to Name IFIW ; Map Node Name to Address IFIW ; Check Entity Id IF1,>,> DTDILL: RET ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDOPN - Open portal ;Still in IFN FTDTE ;DTDOPN - Open a data link layer port ; ; Call: ; T1/ Function (DF.OPN) ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;ON RESOURCE FAILURE ; RETSKP ;On success with T1 = Line state ; ; Uses: T1-T3 DTDOPN: MOVX T1,DD.OPN ; Get function LOAD T3,LNLID,(LN) ; Get line id LOAD T2,LIKON,+T3 ; Get CPU number LOAD T3,LIUNI,+T3 ; And DTE number HRLZS T2 ; Construct CPU,,DTE HRR T2,T3 ; ... MOVE T3,DL ; Callback ID (DL block) SETZ T4, ; Indicate no buffer CALL DLLDTE RET ; Error SETONE DLLIU,(DL) ; Indicate circuit is using the line STOR T1,LNPID,(LN) ; Store portal id CALL DTIPRB ; Post a receive buffer LOAD T1,LNSTA,(LN) ; Get current line state RETSKP ; Return ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDCLS - Close portal ;Still in IFN FTDTE ;DTDCLS - Close a circuit on a DTE line ; ; Call: ; DL/ Data link block address ; LN/ Line tabel block address ; ; Return: ; RET ;On error ; RETSKP ;On success ; DTDCLS: MOVX T1,DD.CLS ; Get DTE driver function LOAD T2,LNPID,(LN) ; Get DTE portal id CALL DLLDTE ; Ask driver to terminate RET ; Error SETZRO DLLIU,(DL) ; Clear the line in use indicator MOVX T2,LS.OFF ; Set new line state as off STOR T2,LNSTA,(LN) ; ... JUMPE T1,RSKP ; If we got an MB return it DECR LNNBP,(LN) ; No longer posted CALL DNFMSG ; Return it to the free pool RETSKP ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDXMT - Transmit packet ;Still in IFN FTDTE ;DTDXMT - Send a packet to DTE driver ; ; Call: ; T3/ Message block ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;On error from driver ; RETSKP ;On success DTDXMT: MOVX T1,DD.QUE ; Get function LOAD T2,LNPID,(LN) ; Get DTE portal id CALLRET DLLDTE ; ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDRED - Read parameter SUBTTL DTEDLL - DTE data link layer -- DTDSET - Set parameter SUBTTL DTEDLL - DTE data link layer -- DTDCLR - Clear parameter ;Still in IFN FTDTE XSWAPCD DTDRED: MOVEI T3,NF.RED ; Funtion will be in T3 CALLRET DTDCPF ; Call common parameter routine DTDSET: MOVEI T3,NF.SET CALLRET DTDCPF ; Call common parameter routine DTDCLR: MOVEI T3,NF.CLR ; CALLRET DTDCPF ; Call common parameter routine DTDCPF: STKVAR MOVEM T3,FUNC ; Save function (read,set,clear) MOVE P1,T2 ; Save NTMAN function block LOAD T1,NFETY,(P1) ; Get the entity type CAIE T1,.NTCKT ; Is it circuit? IFSKP. LOAD T1,NFEID,(P1) ; Yes, get the entity ID again CALL DNDFDL ; Find the data link block RNMXND ; Don't know of this link-Return succes/no data LOAD LN,DLLNB,(DL) ; Address of line data block XMOVEI T1,DTDCPT ; Use the circuit parameter table MOVEI T2,DTDCPL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity type line? IFSKP. LOAD T1,NFEID,(P1) ; Get the entity ID CALL DNDFLN ; Get the line data block for this line RNMXER (NF.MPE) ; We don't support this device XMOVEI T1,DTDLPT ; Get parameter table address MOVEI T2,DTDLPL ; and its length ELSE. RNMXER (NF.MPE) ; We don't support any others ENDIF. ENDIF. MOVE T3,FUNC ; Recover requested function CALLRET NTPARM ; Call the common parameter processer ; T1/ table ; T2/ table's length ; T3/ function XRESCD ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDSHC - Show counters SUBTTL DTEDLL - DTE data link layer -- DTDSZC - Show and zero counters ;Still in IFN FTDTE XSWAPCD DTDSHC: SKIPA T3,[NF.COU] ;Load function code and skip DTDSZC: MOVX T3,NF.SZC ;Load function code STKVAR MOVEM T3,FUNC ;T3 will be used later MOVE P1,T2 ;Move NF pointer to where it should be LOAD T1,NFETY,(P1) ;Get the entity type CAIE T1,.NTCKT ;Is it a circuit IFSKP. LOAD T1,NFEID,(P1) ;Get circuit identifier CALL DNDFDL ;Get the data link block block RNMXND XMOVEI T1,DTDCCT ;Address of circuit counter table MOVEI T2,DTDCCL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity a line? IFSKP. RNMXND ; Return with no data ELSE. RNMXER (NF.OPF) ; We don't do any others ENDIF. ENDIF. ;Call NTCTRS to do the real work MOVE T3,FUNC ;Get function to do CALLRET NTCTRS ;Read the counters and return ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTDRTL - Return list SUBTTL DTEDLL - DTE data link layer -- DTDCET - Check entity ;Still in IFN FTDTE DTDRTL: DTDCET: RNMXER (NF.MPE) ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTE Parameters ;Still in IFN FTDTE XSWAPCD DTDLPT: PARAMETER (^D0,,,,,,,,) PARAMETER (^D1105,,^D20,^D5,^D10,,,< STOR T2,LNBNO,(LN)>,) PARAMETER(^D1110,,,,,,,,< Controller>) PARAMETER(^D1112,,,,,,,,< Protocol>) PARAMETER(^D2500,,,,,,,,< Receive buffer size>) DTDLPL==.-DTDLPT DTDCPT: PARAMETER (^D1112,,,,,,,,< Circuit type>) DTDCPL==.-DTDCPT XRESCD ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTE Counters ;Still in IFN FTDTE XSWAPCD ;Circuit counters maintained by the line DTDCCT: COUNTER (^D1000,^D32,,,,< Bytes received>) COUNTER (^D1001,^D32,,,,) COUNTER (^D1010,^D32,,,,< Data blocks received>) COUNTER (^D1011,^D32,,,,< Data blocks sent>) COUNTER (^D1065,^D16,,,,< User buffer unavailable>) DTDCCL==.-DTDCCT XRESCD ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DLLDTE - Call DTE driver ;Still in IFN FTDTE XRESCD IFN FTOPS20,< DLLDTE: XCALLRET (MSEC1,DTEDSP) ; Call DTE driver >; END IFN FTOPS20 IFN FTOPS10,< DLLDTE: SNCALL (DTEDSP##,MCSEC1) RET RETSKP >; END IFN FTOPS10 ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTIPPI - DTE driver callback ;Still in IFN FTDTE ;DTIPPI - Interrupt from DTE driver for MCB functions ; ;Call: ; T1/ Function code (DI.xxx) ; T2/ Data link block address INTERNAL DTIPPI XRENT DTIPPI CAXL T1,DI.ODN CAXLE T1,DI.ICB BUG. (CHK,DTIIFK,DNADLL,SOFT,,,< This BUG is not documented yet. >,RTN) SAVEAC ; Save DL and LN SKIPE DL,T2 ; Get address of data link block LOAD LN,DLLNB,(DL) ; and line data block address MOVE T1,DTIDLI(T1) ; Get address of function specific routine CALLRET (T1) ; Dispatch to routine and return DTIDLI: IFIW ; Unused IFIW ; Output done IFIW ; Input complete IFIW ; Line state change IFIW ; Initialize circuit block IF1,>,> DTIILL: RET ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTIODN - Transmit done ;Still in IFN FTDTE ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address DTIODN: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYS,(DL) ; Update bytes sent INCR DLDBS,(DL) ; Another packet sent MOVEI T1,DI.ODN ; Function is Output Done CALLRET DNDQUE ; Queue message up and return ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTIINC - Receive done ;Still in IFN FTDTE ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address DTIINC: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYR,(DL) ; Update bytes received INCR DLDBR,(DL) ; Another packet received DECR LNNBP,(LN) ; Account for buffer received MOVEI T1,DI.INC ; Function is input complete CALL DNDQUE ; Queue message up CALLRET DTIPRB ; Post a buffer for driver ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTILSC - Line state change ;Still in IFN FTDTE ;Call: ; T3/ New state ; DL/ Data link block address ; LN/ line data block address DTILSC: STOR T3,LNSTA,(LN) ; Save the new state TMNN DLLIU,(DL) ; Is Router using this line? IFSKP. MOVEI T1,DI.LSC ; Yes, notify ROUTER CALL DNDQUE ENDIF. LOAD T1,LNSTA,(LN) ; Get state again CAIN T1,LS.ON ; Is new state = on? CALL DTIPRB ; Yes, post a buffer RET ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTIICB - Initialize circuit block ;Still in IFN FTDTE ;DTIICB - Create DTE line and circuit blocks ; ;Call: ; T3/ Line id ; ;Returns: ; RET on error ; RETSKP on success DTIICB: SAVEAC ; Save DL and LN MOVE T1,T3 ; Get line id XMOVEI T2,DTDPLN ; Get address of prototype DTE line block CALL DNDCLN ; Create line block if needed RET ; Can't, give error return LOAD T1,LNLID,(LN) ; Get line id TXZ T1,LILXC ; Make into circuit id CALL DNDCDL ; Create circuit block if needed RET ; Can't, give error return RETSKP ; Return ;Still in IFN FTDTE SUBTTL DTEDLL - DTE data link layer -- DTIPRB - Post receive buffer ;Still in IFN FTDTE ; Call: ; DL/ Data link block address ; LN/ line data block address ; ; Uses: T1-T3 DTIPRB: SAVEAC LOAD T1,LNNBP,(LN) ; Get number posted OPSTR ,LNBNO,(LN) ; Enough posted? RET LOAD T1,LNBSZ,(LN) ; Get the size to post for this link CALL DNGMSG ; Request a message block RET ; None available, return MOVE MB,T1 ; Save address of block XMOVEI T2,IN.MSD(MB) ; Point to the input MSD STOR T2,MBFMS,(MB) ; Store in forst MSD slot MOVE T3,MB ; Get MSD address for DTE driver MOVEI T1,DD.PRB ; Function is post receive buffer LOAD T2,LNPID,(LN) ; Get DTE portal id CALL DLLDTE ; Attempt to post the buffer JRST [MOVE T1,MB ; Get message block address CALL DNFMSG ; Free message block we couldn't post RET] ; and return INCR LNNBP,(LN) ; Account for buffer posted RET ; And return >; END IFN FTDTE SUBTTL KDPDLL - KDP data link layer -- Dummy Routines ;Dummy routines if KDP circuits not supported IFE FTKDP,< KDDINI: KDDSEC: KDDDSP: RET >; END IFE FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDINI - Initialize lines IFN FTKDP,< ;Call: ; CALL KDDINI ;Returns: ; RET always ;Side effects: ; Creates LN blocks for any existing KDP lines KDDINI: RET ; KDPs initialize from KDIPPI ;Prototype KDP line block KDDPLN: $BUILD (LN.LEN) $SET (LNSTA,LS.OFF) ; Default line state = OFF (KDPLDR must run) $SET (LNPRO,0) ; Default protocol type = DDCMP-POINT $SET (LNCTY,0) ; Default circuit type = DDCMP-POINT $SET (LNDBF,0) ; Default number of receive buffers = 0 $EOB ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDSEC - Once a second code ;Still in IFN FTKDP ;Call: ; DL/ Address of data link block ; LN/ Address of line data block ; CALL KDDSEC ;Returns: ; RET always KDDSEC: RET ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDDSP - Function dispatch ;Still in IFN FTKDP ;Call: (for non-network management functions) ; T1/ Function code (DF.xxx) ; T3-T4/ Function specific data ; DL/ Address of data link block ; LN/ Address of link table block ; CALL KDDDSP ;Call: (for network management functions) ; T1/ Function code (DF.xxx) ; T2/ Address of NF block ; CALL KDDDSP KDDDSP: MOVE CX,KDDDTB(T1) ; Get dispatch address CALLRET (CX) KDDDTB: IFIW ; Open a portal/circuit IFIW ; Close a portal/circuit IFIW ; Transmit a packet IFIW ; Set a parameter IFIW ; Clear a parameter IFIW ; Read paramater IFIW ; Show counters IFIW ; Show and zero counters IFIW ; Return list IFIW ; Map Node Address to Name IFIW ; Map Node Name to Address IFIW ; Check Entity Id IF1,>,> KDDILL: RET ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDOPN - Open portal ;Still in IFN FTKDP ;KDDOPN - Open a data link layer port ; ; Call: ; T1/ Function (DF.OPN) ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;ON RESOURCE FAILURE ; RETSKP ;On success with T1 = Line state ; ; Uses: T1-T3 KDDOPN: MOVX T1,DC.FAL ; Get function (Assign line) LOAD T2,LNLID,(LN) ; Get line id MOVE T3,DL ; Callback ID (DL block) CALL DLLKDP ; Call KDPINT RET ; Error SETONE DLLIU,(DL) ; Indicate circuit is using the line STOR T1,LNPID,(LN) ; Store portal id MOVX T1,DC.FIL ; Get function (Initialize protocol) LOAD T2,LNPID,(LN) ; Get portal id MOVE T3,DL ; Callback ID (DL block) CALL DLLKDP ; Call KDPINT RET ; Error LOAD T1,LNSTA,(LN) ; Get current line state RETSKP ; Return ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDCLS - Close portal ;Still in IFN FTKDP ;KDDCLS - Close a circuit on a KDP line ; ; Call: ; DL/ Data link block address ; LN/ Line tabel block address ; ; Return: ; RET ;On error ; RETSKP ;On success ; KDDCLS: MOVX T1,DC.FHL ; Get KDP driver function LOAD T2,LNPID,(LN) ; Get KDP portal id CALL DLLKDP ; Ask driver to terminate RET ; Error SETZRO DLLIU,(DL) ; Clear the line in use indicator MOVX T2,LS.OFF ; Save new line state as off STOR T2,LNSTA,(LN) ; ... RETSKP ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDXMT - Transmit packet ;Still in IFN FTKDP ;KDDXMT - Send a packet to KDP driver ; ; Call: ; T3/ Message block ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;On error from driver ; RETSKP ;On success KDDXMT: MOVX T1,DC.FQB ; Get function LOAD T2,LNPID,(LN) ; Get KDP portal id CALLRET DLLKDP ; ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDRED - Read parameter SUBTTL KDPDLL - KDP data link layer -- KDDSET - Set parameter SUBTTL KDPDLL - KDP data link layer -- KDDCLR - Clear parameter ;Still in IFN FTKDP XSWAPCD KDDRED: MOVEI T3,NF.RED ; Funtion will be in T3 CALLRET KDDCPF ; Call common parameter routine KDDSET: MOVEI T3,NF.SET CALLRET KDDCPF ; Call common parameter routine KDDCLR: MOVEI T3,NF.CLR ; CALLRET KDDCPF ; Call common parameter routine KDDCPF: STKVAR MOVEM T3,FUNC ; Save function (read,set,clear) MOVE P1,T2 ; Save NTMAN function block LOAD T1,NFETY,(P1) ; Get the entity type CAIE T1,.NTCKT ; Is it circuit? IFSKP. LOAD T1,NFEID,(P1) ; Yes, get the entity ID again CALL DNDFDL ; Find the data link block RNMXND ; Don't know of this link-Return succes/no data LOAD LN,DLLNB,(DL) ; Address of line data block XMOVEI T1,KDDCPT ; Use the circuit parameter table MOVEI T2,KDDCPL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity type line? IFSKP. LOAD T1,NFEID,(P1) ; Get the entity ID CALL DNDFLN ; Get the line data block for this line RNMXER (NF.MPE) ; We don't support this device XMOVEI T1,KDDLPT ; Get parameter table address MOVEI T2,KDDLPL ; and its length ELSE. RNMXER (NF.MPE) ; We don't support any others ENDIF. ENDIF. MOVE T3,FUNC ; Recover requested function CALLRET NTPARM ; Call the common parameter processer ; T1/ table ; T2/ table's length ; T3/ function ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDSHC - Show counters SUBTTL KDPDLL - KDP data link layer -- KDDSZC - Show and zero counters ;Still in IFN FTKDP XSWAPCD KDDSHC: SKIPA T3,[NF.COU] ;Load function code and skip KDDSZC: MOVX T3,NF.SZC ;Load function code STKVAR MOVEM T3,FUNC ;T3 will be used later MOVE P1,T2 ;Move NF pointer to where it should be LOAD T1,NFETY,(P1) ;Get the entity type CAIE T1,.NTCKT ;Is it a circuit IFSKP. LOAD T1,NFEID,(P1) ;Get circuit identifier CALL DNDFDL ;Get the data link block block RNMXND XMOVEI T1,KDDCCT ;Address of circuit counter table MOVEI T2,KDDCCL ; and its length ELSE. CAIE T1,.NTLIN ; Is entity a line? IFSKP. RNMXND ; Return with no data ELSE. RNMXER (NF.OPF) ; We don't do any others ENDIF. ENDIF. ;Call NTCTRS to do the real work MOVE T3,FUNC ;Get function to do CALLRET NTCTRS ;Read the counters and return ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDDRTL - Return list SUBTTL KDPDLL - KDP data link layer -- KDDCET - Check entity ;Still in IFN FTKDP KDDRTL: KDDCET: RNMXER (NF.MPE) ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDP Parameters ;Still in IFN FTKDP XSWAPCD KDDLPT: PARAMETER (^D0,,,,,,,,) PARAMETER(^D1110,,,,,,,,< Controller>) PARAMETER(^D1112,,,,,,,,< Protocol>) KDDLPL==.-KDDLPT KDDCPT: PARAMETER (^D1112,,,,,,,,< Circuit type>) KDDCPL==.-KDDCPT XRESCD ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDP Counters ;Still in IFN FTKDP XSWAPCD ;Circuit counters maintained by the line KDDCCT: COUNTER (^D1000,^D32,,,,< Bytes received>) COUNTER (^D1001,^D32,,,,) COUNTER (^D1010,^D32,,,,< Data blocks received>) COUNTER (^D1011,^D32,,,,< Data blocks sent>) KDDCCL==.-KDDCCT XRESCD ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- DLLKDP - Call KDP driver ;Still in IFN FTKDP DLLKDP==KDPDSP## ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDIPPI - KDP driver callback ;Still in IFN FTKDP ;KDIPPI - Interrupt from KDPINT ; ;Call: ; T1/ Function code (DC.Ixx) ; T2/ Address of data link block ; T3/ Function specific data INTERNAL KDIPPI XRENT KDIPPI CAXL T1,DC.IPU CAXLE T1,DC.ICC BUG. (CHK,KDIIFD,DNADLL,SOFT,,,< This BUG is not documented yet. >,RTN) SAVEAC ; Save DL and LN SKIPE DL,T2 ; Get address of data link block LOAD LN,DLLNB,(DL) ; and line data block address MOVE T1,KDIDLI(T1) ; Get address of function specific routine CALLRET (T1) ; Dispatch to routine and return KDIDLI: IFIW ; Protocol up IFIW ; Protocol down IFIW ; Maint msg received IFIW ; Start received IFIW ; Output done IFIW ; Output not done IFIW ; Input complete IFIW ; Get buffer IFIW ; Initialize circuit block IFIW ; Destroy circuit block IF1,>,> KDIDCB: KDIILL: RET ; Still FTKDP SUBTTL KDPDLL - KDP data link layer -- KDILSC - Line state change KDISTR: KDIPRU: SKIPA T3,[LS.ON] ; Protocol is now up KDIPRD: MOVEI T3,LS.OFF ; Protocol is down JRST KDILSC ; Line state changed KDIMAI: MOVEI T3,LS.SRV ; Service ; JRST KDILSC ; We changed KDILSC: STOR T3,LNSTA,(LN) ; Save new state TMNN DLLIU,(DL) ; In use by router? IFSKP. MOVEI T1,DI.LSC ; Yes, notify ROUTER CALL DNDQUE ENDIF. RET ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDIODN - Transmit done ;Still in IFN FTKDP ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address KDIOND: ; Output not done, who cares? KDIODN: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYS,(DL) ; Update bytes sent INCR DLDBS,(DL) ; Another packet sent MOVEI T1,DI.ODN ; Function is Output Done CALLRET DNDQUE ; Queue message up and return ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDIINC - Receive done ;Still in IFN FTKDP ; T3/ MB address ; DL/ Data link block address ; LN/ line data block address KDIINC: MOVE T1,T3 ; Get MB address CALL DNLENG ; Get message length OPSTRM ,DLBYR,(DL) ; Update bytes received INCR DLDBR,(DL) ; Another packet received MOVEI T1,DI.INC ; Function is input complete CALL DNDQUE ; Queue message up RET ; OK, done ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDIICB - Initialize circuit block ;Still in IFN FTKDP ;KDIICB - Create KDP line and circuit blocks ; ;Call: ; T3/ Line id ; ;Returns: ; RET on error ; RETSKP on success KDIICB: SAVEAC ; Save DL and LN MOVE T1,T3 ; Get line id XMOVEI T2,KDDPLN ; Get address of prototype KDP line block CALL DNDCLN ; Create line block if needed RET ; Can't, give error return LOAD T1,LNLID,(LN) ; Get line id TXZ T1,LILXC ; Make into circuit id CALL DNDCDL ; Create circuit block if needed RET ; Can't, give error return RETSKP ; Return ;Still in IFN FTKDP SUBTTL KDPDLL - KDP data link layer -- KDIBFR - Provide receive buffer ;Still in IFN FTKDP ; Call: ; DL/ Data link block address ; LN/ line data block address ; ; Uses: T1-T3 KDIBFR: MOVE T1,T3 ; Get the size to get for this link CALL DNGMSG ; Request a message block JRST [SETZ T1, RET] XMOVEI T2,IN.MSD(T1) ;POINT SERVICE AT THE BUFFER MOVEM T2,MB.FMS(T1) ;SO WE AREN'T CONFUSED LATER RET ; And return >; END IFN FTKDP SUBTTL NIDLL - Ethernet data link layer -- Dummy Routines ;Dummy routines if ethernet circuits not supported IFE FTNI,< NIDINI: NIDSEC: NIDDSP: RET >; END IFE FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDINI - Initialize lines IFN FTNI,< ;Call: ; CALL NIDINI ;Returns: ; RET always ;Side effects: ; Creates LN blocks for any existing ethernet channels NIDINI: SAVEAC CALL GETUNB ; Try to allocate space for a UN block RET MOVEI T1,4 ; Length of buffer for channel list STOR T1,UNBSZ,(UN) ; Remember length for NISRV CALL DNGWDZ CALLRET FREUNB STOR T1,UNBFA,(UN) MOVX T1,NU.RCL ; Function is "Return channel list" MOVE T2,UN ; Address of UN block CALL DLLNI JRST NIDIN3 ; Return error - (BUGINF) LOAD T1,UNBSZ,(UN) ; Get number of channels found JUMPE T1,NIDIN3 ; Return if no ethernet channels MOVN P1,T1 ; Create AOBJN for number of channels HRLZS P1 ; ... NIDIN1: MOVX T1,LILXC!FLD(LD.ETH,LIDEV) ; Build a line id for this channel STOR P1,LIKON,+T1 ; Store ethernet channel number XMOVEI T2,NIDPLN ; Get address of prototype NI line block CALL DNDCLN ; Create line block if needed JRST NIDIN2 ; Can't, skip this channel LOAD T1,LNLID,(LN) ; Get line id TXZ T1,LILXC ; Make into circuit id CALL DNDCDL ; Create circuit block if needed JFCL ; Error NIDIN2: AOBJN P1,NIDIN1 ; Loop back for all channels NIDIN3: LOAD T1,UNBFA,(UN) ; Free the buffer CALL DNFWDS CALL FREUNB ; Free the UN block RET ; Prototype NI line block NIDPLN: $BUILD (LN.LEN) $SET (LNSTA,LS.ON) ; Default line state of on $SET (LNPRO,6) ; Protocol type = Ethernet $SET (LNCTY,6) ; Circuit type = Ethernet $SET (LNDBF,6) ; Default number of receive buffers = 6 $EOB ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDSEC - Once a second code ;Still in IFN FTNI ;Call: ; DL/ Address of data link block ; LN/ Address of line data block ; CALL NIDSEC ;Returns: ; RET always NIDSEC: LOAD T1,LNSTA,(LN) ; Get line's state TMNE DLLIU,(DL) ; Is DECnet using the data link? CAIE T1,LS.ON ; Yes, is line running? RET ; No, return CALLRET NIDPRB ; Try to post some buffers ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDDSP - Function dispatch ;Still in IFN FTNI ;Call: (for non-network management functions) ; T1/ Function code (DF.xxx) ; T3-T4/ Function specific data ; DL/ Address of data link block ; LN/ Address of link table block ; CALL NIDDSP ;Call: (for network management functions) ; T1/ Function code (DF.xxx) ; T2/ Address of NF block ; CALL NIDDSP NIDDSP: SAVEAC MOVE T1,NIDDTB(T1) ; Get processor address CALLRET (T1) ; and dispatch NIDDTB: IFIW ; Open portal/circuit IFIW ; Close portal/circuit IFIW ; Transmit packet IFIW ; Set parameter IFIW ; Clear parameter IFIW ; Read parameter IFIW ; Show counters IFIW ; Show and zero counters IFIW ; Return list IFIW ; Map Node Address to Name IFIW ; Map Node Name to Address IFIW ; Check Entity Id IF1,>,> NIDILL: RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDOPN - Open portal ;Still in IFN FTNI ;NIDOPN - Open a data link layer port ; ; Call: ; T1/ Function (DF.OPN) ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;ON RESOURCE FAILURE ; RETSKP ;On success with T1 = Line state ; ; Uses: T1-T3 NIDOPN: ; CALL CHKADR ; Verify that the physical address is DECnet's ; RET ; It is not, return error CALL GETUNB ; Get a UN block RET ; Return error XMOVEI T1,DNDNII ; Where DLL should call us back STOR T1,UNCBA,(UN) ; Give the driver tha callback address LOAD T1,LNLID,(LN) ; Get the line's ID LOAD T1,LIKON,+T1 ; Get ethernet channel number STOR T1,UNCHN,(UN) ; Store in UN block STOR DL,UNUID,(UN) ; Associate DL block with callbacks MOVE T1,RTRPRO ; Router's protocol type STOR T1,UNPRO,(UN) SETONE UNPAD,(UN) ; Padding is to be done MOVEI T1,NU.OPN ; Function is open a port MOVE T2,UN ; Address of UN block CALL DLLNI ; Call the driver CALLRET FREUNB ; Open failed! LOAD T1,UNPID,(UN) ; Get portal ID STOR T1,LNPID,(LN) ; Save for transmits later MOVEI T1,LS.OFF ; Assume line's state is off TMNE UNRUN,(UN) ; Is channel running? MOVEI T1,LS.ON ; Yes, get proper line state STOR T1,LNSTA,(LN) ; Save state of channel ;Now enable the multi-cast address(es) we will use ;Do both if endnode so we get the routing messages MOVX T1,%RTRMA ; Multi-cast address "ALL ROUTERS" CALL NIFEMA ; Enable us to receive on this address CALLRET FREUNB MOVE T2,DNDRNT ; Get Router's node type CAIE T2,RNT.NR ; Endnode? IFSKP. MOVX T1,%RTEMA ; Yes, then enable to receive endnode multicast CALL NIFEMA CALLRET FREUNB ENDIF. ;Now post some buffers for the NI driver CALL NIDPRB ; This will post as many as we ask for ; or as many as it can SETONE DLLIU,(DL) ; Router is using the line CALL FREUNB LOAD T1,LNSTA,(LN) ; Return line state to Router RETSKP ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDCLS - Close portal ;Still in IFN FTNI ;NIDCLS - Close a circuit on an ethernet portal ; ; Call: ; DL/ Data link block address ; LN/ Line tabel block address ; ; Return: ; RET ;On error ; RETSKP ;On success NIDCLS: CALL GETUNB ; Get a UN block RET LOAD T1,LNPID,(LN) ; Get the portal ID STOR T1,UNPID,(UN) ; and put it in UN block for DLL MOVX T1,NU.CLO ; Function is "close portal" MOVE T2,UN ; UN block address CALL DLLNI CALLRET FREUNB SETZRO DLLIU,(DL) ; Indicate Router is no longer using the line CALL FREUNB RETSKP ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDXMT - Transmit packet ;Still in IFN FTNI ;NIDXMT - Send a packet to NISRV ; ; Call: ; T3/ Message block ; DL/ Data link block address ; LN/ Line data block address ; ; Return: ; RET ;On error from driver ; RETSKP ;On success NIDXMT: SAVEAC DMOVE P1,T3 ; Save these from destruction ; P2 will have the next hop address CALL GETUNB RET LOAD T1,LNPID,(LN) ; Get the portal ID STOR T1,UNPID,(UN) ; and put it in UN block for DLL SETZRO UNBSZ,(UN) ; Byte count is zero for MSD buffers LOAD T1,MBFMS,(P1) ; Get address of MSD string STOR T1,UNBFA,(UN) STOR MB,UNRID,(UN) ; So we can easily recover MB address JUMPE P2,NIFXN1 ; No nexthop, must be multicast MOVE T1,RTRHIO ; Build nexthop ethernet address STOR T1,UNDAD,(UN) ; Store the destination address STOR P2,UNDAD,+1(UN) ; JRST NIFXN2 NIFXN1: LOAD T1,MBDS1,(MB) ; Destination in MB is the multicast address STOR T1,UNDAD,(UN) SETZRO UNDAD,+1(UN) ; This is always 0 anyway NIFXN2: IFN FTRTST,< JE RMTST,(MB),NIFXN3 ; Test flag on? MOVEI P1,TSTBLK ; Yes, then get current time S1XCT ; Must be executed in section 1 because of ; RDTIME bug STOR T1,TRTTD,(P1) ; Save it for later computation LOAD T2,TRTAF,(P1) ; and then compute the time latency SUB T1,T2 ; since we entered STOR T1,TRTED,(P1) ; RTRFWD NIFXN3: > MOVX T1,NU.XMT ; Function is transmit message MOVE T2,UN ; CALL DLLNI TRNA ; Fail but release the UN block first AOS (P) ; Indicate success CALLRET FREUNB ; and return the UN memory ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDRED - Read parameter SUBTTL NIDLL - Ethernet data link layer -- NIDSET - Set parameter SUBTTL NIDLL - Ethernet data link layer -- NIDCLR - Clear parameter ;Still in IFN FTNI XSWAPCD NIDRED: MOVEI T3,NF.RED ; Read parameter CALLRET NIDCPF ; Call our common setup for parameters NIDSET: MOVEI T3,NF.SET ; Set parameter CALLRET NIDCPF ; Call our common setup for parameters NIDCLR: MOVEI T3,NF.CLR ; Clear parameter ; CALLRET NIDCPF ; Call our common setup for parameters NIDCPF: STKVAR MOVEM T3,FUNC ; Save function (read,set,clear) MOVE P1,T2 ; NTPARM wants function block here LOAD T1,NFETY,(P1) ; Get the entity type CAIE T1,.NTCKT ; Is it a circuit? IFSKP. LOAD T1,NFEID,(P1) ; Get the entity ID CALL DNDFDL ; Get the correct data link block RNMXND ; Return success but no data LOAD LN,DLLNB,(DL) ; Get line data block address XMOVEI T1,NIDCPT ; Address of circuit parameter table MOVEI T2,NIDCPL ; And its length ELSE. CAIE T1,.NTLIN ; Is it line? IFSKP. LOAD T1,NFEID,(P1) ; Get the entity ID CALL DNDFLN ; Get the line data block for this line RNMXER (NF.MPE) ; We don't support this device XMOVEI T1,NIDLPT ; Address of line parameter table MOVEI T2,NIDLPL ; and its length ELSE. XMOVEI T1,NIDNPT ; Use Node parameter table MOVEI T2,NIDNPL ; ENDIF. ENDIF. MOVE T3,FUNC ; Recover requested function CALLRET NTPARM ; Call the common parameter processer ; T1/ table ; T2/ table's length ; T3/ function XRESCD ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDSHC - Show counters SUBTTL NIDLL - Ethernet data link layer -- NIDSZC - Show and zero counters ;Still in IFN FTNI XSWAPCD NIDSHC: SKIPA T3,[NF.COU] ; Show counters NIDSZC: MOVEI T3,NF.SZC ; Show and zero counters STKVAR MOVEM T3,FUNC ; T3 will be used later CALL NIDLKW ; Get the interlock (wait if have too) MOVE P1,T2 ; Save the NF block pointer LOAD T1,NFBLN,(P1) ; Get length of buffer AOJ T1, ; Plus one more for flags CALL DNGWDS ; Get a buffer of at least that size for NISRV RNMXER (,) MOVEM T1,BUFADR ; Buffer address LOAD T1,NFETY,(P1) ; Get the entity type CAIE T1,.NTCKT ; Is it a circuit? IFSKP. LOAD T1,NFEID,(P1) ; Get circuit identifier CALL DNDFDL ; Get the data link block block IFNSK. MOVE T1,BUFADR ; Failed so free up the buffer we have CALL DNFWDS RNMXER (,) ENDIF. MOVE T1,FUNC ; Recover function MOVE T2,BUFADR ; Buffer address AOJ T2, ; Step over flags LOAD T3,NFBLN,(P1) ; and length CALL NIFRPC ; Read the portal counters IFNSK. MOVE T1,BUFADR CALL DNFWDS RNMXER (,) ENDIF. ELSE. CAIE T1,.NTLIN ; Is entity a line? IFSKP. MOVE T1,FUNC ; Get function (read or read/clear) MOVE T2,BUFADR ; Buffer address AOJ T2, ; Step over flags LOAD T3,NFBLN,(P1) ; and length CALL NIFRCC ; Read channel counters IFNSK. MOVE T1,BUFADR ; Error, free the buffer CALL DNFWDS RNMXER (,) ENDIF. ELSE. MOVE T1,BUFADR ; Don't need this buffer any more CALL DNFWDS RNMXER (,) ENDIF. ENDIF. IFN FTOPS10,< NIDSC1: MOVEI T1,1 ; Sleep a second IFE FTXMON, ; ... IFN FTXMON, SKIPN RCCFLG ; Counters available yet? JRST NIDSC1 ; No, loop back >; END IFN FTOPS10 IFN FTOPS20,< MOVEI T1,NISCHK ; Scheduler test routine (uses only 18 bits) MDISMS ; Dismiss this process until NISRV returns data >; END IFN FTOPS20 SETOM NIDLOK ; Free the lock LOAD T1,NFETY,(P1) ; Get the entity type again ... CAIE T1,.NTCKT ; Is it a circuit? IFSKP. XMOVEI T1,NIDCCT ; Address of circuit (portal) counter table MOVEI T2,NIDCCL ; and its length ELSE. XMOVEI T1,NIDLCT ; Address of line (channel) counter table MOVEI T2,NIDLCL ; and its length ENDIF. MOVE P2,BUFADR ; NTCTRS needs the buffer address SKIPE (P2) ; Any errors from NISRV? JRST NIFSCE ; Yes.. MOVE T3,FUNC AOJ P2, ; Step over flags CALL NTCTRS ; Now copy the data to NTMAN's buffer JRST NIFSCE ; Did not successfully copy data MOVE T1,BUFADR ; Data copied, free the buffer CALL DNFWDS RETSKP NIFSCE: MOVE T1,BUFADR ; Free the buffer CALL DNFWDS RNMXER (NF.OPF) ; and return operation failure ENDSV. ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- Ethernet Parameters ;Still in IFN FTNI XSWAPCD NIDLPT: PARAMETER (^D0,,,,,,,,) PARAMETER (^D1105,,^D20,^D5,^D10,,,< STOR T2,LNBNO,(LN)>,) ; This works for all but CI PARAMETER (^D1110,,,,,,,,< Controller>) PARAMETER (^D1112,,,,,,,,< Protocol>) PARAMETER (^D1160,,,,,,,,< Hardware address>) PARAMETER(^D2500,,,,,,,,< Receive buffer size>) NIDLPL==.-NIDLPT NIDCPT: PARAMETER (^D1112,,,,,,,,< Circuit type>) NIDCPL==.-NIDCPT NIDNPT: PARAMETER (^D10,,,,,,,,< Physical address>) NIDNPL==.-NIDNPT XRESCD ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- Ethernet counters ;Still in IFN FTNI XSWAPCD NIDLCT: COUNTER (^D0,^D16,,,,) COUNTER (^D1000,^D32,,,,) COUNTER (^D1001,^D32,,,,) COUNTER (^D1002,^D32,,,,) COUNTER (^D1010,^D32,,,,) COUNTER (^D1011,^D32,,,,) COUNTER (^D1012,^D32,,,,< Multicast data blocks received>) COUNTER (^D1013,^D32,,,,< Data blocks sent, initially deferred>) COUNTER (^D1014,^D32,,,,< Data blocks sent, single collision>) COUNTER (^D1015,^D32,,,,< Data blocks sent multiple collisions>) COUNTER (^D1060,^D16,,,,) COUNTER (^D1062,^D16,,,,) COUNTER (^D1063,^D16,,,,) COUNTER (^D1064,^D16,,,,) COUNTER (^D1065,^D16,,,,) COUNTER (^D1066,^D16,,,,) NIDLCL==.-NIDLCT ;Ethenet portal counters NIDCCT: COUNTER (^D1000,^D32,,,,) COUNTER (^D1001,^D32,,,,) COUNTER (^D1010,^D32,,,,) COUNTER (^D1011,^D32,,,,) COUNTER (^D1065,^D16,,,,) NIDCCL==.-NIDCCT XRESCD ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- DLLNI - Call Ethernet driver ;Still in IFN FTNI XRESCD IFN FTOPS20,< DLLNI: XCALLRET (MSEC1,DLLUNI) ; Call NISRV wherever he may be >; END IFN FTOPS20 IFN FTOPS10,< DLLNI: SNCALL (ETHSER##,MCSEC1) RET RETSKP >; END IFN FTOPS10 ;Still in IFN FTNI SUBTTL Network management - Read portal counters ;Still in IFN FTNI ;Call: ; T1/ Function (read/read and zero) ; T2/ Buffer for counter data ; T3/ Buffer length ; DL/ Data link block XSWAPCD NIFRPC: STKVAR MOVEM T1,FUNC MOVEM T2,BUFADR MOVEM T3,BUFLEN CALL GETUNB ; Get a UN block RET LOAD T1,LNPID,(LN) ; Get the portal ID SKIPE T1 ; Portal closed? IFSKP. SETOM RCCFLG ; Yes, mark function as completed CALLRET NMXGUD ; And return success ENDIF. STOR T1,UNPID,(UN) ; Store portal id STOR T1,UNSID,(UN) ; Portal to read buffers for MOVE T1,BUFADR ; Get address of buffer for NISRV STOR T1,UNBFA,(UN) MOVE T1,BUFLEN ; and its length STOR T1,UNBSZ,(UN) MOVE T1,FUNC CAIE T1,NF.SZC ; Is function show and zero? IFSKP. SETONE UNZRO,(UN) ; Yes, set the to be zeroed flag ENDIF. SETZM RCCFLG ; Clear read/clear complete flag MOVX T1,NU.RPC ; Function is read portal counters MOVE T2,UN CALL DLLNI CALLRET NMXERR ; Failed with error in T1 CALLRET NMXGUD ; Success - counters loaded into users buffer ENDSV. XRESCD ;Still in IFN FTNI SUBTTL Network management - Read channel counters ;Still in IFN FTNI ;Call: ; T1/ Function to perform ; T2/ Counter buffer address ; T3/ Counter buffer length XSWAPCD NIFRCC: STKVAR MOVEM T1,FUNC MOVEM T2,BUFADR MOVEM T3,BUFLEN CALL GETUNB ; Get a UN block RET CALL NIFOIP ; Get the info portal ID RET ; Can't get it STOR T1,UNPID,(UN) LOAD T1,NFETY,(P1) ; Get line ID LOAD T1,LIKON,+T1 ; Get ethernet channel number STOR T1,UNSID,(UN) MOVE T1,BUFADR ; Get users buffer address STOR T1,UNBFA,(UN) MOVE T1,BUFLEN ; and length of buffer STOR T1,UNBSZ,(UN) MOVE T1,FUNC CAIE T1,NF.SZC ; Is function show and zero? IFSKP. SETONE UNZRO,(UN) ; Yes, set the to be zeroed flag ENDIF. SETZM RCCFLG ; Clear read/clear complete flag MOVX T1,NU.RCC ; Function is read channel counters MOVE T2,UN CALL DLLNI CALLRET NMXERR ; Failed with error in T1 CALLRET NMXGUD ; Success - Wait for counters to be loaded ENDSV. ; into data buffer XRESCD ;Still in IFN FTNI SUBTTL Network management - Get informational portal ID ;Still in IFN FTNI ;Call: ; With nothing ; ;Uses: T1-T4 XSWAPCD NIFOIP: SKIPE T1,INFPID ; Do we have one already? RETSKP ; Return it in T1 SAVEAC CALL GETUNB RET SETO T1, ; Get a -1 STOR T1,UNPRO,(UN) ; Indicate we want an information portal SETZM $UNUID(UN) ; Zero user id XMOVEI T1,DNDNII ; Get callback routine address STOR T1,UNCBA,(UN) ; Save it MOVX T1,NU.OPN ; Open the portal MOVE T2,UN ; Get UN block addr into T2 CALL DLLNI CALLRET FREUNB ; Sigh... LOAD T1,UNPID,(UN) ; Get informational portal ID MOVEM T1,INFPID ; Save for posterity CALL FREUNB MOVE T1,INFPID ; Return portal ID to caller RETSKP ; Return PID in T1 XRESCD ;Still in IFN FTNI SUBTTL NIFCIP - Close the information portal ;Still in IFN FTNI ;Call: NIFCIP: SKIPN INFPID ; Is there an information portal open? RET ; No SAVEAC CALL GETUNB ; Yes, get a UN block RET MOVE T1,INFPID ; Get the portal ID for NISRV STOR T1,UNPID,(UN) MOVX T1,NU.CLO ; Function is "close portal" MOVE T2,UN CALL DLLNI TRNA SETZM INFPID ; No longer have a portal open CALLRET FREUNB ;Still in IFN FTNI SUBTTL Network management - Read Ethernet addreses ;Still in IFN FTNI ;NMFRHA - Read hardware address XSWAPCD NMFRHA: JSP T1,NIFRCI ; Read the address from the driver LOAD T1,UNHAD,(UN) ; Get hi-order of address LOAD T2,UNHAD,+1(UN) ; and lo-order LOAD T3,NFBUF,(P1) ; Get the buffer address MOVEM T1,(T3) ; and store the hardware address in it MOVEM T2,1(T3) RET ;Read current physical address NMFRPA: JSP T1,NIFRCI ; Read the physical address from the driver LOAD T1,UNCAR,(UN) ; Get hi-order of address LOAD T2,UNCAR,+1(UN) ; and lo-order LOAD T3,NFBUF,(P1) ; Get the buffer address MOVEM T1,(T3) ; and store the hardware address in it MOVEM T2,1(T3) RET XRESCD ;Still in IFN FTNI SUBTTL Network management - Read channel information ;Still in IFN FTNI ;Call: ; P1/ NF argument block XSWAPCD NIFRCI: STKVAR MOVEM T1,RETADR CALL GETUNB ; Get a UN block RET LOAD T1,NFETY,(P1) ; Get entity type CAIE T1,.NTNOD ; Is it node? IFSKP. SETZ T1, ; Use channel 0 ELSE. LOAD T1,NFEID,(P1) ; Get entity ID LOAD T1,LIKON,+T1 ; Get ethernet channel number ENDIF. STOR T1,UNSID,(UN) SETZRO UNBSZ,(UN) ; Indicate no aux buffer MOVX T1,NU.RCI ; Function is read channel information MOVE T2,UN CALL DLLNI ; Call NISRV CALLRET NMXERR ; Error - T1 contains reason (???) NTMAN? MOVE T1,RETADR CALL (T1) ; Let caller copy the data he wants CALL FREUNB MOVX T1,NF.FCS ; Indicate success ; Can't use NMXGUD here - Must be non-skip RET ; Success - Parameter loaded into users buffer XRESCD ;Still in IFN FTNI SUBTTL Network management - Read counters interlock ;Still in IFN FTNI ;NIDLKW - Interlock routine for process level callers ; ; Call: ; T1/ Address of processor to call with the interlock ; ; Return: ; RET ; ; Uses: T1 ; ;This version of the interlock will spin on NIDLOK until it is freed. ;This is to be called only from process level, thus it will only spin ;if another process has the interlock. NIDLKW: AOSN NIDLOK ; Test and set the interlock RET ; Its free, continue processing IFN FTOPS10,< MOVEI T1,1 ; Sleep a second PUSHJ P,SLEEPF## ; ... JRST NIDLKW ; And try again >; END IFN FTOPS10 IFN FTOPS20,< XMOVEI T1,NIDLST ; No, set up scheduler test MDISMS ; Wait for competing process to finish JRST NIDLKW ; Ok, lets try again RESCD NIDLST: SKIPL NIDLOK ; Is read counters lock free yet? RET ; No, sleep on RETSKP ; Yes, wake up fork NISCHK: SKIPL RCCFLG ; Has data been returned yet? RET ; No, sleep on RETSKP ; Yes, wake up fork XRESCD > ;End FTOPS20 NMXGUD: AOS (P) ; Make a skip return NMXERR: SAVEAC ; Preserve error code if any CALL FREUNB RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIDPRB - Post receive buffers ;Still in IFN FTNI ;Call: ; DL/ Data link block NIDPRB: SAVEAC CALL GETUNB ; Get a fresh UN block RET LOAD T1,LNPID,(LN) ; Get the portal ID STOR T1,UNPID,(UN) ; and put it in UN block for DLL DO. LOAD T1,LNNBP,(LN) ; Get number posted OPSTR ,LNBNO,(LN) ; Enough posted? CALLRET FREUNB ; Yes, return LOAD T1,LNBSZ,(LN) ; Get the size to post for this link ADDI T1,%RTEHS ; Add overhead for Ethernet header CALL DNGMSG ; Request a message block CALLRET FREUNB ; None available MOVE MB,T1 ; Save message block address STOR T1,UNRID,(UN) ; Store the MB as request ID XMOVEI T1,+UD.MSD(MB) ; Get address of MSD CALL DNF2WG## ; Fetch a two word global byte pointer OPSTR ,UNBFA,(UN) ; Store buffer address MOVEI T2,UNA.EV ; We are using EXEC virtual memory STOR T2,UNADS,(UN) ; ... LOAD T1,MDALL,+UD.MSD(MB) ; Get allocated length STOR T1,UNBSZ,(UN) ; So the port knows what it can swallow MOVEI T1,NU.RCV ; Function is post receive buffer MOVE T2,UN ; Get address of UN block CALL DLLNI ; Attempt to post the buffer JRST [MOVE T1,MB ; Get message block address CALL DNFMSG ; Free message block we couldn't post CALLRET FREUNB] ; and return INCR LNNBP,(LN) ; Account for buffer posted LOOP. ; Loop back ENDDO. ;Still in IFN FTNI SUBTTL NIFEMA - Enable multicast address ;Still in IFN FTNI ;Call: T1/ Address to enable ; UN/ UN block to use NIFEMA: STOR T1,UNDAD,(UN) ; Save the address for the port SETZRO UNDAD,+1(UN) ; Node address field is zero MOVX T1,NU.EMA ; Enable this address MOVE T2,UN CALLRET DLLNI ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- DNDNII - Ethernet driver callback ;Still in IFN FTNI ;DNDNII - Interrupt from NISRV ; ;Call: ; T1/ Function code (NU.xxx) ; T2/ UN block address DNDNII: CAXL T1,NU.OPN CAXLE T1,NU.MAX BUG. (CHK,DNDIKF,DNADLL,SOFT,,,< This BUG is not documented yet. >,RTN) SAVEAC MOVE UN,T2 ; UN block address SKIPN DL,$UNUID(UN) ; From that get the data link block TDZA LN,LN ; If none, zero LN and skip LOAD LN,DLLNB,(DL) ; Point to line data block address MOVE T1,NIIDLI(T1) CALLRET (T1) ; Dispatch to correct routine NIIDLI: IFIW ; Unused IFIW ; Open portal (unused) IFIW ; Close a Portal Callback IFIW ; Datagram Received Callback IFIW ; Datagram Sent Callback IFIW ; Enable Multicast Callback IFIW ; Disable multicast callback IFIW ; Read channel list IFIW ; Read channel information IFIW ; Read channel counters IFIW ; Set channel address IFIW ; Read portal list IFIW ; Read portal information IFIW ; Read portal counters IFIW ; Read kontroller list IFIW ; Read kontroller information IFIW ; Read kontroller counters NIIILL: RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIICLS - Close done ;Still in IFN FTNI ;Call ; UN/ UN block from driver ; DL/ Address of DL block ; LN/ Address of line block NIICLS: JUMPE LN,RTN ; Return if information portal SETZRO LNPID,(LN) ; Clear portal id RET ; And return ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIIRCV - Receive done ;Still in IFN FTNI ;Call ; UN/ UN block returned by NISRV NIIRCV: DECR LNNBP,(LN) ; Another buffer used up ;** BUGCHK?? LOAD MB,UNRID,(UN) ; Set up MB SKIPE T3 ; Any errors? JRST NIIRCE ; Yes, log event and return message LOAD T1,UNSAD,(UN) ; Get the high order source address STOR T1,MBSR1,(MB) ; Put it into the MB SETZ T1, LOAD T2,UNSAD,+1(UN) ; Get the low order (node address) in LSHC T1,^D8 ; string format. Shift nn-2 into T1 LSH T2,-^D20 ; Right justify the area+2 IOR T1,T2 ; and include the number STOR T1,MBSRC,(MB) ; Stuff it into the MB OPSTR ,UNBFA,(UN) ; Fetch two word global byte pointer XMOVEI T3,+UD.MSD(MB) ; Get address of MSD CALL DNSBP## ; Store the byte pointer into the MSD LOAD T1,UNBSZ,(UN) ; Get the length received STOR T1,MDBYT,+UD.MSD(MB) ; Save as bytes written MOVEI T1,DI.INC ; Function is input complete MOVE T3,MB ; LOAD T4,UNDAD,(UN) ; So Router knows destination multi- ; cast if running as endnode CALL DNDQUE ; Queue up the buffer for jiffy level CALLRET NIDPRB ; Post another buffer if possible NIIRCE: CAIE T3,UNLER% ; Length error? IFSKP. MOVEI T1,DE%RCF ; Yes, say receive failed CALL NIEVNT ; See if we need to log an event ENDIF. ; CAIE T3,UNRAB% ; Buffer being returned because port ; is shutting down? ; Remove next ; when NISRV etc is fixed ; CALL NIDPRB ; Post another buffer MOVE T1,MB ; Get message block address CALLRET DNFMSG ; and return to free list ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIIXMT - Transmit done ;Still in IFN FTNI NIIXMT: SKIPN T3 ; Any errors? IFSKP. MOVEI T1,DE%XMF ; Transmit failed CALL NIEVNT ; See if we need to log an event ENDIF. MOVEI T1,DI.ODN ; Function is Output Done LOAD T3,UNRID,(UN) ; Address of message block CALL DNDQUE ; Queue it up RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIIRPC - Read portal counters ;Still in IFN FTNI NIIRPC: SETOM RCCFLG ; Read counters is complete LOAD T1,UNBFA,(T2) ; Get buffer address MOVEM T3,-1(T1) ; Store flags ahead of data RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIIRCI - Read channel info ;Still in IFN FTNI ;Call: ; UN/ UN block ; DL/ DL block ; LN/ Line data block address NIIRCI: MOVEI T3,LS.OFF ; Assume state is off TMNE UNRUN,(UN) ; Is new state "running"? MOVEI T3,LS.ON ; Yes, change to on state LOAD T1,LNSTA,(LN) ; Get current state CAIN T1,(T3) ; Any change? RET ; No, then done STOR T3,LNSTA,(LN) ; Save new state TMNN DLLIU,(DL) ; Is Router using this line? IFSKP. CAIN T3,LS.ON ; Yes, is new state "running"? CALL NIDPRB ; Yes, try to post buffers MOVEI T1,DI.LSC ; Notify ROUTER for either state CALL DNDQUE ENDIF. RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIISCA - Set channel address ;Still in IFN FTNI ;Call: ; DL/ Data link block (if any) ; LN/ Line data block address ; UN/ UN block address NIISCA: LOAD T3,UNCAR,(UN) ; Get hi-order of new address LOAD T4,UNCAR,+1(UN) ; Get low order address DMOVEM T3,DCNNIA ; Save address JUMPE DL,RTN ; If no data link block then don't check for ; DECnet address TMNN DLLIU,(DL) ; Is Router using this data link? RET ; No, not to worry then CAMN T3,RTRHIO ; YES, is the address still DECnet's? CAME T4,RTRLOO ; Is it our local address? IFSKP. TMNE LNCAD,(LN) ; Was it DECnet before? RET ; Yes, then done SETONE LNCAD,(LN) ; Indicate channel address is DECnet MOVX T3,LS.ON ; Signal a line state change to on MOVX T1,DI.LSC CALL DNDQUE ; Notify Router ELSE. TMNN LNCAD,(LN) ; Was it DECnet before? RET ; No, then done SETZRO LNCAD,(LN) ; Channel address is not DECnet's MOVEI T1,DI.LSC ; Yes, notify ROUTER MOVX T3,LS.OFF ; Report new line state is off CALL DNDQUE ENDIF. RET ;Still in IFN FTNI SUBTTL NIDLL - Ethernet data link layer -- NIIRCC - Read channel counters ;Still in IFN FTNI NIIRCC: SETOM RCCFLG ; Read couters is complete LOAD T1,UNBFA,(T2) ; Get buffer address MOVEM T3,-1(T1) ; Store flags ahead of data CALLRET NIFCIP ; Close information portal and return ;Still in IFN FTNI SUBTTL - Ethernet event reporter ;Still in IFN FTNI ;Call: ; T1/ Type ; T3/ Reason ; DL/ data link block ; NIEVNT: STKVAR MOVEM T1,EVNTYP MOVNI T2,NIETBL ; Length of event table HRLZ T2,T2 NIEVN1: HLRZ T1,NIEVTB(T2) ; Get reason code CAIN T1,(T3) ; Is this the one? JRST NIEVN2 ; Yes, try to log the event AOBJN T2,NIEVN1 ; No, try next RET NIEVN2: MOVE T1,EVNTYP ; Get type HRRZ T3,NIEVTB(T2) ; Get event reason LOAD T2,DLDID,(DL) ; Get entity ID CALLRET RTNEVT ;Data link layer events DE%XMF==^D14 ; Transmit failed DE%RCF==^D15 ; Receive failed NIEVTB: XWD UNEXC%,^D0 ; Excessive collisions XWD UNCCF%,^D1 ; Carrier check failed XWD UNSHT%,^D3 ; Short circuit XWD UNOPN%,^D4 ; Open circuit XWD UNLER%,^D5 ; Length error (frame too long) XWD UNRFD%,^D6 ; Remote failure to defer NIETBL=.-NIEVTB ;Still in IFN FTNI SUBTTL Network Management Interface -- RTNEVT - Event Reporter ;Still in IFN FTNI ;RTNEVT - Report Router event ; ; Call: ; T1/ Event type ; T2/ Entity ID (we know the entity type from DNETAB) ; T3/ Event specific word (REASON, STATUS, etc.) ; ; Return: ; RET ;ALWAYS ; ; Uses: T1-T4 ; ;This calls something which will call network management to log this event ;which has taken place. This routine is called by the EVENT macro. EVTMLN==^D15 ;Maximum length of event parameter data (bytes) RTNEVT: SAVEAC DMOVE P1,T1 MOVEM T3,DNDEVW ; Save the event argument ;Check if event should be thrown away MOVX T1,.NCDLL ; DNADLL event class STOR T1,FACCL,+T2 STOR P1,FACTY,+T2 ; and event type to T2 MOVX T1,EV.FIL ; Function code "filter event" CALL NMXEVT RET ; -throw it away SKIPN DNDECP ; Verify that EC pointer is non-zero RET ; -was zero, must have failed to initialize ; Continued... ;Still in IFN FTNI ;Still in IFN FTNI ;Ok, to log an event MOVX T1,NE.LEN+</4> ;Get enough for arg block and ; Maximum amount of event parameter data CALL DNGWDZ ;Get the words BUG.(CHK,DNDCGV,DNADLL,SOFT,,,< Cause: This BUG is not documented yet. >,RTN) STOR P1,NECTY,(T1) ; Put the event type in the arg block STOR P2,NEEID,(T1) ; Put entity-id in event block MOVE P1,T1 ; Save the pointer to the block MOVE T1,DNDECP ; Get EC pointer STOR T1,NEECP,(P1) ; and store it in NE block MOVX T1,.NTLIN ; Get our entity type STOR T1,NEETP,(P1) MOVX T1,.NCDLL ; The event class is data link STOR T1,NECCL,(P1) ; Put in ne arg block XMOVEI T1,NE.LEN(P1) ; Make a fullword pointer to data STOR T1,NEDAT,(P1) ; Store pointer to it in arg block MOVE P2,[POINT 8,NE.LEN(P1)] ; Make up byte pointer to parameter data SETZ T4, ; Intialize count of bytes written CALL DNDRFR ; Write parameter strings into the data area STOR T4,NEDLN,(P1) ; Save count of bytes actually written MOVX T1,EV.LOG ; Function code is "log an event" MOVE T2,P1 ; NE pointer in T2 CALL NMXEVT ; Call the event processor TRN RET ; Return, NTMAN will deallocate NE block DNDRFR: MOVEI T1,^D16 ; Parameter number - Failure reason MOVEI T2,2 ; Get number of bytes CALL PUTNBT ; Insert the bytes swapped MOVEI T1,201 ; Coded, single field, length 1 byte CALL PUTBYT ; Stuff it MOVE T1,DNDEVW ; Get the reason CALLRET PUTBYT ; Insert it and return ;Still in IFN FTNI ;Still in IFN FTNI ;Put n (in T2) bytes of the number in T1. PUTNBT: JUMPE T2,RTN ; Return if nothing left IDPB T1,P2 ; Put the byte in the message LSH T1,-^D8 ; Shift over to the next byte ADDI T4,1 ; Update the count SOJA T2,PUTNBT ; Do the rest ;Put one byte (in T1) into the data string for network management PUTBYT: IDPB T1,P2 ; Install the byte AOJA T4,RTN ; Increment the number of bytes ;Still in IFN FTNI SUBTTL Miscellaneous routines ;Still in IFN FTNI ;GETUNB - Get a UN block GETUNB: SYSPIF ; No interrupts please SKIPN UN,DNDUNQ ; Any free blocks on the queue? IFSKP. MOVE T1,(UN) ; Yes, take the first one MOVEM T1,DNDUNQ SOS DNDUQL ; and account for it SYSPIN ELSE. SYSPIN MOVX T1,UN.LEN ; Get length of user NI block CALL DNGWDS ; Try to get the words RET ; Can't, return error MOVE UN,T1 ; Get address of UN block ENDIF. MOVEI T1,UN.LEN-1 ; Clear UN block MOVE T2,UN ; ... XMOVEI T3,1(T2) ; ... SETZM (UN) ; Zero first word CALL XBLTA## ; Zero remainder RETSKP ; Return address in UN ;Free a UN block. ;This means put it on the queue of free UN blocks or return it to the ; the free pool if the queue is at the desired maximum. FREUNB: MOVE T1,DNDUQL ; Get the length of the UN block queue CAIG T1,6 ; Is it greater than the desired maximum? IFSKP. MOVE T1,UN ; Yes, the free the block CALL DNFWDS ELSE. SYSPIF MOVE T1,DNDUNQ ; No, get the queue head MOVEM T1,(UN) ; and put this one at the head MOVEM UN,DNDUNQ AOS DNDUQL ; Add it into the count SYSPIN ENDIF. RET ;Still in IFN FTNI SUBTTL Miscellaneous routines -- Check Ethernet address ;Still in IFN FTNI CHKADR: DMOVE T1,DCNNIA ; Get the current address CAMN T1,RTRHIO ; and see if it is DECnet's CAME T2,RTRLOO RET ; No, then non-skip RETSKP >; END IFN FTNI SUBTTL Local storage for DNADLL RESDT DNDINQ: BLOCK QH.LEN ; Queue of interrupt callback functions DLBQUE: BLOCK QH.LEN ; Queue of data link blocks LNBQUE: BLOCK QH.LEN ; Queue of line data blocks DNDUNQ: BLOCK 1 ; Queue of free UN blocks DNDUQL: BLOCK 1 ; Length of UN block queue DNDQBQ: BLOCK 1 ; Queue of free function blocks DNDQBL: BLOCK 1 ; Length of QB queue DNDRNT: BLOCK 1 ; Router's node type RCCFLG: EXP -1 ; Read couter complete flag for NIDLL NIDLOK: EXP -1 ; Interlock so only one counter reader NIDLKO: BLOCK 1 ; Owner of interlock DNDEVW: BLOCK 1 ; Event reason DNDECP: EXP 0 ; Event communication pointer INFPID: EXP 0 ; Informational portal ID DCNNIA: BLOCK 2 ; DECnet Ethernet address XRESCD IFN FTOPS10,< RESDT DNDLOW::! XRESCD >; END IFN FTOPS10 END