Trailing-Edge
-
PDP-10 Archives
-
tops10_704_monitoranf_bb-x140c-sb
-
10,7/mon/dnadll.mac
There are 20 other files named dnadll.mac in the archive. Click here to see a list.
;TITLE DNADLL - DLL use interface for DECnet-36 V024
SUBTTL Marty Palmieri 19-APR-88
SEARCH ETHPRM,D36PAR,MACSYM
SALL
ENTRY DNDINI
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1983,1984,1986,1988.
;ALL RIGHTS RESERVED.
XP DNADLL,024
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,1988>
>;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,<PRINTX ?Missing $EOB after a $BUILD>
..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,<PRINTX ?$SET without previous $BUILD>
IFNB <STR>,<
IFB <OFFSET>,<..STR0 (..SET,<VALUE>,STR)>
IFNB <OFFSET>,<..STR0 (..SET,<VALUE>,STR,OFFSET)>>
IFB <STR>,<
IFB <OFFSET>,<..STR0 (..SET,<VALUE>,FWMASK)>
IFNB <OFFSET>,<..STR0 (..SET,<VALUE>,FWMASK,OFFSET)>>
> ; END OF $SET DEFINITION
DEFINE ..SET (VALUE,LOC,MSK) <
IFGE <<<LOC>&777777>-..BSIZ>,<
PRINTX ?WORD offset greater than $BUILD size parameter>
SET0. (\<LOC>,MSK,<VALUE>)
> ;END ..SET DEFINITION
; After all values are declared, the block must be closed to do its actual
; creation.
DEFINE $EOB,<
IFNDEF ..BSIZ,<PRINTX ?$EOB without previous $BUILD>
IFN <.-..BLOC>,<PRINTX ?Address change between $BUILD and $EOB>
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,<EXP ..T'N
PURGE ..T'N>
> ;END OF BLD0. DEFINITION
DEFINE SET0.(LOC,MSK,VALUE),<
IFN <<..T'LOC>&MSK>,<PRINTX ?Initial field not zero in $SET>
..TVAL==<VALUE>
..TMSK==<MSK>
..T'LOC==..T'LOC!<FLD(..TVAL,..TMSK)>
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
TRACE DND,<Initializing DNADLL>
SAVEAC <P1,DL,LN>
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 <RTN&777777> ; Test bed driver (obsolete)
IFIW <DTDINI&777777> ; DTE line driver
IFIW <KDDINI&777777> ; KDP line driver
IFIW <DDDINI&777777> ; DDP (ANF-10) line driver
IFIW <CIDINI&777777> ; CI-20 SCA line driver
IFIW <NIDINI&777777> ; NIA-20 Ethernet line driver
IFIW <DMDINI&777777> ; DMR-11 line driver
IF1,<IFN <LD.MAX-<.-INITBL-1>>,<? Wrong number of entries in INITBL>>
XRESCD
SUBTTL DNADLL - Generic data link layer -- DNDJIF - Once a jiffy code
INTERNAL DNDJIF
XRENT DNDJIF
SAVEAC <P1,DL>
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 <SKIPN>, 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 <DL,LN> ; 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 <RTN&777777> ; Test bed driver (obsolete)
IFIW <DTDSEC&777777> ; DTE line driver
IFIW <KDDSEC&777777> ; KDP line driver
IFIW <DDDSEC&777777> ; DDP (ANF-10) line driver
IFIW <CIDSEC&777777> ; CI-20 SCA line driver
IFIW <NIDSEC&777777> ; NIA-20 Ethernet line driver
IFIW <DMDSEC&777777> ; DMR-11 line driver
IF1,<IFN <LD.MAX-<.-SECTBL-1>>,<? Wrong number of entries in SECTBL>>
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 <P1,P2,P3> ; 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 <DL,LN>
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,<Illegal function code from ROUTER>,,<
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 <RTN&777777> ; Test bed driver (obsolete)
IFIW <DTDDSP&777777> ; DTE line driver
IFIW <KDDDSP&777777> ; KDP line driver
IFIW <DDDDSP&777777> ; DDP (ANF-10) line driver
IFIW <CIDDSP&777777> ; CI-20 SCA line driver
IFIW <NIDDSP&777777> ; NIA-20 Ethernet line driver
IFIW <DMDDSP&777777> ; DMR-11 line driver
IF1,<IFN <LD.MAX-<.-DSPTBL-1>>,<? Wrong number of entries in DSPTBL>>
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 <DL,LN>
CAXL T1,NF.SET ; Range check the
CAXLE T1,NF.CET ; function code
BUG.(CHK,DNDINF,DNADLL,SOFT,<Illegal function code from NTMAN>,,<
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,<IFN <NF.MAX-<.-NXFTBL-1>>,<? Wrong number of entries in NXFTBL>>
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 <P1>
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 <NMXILS&777777> ; SIGNIFICANT lines not supported
IFIW <NMXILS&777777> ; ADJACENT lines
IFIW <NMXILS&777777> ; LOOP line
IFIW <NMXSAL&777777> ; ACTIVE lines
IFIW <NMXSKL&777777>](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 <P2,LN>
STKVAR <FUNC>
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 <P1> ; 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 <P1,P2> ; 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 <CAML T1,>,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 <FUNC>
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==RTN
DDDSEC==RTN
DDDDSP==RTN
DDIINE==:RTN
DDIPPI==:RTN
>; 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 <DDDOPN&777777> ; Open a portal/circuit
IFIW <DDDCLS&777777> ; Close a portal/circuit
IFIW <DDDXMT&777777> ; Transmit a packet
IFIW <DDDSET&777777> ; Set a parameter
IFIW <DDDCLR&777777> ; Clear a parameter
IFIW <DDDRED&777777> ; Read paramater
IFIW <DDDSHC&777777> ; Show counters
IFIW <DDDSZC&777777> ; Show and zero counters
IFIW <DDDILL&777777> ; Return list
IFIW <DDDILL&777777> ; Map Node Address to Name
IFIW <DDDILL&777777> ; Map Node Name to Address
IFIW <DDDILL&777777> ; Check Entity Id
IF1,<IFN <DF.MAX-<.-DDDDTB-1>>,<? Wrong number of entries in DDDDTB>>
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,,,,,<TRN>,<LOAD T2,LNSTA,(LN)>,<TRN>,<
Line state>)
PARAMETER (^D1105,,^D20,^D5,^D10,<STOR T2,LNBNO,(LN)>,<LOAD T2,LNBNO,(LN)>,<
STOR T2,LNBNO,(LN)>,<Receive buffers>)
PARAMETER(^D1110,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCON,(LN)>,<TRN>,<
Controller>)
PARAMETER(^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNPRO,(LN)>,<TRN>,<
Protocol>)
PARAMETER(^D2500,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNBSZ,(LN)>,<TRN>,<
Receive buffer size>)
DDDLPL==.-DDDLPT
DDDCPT:
PARAMETER (^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCTY,(LN)>,<TRN>,<
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,<LOAD T1,DLBYR,(DL)>,<SETZRO DLBYR,(DL)>,,<
Bytes received>)
COUNTER (^D1001,^D32,<LOAD T1,DLBYS,(DL)>,<SETZRO DLBYS,(DL)>,,<Bytes sent>)
COUNTER (^D1010,^D32,<LOAD T1,DLDBR,(DL)>,<SETZRO DLDBR,(DL)>,,<
Data blocks received>)
COUNTER (^D1011,^D32,<LOAD T1,DLDBS,(DL)>,<SETZRO DLDBS,(DL)>,,<
Data blocks sent>)
COUNTER (^D1065,^D16,<LOAD T1,DLUBU,(DL)>,<SETZRO DLUBU,(DL)>,,<
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 <FUNC>
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 <FUNC>
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
INTERNAL DDIPPI
XRENT DDIPPI
CAXL T1,DI.ODN
CAXLE T1,DI.ICB
BUG. (CHK,DDIIFD,DNADLL,SOFT,<Illegal function from DDP driver>,,<
This BUG is not documented yet.
>,RTN)
SAVEAC <DL,LN> ; 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 <DDIILL&777777> ; Unused
IFIW <DDIODN&777777> ; Output done
IFIW <DDIINC&777777> ; Input complete
IFIW <DDILSC&777777> ; Line state change
IFIW <DDIICB&777777> ; Initialize circuit block
IF1,<IFN <DI.MAX-<.-DDIDLI-1>>,<? Wrong number of entries in DDIDLI>>
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 <ADDM T1,>,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 <ADDM T1,>,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 [crock] 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
INTERNAL DDIINE
XRENT DDIINE
SAVEAC <DL,LN> ; Save the usual ACs
SKIPN DL,T2 ; Must have the data link block address
STOPCD .,STOP,DNAWEM, ;++ 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 <DL,LN> ; 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 <MB>
LOAD T1,LNNBP,(LN) ; Get number posted
OPSTR <CAML T1,>,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 <DMDOPN&777777> ; Open a portal/circuit
IFIW <DMDCLS&777777> ; Close a portal/circuit
IFIW <DMDXMT&777777> ; Transmit a packet
IFIW <DMDSET&777777> ; Set a parameter
IFIW <DMDCLR&777777> ; Clear a parameter
IFIW <DMDRED&777777> ; Read paramater
IFIW <DMDSHC&777777> ; Show counters
IFIW <DMDSZC&777777> ; Show and zero counters
IFIW <DMDILL&777777> ; Return list
IFIW <DMDILL&777777> ; Map Node Address to Name
IFIW <DMDILL&777777> ; Map Node Name to Address
IFIW <DMDILL&777777> ; Check Entity Id
IF1,<IFN <DF.MAX-<.-DMDDTB-1>>,<? Wrong number of entries in DDMDTB>>
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 <FUNC>
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 <FUNC>
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,<NOSET!NOCLR>,,,,,<LOAD T2,LNSTA,(LN)>,,<Line state>)
PARAMETER(^D1110,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCON,(LN)>,<TRN>,<
Controller>)
;PARAMETER(^D1111,,,,,<CALL DMDLCP>,<CALL DMDLRP>,<CALL DMDLSP>,<
; Duplex>)
PARAMETER(^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNPRO,(LN)>,<TRN>,<
Protocol>)
DMDLPL==.-DMDLPT
DMDCPT:
PARAMETER (^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCTY,(LN)>,<TRN>,<
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,<LOAD T1,DLBYR,(DL)>,<SETZRO DLBYR,(DL)>,,<
Bytes received>)
COUNTER (^D1001,^D32,<LOAD T1,DLBYS,(DL)>,<SETZRO DLBYS,(DL)>,,<Bytes sent>)
COUNTER (^D1010,^D32,<LOAD T1,DLDBR,(DL)>,<SETZRO DLDBR,(DL)>,,<
Data blocks received>)
COUNTER (^D1011,^D32,<LOAD T1,DLDBS,(DL)>,<SETZRO DLDBS,(DL)>,,<
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,<Illegal function from DMR driver>,,<
This BUG is not documented yet.
>,RTN)
SAVEAC <DL,LN> ; 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 <DMIPRU&777777> ; Protocol up
IFIW <DMIPRD&777777> ; Protocol down
IFIW <DMIMAI&777777> ; Maint msg received
IFIW <DMISTR&777777> ; Start received
IFIW <DMIODN&777777> ; Output done
IFIW <DMIOND&777777> ; Output not done
IFIW <DMIINC&777777> ; Input complete
IFIW <DMIBFR&777777> ; Get buffer
IFIW <DMIICB&777777> ; Initialize circuit block
IFIW <DMIDCB&777777> ; Destroy circuit block
IF1,<IFN <DC.IMX-<.-DMIDLI-1>>,<? Wrong number of entries in DMIDLI>>
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 <ADDM T1,>,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 <ADDM T1,>,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 <DL,LN> ; 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 <P1,P2> ; Save P1 and P2
MOVSI P1,-M.CPU## ; 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 <DTDOPN&777777> ; Open a portal/circuit
IFIW <DTDCLS&777777> ; Close a portal/circuit
IFIW <DTDXMT&777777> ; Transmit a packet
IFIW <DTDSET&777777> ; Set a parameter
IFIW <DTDCLR&777777> ; Clear a parameter
IFIW <DTDRED&777777> ; Read paramater
IFIW <DTDSHC&777777> ; Show counters
IFIW <DTDSZC&777777> ; Show and zero counters
IFIW <DTDILL&777777> ; Return list
IFIW <DTDILL&777777> ; Map Node Address to Name
IFIW <DTDILL&777777> ; Map Node Name to Address
IFIW <DTDILL&777777> ; Check Entity Id
IF1,<IFN <DF.MAX-<.-DTDDTB-1>>,<? Wrong number of entries in DTDDTB>>
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 <FUNC>
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 <FUNC>
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,<NOSET!NOCLR>,,,,,<LOAD T2,LNSTA,(LN)>,,<Line state>)
PARAMETER (^D1105,,^D20,^D5,^D10,<STOR T2,LNBNO,(LN)>,<LOAD T2,LNBNO,(LN)>,<
STOR T2,LNBNO,(LN)>,<Receive buffers>)
PARAMETER(^D1110,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCON,(LN)>,<TRN>,<
Controller>)
PARAMETER(^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNPRO,(LN)>,<TRN>,<
Protocol>)
PARAMETER(^D2500,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNBSZ,(LN)>,<TRN>,<
Receive buffer size>)
DTDLPL==.-DTDLPT
DTDCPT:
PARAMETER (^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCTY,(LN)>,<TRN>,<
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,<LOAD T1,DLBYR,(DL)>,<SETZRO DLBYR,(DL)>,,<
Bytes received>)
COUNTER (^D1001,^D32,<LOAD T1,DLBYS,(DL)>,<SETZRO DLBYS,(DL)>,,<Bytes sent>)
COUNTER (^D1010,^D32,<LOAD T1,DLDBR,(DL)>,<SETZRO DLDBR,(DL)>,,<
Data blocks received>)
COUNTER (^D1011,^D32,<LOAD T1,DLDBS,(DL)>,<SETZRO DLDBS,(DL)>,,<
Data blocks sent>)
COUNTER (^D1065,^D16,<LOAD T1,DLUBU,(DL)>,<SETZRO DLUBU,(DL)>,,<
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,<Illegal function code from DTE kontroller>,,<
This BUG is not documented yet.
>,RTN)
SAVEAC <DL,LN> ; 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 <DTIILL&777777> ; Unused
IFIW <DTIODN&777777> ; Output done
IFIW <DTIINC&777777> ; Input complete
IFIW <DTILSC&777777> ; Line state change
IFIW <DTIICB&777777> ; Initialize circuit block
IF1,<IFN <DI.MAX-<.-DTIDLI-1>>,<? Wrong number of entries in DTIDLI>>
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 <ADDM T1,>,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 <ADDM T1,>,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 <DL,LN> ; 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 <MB>
LOAD T1,LNNBP,(LN) ; Get number posted
OPSTR <CAML T1,>,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 <KDDOPN&777777> ; Open a portal/circuit
IFIW <KDDCLS&777777> ; Close a portal/circuit
IFIW <KDDXMT&777777> ; Transmit a packet
IFIW <KDDSET&777777> ; Set a parameter
IFIW <KDDCLR&777777> ; Clear a parameter
IFIW <KDDRED&777777> ; Read paramater
IFIW <KDDSHC&777777> ; Show counters
IFIW <KDDSZC&777777> ; Show and zero counters
IFIW <KDDILL&777777> ; Return list
IFIW <KDDILL&777777> ; Map Node Address to Name
IFIW <KDDILL&777777> ; Map Node Name to Address
IFIW <KDDILL&777777> ; Check Entity Id
IF1,<IFN <DF.MAX-<.-KDDDTB-1>>,<? Wrong number of entries in DKDDTB>>
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 <FUNC>
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 <FUNC>
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,<NOSET!NOCLR>,,,,,<LOAD T2,LNSTA,(LN)>,,<Line state>)
PARAMETER(^D1110,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCON,(LN)>,<TRN>,<
Controller>)
PARAMETER(^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNPRO,(LN)>,<TRN>,<
Protocol>)
KDDLPL==.-KDDLPT
KDDCPT:
PARAMETER (^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCTY,(LN)>,<TRN>,<
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,<LOAD T1,DLBYR,(DL)>,<SETZRO DLBYR,(DL)>,,<
Bytes received>)
COUNTER (^D1001,^D32,<LOAD T1,DLBYS,(DL)>,<SETZRO DLBYS,(DL)>,,<Bytes sent>)
COUNTER (^D1010,^D32,<LOAD T1,DLDBR,(DL)>,<SETZRO DLDBR,(DL)>,,<
Data blocks received>)
COUNTER (^D1011,^D32,<LOAD T1,DLDBS,(DL)>,<SETZRO DLDBS,(DL)>,,<
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,<Illegal function from KDP driver>,,<
This BUG is not documented yet.
>,RTN)
SAVEAC <DL,LN> ; 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 <KDIPRU&777777> ; Protocol up
IFIW <KDIPRD&777777> ; Protocol down
IFIW <KDIMAI&777777> ; Maint msg received
IFIW <KDISTR&777777> ; Start received
IFIW <KDIODN&777777> ; Output done
IFIW <KDIOND&777777> ; Output not done
IFIW <KDIINC&777777> ; Input complete
IFIW <KDIBFR&777777> ; Get buffer
IFIW <KDIICB&777777> ; Initialize circuit block
IFIW <KDIDCB&777777> ; Destroy circuit block
IF1,<IFN <DC.IMX-<.-KDIDLI-1>>,<? Wrong number of entries in KDIDLI>>
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 <ADDM T1,>,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 <ADDM T1,>,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 <DL,LN> ; 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 <UN>
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 <UN>
MOVE T1,NIDDTB(T1) ; Get processor address
CALLRET (T1) ; and dispatch
NIDDTB: IFIW <NIDOPN&777777> ; Open portal/circuit
IFIW <NIDCLS&777777> ; Close portal/circuit
IFIW <NIDXMT&777777> ; Transmit packet
IFIW <NIDSET&777777> ; Set parameter
IFIW <NIDCLR&777777> ; Clear parameter
IFIW <NIDRED&777777> ; Read parameter
IFIW <NIDSHC&777777> ; Show counters
IFIW <NIDSZC&777777> ; Show and zero counters
IFIW <NIDILL&777777> ; Return list
IFIW <NIDILL&777777> ; Map Node Address to Name
IFIW <NIDILL&777777> ; Map Node Name to Address
IFIW <NIDILL&777777> ; Check Entity Id
IF1,<IFN <DF.MAX-<.-NIDDTB-1>>,<? Wrong number of entries in NIDDTB>>
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
MOVE T2,DNDRNT ; Get Router's node type
CAIE T2,RNT.NR ; Endnode?
IFSKP.
MOVX T1,%RTEMA ; Yes, then multi-cast "ALL ENDNODES"
CALL NIFEMA
CALLRET FREUNB
MOVX T1,%RTRMA ; Multi-cast address "ALL ROUTERS"
SKIPE EVSDRP##
CALL NIFEMA ; Enable us to receive on this address
TRN
ELSE.
MOVX T1,%RTRMA ; Multi-cast address "ALL ROUTERS"
CALL NIFEMA ; Enable us to receive on this address
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 <P1,P2>
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 <CALL UPDTCK> ; 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 <FUNC>
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 <FUNC,BUFADR>
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 (<NF.OPF>,<SETOM NIDLOK>)
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 (<NF.OPF>,<SETOM NIDLOK>)
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 (<NF.OPF>,<SETOM NIDLOK>)
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 (<NF.OPF>,<SETOM NIDLOK>)
ENDIF.
ELSE.
MOVE T1,BUFADR ; Don't need this buffer any more
CALL DNFWDS
RNMXER (<NF.MPE>,<SETOM NIDLOK>)
ENDIF.
ENDIF.
IFN FTOPS10,<
NIDSC1: MOVEI T1,1 ; Sleep a second
IFE FTXMON,<RGCALL (SLEEPF##)> ; ...
IFN FTXMON,<SNCALL (SLEEPF##,MCSEC0)>
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,<NOSET!NOCLR>,,,,,<LOAD T2,LNSTA,(LN)>,,<Line state>)
PARAMETER (^D1105,,^D20,^D5,^D10,<STOR T2,LNBNO,(LN)>,<LOAD T2,LNBNO,(LN)>,<
STOR T2,LNBNO,(LN)>,<Receive buffers>) ; This works for all but CI
PARAMETER (^D1110,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCON,(LN)>,<TRN>,<
Controller>)
PARAMETER (^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNPRO,(LN)>,<TRN>,<
Protocol>)
PARAMETER (^D1160,<NOSET!NOCLR!BEX>,,,,<TRN>,<CALL NMFRHA>,<TRN>,<
Hardware address>)
PARAMETER(^D2500,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNBSZ,(LN)>,<TRN>,<
Receive buffer size>)
NIDLPL==.-NIDLPT
NIDCPT:
PARAMETER (^D1112,<NOSET!NOCLR>,,,,<TRN>,<LOAD T2,LNCTY,(LN)>,<TRN>,<
Circuit type>)
NIDCPL==.-NIDCPT
NIDNPT:
PARAMETER (^D10,<NOSET!NOCLR!BEX>,,,,<TRN>,<CALL NMFRPA>,<TRN>,<
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,<LOAD T1,CCSLZ,(P2)>,,,<Seconds since last zeroed>)
COUNTER (^D1000,^D32,<LOAD T1,CCBYR,(P2)>,,,<Bytes received>)
COUNTER (^D1001,^D32,<LOAD T1,CCBYX,(P2)>,,,<Bytes sent>)
COUNTER (^D1002,^D32,<LOAD T1,CCMBR,(P2)>,,,<Multicast bytes received>)
COUNTER (^D1010,^D32,<LOAD T1,CCDGR,(P2)>,,,<Data blocks received>)
COUNTER (^D1011,^D32,<LOAD T1,CCDGX,(P2)>,,,<Data blocks sent>)
COUNTER (^D1012,^D32,<LOAD T1,CCMDR,(P2)>,,,<
Multicast data blocks received>)
COUNTER (^D1013,^D32,<LOAD T1,CCDXD,(P2)>,,,<
Data blocks sent, initially deferred>)
COUNTER (^D1014,^D32,<LOAD T1,CCDX1,(P2)>,,,<
Data blocks sent, single collision>)
COUNTER (^D1015,^D32,<LOAD T1,CCDXM,(P2)>,,,<
Data blocks sent multiple collisions>)
COUNTER (^D1060,^D16,<LOAD T1,CCXMF,(P2)>,,<LOAD T1,CCXFM,(P2)>,<Send failures>)
COUNTER (^D1062,^D16,<LOAD T1,CCRCF,(P2)>,,<LOAD T1,CCRFM,(P2)>,<Receive failures>)
COUNTER (^D1063,^D16,<LOAD T1,CCUFD,(P2)>,,,<Unrecognized frame destination>)
COUNTER (^D1064,^D16,<LOAD T1,CCDOV,(P2)>,,,<Data overrun>)
COUNTER (^D1065,^D16,<LOAD T1,CCSBU,(P2)>,,,<System buffer unavailable>)
COUNTER (^D1066,^D16,<LOAD T1,CCUBU,(P2)>,,,<User buffer unavailable>)
NIDLCL==.-NIDLCT
;Ethenet portal counters
NIDCCT:
COUNTER (^D1000,^D32,<LOAD T1,PCBYR,(P2)>,,,<Bytes received>)
COUNTER (^D1001,^D32,<LOAD T1,PCBYX,(P2)>,,,<Bytes sent>)
COUNTER (^D1010,^D32,<LOAD T1,PCDGR,(P2)>,,,<Data blocks received>)
COUNTER (^D1011,^D32,<LOAD T1,PCDGX,(P2)>,,,<Data blocks sent>)
COUNTER (^D1065,^D16,<LOAD T1,PCUBU,(P2)>,,,<Use buffer unavailable>)
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 <FUNC,BUFADR,BUFLEN>
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 <FUNC,BUFADR,BUFLEN>
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 <UN>
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 <UN>
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 <RETADR>
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
IFE FTXMON,<RGCALL (SLEEPF##)> ; ...
IFN FTXMON,<SNCALL (SLEEPF##,MCSEC0)>
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 <T1> ; 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 <UN,MB>
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 <CAML T1,>,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 <DMOVEM T1,>,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,<Illegal function code from DLL kontroller>,,<
This BUG is not documented yet.
>,RTN)
SAVEAC <DL,LN,UN,P1,MB>
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 <NIIILL&777777> ; Unused
IFIW <NIIILL&777777> ; Open portal (unused)
IFIW <NIICLS&777777> ; Close a Portal Callback
IFIW <NIIRCV&777777> ; Datagram Received Callback
IFIW <NIIXMT&777777> ; Datagram Sent Callback
IFIW <NIIILL&777777> ; Enable Multicast Callback
IFIW <NIIILL&777777> ; Disable multicast callback
IFIW <NIIILL&777777> ; Read channel list
IFIW <NIIRCI&777777> ; Read channel information
IFIW <NIIRCC&777777> ; Read channel counters
IFIW <NIISCA&777777> ; Set channel address
IFIW <NIIILL&777777> ; Read portal list
IFIW <NIIILL&777777> ; Read portal information
IFIW <NIIRPC&777777> ; Read portal counters
IFIW <NIIILL&777777> ; Read kontroller list
IFIW <NIIILL&777777> ; Read kontroller information
IFIW <NIIILL&777777> ; 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 <DMOVE T1,>,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% ; Port shutting down?
CALL NIDPRB ; No, 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 <EVNTYP>
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 <P1,P2>
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+<<EVTMLN+3>/4> ;Get enough for arg block and
; Maximum amount of event parameter data
CALL DNGWDZ ;Get the words
BUG.(CHK,DNDCGV,DNADLL,SOFT,<Couldn't get memory for event arg block>,,<
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