1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-02-26 00:23:34 +00:00
Files
PDP-10.stacken/files/stacken-tape-backup/dskb:10_7/mon/dnadll.mac
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

3926 lines
108 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;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