Google
 

Trailing-Edge - PDP-10 Archives - BB-X117B-SB_1986 - 10,7/nml/nmlvdb.bli
There are 2 other files named nmlvdb.bli in the archive. Click here to see a list.
! UPD ID= 295, SNARK:<6.1.NML>NMLVDB.BLI.22,  15-Mar-85 17:18:34 by GLINDELL
!  Restrict setting and clearing of NAME for LOGGING CONSOLE and LOGGING FILE.
!
! UPD ID= 273, SNARK:<6.1.NML>NMLVDB.BLI.21,   4-Mar-85 17:49:50 by GLINDELL
!  More work on STATE SERVICE - hopefully works now (?!)
!
! UPD ID= 272, SNARK:<6.1.NML>NMLVDB.BLI.20,   4-Mar-85 11:55:00 by GLINDELL
!  Fix one bug in the STATE SERVICE code.  However, this doesn't make STATE
!  SERVICE work.
!
! UPD ID= 269, SNARK:<6.1.NML>NMLVDB.BLI.19,   1-Mar-85 10:02:59 by GLINDELL
!  Poke Data Link Watcher on STATE ON as well as on SERVICE ENABLE
!
! UPD ID= 261, SNARK:<6.1.NML>NMLVDB.BLI.18,  11-Feb-85 13:40:24 by GLINDELL
!  Fix bug introduced by upd 250 - SHOW CIRC XYZ didnt return an error
!
! UPD ID= 253, SNARK:<6.1.NML>NMLVDB.BLI.17,   7-Feb-85 21:16:41 by GLINDELL
!  Fix SET KNOWN CIRCUIT commands - dot bug.
!
! UPD ID= 250, SNARK:<6.1.NML>NMLVDB.BLI.16,  28-Jan-85 14:09:25 by GLINDELL
!  SHOW NODE XYZ returns LOOP NODE XYZ - VDB_READ always returns $true
!  for undefined nodes.  Also, NML$VDB SHOW code didnt do the right thing.
!
! UPD ID= 244, SNARK:<6.1.NML>NMLVDB.BLI.15,  25-Jan-85 13:40:51 by HALPIN
! Fix to MATCH_EA. Have it check all 6 bytes of the ETHERnet Address
! instead of just the first byte.
!
! UPD ID= 228, SNARK:<6.1.NML>NMLVDB.BLI.14,  15-Jan-85 15:15:19 by HALPIN
! Make sure any Resource errors returned from the NTMAN% JSYS gets passed
! back to the caller of NML$VDB, so that it will try again with a larger
! buffer.
!
! UPD ID= 213, SNARK:<6.1.NML>NMLVDB.BLI.13,  12-Dec-84 10:22:45 by HALPIN
! Fix HDR_ADR_MATCH to call MATCH_EA instead of MATCH_ID.
! HDR_ADR_MATCH looks for parameter number 114 (HARDWARE ADDRESS), not 110.
! Fix MATCH_EA to use GETB instead of GETMB macro.
!
! UPD ID= 210, SNARK:<6.1.NML>NMLVDB.BLI.12,  10-Dec-84 15:39:23 by HALPIN
! Get MONSYM Library file out of default directory, not BLI:
!
! UPD ID= 173, SNARK:<6.1.NML>NMLVDB.BLI.11,  19-Nov-84 10:23:48 by HALPIN
! Add support to look find a NODE's parameter block from the VDB using
! and ETHERNET Hardware Address as a key.
!
! UPD ID= 166, SNARK:<6.1.NML>NMLVDB.BLI.10,  14-Nov-84 13:57:41 by HALPIN
! ENTITY_IS_VALID always returns $true for Node Entities under $TOPS20
! and $TOPS10 conditionals.
!
! UPD ID= 158, SNARK:<6.1.NML>NMLVDB.BLI.9,   5-Nov-84 14:20:50 by GUNN
! Ident 116.
! Try to fix handling for binary number parameters with length greater
! than %BPVAL/8. Up to 32 bit values continue to be handled as before,
! greater than 32 bit values get returned as pointers to the string as
! it came in the NICE message.
!
! Fix VDB_CHANGE to call NMU$DLX_DEVICE_TYPE.
!
! UPD ID= 136, SNARK:<6.1.NML>NMLVDB.BLI.8,  24-Oct-84 16:15:50 by GUNN
! Ident 115.
! Change check for duplicate NODEs with the same SERVICE CIRCUIT parameters
! in VDB_CHANGE. Only do this if it's a DTE. This has to be allowed for the
! Ethernet. Need to expand this eventually to have routine which returns the
! device type from NMU$DLX.
!
! UPD ID= 130, SNARK:<6.1.NML>NMLVDB.BLI.7,  19-Oct-84 09:56:26 by HALPIN
! Call NML$CALCULATE_CIRCUIT_STATE after setting a new state in the Monitor.
! 
! UPD ID= 120, SNARK:<6.1.NML>NMLVDB.BLI.6,   5-Oct-84 14:25:46 by HALPIN
! Special case for setting circuit states to SERVICE.  Set service value
! in NMLT20's volatile data base, other values go to the monitor.
!
! UPD ID= 115, SLICE:<6.1.NML>NMLVDB.BLI.5,  24-Sep-84 16:39:28 by HALPIN
! Special Case CIRCUIT STATE Parameter on SET functions.  Set new value
! in both the Monitor and in NMLT20's Volatile Database
!
! UPD ID= 92, SLICE:<6.1.NML>NMLVDB.BLI.4,  18-Sep-84 15:16:12 by GUNN
! WORK:<GUNN.NML>NMLVDB.BLI.2 21-Aug-84 12:12:29, Edit by GUNN
!
! Change to accomodate new LIBRARY conventions. MONSYM.L36 and JLNKG.L36
! are now explicity declared here rather than in NMULIB.
!
! UPD ID= 70, SNARK:<6.1.NML>NMLVDB.BLI.3,  31-Aug-84 11:31:36 by HALPIN
! Update all NML$RETURN Macro calls to include an ENTITY ID Field
! Removed code that Removes and inserts Executor Node from RETURN
! LIST OF NODE functions.
!
! UPD ID= 44, SNARK:<6.1.NML>NMLVDB.BLI.2,  24-May-84 16:34:19 by GLINDELL
! PH4:<GLINDELL>NMLVDB.BLI.5 26-Feb-84 18:27:58, Edit by GLINDELL
!   Ident 110.
!    SHOW LOG x CHARAC showed events if there was no EDB defined for "x"
!    Make READ_PARAMETERS supply qualifier when calling NML$EVL_READ_EVENTS
!
! DSKT:NMLVDB.BLI[10,6026,NML703] 22-Feb-84 15:04:32, Edit by DAVENPORT
!
! Enable the event logging code for TOPS10.  Return a parameter not
! applicable error when trying to clear a parameter that wasn't set.
!
! PH4:<GLINDELL>NMLVDB.BLI.3  4-Feb-84 19:34:14, Edit by GLINDELL
!   Ident 109.
!    If there was no EDB or PDB READ_PARAMETERS didnt call the event logger
!    database. That was wrong since there might be event and sink node info
!    without the NAME or STATE being set. => Change READ_PARAMETERS to always
!    call the event logger.
!    Also fix "calls" to $NML$MAP_NODE_ID.
!
! PH4:<GLINDELL>NMLVDB.BLI.6 25-Jan-84 16:16:32, Edit by GLINDELL
!   Ident 108.
!    Fix CONVERT_ENTITY_ID, use $SIGNED_BYTE_VALUE where appropriate
!
! PH4:<GLINDELL>NMLVDB.BLI.4 25-Jan-84 13:56:11, Edit by GLINDELL
!   Ident 107.
!    Add negative returns (KNOWN, ACTIVE, ...)  to NML$CONVERT_ENTITY_ID
!    Fix call to the routine appropriately.
!
! PH4:<GLINDELL>NMLVDB.BLI.7 13-Jan-84 11:25:38, Edit by GLINDELL
!
!   Ident 106.
!    SUMMARY, not CHARACTERISTICS, should list events.
!    Move NML$CONVERT_ENTITY_ID from NMLEVD to NMLVDB.
!    Verify that logging STATE and NAME parameters do not come with 
!     an illegal SINK NODE qualifier.
!
! PH4:<GLINDELL>NMLVDB.BLI.30 21-Dec-83 16:41:07, Edit by GLINDELL
!
!   Ident 105.
!    Remove old filter stuff.
!    Add new interface to event logger volatile database.
!
! PH4:<GLINDELL>NMLVDB.BLI.28 19-Dec-83 09:58:27, Edit by GLINDELL
!
!   Ident 104.
!    From Mark McIntee: add reset of QH_AREA_PARAMETERS
!
!<MCINTEE.WORK>NMLVDB.BLI.2,  9-Aug-83 13:48:32, Edit by MCINTEE
!
!   Ident 103.
!    Update default identification to version 4.0
!
!<MCINTEE.WORK>NMLVDB.BLI.6, 15-Jul-83 14:23:06, Edit by MCINTEE
!
!   Ident 102.
!    Entity type now has subentity type in it. Fix all occurrences.
!    Remove all occurences of $X25. 
!
! PVC:<VOBA.NML.DEVELOPMENT>NMLVDB.BLI.5 13-Jun-83 15:02:06, Edit by VOBA
!
!   Ident 101.
!     Fix NML$VDB to correct the side-effect of edit #100.  Edit #100 should
!     have effected the NMLMCB code only.
!
! PVC:<VOBA.NML.DEVELOPMENT>NMLVDB.BLI.5 16-May-83 14:20:15, Edit by VOBA
!
!   Ident 100.
!     Fix NML$VDB to return error code from lower layers for MODULE entity.
!     Make allowance for the MODULE entity to report the actual error code
!     returned by NMX.
!
! XNM:<VOBA.NML.DEVELOPMENT>NMLVDB.BLI.9 23-Mar-83 10:13:49, Edit by VOBA
!
!   Ident 99.
!     Fix VDB_CHANGE routine to recognize and to clear the MODULE X25-PROTOCOL
!     parameter COUNTER TIMER.
!
! XNM:<VOBA.NML.DEVELOPMENT>NMLVDB.BLI.8  9-Mar-83 11:43:56, Edit by VOBA
!
!   Ident 98.
!     Change REMOVE_QUALIFIED_PARAMETER so that if clearing all parameters,
!     override set/clear restrictions and clear all parameters in the entry.
!
!<MCINTEE.WORK>NMLVDB.BLI.2, 14-Jun-83 14:28:21, Edit by MCINTEE
!
! Ident 97.
!   New style entity type names. AREA entity.
!
! PH4:<PECKHAM>NMLVDB.BLI.2 16-Jun-83 13:25:32, Edit by PECKHAM
!
! Ident 96.
!  Replace calls to NML$SUMMARY, NML$STATUS, NML$CHARACTERISTIC
!  with single NML$INFORMATION call.
!
!<MCINTEE.WORK>NMLVDB.BLI.4,  8-Jun-83 10:37:21, Edit by MCINTEE
!
! Ident 95.
!  Fix NML$VDB so that if executor node is in list it is displayed first
!
! Ident 94.
!  Typo in previous edit
!
! PH4:<MCINTEE>NMLVDB.BLI.2, 31-May-83 14:37:19, Edit by MCINTEE
!
!  Ident 93.
!   Remove ident 90, since the monitor does not yet support it.
!
! PH4:<PECKHAM>NMLVDB.BLI.3 17-May-83 13:05:16, Edit by PECKHAM
!
!  Ident 92.
!   Use new NML$DATA_TYPE instead of NML$GET_PDB_DATA_TYPE.  The new
!   routine returns an altered value if the DATA TYPE is CM-n.  This
!   value contains the data format value in bits 0-5, instead of the
!   number of fields. Thus, various forms of CM-n can be more easily
!   identified and dealt with.
!
! PH4:<MCINTEE>NMLVDB.BLI.10,  5-May-83 13:12:06, Edit by MCINTEE
!
!  Ident 91.
!  Move definition of NML$CFG_FILTERS to NMLCOM.
!  Put reference to NML$DLW_CALL under $MCB or $TOPS10
!
! PH4:<BUILD>NMLVDB.BLI.2  4-Mar-83 17:59:07, Edit by GUNN
!
!   Ident 90.
!     Provide for handling of CIRCUIT/LINE parameters across .NTMAN
!     interface in TOPS-20 V6.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 8-Dec-82 11:45:13, Edit by BRANDT
!
!   Ident 89.
!     Change MATCH_NODE_ID so that it checks only for matching addresses
!     rather than matching addresses and names.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 13-Oct-82 10:54:23, Edit by BRANDT
!
!   Ident 88.
!     For CLEAR functions in NML$VDB, modify the code for returning
!     value.  Before this edit, the right conditions would return the
!     value of of an uninitialized local variable (NMX).
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 12-Oct-82 00:45:32, Edit by BRANDT
!
!   Ident 87.
!     In VDB_CHANGE, when setting a SERVICE CIRCUIT parameter for a
!     node, don't fail with a CWS error if the circuit is already
!     assigned to that node.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 11-Oct-82 12:23:14, Edit by BRANDT
!
!   Ident 86.
!     In NML$VDB add additional code to return a CWS error for CLEAR
!     ALL, CLEAR NAME, and CLEAR ADDRESS operations for the executor
!     node.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 28-Sep-82 13:43:41, Edit by BRANDT
!
!   Ident 85.
!     In NML$VDB add additional code to return ERR_DETAIL for errors
!     CWS and IID.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 28-Sep-82 12:39:14, Edit by BRANDT
!
!   Ident 84.
!     In ENTITY_IS_VALID, for NODE entities, check for OCM error if MCB
!     and REE error if TOPS20.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 28-Sep-82 11:13:07, Edit by PECKHAM
!
!   Ident 83.
!     Fix X_NOD_NDB dot bugs in NML$VDB_INITIALIZE for setting
!     EXECUTOR HOST and IDENTIFICATION parameters (introduced by #76).
!     Fix NML$SET_VDB_PARAMETER not to exclude node entity changes.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 27-Sep-82 15:38:41, Edit by BRANDT
!
!   Ident 82.
!     In ENTITY_IS_VALID, for NODE entities, check for OCM error rather
!     than REE error.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 23-Sep-82 9:38:14, Edit by BRANDT
!
!   Ident 81.
!     In NML$VDB add additional argument ERR_DETAIL for returning the
!     error detail field for response messages signalling errors.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 20-Sep-82 16:49:32, Edit by BRANDT
!
!   Ident 80.
!     More for edit 78.  Change the way ENTITY_IS_VALID checks for a
!     NODE entity since a valid LOOP node will have a zero address.
!     Also, in NML$VDB, for SET functions, add a check to see if the
!     NODE parameters specified for either SERVICE CIRCUIT or CIRCUIT
!     are valid entities.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 20-Sep-82 10:29:57, Edit by BRANDT
!
!   Ident 79.
!     In NML$VDB, for SET functions, add a check to see if the parameter
!     is applicable for executor nodes only.  If it
!     turns out that the parameter is a lower layer parameter, $NML$SET
!     is called rather than VDB_CHANGE.  (VDB_CHANGE calls APPLICABLE,
!     $NML$SET does not.)  So, if an executor node only param (e.g.,
!     DELAY FACTOR) that is a lower layer param is specified for an
!     entity that is not the executor, we miss the call to APPLICABLE,
!     and the NTMAN JSYS does the wrong thing--sets the parameter for
!     the executor.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 20-Sep-82 9:43:27, Edit by BRANDT
!
!   Ident 78.
!     In NML$VDB, for SHOW functions, immediately return the error code
!     from VDB_READ for REE as well as URC errors.  Since VDB_READ
!     calls ENTITY_IS_VALID, the URC error is valid for NML as well as
!     lower layers.  Without this fix, a SHOW NODE X with the DN20 as
!     EXECUTOR will succeed even though X is invalid.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 17-Sep-82 13:34:43, Edit by BRANDT
!
!   Ident 77.
!     In REMOVE_PARAMETER, fix code that loops over PVB so that CLEAR
!     ALL works.  As loop was coded, some parameters were deleted more
!     than once since after a deletion, the PVB is compacted but we
!     always advanced on to the next entry.  Eventually, we reach the
!     "old copies" of entries that have already bubbled up the vector.
!     This caused problems when we tried to re-release any dynamic
!     memory associated with the entry.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 15-Sep-82 13:43:34, Edit by BRANDT
!
!   Ident 76.
!     Move the executor node's EDB and its associated parameter vector
!     from OWN storage to dynamic storage.  Then when a command is given
!     to modify an executor parameter, we don't die trying to deallocate
!     a chunk of permanent data.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 13-Sep-82 09:59:03, Edit by PECKHAM
!
! Ident 75.
!  Correct input to INSERT_PARAMETER for HOST (bug introduced by #73).
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 2-Sep-82 13:43:34, Edit by BRANDT
!
!   Ident 74.
!     Special case SET NODE foo ADDRESS so it returns CWS error
!     if foo is the EXECUTOR.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.7  2-Sep-82 10:19:42, Edit by PECKHAM
!
! Ident 73.
!  Remove the default EXECUTOR IDENTIFICATION for NMLMCB
!   (it will be set by NMLEVT).
!  Move PRM_BFR from NML$SET_VDB_PARAMETER to module
!   (for access by NML$VDB_INITIALIZE).
!  Make NML$VDB_INITIALIZE get EXECUTOR HOST from SC for NMLMCB.
!  Fix NML$VDB to set EXECUTOR HOST to NMX for NMLMCB.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 29-Jun-82 15:31:35, Edit by PECKHAM
!
! Ident 72.
!  Fix duplicate executor node in returned node list from NML$VDB.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 22-Jun-82 17:34:43, Edit by BRANDT
!
!   Ident 71.
!     Move the check in READ_PARAMETER so that a buffer length of at
!     least 3 is quaranteed before calling READ_PARAMETER_DATA.
!     The current check is useless once we get into the loop.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 9-Jun-82 14:34:43, Edit by BRANDT
!
!   Ident 70.
!     In READ_PARAMETER_DATA always check the current available space
!     remaining in the buffer before copying in any data.
!     This was not done for multiple field parameters, and so buffer
!     overflow occurred.  Also, in READ_PARAMETER, check for an initial
!     availability of at least 3 bytes, since each entry requires a 3
!     byte header.
!
!
! Ident 69.
! Remove TOPS20 accomodation for NICE$_IID.
! Do not change parameters in INSERT_PARAMETER if they are read-only.
! Add PRIVLEDGED parameter to INSERT_PARAMETER to allow read-only override.
! Conditionalize filter handling.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.5 27-May-82 10:20:08, Edit by PECKHAM
!
! Ident 68.
! Incorrect assumptions were being made about the executor entry in
! the returned node list from $NML$RETURN in NML$VDB.
! Fix it so the returned length is correct.
! Do not play with EXECUTOR for return LOOP NODES.
! Accomodate TOPS20's return of NICE$_IID to loop nodes by changing
! that return status to NICE$_URC.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 24-May-82 09:35:07, Edit by PECKHAM
!
! Ident 67.
! Fix NML$VDB_INITIALIZE to dynamically set the IDENTIFICATION
! instead of hard-coding it.
! This is to keep from crashing when someone CLEARs it!
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.5 20-May-82 14:58:04, Edit by PECKHAM
!
! Ident 66.
! Move the code that disables display of CIRCUIT/LINE STATE
! from READ_PARAMETER_DATA to READ_PARAMETERS.
! Also allow display for the TOPS20 version.
! Optimize code in READ_PARAMETERS.
! Optimize layer choice code in NML$VDB and
! avoid setting state in lower layer for TOPS20.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 14-May-82 10:34:43, Edit by BRANDT
!
!   Ident 65.
!     Have ENTITY_IS_VALID return $TRUE for a node only when there is
!     a non zero address specified in the entity id.
!     At this time, the entity id will be the full id, and if an
!     address is associated with the name, it will be specified.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.6 14-May-82 17:50:16, Edit by PECKHAM
!
! Ident 64.
! Fix TOPS20 'SHO KNO/ACT CIR' to call new routine NMU$DLX_RETURN_CIRCUITS
! to get circuit list.
! Move NMU$DLX_KNOWN_DEVICE synonym to NMUCOM.
! Fix returned NODE lists to have the EXECUTOR node first
! Fix TOPS20 SHOW CIRCUIT to return success if RESULT was URC
! and ENTITY_IS_VALID.  This is so circuits with no data bases get recognized.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 14-May-82 10:34:43, Edit by BRANDT
!
!   Ident 63.
!     Special case the STATE parameter in READ_PARAMETER_DATA and do
!     not return any information from the VDB.
!     Routine NML$GET_VDB_PARAMETER will still be able to obtain this
!     parameter from the VDB.
!     This fix prevents the SHOW commands from displaying this
!     parameter twice;  once from the VDB and once from the lower layer.
!     However, other NML processes can still access the data from the
!     VDB.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 10-May-82 10:34:43, Edit by BRANDT
!
!   Ident 62.
!     Rework of edit 60.  Have ENTITY_IS_VALID always return TRUE for
!     NODE entities.  This is as it was before.  In routine VDB_READ,
!     don't call ENTITY_IS_VALID if no entry exists in the volatile
!     database.  Have VDB_READ return URC error.  If the entity does
!     exist in a lower layer, the routine that called VDB_READ will
!     discover this and not return the error.  This eliminates special
!     case checking in ENTITY_IS_VALID to see if this function is a
!     READ or SET, since it is legal to do a SET on a node that does not
!     yet exist in the database.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.1 10-May-82 9:44:43, Edit by BRANDT
!
!   Ident 61.
!     Fix ENTITY_IS_VALID so that for NODE entities, it checks the
!     lower layers for the existence of the entity.  As is, it always
!     returns TRUE for NODE entities, and so a SHOW for a non-existent
!     node returns a NICE success code.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.18 7-May-82 13:36:34, Edit by BRANDT
!
!   Ident 60.
!     Fix NML$VDB and READ_PARAMETER so that NICE$_REE gets returned
!     on read functions when the buffer is inadequate.
!
! <PLATUKIS>NMLVDB.BLI.4  6-May-82 14:26:52, Edit by PLATUKIS
!   ident 59.
!   disallow changing of local node name in routine NML$VDB.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.3  6-May-82 09:53:27, Edit by PECKHAM
!
! Ident 58.
! Allow NML$*_VDB_PARAMETER to override set/clear restrictions:
!  Add PRIVLEDGED switch to REMOVE_PARAMETER and REMOVE_QUALIFIED_PARAMETER.
!
! <BRANDT.DEVELOPMENT>NMLVDB.BLI.18 5-May-82 12:36:34, Edit by BRANDT
!
! Ident 57.
! Remove "Loadtest" from executor node identification parameter
!
! <VOBA.NML.DEVELOPMENT>NMLVDB.BLI.18 14-Apr-82 14:36:34, Edit by VOBA
!
! Ident 56.
! Fix REMOVE_PARAMETER to generate optimized code for the MCB.
! Fix it to clear all parameters appropriately, as well.
! Add REMOVE_QUALIFIED_PARAMETER for X25-ACCESS volatile data base.
! Fix bug in $NML$SHOW macro call (missing actual parameter), in routine
! ENTITY_IS_VALID.
!
! <VOBA.NML.DEVELOPMENT>NMLVDB.BLI.88 25-Mar-82 18:12:36, Edit by VOBA
!
! Ident 55.
! Add code to handle MODULE X25-ACCESS volatile data base.
!
! <VOBA.NML.DEVELOPMENT>NMLVDB.BLI.15 10-Mar-82 14:12:00, Edit by VOBA
!
! Ident 54.
! Condition the X.25 code checking the validity of MODULE entity not to
! be included in the source for now (until we have the X.25 gateway in place).
! Fix a number of bugs in the source.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.27  8-Mar-82 02:27:48, Edit by PECKHAM
!
! Ident 53.
! Provide support for lower layers in this central place.
! Hard-code the event filter settings in.
!
! <VOBA.NML.DEVELOPMENT>NMLVDB.BLI.48  5-Mar-82 08:36:52, Edit by VOBA
!
! Ident 52.
! Added code to handle MODULE entities.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.12  2-Mar-82 15:06:25, Edit by PECKHAM
!
! Ident 51.
! Work on entities too numerous to mention.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.9 25-Feb-82 10:57:31, Edit by PECKHAM
!
! Ident 50.
! Add QH_LOGGING_FILTERS data base queue.
! Add global names of data bases for MCBDA.
! Remove restriction on modules from VDB_READ, VDB_CHANGE.
! Change input parameters to READ_FILTERS.
! Remove references to P$ALL by specifying parameter -1 to REMOVE_PARAMETER
! to remove all parameters.
! Fix REMOVE_PARAMETERS to not RELEASE_PVB until all parameter memory
! is released
! Set FIND_DB_FOR_ENTITY to only create data bases for NODE, LINE and CIRCUIT.
! Make GET_VDB_ENTITY handle the MODULE queue.
! General handling of NMU$MEMORY_GET failures.
! Add routine values to GET_PVB, EXPAND_PVB, SET_PARAMETER_DATA,
! SET_IMAGE_FIELD.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.3 23-Feb-82 13:48:42, Edit by PECKHAM
!
! Ident 49.
! Fix calculated length of existing memory block in SET_IMAGE_FIELD.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 23-Feb-82 08:46:26, Edit by PECKHAM
!
! Ident 48.
! Dummy! Fixed mis-spelled return codes.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.5 22-Feb-82 17:09:07, Edit by PECKHAM
!
! Ident 47.
! Fix NML$VDB, READ_* to return NICE$_SUC when nothing to SHOW
! when no counters to ZERO.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 22-Feb-82 12:17:07, Edit by PECKHAM
!
! Ident 46.
! Fix memory deallocation of image field buffers in CLEAR_PARAMETER_DATA.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 19-Feb-82 09:31:27, Edit by PECKHAM
!
! Ident 45.
! Add more items to EXECUTOR data base (LOOP variables).
! Support logging data base for STATE and NAME logging parameters.
! Increase PRM_BFR_LENGTH in NML$SET_VDB_PARAMETER
! and use OWN space instead of stack space.
!
! NET:<GROSSMAN>NMLVDB.BLI.3 27-Jan-82 08:58:17, Edit by GROSSMAN
!
! Ident 44.
! Fix call to NML$COUNTER_TIMER_SET. It now returns $false if the parameter
! was a counter timer, and its value is out of range. It will now return with
! a nice error code of "Illegal Parameter Value".
!
! NET:<GUNN>NMLVDB.BLI.8 21-Jan-82 17:13:17, Edit by GUNN
!
! Ident 43.
! Fix NODE HOST parameter to map the id when set so that
! a valid node address is displayed.
! Fix call to NML$COUNTER_TIMER_CLEAR.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.2 20-Jan-82 10:04:29, Edit by PECKHAM
!
! Ident 42.
! Fix call from NML$CHARACTERISTICS to NML$CHARACTERISTIC.
!
! NET:<PECKHAM.DEVELOPMENT>NMLVDB.BLI.8 18-Jan-82 19:50:42, Edit by PECKHAM
!
! Ident 41.
! Add selector recognition in READ_PARAMETERS so that right parameters
! are displayed for right selectors.
! Begin work on logging data base support.
! Add calls for counter timer data base maintenance (for GROSSMAN).
!
! NET:<GUNN.DEVELOPMENT>NMLVDB.BLI.4 12-Jan-82 15:45:44, Edit by GUNN
!
! Ident 40.
! Fix C_STRING and C_CHAR macros for BLIS16.
!
! NET:<GUNN.DEVELOPMENT>NMLVDB.BLI.34  6-Jan-82 15:26:52, Edit by GUNN
!
! Ident 39.
!
!   Add support for reading Network Management Version,
!   (Parameter #101) from Volatile Data Base. Initialize
!   a node data base for the EXECUTOR node.
!
!   Add routine SET_NODE_ENTITY.
!
!   Remove declaration of QH_CIRCUIT_NDB. It was not used or needed.
!
! NET:<BRANDT.DEVELOP>NMLVDB.BLI.2 23-Dec-81 17:13:30, Edit by BRANDT
!
! Ident 38.
!   Change names of "matching routines" so they are all unique in
!   the first six characters to facilitate DDT debugging.
!
!   Reduce size of code for MCB by--
!     changing some CASE statements to IF THEN ELSEs
!     restructure code and make common code into callable routines
!     eliminate some parameters in routine interfaces
!
!   Fix SVC_CKT_MATCH to pick up parameter correctly.  Eliminate setting
!   the additional field in the NODE_DB because currently all data base
!   entries are allocated as ENTITY_DBs.  These are smaller than
!   NODE_DBs.
!
!   Change some comments and/or variable names so they are correct
!   and not misleading
!
!   In REMOVE_PARAMETER add an EXITLOOP after the code that clears
!   the parameter.  Otherwise we would loop again with everything
!   off by one because the parameter vector has been shrunk.
!
!   In NML$SET_VDB_PARAMETER make the parameter buffer a local block
!   because it is small, and the dynamic block was never released
!   anyway.
!
!   In NML$SET_VDB_PARAMETER return TRUE or FALSE in all cases.
!
!   Clean up code in INSERT_PARAMETER and add routines RELEASE_PVB,
!   GET_PVB, and EXPAND_PVB.
!
!   Fix MATCH_ID so it does not distinguish between cases.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.MCB>NMLVDB.BLI.2 16-Nov-81 11:31:30, Edit by WEBBER
!
! Ident 37.
!   Modify interface to GET_VDB_PARAMETER to pass back the value of all
!   binary fields, even if the field occupies more than one BLISS value.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLVDB.BLI.15 13-Oct-81 23:45:52, Edit by PECKHAM
!
! Ident 36.
! Correct parameter pass in NML$FIND_NDB.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.4 13-Oct-81 11:52:23, Edit by GUNN
!
! Ident 35.
! Fix READ_COUNTERS routine to make SHOW CIRCUIT xxx COUNTERS command
! to work properly.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLVDB.BLI.13  9-Oct-81 15:59:13, Edit by GUNN
!
! Ident 34.
! Change SELECTOR to not be system dependent.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.MCB>NMLVDB.BLI.2  3-Aug-81 08:46:13, Edit by GUNN
!
! Ident 33.
! Remove $INTERNAL_ERROR$ macros.
!
! NET:<DECNET20-V3P1.NMU.LIBRARY>NMLVDB.BLI.5 30-Jun-81 10:42:58, Edit by GUNN
!
! Ident 32.
! Add routine NML$CLR_VDB_PARAMETER.
!
! NET:<DECNET20-V3P1.NMU.LIBRARY>NMLVDB.BLI.3 29-Jun-81 17:28:23, Edit by GUNN
!
! Ident 31.
! Fix NML$SET_VDB_PARAMETER to pass pointer to begginning of temporary
! parameter buffer when calling INSERT_PARAMETER.
!
! NET:<DECNET20-V3P1.NMU.LIBRARY>NMLVDB.BLI.2 29-Jun-81 16:15:11, Edit by JENNESS
!
! Ident 30.
! Fix dot problems in NML$SET_VDB_PARAMETER.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLVDB.BLI.9 25-Jun-81 16:33:11, Edit by JENNESS
!
! Ident 29.
! Fix SVC_CKT_MATCH, local PVB should be a ref.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.4 18-Jun-81 08:30:20, Edit by GUNN
!
! Ident 28.
! Move check for 'ALL' parameter prior to picking up parameter number
! in REMOVE_PARAMETER.
! Change test condition in loop in REMOVE_PARAMETER.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.3 17-Jun-81 17:08:31, Edit by GUNN
!
! Ident 27.
! Fix REMOVE_PARAMETER to make CLEAR command work. Unneeded dot on
! GETW of parameter number.
! Add code to NML$SET_VDB_PARAMETER.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.6 12-Jun-81 00:04:40, Edit by GUNN
!
! Ident 26.
! Move macro definition of NML$SET_VDB_PARAMETER to NMUCOM.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.5  3-Jun-81 20:19:05, Edit by GUNN
!
! Ident 25.
! Add code for NML$SET_VDB_PARAMETER.
! Fix code in NML$GET_VDB_PARAMETER to eliminate compiler INFO message.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.2  28-May-81 16:56:44, Edit by GUNN
!
! Ident 24.
! Add code to NML$GET_VDB_PARAMETER to return pointer if necessary based
! on data type of parameter.
! Change test in loop in NML$GET_VDB_PARAMETER.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLVDB.BLI.6 26-May-81 13:58:10, Edit by GUNN
!
! Ident 23.
! Remove use of RTN_COD in NML$GET_VDB_PARAMETER and return either
! $TRUE or $FALSE at point of detection.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.47 13-May-81 10:31:30, Edit by GUNN
!
! Ident 22.
! Only allocate new buffer for HOST id first time.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.46 13-May-81 10:19:36, Edit by GUNN
!
! Ident 21.
! Fix ch$move in HOST code.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.45 13-May-81 09:37:32, Edit by GUNN
!
! Ident 20.
! Update PRM_PTR on ch$move when reading HOST parameter.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.44 13-May-81 09:07:49, Edit by GUNN
!
! Ident 19.
! Fix code which sets HOST parameter. Handle fact that input format of
! node entity is either address or name.
! Fix typos in code which reads HOST parameter. Missing dots on PRM_PTR.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.42 12-May-81 17:50:47, Edit by GUNN
!
! Ident 18.
! Fix code to handle read/write parameters.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.41 12-May-81 09:02:00, Edit by GUNN
!
! Ident 17.
! Fix parameter handling routines to use DT_LENGTH for uncoded fields
! instead of DT_NUMBER.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.40 11-May-81 23:45:13, Edit by GUNN
!
! Ident 16.
! Fix code to read long binary number.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.39 11-May-81 10:02:29, Edit by GUNN
!
! Ident 15.
! Only add count for inserted parameter if it's not already in table.
! Handle binary number parameters longer than %BPVAL correctly.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.37  8-May-81 11:25:42, Edit by GUNN
!
! Ident 14.
! Fix REMOVE_PARAMETER code.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.36  8-May-81 11:04:22, Edit by GUNN
!
! Fix typo from last edit.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.35  8-May-81 10:00:31, Edit by GUNN
!
! Fix INSERT_PARAMETER logic. Not properly copying parameters from old
! vector.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.33  6-May-81 18:05:39, Edit by GUNN
!
! Yet more typos.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.32  6-May-81 17:57:38, Edit by GUNN
!
! Fix typos from last edit.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.31  6-May-81 17:39:32, Edit by GUNN
!
! Fix bad code in INSERT_PARAMETER and other places.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.29  5-May-81 17:40:45, Edit by GUNN
!
! Add code in VDB_READ for entities other than NODE.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.28  5-May-81 15:59:26, Edit by GUNN
!
! Remove 'ref' from bind of PVB_QE in READ_PARAMETERS routine.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.27  5-May-81 15:07:34, Edit by GUNN
!
! Make READ_PARAMETERS work.
! Fix call to VDB_READ from NML$VDB to pass pointer address not the
! argument address.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.26  5-May-81 12:08:17, Edit by GUNN
!
! Fix READ_ENTITY to return correct value. $NICE$ERR_MPE was generating
! a procedure call.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.24 17-Apr-81 16:57:19, Edit by GUNN
!
! Pass contents of PVB_QE in call to SET_PARAMETER_DATA from
! INSERT_PARAMETER_DATA.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.21 17-Apr-81 07:59:28, Edit by GUNN
!
! Fix BIND in INSERT_PARAMETER routine.
! Make SET_PARAMETER_DATA handle special cases for multiple fields.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.11  3-Apr-81 14:08:26, Edit by GUNN
!
! Add routine NML$GET_VDB_PARAMETER to return data for a specific parameter
! from the volatile data base.
!
! Add routine NML$FIND_NDB to find a NODE given a circuit id.
!
! Fix coding errors in INSERT_PARAMETER and REMOVE_PARAMETER.
!
! NET:<DECNET20-V3P1.NML>NMLVDB.BLI.71  5-Mar-81 13:00:10, Edit by GUNN
!
! Make NMX interface code symbols be system specific.
!
%title 'NMLVDB -- Volatile Data Base Processing'
module NMLVDB	(
		ident = 'X00.115'
		) =
begin

!                    COPYRIGHT (c) 1981, 1982, 1984 BY
!	      DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
! ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
! INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
! COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
! OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
! TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
! AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!

!++
! FACILITY:	DECnet-10/20 V4.0 Network Management Layer (NML)
!
! ABSTRACT:
!
!	This module contains the volatile data base definitions
!       and access routines.
!
! ENVIRONMENT:	TOPS-10/20 & MCB/RSX11 User mode under NML
!
! AUTHOR: Dale C. Gunn , CREATION DATE:  2-Feb-81
!
! MODIFIED BY:
!
!	, : VERSION
! 01	-
!--
!
! INCLUDE FILES:
!

library 'NMLLIB';                       ! All required definitions

%if $TOPS20
    %then
	library 'MONSYM';			! Monitor symbols

	library 'JLNKG';			! JSYS linkage definitions
    %fi

!
! TABLE OF CONTENTS
!

forward routine
        NML$VDB_INITIALIZE : novalue,   ! Initialize the Volatile DB
        NML$VDB,                        ! Perform NMX operation on DB
        NML$GET_VDB_PARAMETER,          ! Extract data for specific parameter
        NML$SET_VDB_PARAMETER,          ! Set parameter in Volatile DB
        NML$CLR_VDB_PARAMETER,          ! Remove parameter from VDB
        NML$FIND_NDB,                   ! Find NODE associated with CIRCUIT
        NML$FIND_NDB_HDA,               ! Find NODE associated with HARDWARE ADDRESS
        NML$CONVERT_ENTITY_ID,          ! Convert entity ID to canonical format
        SELECT_LOGGING,
        SELECT_MODULE,
	VDB_READ,
        %if not $MCB %then
        READ_QUALIFIED_ENTITY,
        READ_QUALIFIER : novalue,
        %fi
        READ_ENTITY,
        READ_PARAMETERS,
        READ_COUNTERS,
	VDB_CHANGE,
        %if not $MCB %then
        SET_QUALIFIED_ENTITY,
        %fi
        SET_NODE_ENTITY : novalue,
        GET_EXISTING_ENTITY_DB,
        SET_ENTITY_DB,
        ENTITY_IS_VALID,
        LOGGING_IS_VALID,
        MODULE_IS_VALID,
        GET_VDB_ENTITY_QUEUE,
        INSERT_PARAMETER,
        COPY_PARAMETER_VECTOR: novalue,
        APPLICABLE,
        %if not $MCB %then
        REMOVE_QUALIFIED_PARAMETER,
        %fi
        REMOVE_PARAMETER: novalue,
        RELEASE_PVB: novalue,
        GET_PVB,
        EXPAND_PVB,
        SET_PARAMETER_DATA,
        SET_IMAGE_FIELD,
        CLEAR_PARAMETER_DATA: novalue,
        READ_PARAMETER_DATA,
        LOGGING_ID_MATCH,
        NODE_ID_MATCH,
	PARM_NUM_MATCH,
	AREA_ID_MATCH,
        NON_NODE_ID_MATCH,
        SVC_CKT_MATCH,
        HDR_ADR_MATCH,
        MATCH_ID,
        MATCH_EA;

!
! MACROS
!

! Macro - GETMB
!
! Function - To get the next 8 bit value from a byte string
!            and map lower case ASCII codes into the
!            corresponding upper case ASCII code.
!            The byte pointer is updated to point to the next
!	     byte to read.
!
! Parameters -
!
!    PTR_ADR	Address of byte string pointer
!
! Value returned -
!
!    The next byte in the string.
!

macro
     GETMB (PTR_ADR) =
         begin
         local C;

         C = ch$rchar_a(PTR_ADR);
         if .C geq %C'a' and .C leq %C'z'
         then .C - %C'a' + %C'A'
         else .C
         end %;

macro
     $EXPAND_FIELD (FIELD_NAME) =
         %print ('field-name ', %string(FIELD_NAME), ' = [',
                 %fieldexpand(FIELD_NAME,0), ', ',
                 %fieldexpand(FIELD_NAME,1), ', ',
                 %fieldexpand(FIELD_NAME,2), ', ',
                 %fieldexpand(FIELD_NAME,3), ']') %;

macro
     $SHOW_EDB =
         $EXPAND_FIELD (EDB_QLINK)
         $EXPAND_FIELD (EDB_ENTITY_ID)
         $EXPAND_FIELD (NDB_ENTITY_ID)
         $EXPAND_FIELD (NDB_NODE_TYPE)
         $EXPAND_FIELD (EDB_PARAMETER_COUNT)
         $EXPAND_FIELD (EDB_PARAMETER_ALLOCATION)
         $EXPAND_FIELD (EDB_PARAMETER_VECTOR) %;

macro
     $SHOW_NDB =
         $EXPAND_FIELD (EDB_QLINK)
         $EXPAND_FIELD (EDB_ENTITY_ID)
         $EXPAND_FIELD (NDB_ENTITY_ID)
         $EXPAND_FIELD (NDB_NODE_TYPE)
         $EXPAND_FIELD (EDB_PARAMETER_COUNT)
         $EXPAND_FIELD (EDB_PARAMETER_ALLOCATION)
         $EXPAND_FIELD (EDB_PARAMETER_VECTOR)
         $EXPAND_FIELD (EDB_FIELDS)
         $EXPAND_FIELD (NDB_CIRCUIT_QLINK)
         $EXPAND_FIELD (NDB_SVC_CIRCUIT) %;

!
! EQUATED SYMBOLS:
!
$show (fields);                         ! Turn on XPORT field display
$show (literals);                       ! Turn on XPORT literal display

literal
    PRM_BFR_LENGTH = 2 + 1 + 255, ! Length in bytes
    PRM_BFR_SIZE = ch$allocation (PRM_BFR_LENGTH,8),
    PRM_BFR_ALLOCATION = PRM_BFR_SIZE * %upval;

!
! PBF_*
!  Parameter block for logging handling routines
!  This block is used for the return entity function.
$field PBF_FIELDS =
       set
       PBF_BASE = [ $sub_block(0) ],
       PBF_LEN_ADR = [ $address ],      ! Address of buffer length
       PBF_BUF_PTR_ADR = [ $address ],  ! Address of buffer pointer
       PBF_SELECTOR = [ $tiny_integer ] ! Return list selector
       tes;

literal
       PBF_SIZE = $field_set_size;
macro
     PBF_BLOCK = block [PBF_SIZE] field (PBF_FIELDS) %;

!
! PBM_*
!  Parameter block for module handling routines.
!  This block is used to hold all the pertinent parameters to
!  allow generation of more efficient code, and also to allow
!  parameter passage through NMU$QUEUE_SCAN.
!
$field
    PBM_FIELDS =
        set
        PBM_BASE = [$sub_block (0)],
        PBM_BUF_PTR_ADR = [$address],   ! Address of buffer pointer
        PBM_LEN_ADR = [$address],       ! Address of buffer length
        PBM_SELECTOR = [$tiny_integer]  ! Return list selector
        tes;

literal
    PBM_SIZE = $field_set_size;

macro
    PBM_BLOCK = block [PBM_SIZE] field (PBM_FIELDS) %;

!
! Parameter block usage being phased in
!

$field
    PARAMETER_FIELDS =
        set
        PB_BASE = [$sub_block (0)],
        PB_ENTITY_POINTER = [$pointer],
        PB_QUALIFIER_POINTER = [$pointer],
        PB_FUNCTION = [$integer],
        PB_ENTITY_TYPE = [$integer],
        PB_SELECTOR = [$integer],
        PB_DATA_LENGTH = [$integer],
        PB_DATA_POINTER = [$integer],
        PB_PARAMETER_NUMBER = [$integer],
        PB_EDB = [$address],
        PB_PARAMETER_DATA_BLOCK = [$address],
        PB_PRIVLEDGED = [$bit]
        tes;

literal
    PARAMETER_BLOCK_SIZE = $field_set_size,
    PARAMETER_BLOCK_ALLOCATION = $field_set_units;

macro
    PARAMETER_BLOCK = block [PARAMETER_BLOCK_SIZE] field (PARAMETER_BLOCK_FIELDS) %;

$show (none);                           ! Turn off XPORT display
!
! OWN STORAGE:
!

own
   PRM_BFR: block [PRM_BFR_ALLOCATION];

%( N.B. - To ensure integrity of the volatile data base when running
          in the multi-tasking environment, the data bases must be
          locked during access. )%

own                                     ! Heads of NML volatile parameter DB
    QH_NODE_PARAMETERS: Q_HEADER,
    QH_LINE_PARAMETERS: Q_HEADER,
    QH_CIRCUIT_PARAMETERS: Q_HEADER,
    QH_LOGGING_PARAMETERS: Q_HEADER,
    QH_AREA_PARAMETERS : Q_HEADER,
    QH_MODULE_PARAMETERS: Q_HEADER;

%if $MCB %then
global bind
    NODDB = QH_NODE_PARAMETERS,
    LINDB = QH_LINE_PARAMETERS,
    CKTDB = QH_CIRCUIT_PARAMETERS,
    LOGDB = QH_LOGGING_PARAMETERS,
    MODDB = QH_MODULE_PARAMETERS;
%fi

!
! EXTERNAL REFERENCES:
!

external routine
         NMU$MEMORY_MANAGER,
         NMU$QUEUE_MANAGER,
         NMU$NETWORK_LOCAL,
         NMU$DLX_DEVICE_TYPE,
         NMU$DLX_FRONT_END_DEVICE,
         NML$VDB_PARAMETER,
         NML$CALCULATE_CIRCUIT_STATE: novalue,
         NML$EXECUTOR_ONLY,
	 NML$INFORMATION,
         NML$CLEARABLE,
         NML$READ_ONLY,
         NML$DATA_TYPE,
         NML$COUNTER_TIMER_SET,
         NML$COUNTER_TIMER_CLEAR,
         CVLTU,                   ! Convert lower to upper case
	 NML$DLW_CHECK_CIRCUIT: novalue;

! External declarations for event data base
%if $TOPS20 or $TOPS10 %then
external routine
         NML$EVL_INITIALIZE : novalue,
         NML$EVL_INSERT_PARAMETER,
         NML$EVL_DELETE_PARAMETER,
         NML$EVL_READ_EVENTS,
         NML$EVL_SET_VDB_PARAMETER,
         NML$EVL_CLR_VDB_PARAMETER,
         NML$EVL_GET_VDB_PARAMETER;
%fi




%global_routine ('NML$VDB_INITIALIZE') : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Resets the NML volatile data bases to an initially
!       cleared state.
!
!       Initializes volatile data base for EXECUTOR NODE.
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    macro
         C_STRING [ ] =                 ! Counted string
             %if not $MCB
             %then C_CHAR(%char(%charcount(%remaining)), %explode(%remaining))
             %else %string(%char(%charcount(%remaining)), %remaining)
             %fi %;

    %if not $MCB
    %then
    macro
         C_CHAR [B1,B2,B3,B4] =
             ((%C B1 ^ (%bpval-8))
              %if not %null(B2)
              %then or (%C B2 ^ (%bpval-16))
                    %if not %null(B3)
                    %then or (%C B3 ^ (%bpval-24))
                          %if not %null(B4)
                          %then or (%C B4 ^ (%bpval-32)) %fi
                    %fi
              %fi) %;
    %else
    macro
         C_CHAR [] =
             (%string (%remaining)) %;
    %fi

!
! Reset the volatile parameter data base header for each entity.
!

    NMU$QUEUE_RESET (QH_NODE_PARAMETERS);
    NMU$QUEUE_RESET (QH_LINE_PARAMETERS);
    NMU$QUEUE_RESET (QH_CIRCUIT_PARAMETERS);
    NMU$QUEUE_RESET (QH_LOGGING_PARAMETERS);
    NMU$QUEUE_RESET (QH_MODULE_PARAMETERS);
    NMU$QUEUE_RESET (QH_AREA_PARAMETERS);

!
! Set up the initial data base for EXECUTOR NODE.
!
    begin

    external
            NMLVER;                     ! NML Version Number

    literal
           N_PARMS = 4,                 ! Number of initial EXECUTOR parameters
           M_PARMS = 7;                 ! Maximum number of EXECUTOR parameters
                                        ! Allow for maximum number parameters
                                        ! so the parameter vector never needs
                                        ! to be deallocated.

    own
       X_NOD_NDB : ref ENTITY_DB_BLOCK,

       X_NOD_PVB : $NML$PVB_ENTRY_VECTOR (M_PARMS)
                   preset ([0,PE_NUMBER] = 101, ! MANAGEMENT VERSION
                           [0,PE_ADDRESS] = NMLVER,
                           [1,PE_NUMBER] = 150, ! LOOP COUNT 1
                           [1,PE_ADDRESS] = 1,
                           [2,PE_NUMBER] = 151, ! LOOP LENGTH 127
                           [2,PE_ADDRESS] = 127, ! (to work with RSX-11M)
                           [3,PE_NUMBER] = 152, ! LOOP WITH MIXED
                           [3,PE_ADDRESS] = 2);

    X_NOD_NDB = SET_ENTITY_DB (ENTITY_NODE, NMU$NETWORK_LOCAL ());

    X_NOD_NDB[NDB_NODE_TYPE] = NDB$EXECUTOR;
    X_NOD_NDB[EDB_PARAMETER_COUNT] = N_PARMS;
    X_NOD_NDB[EDB_PARAMETER_ALLOCATION] = PVB_ENTRY_ALLOCATION * M_PARMS;
    X_NOD_NDB[EDB_PARAMETER_VECTOR] =
		NMU$MEMORY_GET (.X_NOD_NDB[EDB_PARAMETER_ALLOCATION]);

    COPY_PARAMETER_VECTOR (X_NOD_PVB, .X_NOD_NDB[EDB_PARAMETER_VECTOR],
			   M_PARMS);

%if $MCB
%then
    begin                               ! Get host node from Session Control

    bind
        DATA_ID = uplit (141);

    local
        PTR;

    PTR = ch$ptr (PRM_BFR,, 8);
    PUTW (DATA_ID, PTR);
    PUTB (0, PTR);
    $NML$GET_HOST_ID (uplit (2 + 1 + 6), .PTR);
    INSERT_PARAMETER (.X_NOD_NDB, ENTITY_NODE, ch$ptr (PRM_BFR,,8), $true);
    end;
%else
    begin

    macro
        DEFAULT_IDENTIFICATION =
                %if $TOPS20
                %then 'DECnet-20 Version 4.0'
                %else %if $TOPS10
                      %then 'DECnet-10 Version 4.0'
                      %else '*'
                      %fi
                %fi %;

    INSERT_PARAMETER (.X_NOD_NDB, ENTITY_NODE,
                     ch$ascii (%char ((100 and %o'377'),
                                      (100^-8 and %o'377'),
                                      %charcount (DEFAULT_IDENTIFICATION)),
                               DEFAULT_IDENTIFICATION), $true);
    end;
%fi
    end;

%if $TOPS20 or $TOPS10                      ! Initialize event data base
%then
    NML$EVL_INITIALIZE();
%fi

%( N.B. - Maybe we want to call the interface function here to
   return a list of known entities for each data base. )%

    end;				! End of NML$VDB_INITIALIZE
%global_routine ('NML$VDB', FUNCTION, ENTITY_TYPE, ENTITY, QUALIFIER, SELECTOR, LENGTH, BUFFER, ERR_DETAIL) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Performs operations on NML volatile parameters.
!
! FORMAL PARAMETERS
!
!	FUNCTION  -   Code to denote whether the specified parameter is to be
!                     defined or purged, etc.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       ENTITY    -   Character sequence pointer to the entity id.
!       QUALIFIER -   An optional character sequence pointer to a qualifier in
!                     parameter format.
!       SELECTOR  -   For the return function, the class of entities to return.
!       LENGTH    -   The address of a variable.
!		      For SHOW functions, the variable will
!		      contain the size of space available in the buffer.
!		      It will be reduced by the length of the data
!		      returned in the buffer.
!		      For SET and CLEAR functions, the address will
!		      contain the length of the specified parameter.
!       BUFFER   -    For SHOW functions, the address of a
!		      character sequence pointer to the buffer in which
!		     to return the parameter data.  These functions will
!		     update the pointer to point to the next available
!		     byte in the buffer.
!		     For SET and CLEAR functions, a character sequence
!		     pointer to the specific parameter.
!       ERR_DETAIL - The address of a variable in which to return the
!		     error detail field for the response message if this
!		     request fails.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    case .FUNCTION from %bliss36($NTSET) %bliss16(N$FSET)
                   to %bliss36($NTRET) %bliss16(N$FRET)  of
        set
        [%bliss36($NTSET) %bliss16(N$FSET)]: ! Set parameter
            begin
            macro HIGHER_LAYER = NML <0, 1>%,
                  LOWER_LAYER = NML <1, 1>%;
            local NML, PARAMETER, RESULT;

            PARAMETER = GETW_NA (.BUFFER); ! Get parameter number

            if NML$VDB_PARAMETER (.ENTITY_TYPE, .PARAMETER)
            then NML = 1
            else NML = 2;

            selectone .ENTITY_TYPE [ENTITY_MAIN] of
                set
                [ENTITY_NODE]:
		    begin
                        local PTR, LOCAL_NODE;
                        PTR = NMU$NETWORK_LOCAL();
                        LOCAL_NODE = ch$eql( 9, .PTR, 9, .ENTITY);
%if $TOPS20 or $TOPS10
%then
		    if NML$EXECUTOR_ONLY (.ENTITY_TYPE, .PARAMETER)
		    then
			if not .LOCAL_NODE
                        then return $NICE$ERR_PNA;
%fi
                    selectone .PARAMETER of
                        set
			[110, 501]:	    ! SERVICE CIRCUIT or CIRCUIT
                            begin
			    PTR = ch$plus (.BUFFER, 2); ! Circuit_id
			    if not ENTITY_IS_VALID (ENTITY_CIRCUIT, .PTR)
                            then begin
				.ERR_DETAIL = ENTITY_CIRCUIT;
				 return $NICE$ERR_URC;
				 end;
                            end;

                        [500, 502]:         ! NAME or ADDRESS
                            begin
                            if .local_node
                            then begin
				.ERR_DETAIL = ENTITY_NODE;
				 return $NICE$ERR_CWS;
				 end;
                            end;
%if $MCB
%then
                        [141]:              ! HOST
                            NML = 3;
%fi
                        [otherwise]:
                            0;
                        tes;
		    end;
%if $MCB
%then
                [ENTITY_LINE, ENTITY_CIRCUIT]:
                    if .PARAMETER eql 0
                    then NML = 3;
%else

                 [ENTITY_CIRCUIT]:

                    ! We have to do some work here to accomodate STATE SERVICE.
                    ! If it is STATE SERVICE, then set it in NML AND do a SET
                    ! CIRCUIT STATE OFF operation to ROUTER.  (Monitor does not
                    ! know about STATE SERVICE).  If it is NOT STATE SERVICE,
                    ! then clear old STATE kept in NMLT20 since 'SERVICE' is
                    ! "sticky" in NML$CALCULATE_CIRCUIT_STATE.

                    ! Yes, we know this is a crock but what can we do?

                    if .PARAMETER eql 0
                    then begin
                         literal NML_SERVICE = 2;
                         local TEMP,
                               TEMP_POINTER;

                         TEMP_POINTER = .BUFFER;
                         TEMP = GETW(TEMP_POINTER); ! Read the Paramenter #
                         TEMP = GETB(TEMP_POINTER); ! And the state value

                         if .TEMP eql NML_SERVICE 
                         then begin
                              local NMX_BUFFER : vector [ch$allocation (3,8)],
                                    NMX_PTR, X_PTR, TEMP;

                              NML = 1;  ! Set in NMLT20 only

                              ! Setup for CIRCUIT STATE OFF
                              X_PTR = NMX_PTR = ch$ptr (NMX_BUFFER,,8);
                              TEMP = 0;
                              PUTW (TEMP, X_PTR); ! Parameter 0
                              PUTB (1, X_PTR);    ! Value 1 = OFF

                              TEMP = 3;
                              $NML$SET (.ENTITY_TYPE [ENTITY_MAIN],
                                        .ENTITY,
                                        0,
                                        TEMP,
                                        .NMX_PTR);
                              end
                         else begin
                              NML = 2;  ! Set in monitor only
                              NML$CLR_VDB_PARAMETER (ENTITY_CIRCUIT,
                                                     .ENTITY,
                                                     0);
                              end;
                         end;
%fi


                [ENTITY_LOGGING]:
                    begin

                    ! We have to special case setting the CONSOLE or FILE
                    ! NAME.  None of these may be changed.

                    local TMP : $SIGNED_BYTE_VALUE,
                          PTR;

                    PTR = .ENTITY;
                    TMP = GETB (PTR);
                    TMP = .TMP[VALUE];
                    if ((.TMP eql 1) or (.TMP eql 2))
                    and (.PARAMETER eql 100)
                    then return $NICE$ERR_OPF;

                    end;

                [otherwise]:
                    ;
                tes;

            if .HIGHER_LAYER            ! If NML parameter
            then RESULT = VDB_CHANGE (.FUNCTION,
                                      .ENTITY_TYPE,
                                      .QUALIFIER,
                                      .ENTITY,
                                      ..LENGTH,
                                      .BUFFER,
                                      .ERR_DETAIL);

            if .LOWER_LAYER             ! If NMX parameter
            then begin
                 RESULT = $NML$SET (.ENTITY_TYPE [ENTITY_MAIN] ,
                                    .ENTITY,
                                    .QUALIFIER,
                                    .LENGTH,
                                    .BUFFER);

		 if ((.RESULT eql NICE$_URC) or
		     (.RESULT eql NICE$_CWS) or
		     (.RESULT eql NICE$_IID))
		 then .ERR_DETAIL = .ENTITY_TYPE [ENTITY_MAIN] ;
                 end;

            ! If this is SET CIRC .. STATE ON or OFF, make DLW run a pass
            if .PARAMETER eql 0
            and .ENTITY_TYPE [ENTITY_MAIN] eql ENTITY_CIRCUIT
            then begin
                 NML$CALCULATE_CIRCUIT_STATE (.ENTITY);
                 NML$DLW_CHECK_CIRCUIT (.ENTITY);
                 end;

            return .RESULT;
            end;

        [%bliss36($NTCLR) %bliss16(N$FCLR)]: ! Clear parameter
            begin
            macro HIGHER_LAYER = NML <0, 1>%,
                  LOWER_LAYER = NML <1, 1>%;
            local NML, PARAMETER, VDB, NMX, RESULT;

            if ..LENGTH eql 0
            then
		begin
		PARAMETER = -1;			! Clear ALL
		NML = 3;
		end
            else
		begin
                PARAMETER = GETW_NA (.BUFFER); ! Get parameter number
                if NML$VDB_PARAMETER (.ENTITY_TYPE, .PARAMETER)
                then NML = 1
                else NML = 2;
		end;

            selectone .ENTITY_TYPE [ENTITY_MAIN] of
                set
                [ENTITY_NODE]:
		    begin
                        local PTR, LOCAL_NODE;
                        PTR = NMU$NETWORK_LOCAL();
                        LOCAL_NODE = ch$eql( 9, .PTR, 9, .ENTITY);
%if $TOPS20 or $TOPS10
%then
		    if NML$EXECUTOR_ONLY (.ENTITY_TYPE, .PARAMETER)
		    then
			if not .LOCAL_NODE
                        then return $NICE$ERR_PNA;
%fi
                    selectone .PARAMETER of
                        set
                        [-1, 500, 502]:     ! ALL, NAME, or ADDRESS
                            begin
                            if .local_node
                            then begin
				.ERR_DETAIL = ENTITY_NODE;
				 return $NICE$ERR_CWS;
				 end;
                            end;
%if $MCB
%then
                        [141]:              ! HOST
                            NML = 3;
%fi
                        [otherwise]:
                            ;
                        tes;
		    end;

                [ENTITY_LOGGING]:
                    begin

                    ! We have to special case clearing the CONSOLE or FILE
                    ! NAME.  None of these may be changed.

                    local TMP : $SIGNED_BYTE_VALUE,
                          PTR;

                    PTR = .ENTITY;
                    TMP = GETB (PTR);
                    TMP = .TMP[VALUE];
                    if ((.TMP eql 1) or (.TMP eql 2))
                    and (.PARAMETER eql 100)
                    then return $NICE$ERR_OPF;

                    end;

                [otherwise]:
                    ;
                tes;

            if .HIGHER_LAYER            ! If NML parameter
            then RESULT = (VDB = VDB_CHANGE (.FUNCTION,
                                   	     .ENTITY_TYPE,
                                   	     .QUALIFIER,
                                   	     .ENTITY,
                                   	     ..LENGTH,
                                             .BUFFER,
				   	     .ERR_DETAIL));

            if .LOWER_LAYER             ! If NMX parameter
            then begin
                 RESULT = (NMX = $NML$CLR (.ENTITY_TYPE [ENTITY_MAIN] ,
                                 	   .ENTITY,
	                                   .QUALIFIER,
	                                   .LENGTH,
	                                   .BUFFER));

		 if .NMX eql NICE$_URC
		 then .ERR_DETAIL = .ENTITY_TYPE [ENTITY_MAIN] ;
                 end;

            if (.VDB eql 1) and (.NML eql 3)
            then return 1                      ! If either one succeed, ok
            else return .RESULT                ! Return last result
            end;

        [%bliss36($NTZRO) %bliss16(N$FZRO)]: ! Zero counters
            begin
            local
                NMX;
            NMX = $NML$ZERO (.ENTITY_TYPE [ENTITY_MAIN] , .ENTITY, .QUALIFIER);

	    if .NMX eql NICE$_URC
	    then .ERR_DETAIL = .ENTITY_TYPE [ENTITY_MAIN] ;

            return .NMX
            end;

        [%bliss36($NTSHO) %bliss16(N$FSHO)]: ! Show parameters
            begin
            local VDB_CODE, RESULT, BUFFER_LENGTH;

            !
            ! Get any parameters out of the volatile data base.
            !

            VDB_CODE = VDB_READ (.FUNCTION,
                                 .ENTITY_TYPE,
                                 .ENTITY,
                                 .QUALIFIER,
                                 .SELECTOR,
                                 .LENGTH,
                                 .BUFFER,
                                 .ERR_DETAIL);

            !
            ! Try to get parameters kept at lower layers of architecture.
            ! There may not be any, or entity may not be known there.
            ! Fail only if the entity is not known in either NML or other
            ! layers.
            !

            BUFFER_LENGTH = ..LENGTH;
            RESULT = $NML$SHOW (.ENTITY_TYPE [ENTITY_MAIN] ,
                                .ENTITY,
                                .QUALIFIER,
                                .SELECTOR,
                                BUFFER_LENGTH,
                                ..BUFFER);

            ! If successful, or resource error, update buffer length
            if (.RESULT eql 1) or (.RESULT eql NICE$_REE)
            then .LENGTH = ..LENGTH - .BUFFER_LENGTH;

            !
            ! Only applicable for entities different than MODULE: If call
            ! across NMX interface failed, assume an empty buffer. Return
            ! NICE success if either VDB or NMX calls succeed, unless NMX
            ! returns a resource error.  In which case, return the error
            ! so caller will try again with a larger buffer.
            !

            ! Return success if either VDB or NML returned success unless
            !  NML returned 'resource error'.  If failure, return the error
            !  code NML supplied - we believe it more than NML!
            return (if (.RESULT neq NICE$_REE)
                    and (
                         (.RESULT eql NICE$_SUC)
                         or (.VDB_CODE eql NICE$_SUC)
                         )
                    then $true
                    else begin
                         .ERR_DETAIL = .ENTITY_TYPE[ENTITY_MAIN];
                         .RESULT
                         end);

            end;

        [%bliss36($NTSZC) %bliss16(N$FSZC)]: ! Show and zero counters
            begin
            local BUFFER_LENGTH, STATUS;

            BUFFER_LENGTH = ..LENGTH;
            STATUS = $NML$SHOZC (.ENTITY_TYPE [ENTITY_MAIN] ,
                                 .ENTITY,
                                 .QUALIFIER,
                                 BUFFER_LENGTH,
                                 ..BUFFER);
            .LENGTH = ..LENGTH - .BUFFER_LENGTH;

	    if .STATUS eql NICE$_URC
	    then .ERR_DETAIL = .ENTITY_TYPE [ENTITY_MAIN] ;

            return .STATUS
            end;

        [%bliss36($NTRET) %bliss16(N$FRET)]: ! Return list of entity ids
            selectone .ENTITY_TYPE [ENTITY_MAIN] of
                set
                [ENTITY_NODE]:
                    begin
                    local BUF_LEN, BUF_PTR, LCL_ADDRESS, LCL_LEN, STATUS,
                          CNT, LNG, TEMP;
                    BUF_PTR = ..BUFFER;
                    BUF_LEN = ..LENGTH;

%(                  !
                    ! Put the executor node first in the list.
                    ! Later see if executor is in list. If so, remove the copy
		    ! from the middle of the list.
		    ! If not, remove executor from front of list.
		    !

                    LCL_ADDRESS = NMU$NETWORK_LOCAL ();
                    LCL_LEN = 3 + ch$rchar (ch$plus (.LCL_ADDRESS, 2));
                    if .LCL_LEN gtr ..LENGTH then return NICE$_REE;
                    BUF_PTR = ch$move (.LCL_LEN, .LCL_ADDRESS, .BUF_PTR);
                    BUF_LEN = .BUF_LEN - .LCL_LEN;
                    LCL_ADDRESS = GETW (LCL_ADDRESS);
)%
		    ! Now get the list.
                    STATUS = $NML$RETURN (.ENTITY_TYPE [ENTITY_MAIN] ,
                                          .ENTITY,
                                          .SELECTOR,
                                          .QUALIFIER,
                                          BUF_LEN,
                                          .BUF_PTR);

%(                  if .STATUS eql 1    ! If successful, update length
                    then begin
                        .LENGTH = ..LENGTH - (.BUF_LEN + .LCL_LEN); ! Include our copy.
			LNG = .BUF_LEN;	! Remember in case no executor in list
                        do          	! Look for returned copy of executor
			    begin
                            if .BUF_LEN leq 0 then exitloop;
                            TEMP = GETW(BUF_PTR);
                            CNT = GETB(BUF_PTR);
                            BUF_PTR = ch$plus (.BUF_PTR, .CNT);
                            BUF_LEN = .BUF_LEN - (3 + .CNT);
                            end
                        while .TEMP neq .LCL_ADDRESS;
			if .TEMP eql .LCL_ADDRESS
			then begin        	! Squeeze returned copy out.
                             ch$move (.BUF_LEN, .BUF_PTR, ch$plus (.BUF_PTR, -(3 + .CNT)));
                             .LENGTH = ..LENGTH + (3 + .CNT);
			     end
			else begin		! No executor node at all.
			     ch$move (.LNG, .BUFFER, ch$plus (.BUFFER, -.LCL_LEN));
			     .LENGTH = ..LENGTH + .LCL_LEN;
                             end;
                        end;
)%
                    if .STATUS eql 1 then .LENGTH = ..LENGTH - .BUF_LEN;
                    return .STATUS
                    end;
                [ENTITY_CIRCUIT, ENTITY_LINE]:
                    begin
                    local BUF_LEN, BUF_PTR, STATUS;
                    BUF_PTR = ..BUFFER;
                    BUF_LEN = ..LENGTH;

		    ! Get the list.
                    STATUS = $NML$RETURN (.ENTITY_TYPE [ENTITY_MAIN] ,
                                          .ENTITY,
                                          .SELECTOR,
                                          .QUALIFIER,
                                          BUF_LEN,
                                          .BUF_PTR);

                    if .STATUS eql 1 then   ! If successful, update length
                        .LENGTH = ..LENGTH - .BUF_LEN;

                    return .STATUS
                    end;
                [ENTITY_LOGGING]:
                    begin
                    local PBF : PBF_BLOCK;
                    PBF [PBF_LEN_ADR] = .LENGTH;
                    PBF [PBF_BUF_PTR_ADR] = .BUFFER;
                    PBF [PBF_SELECTOR] = .SELECTOR;
                    NMU$QUEUE_SCAN (QH_LOGGING_PARAMETERS, PBF [PBF_BASE], SELECT_LOGGING);
                    if ..LENGTH lss 0 then return $NICE$ERR_REE;
                    return NICE$_SUC
                    end;

                [ENTITY_MODULE]:
                    begin
                    local LEN, NMX, PBM : PBM_BLOCK;

                    if .SELECTOR neq KNOWN_ ! Check for known qualifier
                    then return $NICE$ERR_MPE;

                    PBM [PBM_LEN_ADR] = .LENGTH;
                    PBM [PBM_BUF_PTR_ADR] = .BUFFER;
                    PBM [PBM_SELECTOR] = .SELECTOR;
                    NMU$QUEUE_SCAN (QH_MODULE_PARAMETERS, PBM [PBM_BASE], SELECT_MODULE);
                    if ..LENGTH lss 0 then return $NICE$ERR_REE;

                    LEN = ..LENGTH;
                    NMX = $NML$RETURN (.ENTITY_TYPE [ENTITY_MAIN] , ! Get entity ids from NMX
                                       .ENTITY,
                                       .SELECTOR,
                                       .QUALIFIER,
                                       LEN,
                                       ..BUFFER);

                    if .NMX eql 1       ! If successful, update buffer length
                    then .LENGTH = ..LENGTH - .LEN;

                    if .NMX eql NICE$_REE then return .NMX;

                    return NICE$_SUC           ! Return success
                    end;

		[ENTITY_AREA]:		! AREA Entity
		    begin
		    local NMX,LEN;
		    NMX = $NML$RETURN (.ENTITY_TYPE [ENTITY_MAIN] ,	 ! Get entity ids for NMX
                                       .ENTITY,
				       .SELECTOR,
				       .QUALIFIER,
				       LEN,
				       ..BUFFER);

		    if .NMX eql 1     	! If successful, update buffer length
		    then .LENGTH = ..LENGTH - .LEN;

		    if .NMX eql NICE$_REE then return .NMX;

		    return NICE$_SUC;
		    end;

                [otherwise]:
                    return $NICE$ERR_MPE;
                tes;

        [inrange,                       ! Invalid function code
         outrange]:
            return $NICE$ERR_MPE;
        tes

    end;				! End of NML$VDB
%global_routine ('NML$GET_VDB_PARAMETER', ENTITY_TYPE, ENTITY_PTR, PARM_NO, DATA_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Extracts the data for a specific parameter from the volatile
!       data base. Upon return the value of the parameter is stored
!       at the address specified by DATA_ADDR.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - Entity type.
!       ENTITY_PTR  - Character pointer to entity id.
!       PARM_NO     - Parameter number.
!       DATA_ADDR   - Address of returned data.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, if the parameter exists in the volatile data base;
!       FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
         EDB_QE: ref ENTITY_DB_BLOCK,
         PVB: ref $NML$PVB_ENTRY_VECTOR (0);

    if (EDB_QE = GET_EXISTING_ENTITY_DB (.ENTITY_TYPE, .ENTITY_PTR)) eql 0
    then return $FALSE;

%if $TOPS20 or $TOPS10
%then
    if (.ENTITY_TYPE eql ENTITY_LOGGING) and (.PARM_NO eql 201)
    then return NML$EVL_GET_VDB_PARAMETER( .ENTITY_TYPE, .ENTITY_PTR,
                                           .PARM_NO, .DATA_ADDR);
%fi
    !
    ! Perform special casing for parameters which have seperate
    ! parameter numbers for reading and writing.
    !

    if (.ENTITY_TYPE [ENTITY_MAIN] eql ENTITY_NODE)        ! HOST Parameter (Read)
    and (.PARM_NO eql 140)
    then PARM_NO = 141;        ! Make it 141

    if ((.EDB_QE[EDB_PARAMETER_ALLOCATION] eql 0) ! They better all be in
    and (.EDB_QE[EDB_PARAMETER_VECTOR] eql 0)) ! agreement.
    or (.EDB_QE[EDB_PARAMETER_COUNT] eql 0)
    then return $FALSE;

    PVB = .EDB_QE[EDB_PARAMETER_VECTOR];  ! Get address of parameter vector

    incr N from 0 to .EDB_QE[EDB_PARAMETER_COUNT] - 1
    do begin
       bind PVB_QE = PVB[.N,0,0,0,0]: $NML$PVB_ENTRY_BLOCK;

       if .PARM_NO leq .PVB_QE[PE_NUMBER]
       then begin
            if .PARM_NO eql .PVB_QE[PE_NUMBER]
            then begin
                 local DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

                 DATA_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .PARM_NO);
                 if .DATA_TYPE[DT_CODED] eql 0 ! Not coded
                 then begin
                      if .DATA_TYPE[DT_FTYPE] eql 0
                      then begin        ! Binary number
                           if .DATA_TYPE[DT_LENGTH] eql 0 ! Image field
                           then .DATA_ADDR = ch$ptr (.PVB_QE[PE_ADDRESS],,8)
                           else begin   ! Data stored in ....
                                if .DATA_TYPE[DT_LENGTH] leq %bpval/8
                                then .DATA_ADDR = .PVB_QE[PE_DATA] ! Value
                                else begin ! Buffer
                                     local PTR;

                                     %( NB - Add a real hack here to make this
                                        code work for the SERVICE PASSWORD
                                        parameter. I don't want to change the
                                        way this works now for fear of breaking
                                        existing functionality. )%

                                     if .DATA_TYPE[DT_LENGTH] leq 4
                                     then
                                         begin
                                         PTR = ch$ptr (.PVB_QE[PE_ADDRESS],,8);
                                         get32 (PTR, .DATA_ADDR);
                                         end
                                     else
                                         .DATA_ADDR = ch$ptr (.PVB_QE[PE_ADDRESS],,8);
                                     end;
                                end;
                           end
                      else begin        ! ASCII image field
                           .DATA_ADDR = ch$ptr (.PVB_QE[PE_ADDRESS],,8);
                           end;
                      end
                 else begin             ! Coded
                      if .DATA_TYPE[DT_FTYPE] eql 0
                      then .DATA_ADDR = .PVB_QE[PE_DATA] ! Single field
                      else selectone .DATA_TYPE[DT_NUMBER] of
                               set      ! Multiple field
                               [CMN] :  ! Node format
                                   .DATA_ADDR = ch$ptr(.PVB_QE[PE_ADDRESS],,8);
                               [otherwise] : ! Unknown multiple parameter
                                   .DATA_ADDR = 0;
                               tes;
                      end;

                 return $TRUE;
                 end;

            exitloop;
            end;
       end;

    return $FALSE;
    end;				! End of NML$GET_VDB_PARAMETER
%global_routine ('NML$SET_VDB_PARAMETER', ENTITY_TYPE, ENTITY_PTR, PARM_NO, DATA_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Inserts the data for a specific parameter into the volatile
!       data base. The value of the parameter is stored
!       at the address specified by DATA_ADDR.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - Entity type.
!       ENTITY_PTR  - Character pointer to entity id.
!       PARM_NO     - Parameter number.
!       DATA_ADDR   - Address of data for value.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, if the parameter was set in the volatile data base;
!       FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         LPVB_QE: $NML$PVB_ENTRY_BLOCK, ! Local PVB entry
         EDB_QE: ref ENTITY_DB_BLOCK,   ! Entity DB entry
         L,                             ! Length of parameter data
         PRM_PTR;                       ! Pointer to parameter buffer

    if (EDB_QE = GET_EXISTING_ENTITY_DB (.ENTITY_TYPE, .ENTITY_PTR)) eql 0
    then if (EDB_QE = SET_ENTITY_DB (.ENTITY_TYPE, .ENTITY_PTR)) eql 0
         then return $FALSE;            ! Could not get entity db

%if $TOPS20 or $TOPS10
%then
    if (.ENTITY_TYPE eql ENTITY_LOGGING) and (.PARM_NO eql 201)
    then return NML$EVL_SET_VDB_PARAMETER( .ENTITY_TYPE, .ENTITY_PTR,
                                           .PARM_NO, .DATA_ADDR );
%fi
    !
    ! Allocate a buffer for parameter, build a local temporary PVB
    ! entry, and place the parameter number and data in the buffer
    ! in format for response. Then get rid of the data type byte in
    ! in the buffer.
    !

    PRM_PTR = ch$ptr (PRM_BFR,,8);

    LPVB_QE[PE_NUMBER] = .PARM_NO;      ! Get parameter number
    LPVB_QE[PE_DATA] = ..DATA_ADDR;

    L = READ_PARAMETER_DATA (.ENTITY_TYPE,
                             LPVB_QE,
                             PRM_BFR_LENGTH,
                             PRM_PTR);

    ch$move (.L, ch$ptr (PRM_BFR,3,8), ch$ptr (PRM_BFR,2,8));

    !
    ! Insert the parameter into the table vector.
    !

    return (INSERT_PARAMETER (.EDB_QE, .ENTITY_TYPE, ch$ptr (PRM_BFR,,8), $true) eql NICE$_SUC);
    end;				! End of NML$SET_VDB_PARAMETER
%global_routine ('NML$CLR_VDB_PARAMETER', ENTITY_TYPE, ENTITY_PTR, PARM_NO) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Removes a parameter from the volatile data base.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - Entity type.
!       ENTITY_PTR  - Character pointer to entity id.
!       PARM_NO     - Parameter number.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, if the parameter exists in the volatile data base;
!       FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
         EDB_QE: ref ENTITY_DB_BLOCK;   ! Entity DB entry

    if (EDB_QE = GET_EXISTING_ENTITY_DB(.ENTITY_TYPE,.ENTITY_PTR)) eql 0
    then return $FALSE;

%if $TOPS20 or $TOPS10
%then
    if (.ENTITY_TYPE eql ENTITY_LOGGING) and (.PARM_NO eql 201)
    then return NML$EVL_CLR_VDB_PARAMETER( .ENTITY_TYPE,
                                           .ENTITY_PTR, .PARM_NO );
%fi
    !
    ! Perform special casing for parameters which have seperate
    ! parameter numbers for reading and writing.
    !

    if (.ENTITY_TYPE [ENTITY_MAIN] eql ENTITY_NODE)        ! HOST Parameter (Read)
    and (.PARM_NO eql 140)
    then PARM_NO = 141;                 ! Make it 141

    !
    ! Remove the parameter from the table vector, always succeeds.
    !

    REMOVE_PARAMETER (.EDB_QE, .ENTITY_TYPE, .PARM_NO, $true);

    return $TRUE;
    end;				! End of NML$CLR_VDB_PARAMETER
%global_routine ('NML$FIND_NDB', CKT_ENTITY_ID) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Searches the NODE entity volatile data base for the node
!       which has the service circuit parameter corresponding to the
!       CIRCUIT entity specified as an argument.
!
! FORMAL PARAMETERS
!
!	CKT_ENTITY_ID - Pointer to circuit entity id.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Pointer to the node entity id if the node is found;
!       0 if not found.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         NDB_QE: ref NODE_DB_BLOCK;

    $SHOW_NDB

    NDB_QE = NMU$QUEUE_SCAN (QH_NODE_PARAMETERS, .CKT_ENTITY_ID, SVC_CKT_MATCH);

    if .NDB_QE neq 0
    then return ch$ptr (NDB_QE[NDB_ENTITY_ID],,8)
    else return 0;

    end;				! End of NML$FIND_NDB

%global_routine ('NML$FIND_NDB_HDA', HARDWARE_ADDR_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Searches the NODE entity volatile data base for the node
!       which has the HARDWARE ADDRESS parameter corresponding to the
!       Hardware Address  specified as an argument.
!
! FORMAL PARAMETERS
!
!       HARDWARE_ADDR_PTR - pointer to an ETHERnet Hardware Address
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Pointer to the node entity id if the node is found;
!       0 if not found.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         NDB_QE: ref NODE_DB_BLOCK;

    $SHOW_NDB

    NDB_QE = NMU$QUEUE_SCAN (QH_NODE_PARAMETERS, .HARDWARE_ADDR_PTR, HDR_ADR_MATCH);

    if .NDB_QE neq 0
    then return ch$ptr (NDB_QE[NDB_ENTITY_ID],,8)
    else return 0;

    end;				! End of NML$FIND_NDB_HDA

%global_routine ('NML$CONVERT_ENTITY_ID', ENTITY_TYPE,
                                            INPUT_PTR, OUTPUT_PTR) =

!++
!
! Functional description:
!
!	This function reads an entity ID and converts it to its 'canonical'
!	format. If the entity ID refers to a class of objects (SIGNIFICANT,
!       ACTIVE, KNOWN,...) the corresponding code is returned. (See below).
!
!	NODE:	B2 Node address
!		B1 length of node name
!		Bn ascii node name
!
!	AREA:	B1 0
!		B1 area #
!
!	Other:	B1 length of entity name
!		Bn ascii entity name
!
! Parameters:
!
!	ENTITY_TYPE	Entity type of entity ID
!	INPUT_PTR	Address of character sequence pointer to input string
!	OUTPUT_PTR	Character sequence pointer to output string
!
! Implicit output:
!       INPUT_PTR is updated.
!
! Value:  +1   Success, single entity has been converted.
!          0   Failure to parse
!         -1   KNOWN
!         -2   ACTIVE
!         -3   LOOP (Node only)
!         -4   ADJACENT (Node only)
!         -5   SIGNIFICANT
!          
!--

   begin

   selectone .ENTITY_TYPE of
   set

      [NO_ENTITY_] : return $true;      ! For no entity, no more to do

      [ENTITY_NODE] :
         begin
         local LEN,
               ADDRESS,
               SAVE_OUTPUT_PTR,
               NODE_LEN,
               TMP : $SIGNED_BYTE_VALUE;
      
         NODE_LEN = NODE_ID_BUFFER_LENGTH;
         SAVE_OUTPUT_PTR = .OUTPUT_PTR;
      
         if ..INPUT_PTR eql 0           ! If no input pointer at all : default
         then begin
              ch$move(NODE_ID_BUFFER_LENGTH, NMU$NETWORK_LOCAL(), .OUTPUT_PTR);
              return $true;
              end;
      
         TMP = GETB(.INPUT_PTR);        ! Get first byte
         LEN = .TMP[VALUE];             ! Expand signed byte
         if .LEN eql 0                  ! If zero, node address, otherwise
                                        !  length of node name
         then begin                     ! Node address..
              ADDRESS = GETW(.INPUT_PTR);
              if .ADDRESS eql 0 then    !  If 0 then get local name
                 ch$move(NODE_ID_BUFFER_LENGTH,NMU$NETWORK_LOCAL(),
                         .OUTPUT_PTR)
              else begin
                   PUTW(ADDRESS,OUTPUT_PTR);  ! Store address
                   PUTB(0,OUTPUT_PTR);        ! Store a zero count byte
                   $NML$MAP_NODE_ID(NODE_LEN, .SAVE_OUTPUT_PTR);
              end;
         end else if .LEN gtr 0 then begin    ! A node name was given
              ADDRESS = 0;
              PUTW(ADDRESS , OUTPUT_PTR);     ! Store a zero node address
              PUTB(.LEN,OUTPUT_PTR);          ! Store count byte
              ch$copy(.LEN,..INPUT_PTR, 0, NODE_ID_BUFFER_LENGTH, .OUTPUT_PTR);
              .INPUT_PTR = ch$plus(..INPUT_PTR, .LEN);
              $NML$MAP_NODE_ID(NODE_LEN, .SAVE_OUTPUT_PTR);
              end else return .LEN;           ! LEN < 0
         return $true;
         end;

      [ENTITY_AREA] :
         begin
         local TMP : $SIGNED_BYTE_VALUE;

         TMP = GETB(.INPUT_PTR);         ! Get byte 1, should be 0
         if .TMP[VALUE] eql 0
         then begin
              PUTB(0,OUTPUT_PTR);
              PUTB(GETB(.INPUT_PTR),OUTPUT_PTR);
              return $true;
         end else return .TMP[VALUE];    ! TMP < 0

         end;

      [ENTITY_CIRCUIT, ENTITY_LINE, ENTITY_MODULE] :
         begin
         local SAV_PTR, LEN, TMP : $SIGNED_BYTE_VALUE;

         TMP = GETB(.INPUT_PTR);
         LEN = .TMP[VALUE];
         if .LEN gtr 0
         then begin
              PUTB(.LEN,OUTPUT_PTR);    ! Put out length byte
              SAV_PTR = .OUTPUT_PTR;    ! Save output pointer for a while
              ch$copy(.LEN, ..INPUT_PTR, 0, 2+max(0,9,17), .OUTPUT_PTR);
              .INPUT_PTR = ch$plus(..INPUT_PTR, .LEN);
              cvltu(.SAV_PTR, .LEN);    ! Make upper case
              return $true;
         end else return .LEN;          ! LEN < 0
         end;

      [otherwise] : return $false;      ! Shouldnt get here

      tes;                              ! End of select
      end;                              ! End of NML$CONVERT_ENTITY_ID

%routine ('SELECT_LOGGING', EDB_QE : ref ENTITY_DB_BLOCK, PBF : ref PBF_BLOCK) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       No filters supported yet.
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    selectone .PBF [PBF_SELECTOR] of
        set
        [KNOWN_]:
            ;
        [otherwise]:
            begin
            literal ON = 0, OFF = 1, HOLD = 2;
            local STATE;

            NML$GET_VDB_PARAMETER (ENTITY_LOGGING,
                                   ch$ptr (EDB_QE[EDB_ENTITY_ID],,8),
                                   0,
                                   STATE);
            selectone .STATE of
                set
                [ON, HOLD]:
                    ;
                [otherwise]:
                    return 0;
                tes;
            end;
        tes;

    if (.PBF [PBF_LEN_ADR] = ..PBF [PBF_LEN_ADR] - 1) geq 0
    then
        ch$wchar_a (ch$rchar (ch$ptr (EDB_QE[EDB_ENTITY_ID],,8)),
                    .PBF [PBF_BUF_PTR_ADR]);

    return 0
    end;				! End of SELECT_LOGGING
%routine ('SELECT_MODULE', EDB_QE : ref ENTITY_DB_BLOCK, PBM : ref PBM_BLOCK) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       No filters supported yet.
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin
    local LEN;

    selectone .PBM [PBM_SELECTOR] of
        set
        [KNOWN_]:
            ;
        [otherwise]:
            return 0;
        tes;

    LEN = ch$rchar (ch$ptr (EDB_QE[EDB_ENTITY_ID],,8)) + 1;

    if (.PBM [PBM_LEN_ADR] = ..PBM [PBM_LEN_ADR] - .LEN) geq 0
    then
        .PBM [PBM_BUF_PTR_ADR] = ch$move (.LEN,
                                          ch$ptr (EDB_QE[EDB_ENTITY_ID],,8),
                                          ..PBM [PBM_BUF_PTR_ADR]);

    return 0
    end;				! End of SELECT_MODULE
%routine ('VDB_READ', FUNCTION, ENTITY_TYPE, ENTITY, QUALIFIER, SELECTOR, LENGTH, BP_ADDR, ERR_DETAIL) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Performs the NML NICE read function for NML volatile parameters.
!
! FORMAL PARAMETERS
!
!	FUNCTION  -   Code to denote whether the specified parameter is to be
!                     defined or purged.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       ENTITY    -   Character sequence pointer to the entity id.
!       QUALIFIER -   An optional character sequence pointer to a qualifier in
!                     parameter format.
!       SELECTOR  -   For the return function, the class of entities to return.
!       LENGTH    -   The address of a variable to be updated with the length
!                     of the data returned in the buffer.
!       BP_ADDR   -   The address of a character sequence pointer to
!                     the parameter buffer.
!       ERR_DETAIL-   The address of a variable in which to return the
!		      error detail field for the response message if this
!		      request fails.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NML specified NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
         RESULT,
         EDB_QE: ref ENTITY_DB_BLOCK;

    $SHOW_EDB

    if (EDB_QE = GET_EXISTING_ENTITY_DB (.ENTITY_TYPE, .ENTITY)) eql 0
    then RESULT = (begin
                  .ERR_DETAIL = .ENTITY_TYPE [ENTITY_MAIN];
                  $NICE$ERR_URC
                  end)

    else begin
         %if not $MCB
         %then

         if .ENTITY_TYPE [ENTITY_MAIN] eql ENTITY_MODULE
         then begin
              RESULT = READ_QUALIFIED_ENTITY (.EDB_QE,
                                              .FUNCTION,
                                              .ENTITY_TYPE,
                                              .ENTITY,
                                              .QUALIFIER,
                                              .SELECTOR,
                                              .LENGTH,
                                              .BP_ADDR);

              return .RESULT;
              end;

         %fi

         RESULT = READ_ENTITY (.EDB_QE,
                               .FUNCTION,
                               .ENTITY_TYPE,
                               .ENTITY,
                               .QUALIFIER,
                               .SELECTOR,
                               .LENGTH,
                               .BP_ADDR);
         end;

    return .RESULT;
    end;				! End of VDB_READ
%if not $MCB %then
%routine ('READ_QUALIFIED_ENTITY', EDB_QE, FUNCTION, ENTITY_TYPE, ENTITY, QUALIFIER, SELECTOR, LENGTH, POINTER) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Perform the read information function for a specific entity
!       in the volatile data base which has qualifier sub-queues.
!
! FORMAL PARAMETERS
!
!	EDB_QE    -   Address of the entity data base entry.
!	FUNCTION  -   Code to denote whether a straight read parameters/counters
!                     operation or a show and zero counters is performed.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       ENTITY    -   Character sequence pointer to the entity id.
!       QUALIFIER -   An optional character sequence pointer to a qualifier in
!                     parameter format.
!       SELECTOR  -   For the return function, the class of entities to return.
!       LENGTH    -   The address of a variable to be updated with the length
!                     of the data returned in the buffer.
!       POINTER   -   The address of a character sequence pointer to
!                     the parameter buffer.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
        EDB_QE: ref ENTITY_DB_BLOCK;

    local
        QUALIFIER_QUEUE: ref Q_HEADER,
        ENTRY: ref ENTITY_DB_BLOCK;

    QUALIFIER_QUEUE = EDB_QE[EDB_QUALIFIER_QUEUE]; ! Get qualified queue header

    if .QUALIFIER eql 0
    then begin                          ! Read default existing queue

         ! If the queue length (number of entries) is not 1,
         ! i.e. the queue does not have any entries or more than one

         if NMU$QUEUE_LENGTH (.QUALIFIER_QUEUE) neq 1
         then begin                     ! Return list of network names
              local NEXT: ref Q_ENTRY;

              NEXT = .QUALIFIER_QUEUE[Q_FORWARD];
              while ((ENTRY = .NEXT) neq .QUALIFIER_QUEUE)
              do begin
                 NEXT = .NEXT[Q_FORWARD];
                 READ_QUALIFIER (.ENTRY, .LENGTH, .POINTER);
                 end;

              return NICE$_SUC;
              end;

         ENTRY = .QUALIFIER_QUEUE[Q_FORWARD]; ! Default qualified queue
         end
    else begin                          ! Read specific queue
         local ID_STRING, COUNT: $SIGNED_BYTE_VALUE;

         ID_STRING = ch$plus (.QUALIFIER, 2);
         COUNT = ch$rchar (.ID_STRING); ! Get the count byte

         if .COUNT[VALUE] lss 0         ! If count byte is negative ....
         then begin                     ! Read KNOWN qualified queues
              local RESULT, NEXT: ref Q_ENTRY;

              NEXT = .QUALIFIER_QUEUE[Q_FORWARD];
              RESULT = NICE$_SUC;

              while (.RESULT eql NICE$_SUC)
              and ((ENTRY = .NEXT) neq .QUALIFIER_QUEUE)
              do begin
                 NEXT = .NEXT[Q_FORWARD];
                 READ_QUALIFIER (.ENTRY, .LENGTH, .POINTER);
                 RESULT = READ_ENTITY (.ENTRY,
                                       .FUNCTION,
                                       .ENTITY_TYPE,
                                       .ENTITY,
                                       .QUALIFIER,
                                       .SELECTOR,
                                       .LENGTH,
                                       .POINTER);
                 end;

              return .RESULT;
              end
         else begin                     ! Read specific qualified queue
              ENTRY = NMU$QUEUE_SCAN (.QUALIFIER_QUEUE,
                                      .ID_STRING,
                                      NON_NODE_ID_MATCH);

              if .ENTRY eql 0           ! No data base for specified qualifier
              then return NICE$_SUC;
              end;
         end;

    READ_QUALIFIER (.ENTRY, .LENGTH, .POINTER);

    return READ_ENTITY (.ENTRY,
                        .FUNCTION,
                        .ENTITY_TYPE,
                        .ENTITY,
                        .QUALIFIER,
                        .SELECTOR,
                        .LENGTH,
                        .POINTER);
    end;				! End of READ_QUALIFIED_ENTITY
%fi
%sbttl ''
%if not $MCB %then
%routine ('READ_QUALIFIER', ENTRY, LENGTH, POINTER) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Perform the read qualifier for a specific qualifier queue
!       in the volatile data base.
!
! FORMAL PARAMETERS
!
!	ENTRY   Address of the entity data base entry.
!       LENGTH  The address of a variable to be updated with the length
!               of the data returned in the buffer.
!       POINTER The address of a character sequence pointer to
!               the parameter buffer.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
        ENTRY: ref ENTITY_DB_BLOCK;

    local
        VAL;

    VAL = 1110;                         ! NETWORK parameter number
    PUTW (VAL, .POINTER);

    PUTB (%O'100', .POINTER);           ! Data type byte

    VAL = ch$rchar (ch$ptr (ENTRY[EDB_QUALIFIER],,8)) + 1;
    .POINTER = ch$move (.VAL,           ! Network name string
                        ch$ptr (ENTRY[EDB_QUALIFIER],,8),
                        ..POINTER);

    .LENGTH = ..LENGTH - .VAL - 3;      ! Remaining length of the buffer

    return;
    end;                                ! End of READ_QUALIFIER
%fi
%routine ('READ_ENTITY', EDB_QE, FUNCTION, ENTITY_TYPE, ENTITY, QUALIFIER, SELECTOR, LENGTH, BP_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Perform the read information function for a specific entity
!       in the volatile data base.
!
! FORMAL PARAMETERS
!
!	EDB_QE    -   Address of the entity data base entry.
!	FUNCTION  -   Code to denote whether a straight read parameters/counters
!                     operation or a show and zero counters is performed.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       ENTITY    -   Character sequence pointer to the entity id.
!       QUALIFIER -   An optional character sequence pointer to a qualifier in
!                     parameter format.
!       SELECTOR  -   For the return function, the class of entities to return.
!       LENGTH    -   The address of a variable to be updated with the length
!                     of the data returned in the buffer.
!       BP_ADDR   -   The address of a character sequence pointer to
!                     the parameter buffer.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    local
         PVB_QE: ref $NML$PVB_ENTRY_BLOCK;

    selectone .FUNCTION of
        set
        [%bliss36($NTSHO)
         %bliss16(N$FSHO)]:               ! Show parameters
            begin
            case .SELECTOR from SUMMARY_ to EVENTS_ of
                set
                [SUMMARY_, STATUS_, CHARACTERISTICS_]:
                    READ_PARAMETERS (.EDB_QE, .ENTITY_TYPE, .ENTITY,
                                     .QUALIFIER, .SELECTOR, .LENGTH, .BP_ADDR);
                [COUNTERS_]:
                    READ_COUNTERS (.EDB_QE, .ENTITY_TYPE, .SELECTOR,
                                   .LENGTH, .BP_ADDR);
                [EVENTS_]:
                    NML$EVL_READ_EVENTS (.ENTITY, .QUALIFIER, .SELECTOR,
                                         .LENGTH, .BP_ADDR);
                tes
            end;

        [%bliss36($NTSZC)
         %bliss16(N$FSZC)]:             ! Show and zero counters
            READ_COUNTERS (.EDB_QE, .ENTITY_TYPE, .SELECTOR,
                           .LENGTH, .BP_ADDR);
        [otherwise]:
            $NICE$ERR_MPE;
        tes

    end;				! End of READ_ENTITY
%routine ('READ_PARAMETERS', EDB_QE, ENTITY_TYPE, ENTITY, QUALIFIER, SELECTOR, LENGTH, BP_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Reads all of the NML parameters out of the volatile
!       data base for an entity.
!
! FORMAL PARAMETERS
!
!	EDB_QE    -   Address of the entity data base entry.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       ENTITY    -   Character sequence pointer to the entity
!       QUALIFIER -   Character sequence pointer to qualifier string
!       SELECTOR  -   For the return function, the class of entities to return.
!       LENGTH    -   The address of a variable to be updated with the length
!                     of the data returned in the buffer.
!       BP_ADDR   -   The address of a character sequence pointer to
!                     the parameter buffer.
!
! IMPLICIT INPUTS
!
!	When called, the contents of the address passed as LENGTH
!	specifies the characters currently available in the buffer.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	The contents of LENGTH are updated.
!
!--

    begin

    map
        EDB_QE: ref ENTITY_DB_BLOCK,
        ENTITY_TYPE : FULL_ENTITY;


    label
        DISPLAY_CHECK;

    literal
	CPARM_STATE = 0;                ! Circuit STATE

    !
    ! If parameter count is zero or a parameter vector is not currently
    ! allocated there is nothing to show.
    !

    ! -- Unless there is something in the event logger database.. --

    if ((.EDB_QE[EDB_PARAMETER_ALLOCATION] eql 0) ! They better all be in
    and (.EDB_QE[EDB_PARAMETER_VECTOR] eql 0)) ! agreement.
    or (.EDB_QE[EDB_PARAMETER_COUNT] eql 0)
    then return (
         if (.ENTITY_TYPE eql ENTITY_LOGGING) and (.SELECTOR eql SUMMARY_)
         then NML$EVL_READ_EVENTS(.ENTITY, .QUALIFIER, .SELECTOR,
                                  .LENGTH, .BP_ADDR)
         else NICE$_SUC
         );

    !
    ! Otherwise, if the count is non-zero and a parameter vector is
    ! allocated, then search through the vector for each parameter
    ! in the volatile data base and place a formatted entry in the
    ! buffer representing its current value.
    !

    begin

    local
        PVB_QE: ref $NML$PVB_ENTRY_BLOCK;

    PVB_QE = .EDB_QE[EDB_PARAMETER_VECTOR];

    decru N from .EDB_QE[EDB_PARAMETER_COUNT] to 1
    do begin
DISPLAY_CHECK:
       begin                            ! DISPLAY_CHECK
       local L;

       if not NML$INFORMATION (.ENTITY_TYPE, .PVB_QE[PE_NUMBER], .SELECTOR)
       then leave DISPLAY_CHECK;


%if $MCB
%then
       selectone .ENTITY_TYPE [ENTITY_MAIN] of
           set
           [ENTITY_LINE, ENTITY_CIRCUIT]:
               if .PVB_QE[PE_NUMBER] eql CPARM_STATE
               then leave DISPLAY_CHECK;
           [otherwise]:
               ;
           tes;
%fi

       !
       ! If the parameter buffer length is 3 or less, we can't fill in
       ! any data in the buffer.
       !

       if ..LENGTH leq 3 then return NICE$_REE;

       L = READ_PARAMETER_DATA (.ENTITY_TYPE, .PVB_QE, ..LENGTH-3, .BP_ADDR) + 3;

       if ..LENGTH lss .L then return $NICE$ERR_REE;

       .LENGTH = ..LENGTH - .L
       end;                             ! DISPLAY_CHECK
       PVB_QE = vector [.PVB_QE, PVB_ENTRY_SIZE];
       end;

    end;

    if (.ENTITY_TYPE eql ENTITY_LOGGING) and (.SELECTOR eql SUMMARY_)
    then NML$EVL_READ_EVENTS (.ENTITY, .QUALIFIER, .SELECTOR,
                              .LENGTH, .BP_ADDR );

    return NICE$_SUC;
    end;				! End of READ_PARAMETERS
%routine ('READ_COUNTERS', EDB_QE, ENTITY_TYPE, SELECTOR, LENGTH, BP_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Reads all of the NML counters out of the volatile
!       data base for an entity.
!
! FORMAL PARAMETERS
!
!	EDB_QE    -   Address of the entity data base entry.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       SELECTOR  -   For the return function, the class of entities to return.
!       LENGTH    -   The address of a variable to be updated with the length
!                     of the data returned in the buffer.
!       BP_ADDR   -   The address of a character sequence pointer to
!                     the parameter buffer.
!
! IMPLICIT INPUTS
!
!	When called, the contents of the address passed as LENGTH
!	specifies the characters currently available in the buffer.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	The contents of LENGTH are updated.
!
!--

!There are no counters supported at this level !!!

    begin

    return $TRUE;
    end;				! End of READ_COUNTERS

%routine ('VDB_CHANGE', FUNCTION, ENTITY_TYPE, QUALIFIER, ENTITY, LENGTH, POINTER, ERR_DETAIL) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Performs the NML NICE change function for NML volatile parameters.
!
! FORMAL PARAMETERS
!
!	FUNCTION  -   Code to denote whether the specified parameter is to be
!                     set or cleared.
!       ENTITY_TYPE - The NML entity type of the entity to which the
!                     parameter pertains.
!       QUALIFIER -   An optional character sequence pointer to a qualifier in
!                     parameter format.
!       ENTITY    -   Character sequence pointer to the entity id.
!       LENGTH    -   The length of the parameter data passed in the
!		      parameter buffer.
!       POINTER   -   A character sequence pointer to the parameter buffer.
!       ERR_DETAIL-   The address of a variable in which to return the
!		      error detail field for the response message if this
!		      request fails.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NML specified NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
         EDB_QE: ref ENTITY_DB_BLOCK;

    selectone .FUNCTION of
        set
        [%bliss36($NTSET) %bliss16(N$FSET)]: ! SET parameter
            begin
            if (EDB_QE = GET_EXISTING_ENTITY_DB (.ENTITY_TYPE, .ENTITY)) eql 0
            then begin                  ! Could not locate data base entry
                 if not ENTITY_IS_VALID (.ENTITY_TYPE, .ENTITY) ! Is entity valid ?
                 then begin
		      .ERR_DETAIL = .ENTITY_TYPE;
		      return $NICE$ERR_URC; ! No, return error
		      end;

                 if (EDB_QE = SET_ENTITY_DB (.ENTITY_TYPE, .ENTITY)) eql 0
                 then return $NICE$ERR_NRE; ! Try to create data base entry

                 %if not $MCB
                 %then

                 if .ENTITY_TYPE [ENTITY_MAIN] eql ENTITY_MODULE   ! Initialize queue for network entries
                 then NMU$QUEUE_RESET (EDB_QE[EDB_QUALIFIER_QUEUE]);

                 %fi
                 end;

            selectone .ENTITY_TYPE [ENTITY_MAIN] of     ! Put the parameter entry into
                set                     ! the parameter data vector.
                [ENTITY_NODE]:
                    begin
                    local PTR;

                    PTR = .POINTER;     ! Get local copy of pointer
                    if GETW (PTR) eql 110 ! SERVICE CIRCUIT
                    then begin          ! Check if circuit already assigned
                         if NMU$DLX_DEVICE_TYPE (.PTR) neq 15
                         then begin     ! But only if it's non-Ethernet
                              if (PTR = NML$FIND_NDB (.PTR)) neq 0
                              then
                                  if not ch$eql (9, .PTR, 9, .ENTITY)
                                  then begin
                                       .ERR_DETAIL = ENTITY_CIRCUIT;
                                       return $NICE$ERR_CWS;
                                       end;
                              end;
                         end;

                    return INSERT_PARAMETER (.EDB_QE, .ENTITY_TYPE, .POINTER, $false);
                    end;

                %if not $MCB   		! MODULE X25-ACCESS volatile data base
                %then                   ! exists in the TOPS only

                [ENTITY_MODULE]:
                    return SET_QUALIFIED_ENTITY (.EDB_QE,
                                                 .ENTITY_TYPE,
                                                 .QUALIFIER,
                                                 .POINTER);
                %fi

!
! If we are enabling service for a circuit (ie: SET CIRCUIT xxxx SERVICE
! ENABLED), call the Data Link Watcher so that we can have it take a look
! at the circuit immediately.
!

		[ENTITY_CIRCUIT]:
		    begin
		    local TEMP;

                    ! If this is SET CIRC .. SERVICE ENABLE,
                    ! make the data link watcher run a pass
		    TEMP = .POINTER;
		    if GETW (TEMP) eql 100 then
		    if GETW (TEMP) eql 0 then NML$DLW_CHECK_CIRCUIT (.ENTITY);
                    return INSERT_PARAMETER (.EDB_QE,
                                             .ENTITY_TYPE,
                                             .POINTER,
                                             $false);
		    end;

%if $TOPS20 or $TOPS10
%then
                [ENTITY_LOGGING]:       ! Come here for LOGGING parameters
                    begin
                    local TEMP;

                    TEMP = .POINTER;    ! Get a pointer to parameter string
                    if GETW(TEMP) eql 201 ! EVENT parameter
                    then return NML$EVL_INSERT_PARAMETER( .ENTITY, .QUALIFIER,
                                                          .LENGTH, .POINTER)
                    else begin

                         ! Before inserting the logging parameter (NAME or
                         ! STATE) make sure that if a qualifier is given that
                         ! it is the local node. It is not allowed to set NAME
                         ! or STATE for a remote sink node.

                         local
                             TEMP,      ! Temporary address
                             TEMPSTR : block [ch$allocation(2+1+6,8)];
                                        ! Temporary node name string

                         TEMP = .QUALIFIER; ! See if there is a qualifier
                         if .QUALIFIER neq 0
                         then begin
                              ! If qualifier, must be SINK NODE
                              if GETW(TEMP) neq 200
                              then return $NICE$ERR_PNA;
                              end;
                         ! Now expand qualifier
                         if NML$CONVERT_ENTITY_ID(ENTITY_NODE, TEMP,
                                                  ch$ptr(TEMPSTR,,8))
                            neq $true then return $NICE$ERR_PNA;
                         ! Node id is in TEMPSTR, make sure it is local node
                         if ch$eql(2+1+6, ch$ptr(TEMPSTR,,8),
                                   2+1+6, NMU$NETWORK_LOCAL(),
                                   0)
                            neq 1 then return $NICE$ERR_PNA;

                         return INSERT_PARAMETER (.EDB_QE, .ENTITY_TYPE,
                                                  .POINTER, $false);
                         end;
                    end;
%fi

                [otherwise]:
                    return INSERT_PARAMETER (.EDB_QE, .ENTITY_TYPE, .POINTER, $false);
                tes;
            end;

        [%bliss36($NTCLR) %bliss16(N$FCLR)]: ! CLEAR parameter
            begin
            if (EDB_QE = GET_EXISTING_ENTITY_DB (.ENTITY_TYPE, .ENTITY)) eql 0
            then begin
		 .ERR_DETAIL = .ENTITY_TYPE;
		 return $NICE$ERR_URC;
		 end
            else begin
                 selectone .ENTITY_TYPE [ENTITY_MAIN] of
                     set
                     [ENTITY_MODULE]:
			 begin
                         %if $MCB
                         %then REMOVE_PARAMETER (.EDB_QE,
                                                 .ENTITY_TYPE,
                                                 (if .LENGTH gtr 0
                                                  then GETW_NA (.POINTER)
                                                  else -1),
                                                 $false);
                         %else return REMOVE_QUALIFIED_PARAMETER (.EDB_QE,
                                                                  .ENTITY_TYPE,
                                                                  .QUALIFIER,
                                                                  .POINTER,
                                                                  .LENGTH,
                                                                  $false);
                         %fi
			 end;

%if $TOPS20 or $TOPS10
%then
                     [ENTITY_LOGGING]:
                         begin
                         local TEMP;

                         TEMP = .POINTER;
                         if GETW(TEMP) eql 201 ! EVENT parameter
                         then NML$EVL_DELETE_PARAMETER( .ENTITY, .QUALIFIER,
                                                        .LENGTH, .POINTER )
                         else
                         REMOVE_PARAMETER (.EDB_QE,
                                           .ENTITY_TYPE,
                                           (if .LENGTH gtr 0
                                            then GETW_NA (.POINTER)
                                            else -1), ! Zero implies ALL
                                           $false)
                         end;
                                           
%fi
                     [otherwise]:
                         REMOVE_PARAMETER (.EDB_QE,
                                           .ENTITY_TYPE,
                                           (if .LENGTH gtr 0
                                            then GETW_NA (.POINTER)
                                            else -1), ! Zero implies ALL
                                           $false);
                     tes;
                 end;
            end;

        [otherwise]:
            return $NICE$ERR_UFO;
        tes;

    return NICE$_SUC;
    end;				! End of VDB_CHANGE
%if not $MCB %then
%routine ('SET_QUALIFIED_ENTITY', EDB_QE, ENTITY, QUALIFIER, PARAMETER) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Set the parameter entry in the qualified sub queues.
!
! FORMAL PARAMETERS
!
!	EDB_QE          Address of the qualified entity data base structure to
!                       which the parameter is to be inserted.
!       ENTITY          The entity type number to which the parameter applies.
!       QUALIFIER       A character sequence pointer to the qualifier
!                       parameter.
!       PARAMETER       A character sequence pointer to the parameter to
!                       be inserted.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
        EDB_QE: ref ENTITY_DB_BLOCK;

    local
        QH_QUALIFIER: ref Q_HEADER,
        QE_QUALIFIER: ref ENTITY_DB_BLOCK;

    QH_QUALIFIER = EDB_QE[EDB_QUALIFIER_QUEUE];

    if .QUALIFIER eql 0
    then begin                          ! Use default existing qualifier queue
         if NMU$QUEUE_LENGTH (.QH_QUALIFIER) eql 1 ! Queue has only 1 entry ?
         then QE_QUALIFIER = .QH_QUALIFIER[Q_FORWARD] ! Yes, default queue
         else return $NICE$ERR_PAM;     ! No, expecting qualifier name
         end
    else begin                          ! Use specific qualifier queue
         local ID_STRING, COUNT: $SIGNED_BYTE_VALUE;

         ID_STRING = ch$plus (.QUALIFIER, 2); ! Get qualifier id string
         COUNT = ch$rchar (.ID_STRING); ! Get count byte

         if .COUNT[VALUE] lss 0         ! If count byte is negative ....
         then begin                     ! Set KNOWN qualified queues
              local RESULT, NEXT: ref Q_ENTRY;

              NEXT = .QH_QUALIFIER[Q_FORWARD];
              RESULT = NICE$_SUC;

              while (.RESULT eql NICE$_SUC)
              and ((QE_QUALIFIER = .NEXT) neq .QH_QUALIFIER)
              do begin
                 NEXT = .NEXT[Q_FORWARD];
                 RESULT = INSERT_PARAMETER (.QE_QUALIFIER,
                                            .ENTITY,
                                            .PARAMETER,
                                            $false);
                 end;

              return .RESULT;
              end
         else begin                     ! Set specific qualified queue
              QE_QUALIFIER = NMU$QUEUE_SCAN (.QH_QUALIFIER,
                                             .ID_STRING,
                                             NON_NODE_ID_MATCH);

              if .QE_QUALIFIER eql 0    ! Does entry exist ?
              then begin                ! No, create new entry for qualifier
                   QE_QUALIFIER = NMU$MEMORY_GET (ENTITY_DB_BLOCK_ALLOCATION);

                   if .QE_QUALIFIER eql 0 ! Fail to allocate memory
                   then return $NICE$ERR_NRE;

                   ch$move ((.COUNT[VALUE] + 1),
                            .ID_STRING,
                            ch$ptr (QE_QUALIFIER[EDB_QUALIFIER],,8));

                   NMU$QUEUE_INSERT (.QH_QUALIFIER, .QE_QUALIFIER);
                   end;
              end;
         end;

    return INSERT_PARAMETER (.QE_QUALIFIER, .ENTITY, .PARAMETER, $false);
    end;				! End of SET_QUALIFIED_ENTITY
%fi
%sbttl ''
%routine ('SET_NODE_ENTITY', NDB_QE: ref NODE_DB_BLOCK, ENTITY_PTR) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Sets up the entity id portion of an EDB for NODE entity.
!
! FORMAL PARAMETERS
!
!	NDB_QE - Address of the NDB Queue Entry.
!       ENTITY_PTR - Pointer to the NODE id.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         NODE_PTR,
         NODE_ADDR;

    NODE_ADDR = GETW (ENTITY_PTR);
    NODE_PTR = ch$ptr (NDB_QE[NDB_ENTITY_ID],,8);
    PUTW (NODE_ADDR, NODE_PTR);
    ch$move ((ch$rchar (.ENTITY_PTR) + 1), .ENTITY_PTR, .NODE_PTR);

    end;				! End of SET_NODE_ENTITY
%routine ('GET_EXISTING_ENTITY_DB', ENTITY_TYPE, ENTITY_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Searches the volatile data base for the specified entity,
!	and if found, returns the address of the entity data block.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - Entity type.
!       ENTITY_PTR  - Character pointer to entity id.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	The address of the entity data block if the entity exists
!	    in the volatile data base.
!       Otherwise, 0.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
	QUEUE,
	MATCH_ROUTINE;

    !
    ! Determine the queue to which this entity belongs and the routine
    ! to be used for matching the entity id.
    !

    if GET_VDB_ENTITY_QUEUE (.ENTITY_TYPE, QUEUE, MATCH_ROUTINE)
    then NMU$QUEUE_SCAN (.QUEUE, .ENTITY_PTR, .MATCH_ROUTINE)
    else 0

    end;				! End of GET_EXISTING_ENTITY_DB
%routine ('SET_ENTITY_DB', ENTITY_TYPE, ENTITY_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Allocate and initialize an entry in the data base.
!       Returns the address of the entry in all cases.
!
! FORMAL PARAMETERS
!
!       ENTITY_TYPE - The entity type.
!       ENTITY_PTR - A character sequence pointer to the entity id
!                    to be created.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of the entity data base block.
!	0 if no insufficient resources for data base creation.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
         QHEADER,
         EDB_QE: ref ENTITY_DB_BLOCK;

    selectone .ENTITY_TYPE [ENTITY_MAIN] of
        set
        [ENTITY_NODE]:
            begin
            if (EDB_QE = NMU$MEMORY_GET (ENTITY_DB_BLOCK_ALLOCATION)) eql 0
            then return 0;

            SET_NODE_ENTITY (.EDB_QE, .ENTITY_PTR);
            end;

        [ENTITY_LINE,
         ENTITY_CIRCUIT,
         ENTITY_LOGGING,
	 ENTITY_MODULE]:
            begin
            if (EDB_QE = NMU$MEMORY_GET (ENTITY_DB_BLOCK_ALLOCATION)) eql 0
            then return 0;

            ch$move ((ch$rchar (.ENTITY_PTR) + 1), ! Copy entity id
                     .ENTITY_PTR,
                     ch$ptr (EDB_QE[EDB_ENTITY_ID],,8));
            end;

	[ENTITY_AREA]:	! $$UNDER DEVELOPMENT$$
	    begin
            if (EDB_QE = NMU$MEMORY_GET (ENTITY_DB_BLOCK_ALLOCATION)) eql 0
            then return 0;

	    ch$wchar (ch$rchar (.ENTITY_PTR),
		      ch$ptr (EDB_QE[EDB_ENTITY_ID],,8));
	    end;
        [otherwise]:                    ! NOT supported entity
            begin
            TASK_ERROR ('Invalid entity for data base creation');
            return 0;
            end;
        tes;

    if GET_VDB_ENTITY_QUEUE (.ENTITY_TYPE, QHEADER, 0) ! Get queue header
    then NMU$QUEUE_INSERT (.QHEADER, .EDB_QE) ! Insert the entity in data base.
    else begin                          ! No queue header for this entity
         TASK_ERROR ('Missing queue for data base creation');
         return 0;
         end;

    return .EDB_QE;                     ! Return address of entry
    end;				! End of SET_ENTITY_DB
%routine ('ENTITY_IS_VALID', ENTITY_TYPE, ENTITY_PTR) =
!++
! FUNCTIONAL DESCRIPTION:
!
!       Determine if we should allow this entity to be added
!       to the data bases.  In MCB, we ask NMX about LINEs and CIRCUITs.
!       In TOPS20 or TOPS10, determine if a DTE is legal.
!
! FORMAL PARAMETERS
!
!       ENTITY_TYPE - The entity type.
!       ENTITY_PTR - A character sequence pointer to the entity id
!                    to be created.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	$true - if entity is acceptable
!       $false - Don't add this to the data bases!
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
         EDB_QE: ref ENTITY_DB_BLOCK;

    selectone .ENTITY_TYPE [ENTITY_MAIN] of
        set
        [ENTITY_NODE]:
            begin                    ! Verify existence of entity ....
            EDB_QE = 2;
            %if $MCB
                %then
                return ($NML$SHOW (.ENTITY_TYPE [ENTITY_MAIN] , ! Returns OCM error
                                   .ENTITY_PTR,	   !  if valid entity
                                   0,		   !  since buffer is
                                   SUMMARY_,           !  too small.
                                   EDB_QE,		   ! Otherwise,
                                   ch$ptr (EDB_QE,,8)) !  entity is invalid.
                        eql $NICE$ERR_OCM);      ! in the MCB
                %else
                return $true;   ! Always return true for TOPS.
                %fi
            end;
        [ENTITY_LINE]:
            begin
            EDB_QE = 2;
            return ($NML$SHOW (.ENTITY_TYPE [ENTITY_MAIN] , ! Returns OCM error
                               .ENTITY_PTR,	   !  if valid entity
                               0,		   !  since buffer is
                               CHARACTERISTICS_,   !  too small.
                               EDB_QE,		   ! Otherwise,
                               ch$ptr (EDB_QE,,8)) !  entity is invalid.
                    eql
			%if $MCB
			%then
			      $NICE$ERR_OCM);      ! in the MCB
			%else
			      $NICE$ERR_REE);      ! in the TOPS
			%fi
            end;

        [ENTITY_MODULE]:
            return (MODULE_IS_VALID (.ENTITY_TYPE));

        [ENTITY_LOGGING]:
            return (LOGGING_IS_VALID(.ENTITY_PTR));

        [ENTITY_CIRCUIT]:
            begin
            %if $MCB          		! Verify existence of entity ....
            %then                       ! in the MCB
            EDB_QE = 2;
            return ($NML$SHOW (.ENTITY_TYPE [ENTITY_MAIN] ,
                               .ENTITY_PTR,
                               0,
                               SUMMARY_,
                               EDB_QE,
                               ch$ptr (EDB_QE,,8))
                    neq $NICE$ERR_URC);

            %else                       ! in TOPS-10
            external routine NMU$DLX_KNOWN_DEVICE;

            return (NMU$DLX_KNOWN_DEVICE (.ENTITY_PTR));
            %fi

            end;

	[ENTITY_AREA]:		! Area Entity $$UNDER DEVELOPMENT$$
	    begin
	    EDB_QE = 2;
	    return ($NML$SHOW (.ENTITY_TYPE [ENTITY_MAIN] ,
			       .ENTITY_PTR,
			       0,
			       SUMMARY_,
			       EDB_QE,
			       ch$ptr (EDB_QE,,8))
		    neq $NICE$ERR_URC);
	    end;
        [otherwise]:
            TASK_ERROR ('Invalid entity for data base creation');
        tes;

    return $FALSE;
    end;				! End of ENTITY_IS_VALID
%routine ('LOGGING_IS_VALID', ENTITY_TYPE, ENTITY_PTR) =

!++
! FUNCTIONAL DESCRIPTION
!
!       Determine if this logging entity ID is valid, and should be
!       created in database.
!
! FORMAL PARAMETERS
! 
!       ENTITY_TYPE - The entity type
!
!       ENTITY_PTR - A character sequence pointer to the entity ID
!                    to be created.
!
! IMPLICIT INPUTS
!
!       None.
!
! ROUTINE VALUE
!
!       $TRUE - Entity ID is acceptable
!       $FALSE - Entity ID is not acceptable
!
! SIDE EFFECTS
!
!       None.
!
!--

   begin

%if $mcb
%then                                   ! For MCB, do not allow entity
                                        !  ID's to be added.
   return (GET_EXISTING_ENTITY_DB (.ENTITY_TYPE, .ENTITY_PTR));

%else                                   ! For TOPS-x0, verify that entity
                                        !  ID is CONSOLE, FILE or MONITOR
   local ENTITY_ID;

   ENTITY_ID = ch$rchar (.ENTITY_PTR);
   return ((.ENTITY_ID eql CONSOLE_) or (.ENTITY_ID eql FILE_)
        or (.ENTITY_ID eql MONITOR_));

%fi

   end;                                 ! End of LOGGINGS_IS_VALID

%routine ('MODULE_IS_VALID', ENTITY_TYPE) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Determine if we should allow this module data base to be handled
!       in this layer.
!
! FORMAL PARAMETERS
!
!       ENTITY_TYPE     The full entity type
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	$TRUE           If module is acceptable
!       $FALSE          Otherwise
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    %if $MCB
    %then                         ! These modules are valid in the MCB
    return ((.ENTITY_TYPE eql ENTITY_MODULE_X25_PROTOCOL) or
	    (.ENTITY_TYPE eql ENTITY_MODULE_X25_SERVER));

    %else                         ! This modules are valid in the TOPS
    return (.ENTITY_TYPE eql ENTITY_MODULE_X25_ACCESS);

    %fi

    end;				! End of MODULE_IS_VALID
%routine ('GET_VDB_ENTITY_QUEUE', ENTITY_TYPE, QUEUE, MATCH_ROUTINE) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine determines the queue in the volatile data base
!       as well as the matching routine associated with the specified
!       entity type.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE     Entity type.
!       QUEUE           The address in which to return the address of the
!                       queue header for this type of entity.
!       MATCH_ROUTINE   The address in which to return the address
!                       of the associated string matching routine.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	$TRUE   If the volatile data base contains this entity type.
!       $FALSE  Otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map ENTITY_TYPE : FULL_ENTITY;

    local
        QUEUE_HEADER,
        QUEUE_MATCH_ROUTINE;

    case .ENTITY_TYPE [ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
        set
        [ENTITY_NODE]:
            begin
            QUEUE_HEADER = QH_NODE_PARAMETERS;
            QUEUE_MATCH_ROUTINE = NODE_ID_MATCH;
            end;

        [ENTITY_LINE]:
            begin
            QUEUE_HEADER = QH_LINE_PARAMETERS;
            QUEUE_MATCH_ROUTINE = NON_NODE_ID_MATCH;
            end;

        [ENTITY_LOGGING]:
            begin
            QUEUE_HEADER = QH_LOGGING_PARAMETERS;
            QUEUE_MATCH_ROUTINE = LOGGING_ID_MATCH;
            end;

        [ENTITY_CIRCUIT]:
            begin
            QUEUE_HEADER = QH_CIRCUIT_PARAMETERS;
            QUEUE_MATCH_ROUTINE = NON_NODE_ID_MATCH;
            end;

        [ENTITY_MODULE]:
            begin
            QUEUE_HEADER = QH_MODULE_PARAMETERS;
            QUEUE_MATCH_ROUTINE = NON_NODE_ID_MATCH;
	    end;
	[ENTITY_AREA]:
	    begin
	    QUEUE_HEADER = QH_AREA_PARAMETERS;
	    QUEUE_MATCH_ROUTINE = AREA_ID_MATCH;
            end;

        [inrange,
         outrange]:
            return $FALSE;
        tes;

!
! If no address is specified do not return value
!

    if .QUEUE neq 0
    then .QUEUE = .QUEUE_HEADER;

    if .MATCH_ROUTINE neq 0
    then .MATCH_ROUTINE = .QUEUE_MATCH_ROUTINE;

    return $TRUE;
    end;				! End of GET_VDB_ENTITY_QUEUE
%routine ('INSERT_PARAMETER', EDB_QE, ENTITY_TYPE, PRM_PTR, PRIVLEDGED) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Inserts a parameter entry into the parameter vector of the
!       data base for an entity.
!
! FORMAL PARAMETERS
!
!	EDB_QE      - The address of the entity data base structure to
!                     which the parameter is to be inserted.
!       ENTITY_TYPE - The entity type to which the parameter
!		      applies.
!       PRM_PTR     - A character sequence pointer to the parameter to
!                     be inserted.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    local
         PVB: ref $NML$PVB_ENTRY_VECTOR (0),
	 PVB_QE: ref $NML$PVB_ENTRY_BLOCK,
         PARM_NO;

    PARM_NO = GETW (PRM_PTR);

%( Does the parameter apply to this entity?
   Does the entity exist and is it in the ON state?
   If a node entity and the parameter is one which applies to
   an adjacent node, is the node address valid? )%

    if not APPLICABLE (.ENTITY_TYPE, .EDB_QE, .PARM_NO)
    then return $NICE$ERR_PNA;

    if NML$READ_ONLY (.ENTITY_TYPE, .PARM_NO) and not .PRIVLEDGED
    then return $NICE$ERR_PNA;

    !
    ! If this is a counter timer, adjust the counter time data base
    ! to reflect the time change.
    !

    if not NML$COUNTER_TIMER_SET (.PARM_NO,
                                  .ENTITY_TYPE,
                                  EDB_QE[EDB_ENTITY_ID],
				  .PRM_PTR)
    then return $NICE$ERR_IPV;          ! Illegal parameter value

    !
    ! Search through the vector for the location to insert the
    ! parameter.  If the parameter is already in the vector,
    ! simply change its value.  Otherwise, ripple all parameters
    ! numbered higher than the new one up one position in the vector,
    ! and then insert the new parameter.
    !

    PVB = .EDB_QE[EDB_PARAMETER_VECTOR];

    incr N from 0 to .EDB_QE[EDB_PARAMETER_COUNT] - 1
    do begin
       PVB_QE = PVB[.N,0,0,0,0];

       if .PARM_NO leq .PVB_QE[PE_NUMBER]
       then begin
            if .PARM_NO eql .PVB_QE[PE_NUMBER]
            then begin			! Found in table
		 if SET_PARAMETER_DATA (.ENTITY_TYPE, .PRM_PTR, .PVB_QE)
                 then return NICE$_SUC
                 else return $NICE$ERR_REE;
		 end
	    else begin			! Entry not in table
		 if not EXPAND_PVB (.EDB_QE, .N)
                 then return $NICE$ERR_REE;

		 PVB = .EDB_QE[EDB_PARAMETER_VECTOR];
		 PVB_QE = PVB[.N,0,0,0,0];
 		 PVB_QE[PE_NUMBER] = .PARM_NO;
		 if not SET_PARAMETER_DATA (.ENTITY_TYPE, .PRM_PTR, .PVB_QE)
                 then return $NICE$ERR_REE;

		 EDB_QE[EDB_PARAMETER_COUNT] = .EDB_QE[EDB_PARAMETER_COUNT] + 1;
		 return NICE$_SUC;
		 end;
            end;
       end;

    !
    ! If we get here, the parameter could not be inserted within the
    ! vector.  If there were initially no parameters, this will be the
    ! first entry;  otherwise it will be the last entry.
    !

    if not GET_PVB (.EDB_QE)
    then return $NICE$ERR_REE;

    PVB = .EDB_QE[EDB_PARAMETER_VECTOR];
    PVB_QE = PVB[.EDB_QE[EDB_PARAMETER_COUNT],0,0,0,0];
    PVB_QE[PE_NUMBER] = .PARM_NO;

    if not SET_PARAMETER_DATA (.ENTITY_TYPE, .PRM_PTR, .PVB_QE)
    then return $NICE$ERR_REE;

    EDB_QE[EDB_PARAMETER_COUNT] = .EDB_QE[EDB_PARAMETER_COUNT] + 1;

    return NICE$_SUC;
    end;				! End of INSERT_PARAMETER
%routine ('COPY_PARAMETER_VECTOR', OPVB, NPVB, COUNT) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
! Copy a parameter vector.
!
! FORMAL PARAMETERS
!
!	OPVB - The address of the old parameter vector.
!       NPVB - The address of the new parameter vector.
!       COUNT - The number of elements to copy.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
       CNPVB: ref vector,
       COPVB: ref vector;

    CNPVB = .NPVB;
    COPVB = .OPVB;

    decru CNT from (.COUNT*PVB_ENTRY_SIZE) to 1
    do begin
       CNPVB [0] = .COPVB [0];
       CNPVB = CNPVB [1];
       COPVB = COPVB [1];
       end;

    end;				! End of COPY_PARAMETER_VECTOR
%routine ('APPLICABLE', ENTITY_TYPE, EDB_QE, PARM_NO) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Determines whether a parameter, if an NML data base parameter,
!       applies to an entry in the NML data base which represents a
!       specific entity. I.e., if a parameter is applicable to the
!       executor node only, then it could not apply to a data base
!       entry for a remote node.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The entity type of this entity.
!       EDB_QE      - The address of the entity data base entry for
!                     particular entity.
!       PARM_NO     - The parameter type number.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, if the parameter is applies to this entity;
!       FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK,
       ENTITY_TYPE : FULL_ENTITY;


    case .ENTITY_TYPE [ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
        set
        [ENTITY_NODE]:
            if NML$EXECUTOR_ONLY (.ENTITY_TYPE, .PARM_NO)
            then begin
                 if .EDB_QE[NDB_NODE_TYPE] eql NDB$EXECUTOR
                 then return $TRUE
                 else return $FALSE;
                 end
            else return $TRUE;

        [ENTITY_LINE,
         ENTITY_CIRCUIT,
         ENTITY_LOGGING,
         ENTITY_AREA,
         ENTITY_MODULE]:
            return $TRUE;

        [inrange,
         outrange]:
        tes;

    return $FALSE;
    end;				! End of APPLICABLE
%if not $MCB %then
%routine ('REMOVE_QUALIFIED_PARAMETER', EDB_QE, ENTITY, QUALIFIER, POINTER, LENGTH, PRIVLEDGED) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Remove parameters in the qualifier sub queues.
!
! FORMAL PARAMETERS
!
!	EDB_QE          Address of the qualified entity data base structure to
!                       which the parameter is to be inserted.
!       ENTITY          The entity type to which the parameter applies.
!       QUALIFIER       A character sequence pointer to the qualifier
!                       parameter.
!       POINTER         A character sequence pointer to the parameter to
!                       be inserted.
!       LENGTH          The length of the parameter data passed in the
!                       parameter buffer.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NICE return code.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
        EDB_QE: ref ENTITY_DB_BLOCK;

    local
        PARAMETER,
        QH_QUALIFIER: ref Q_HEADER,
        QE_QUALIFIER: ref ENTITY_DB_BLOCK;

    QH_QUALIFIER = EDB_QE[EDB_QUALIFIER_QUEUE];
    PARAMETER = (if .LENGTH gtr 0       ! Get parameter number
                 then GETW_NA (.POINTER)
                 else begin             ! Zero length implies ALL
                      PRIVLEDGED = $true; ! Always succeed in clearing all
                      -1
                      end);

    if .QUALIFIER eql 0
    then begin                          ! Use default existing qualifier queue
         if NMU$QUEUE_LENGTH (.QH_QUALIFIER) eql 1 ! Queue has only 1 entry ?
         then QE_QUALIFIER = .QH_QUALIFIER[Q_FORWARD] ! Yes, default queue
         else return $NICE$ERR_PAM;     ! No, expecting qualifier name
         end
    else begin                          ! Use specific qualifier queue
         local ID_STRING, COUNT: $SIGNED_BYTE_VALUE;

         ID_STRING = ch$plus (.QUALIFIER, 2); ! Get qualifier id string
         COUNT = ch$rchar (.ID_STRING); ! Get count byte

         if .COUNT[VALUE] lss 0         ! If count byte is negative ....
         then begin                     ! Set KNOWN qualified queues
              local NEXT: ref Q_ENTRY;

              NEXT = .QH_QUALIFIER[Q_FORWARD];

              while (QE_QUALIFIER = .NEXT) neq .QH_QUALIFIER
              do begin
                 NEXT = .NEXT[Q_FORWARD];
                 REMOVE_PARAMETER (.QE_QUALIFIER, .ENTITY, .PARAMETER, .PRIVLEDGED);
                 if .PRIVLEDGED         ! If clearing all, remove entry
                 then NMU$QUEUE_EXTRACT (.QH_QUALIFIER, .QE_QUALIFIER);
                 end;

              return NICE$_SUC;
              end
         else begin                     ! Set specific qualified queue
              QE_QUALIFIER = NMU$QUEUE_SCAN (.QH_QUALIFIER,
                                             .ID_STRING,
                                             NON_NODE_ID_MATCH);

              if .QE_QUALIFIER eql 0    ! Does entry exist ?
              then return $NICE$ERR_IPV;
              end;
         end;

    REMOVE_PARAMETER (.QE_QUALIFIER, .ENTITY, .PARAMETER, .PRIVLEDGED);

    if .PRIVLEDGED                      ! If clearing all, remove entry
    then NMU$QUEUE_EXTRACT (.QH_QUALIFIER, .QE_QUALIFIER);

    return NICE$_SUC;
    end;				! End of REMOVE_QUALIFIED_PARAMETER
%fi
%sbttl ''
%routine ('REMOVE_PARAMETER', EDB_QE, ENTITY_TYPE, PARM_NO, PRIVLEDGED) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Removes a parameter entry from the parameter vector of the
!       data base for an entity.
!
! FORMAL PARAMETERS
!
!	EDB_QE      - The address of the entity data base structure from
!                     which the parameter is to be removed.
!       ENTITY_TYPE - The entity type to which the parameter applies.
!       PARM_NO     - The parameter number for the parameter to be removed.
!       PRIVLEDGED  - If true, clear the parameter even if not clearable.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    !
    !  Verify that all fields related to the parameter vector are
    !  in agreement.  If there is any indication that there is no
    !  PVB, reset all the fields.
    !

    if (.EDB_QE[EDB_PARAMETER_COUNT] eql 0)
    or (.EDB_QE[EDB_PARAMETER_VECTOR] eql 0)
    or (.EDB_QE[EDB_PARAMETER_ALLOCATION] eql 0)
    then begin
	 RELEASE_PVB (.EDB_QE);
	 return;
	 end;

    !
    ! Otherwise, get the parameter number and check it for applicability.
    !

    if not APPLICABLE (.ENTITY_TYPE, .EDB_QE, .PARM_NO)
    then return $NICE$ERR_PNA

    !
    ! Search through the vector for the parameter to
    ! to be removed and ripple all parameters numbered higher than
    ! the one to be removed down one position in the vector.
    !

    else begin
         local CNT,
               ENTRY: ref $NML$PVB_ENTRY_BLOCK;

         ENTRY = .EDB_QE[EDB_PARAMETER_VECTOR];
         CNT = .EDB_QE[EDB_PARAMETER_COUNT];

         do begin

            ! Note: ALL (-1) is less than any parameter number

            if .PARM_NO leq .ENTRY[PE_NUMBER]
            then begin
                 if not ((.PARM_NO eql .ENTRY[PE_NUMBER]) or ! parameter #
                         (.PARM_NO lss 0))                   ! ALL
                 then return $NICE$ERR_PNA;        ! No match

                 ! Found parameter or removing all

                 if NML$CLEARABLE (.ENTITY_TYPE, .ENTRY[PE_NUMBER]) or
                    .PRIVLEDGED
                 then begin             ! Check if user can clear parameter

                      ! If this is a counter timer, adjust the counter
                      ! timer data base to reflect the time change.

                      NML$COUNTER_TIMER_CLEAR (.PARM_NO,
                                               .ENTITY_TYPE,
                                               EDB_QE[EDB_ENTITY_ID]);

                      CLEAR_PARAMETER_DATA (.ENTITY_TYPE, .ENTRY);
                      COPY_PARAMETER_VECTOR (vector [.ENTRY, PVB_ENTRY_SIZE],
                                             .ENTRY,
                                             .CNT - 1);
                      EDB_QE[EDB_PARAMETER_COUNT] = .EDB_QE[EDB_PARAMETER_COUNT] - 1;
                      end
                 else begin             ! Move down one entry
                      ENTRY = vector [.ENTRY, PVB_ENTRY_SIZE];
                      end;

                 if .PARM_NO geq 0 then exitloop; ! Done Removing single parameter
                 end
            else				  ! Move down one entry
                 ENTRY = vector [.ENTRY, PVB_ENTRY_SIZE];
            end
         while (CNT = .CNT - 1) neq 0;
         end;

    ! If there are now no more parameters left in the vector, release
    ! storage used by the vector.

    if .EDB_QE[EDB_PARAMETER_COUNT] eql 0
    then RELEASE_PVB (.EDB_QE);

    return;
    end;				! End of REMOVE_PARAMETER
%routine ('RELEASE_PVB', EDB_QE) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Clears all related fields and releases the parameter entry
!       vector block for a specific entity data base structure.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - The address of the entity data base structure from
!                 which the PVB is to be removed.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!   The following fields of the entity data base entry will be cleared:
!         EDB_QE[EDB_PARAMETER_ALLOCATION]
!         EDB_QE[EDB_PARAMETER_VECTOR]
!         EDB_QE[EDB_PARAMETER_COUNT]
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    !
    ! If a parameter vector is not currently allocated there is
    !  no memory to be released.
    !

    if (.EDB_QE[EDB_PARAMETER_ALLOCATION] neq 0) ! They better all be in
    and (.EDB_QE[EDB_PARAMETER_VECTOR] neq 0) ! agreement.
    then NMU$MEMORY_RELEASE (.EDB_QE[EDB_PARAMETER_VECTOR],
                             .EDB_QE[EDB_PARAMETER_ALLOCATION]);

    EDB_QE[EDB_PARAMETER_ALLOCATION] = 0;
    EDB_QE[EDB_PARAMETER_VECTOR] = 0;
    EDB_QE[EDB_PARAMETER_COUNT] = 0;

    return;
    end;				! End of RELEASE_PVB
%routine ('GET_PVB', EDB_QE) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Gets a parameter entry vector block for a specific entity
!	data base structure.  If a parameter vector is already
!	allocated, a new one will not be allocated provided there
!	is enough room for 1 more entry in the existing vector.
!	If there is not enough room, a larger vector will be allocated
!	and the existing entries will be copied to the new vector.
!	The associated fields in the data base structure will be
!	updated.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - The address of the entity data base structure from
!                 which the PVB is to be allocated.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!   The following fields of the entity data base entry will be changed:
!         EDB_QE[EDB_PARAMETER_ALLOCATION]
!         EDB_QE[EDB_PARAMETER_VECTOR]
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    if .EDB_QE[EDB_PARAMETER_ALLOCATION] lss
    ((.EDB_QE[EDB_PARAMETER_COUNT] + 1) * PVB_ENTRY_ALLOCATION)
    then begin
         local COUNT, NPVB: ref $NML$PVB_ENTRY_VECTOR (0);
         bind NEW_ALLOCATION = .EDB_QE[EDB_PARAMETER_ALLOCATION] +
                               PVB_ENTRY_ALLOCATION;

         if (NPVB = NMU$MEMORY_GET (NEW_ALLOCATION)) eql 0
         then return $FALSE;

         COUNT = .EDB_QE[EDB_PARAMETER_COUNT];
         COPY_PARAMETER_VECTOR(.EDB_QE[EDB_PARAMETER_VECTOR],
                               .NPVB,
                               .EDB_QE[EDB_PARAMETER_COUNT]);

         RELEASE_PVB (.EDB_QE);
         EDB_QE[EDB_PARAMETER_VECTOR] = .NPVB;
         EDB_QE[EDB_PARAMETER_ALLOCATION] = NEW_ALLOCATION;
         EDB_QE[EDB_PARAMETER_COUNT] = .COUNT;
         end;

    return $TRUE;
    end;				! End of GET_PVB
%routine ('EXPAND_PVB', EDB_QE, N) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Expands the parameter entry vector block for a specific entity
!	data base structure.  If a parameter vector is already
!	allocated, a new one will not be allocated provided there
!	is enough room for 1 more entry in the existing vector.
!	If there is not enough room, a larger vector will be allocated
!	and the existing entries will be copied to the new vector.
!	In any case, the parameter vector will be opened up and
!	a null entry will be placed in the vector at position N,
!	where N varies from 0 to count-1.
!	The associated fields in the data base structure will be
!	updated.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - The address of the entity data base structure from
!                 which the PVB is to be expanded.
!	N	- The number of the vector entry, where the null
!		  entry is to be placed. (0 <= N < count)
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!   The following fields of the entity data base entry will be changed:
!         EDB_QE[EDB_PARAMETER_ALLOCATION]
!         EDB_QE[EDB_PARAMETER_VECTOR]
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    local
         PVB: ref $NML$PVB_ENTRY_VECTOR (0);

    if .EDB_QE[EDB_PARAMETER_ALLOCATION]
    lss ((.EDB_QE[EDB_PARAMETER_COUNT] + 1) * PVB_ENTRY_ALLOCATION)
    then if not GET_PVB (.EDB_QE)
         then return $FALSE;

    PVB = .EDB_QE[EDB_PARAMETER_VECTOR];
    decr M from .EDB_QE[EDB_PARAMETER_COUNT] - 1 to .N
    do begin
       PVB[.M+1,PE_NUMBER] = .PVB[.M,PE_NUMBER];
       PVB[.M+1,PE_DATA] = .PVB[.M,PE_DATA];
       end;

    PVB[.N,PE_NUMBER] = 0;
    PVB[.N,PE_DATA] = 0;

    return $TRUE;
    end;				! End of EXPAND_PVB
%routine ('SET_PARAMETER_DATA', ENTITY_TYPE, PRM_PTR, PVB_QE) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Stores the data for a parameter in the parameter vector block.
!       The data stored is dependent on the type of data for the
!       parameter. For coded and binary value parameters the data is
!       stored directly. For image fields the address of a dynamically
!       allocated block containing the image field is stored.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - Entity type.
!       PRM_PTR     - Pointer to data portion of parameter.
!       PVB_QE      - Address of Parameter Vector Block Queue Entry.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       PVB_QE: ref $NML$PVB_ENTRY_BLOCK;

    local
         DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

    DATA_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .PVB_QE[PE_NUMBER]);

    if .DATA_TYPE[DT_CODED] eql 0       ! Not coded
    then begin
         if .DATA_TYPE[DT_FTYPE] eql 0  ! Binary number
         then begin
              if .DATA_TYPE[DT_LENGTH] eql 0 ! Image field
              then begin
                   if not SET_IMAGE_FIELD (PVB_QE[PE_ADDRESS], .PRM_PTR)
                   then return $FALSE;
                   end
              else begin
                   if .DATA_TYPE[DT_LENGTH] leq %bpval/8
                   then PVB_QE[PE_DATA] = GETN (PRM_PTR, .DATA_TYPE[DT_LENGTH])
                   else begin
                        bind L = .DATA_TYPE[DT_LENGTH],
                             A = ch$allocation (L,8) * %upval;

                        if .PVB_QE[PE_ADDRESS] eql 0
                        then if (PVB_QE[PE_ADDRESS] = NMU$MEMORY_GET (A)) eql 0
                             then return $FALSE;

                        ch$move (L, .PRM_PTR, ch$ptr (.PVB_QE[PE_ADDRESS],,8));
                        end;
                   end;
              end
         else begin                     ! ASCII image field
              if not SET_IMAGE_FIELD (PVB_QE[PE_ADDRESS], .PRM_PTR)
              then return $FALSE;
              end;
         end
    else begin                          ! Coded
         if .DATA_TYPE[DT_FTYPE] eql 0  ! Single field
         then PVB_QE[PE_DATA] = GETN (PRM_PTR, .DATA_TYPE[DT_NUMBER])
         else selectone .DATA_TYPE[DT_NUMBER] of
                  set                   ! Multiple field
                  [CMN] :               ! Node format
                      begin
                      local PTR, TEMP;

                      if .PVB_QE[PE_ADDRESS] eql 0
                      then if (PVB_QE[PE_ADDRESS] = NMU$MEMORY_GET (NODE_ID_BUFFER_ALLOCATION)) eql 0
                           then return $FALSE;

                      PTR = ch$ptr (.PVB_QE[PE_ADDRESS],,8);
                      TEMP = GETB (PRM_PTR);
                      if .TEMP eql 0
                      then begin
                           TEMP = GETW (PRM_PTR);
                           PUTW (TEMP, PTR);
                           PUTB (0, PTR);
                           end
                      else begin
                           local ADDR;

                           ADDR = 0;
                           PUTW (ADDR, PTR);
                           PUTB (.TEMP, PTR);
                           ch$move (.TEMP, .PRM_PTR, .PTR);
                           end;

                      PTR = ch$ptr (.PVB_QE[PE_ADDRESS],,8);
                      TEMP = NODE_ID_BUFFER_LENGTH;

                      !
                      ! Map node address so a valid address
                      ! is displayed.
                      !

                      $NML$MAP_NODE_ID (TEMP, .PTR);
                      end;
                  [otherwise] :         ! Unknown multiple parameter
                      PVB_QE[PE_ADDRESS] = 0;
                  tes;
         end;

    return $TRUE;
    end;				! End of SET_PARAMETER_DATA

%routine ('SET_IMAGE_FIELD', ADDR, PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Sets an image field in the parameter data base.
!
! FORMAL PARAMETERS
!
!	ADDR - The address within the parameter data base vector which
!              contains the address of the dynamically allocated storage
!              which contains the image string. If zero a block will be
!              allocated.
!
!	PTR  - A pointer to the image field to be set in the data base.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         XLEN,
         TLEN;

    TLEN = ch$rchar(.PTR) + 1;

    if ..ADDR eql 0
    then .ADDR = NMU$MEMORY_GET ((ch$allocation (.TLEN,8) * %upval))
    else if .TLEN neq (XLEN = ch$rchar (ch$ptr (..ADDR,,8)) + 1)
         then begin
              NMU$MEMORY_RELEASE (..ADDR, (ch$allocation (.XLEN,8) * %upval));
              .ADDR = NMU$MEMORY_GET ((ch$allocation (.TLEN,8) * %upval));
              end;

    if ..ADDR eql 0
    then return $FALSE;

    ch$move (.TLEN, .PTR, ch$ptr (..ADDR,,8));

    return $TRUE;
    end;				! End of SET_IMAGE_FIELD
%routine ('CLEAR_PARAMETER_DATA', ENTITY_TYPE, PVB_QE) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Clears the data for a parameter in the parameter vector block.
!       The data stored is dependent on the type of data for the
!       parameter. For coded and binary value parameters the data is
!       cleared to zero. For image fields the address of a dynamically
!       allocated block containing the image field is used to release
!       the storage containing the image field. The address is then set
!       to zero.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - Entity type.
!       PVB_QE      - Address of Parameter Vector Block Queue Entry.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       PVB_QE: ref $NML$PVB_ENTRY_BLOCK;

    local
         DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

    DATA_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .PVB_QE[PE_NUMBER]);

    if .DATA_TYPE[DT_CODED] eql 0       ! Not coded
    then begin
         if .DATA_TYPE[DT_FTYPE] eql 0  ! Binary number
         then begin
              if .DATA_TYPE[DT_LENGTH] eql 0
              then begin                ! Image binary
                   bind L = ch$rchar (ch$ptr (.PVB_QE[PE_ADDRESS],,8)) + 1,
                        A = ch$allocation (L,8) * %upval;

                   NMU$MEMORY_RELEASE (.PVB_QE[PE_ADDRESS], A);
                   PVB_QE[PE_ADDRESS] = 0;
                   end
              else begin
                   if .DATA_TYPE[DT_LENGTH] leq %bpval/8
                   then PVB_QE[PE_DATA] = 0
                   else begin
                        bind L = .DATA_TYPE[DT_LENGTH],
                             A = ch$allocation (L,8) * %upval;

                        NMU$MEMORY_RELEASE (.PVB_QE[PE_ADDRESS], A);
                        PVB_QE[PE_ADDRESS] = 0;
                        end;
                   end;
              end
         else begin                     ! ASCII image field
              bind L = ch$rchar (ch$ptr (.PVB_QE[PE_ADDRESS],,8)) + 1,
                   A = ch$allocation (L,8) * %upval;

              NMU$MEMORY_RELEASE (.PVB_QE[PE_ADDRESS], A);
              PVB_QE[PE_ADDRESS] = 0;
              end;
         end
    else begin                          ! Coded

         %( N.B. - Do special casing here just like in SET_PARAMETER_DATA.
            Else we gonna mess up storage allocation. )%

         if .DATA_TYPE[DT_FTYPE] eql 0  ! Single field
         then PVB_QE[PE_DATA] = 0
         else selectone .DATA_TYPE[DT_NUMBER] of
                  set                   ! Multiple field
                  [CMN] :               ! Node format
                      NMU$MEMORY_RELEASE (.PVB_QE[PE_ADDRESS], NODE_ID_BUFFER_ALLOCATION);
                  [otherwise] :         ! Unknown multiple parameter
                      PVB_QE[PE_ADDRESS] = 0;
                  tes;
         end;

    end;				! End of CLEAR_PARAMETER_DATA
%routine ('READ_PARAMETER_DATA', ENTITY_TYPE, ENTRY, LENGTH, POINTER) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Reads the data portion of a volatile data base parameter
!       into the parameter buffer.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE     Entity type.
!	ENTRY           The address of the parameter vector block entry
!                       for this parameter.
!       LENGTH          The length of the buffer remaining.
!       POINTER         The address of a character sequence pointer to the
!                       buffer.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	The number of bytes for this parameter excluding data id
!	and datatype bytes.
!
! SIDE EFFECTS:
!
!	If the parameter will fit in the buffer, it is copied into
!	the buffer.
!
!--

    begin

    macro
         PUTN (VALUE, PTR_ADR, N) =
             begin
             local L, X;

             X = VALUE;
             ch$wchar_a (.X, PTR_ADR);
             incr L from 256 to ((N - 1) * 256) by 256
             do begin
                X = .X / .L;
                ch$wchar_a (.X, PTR_ADR);
                end;

             .L / 256
             end %;

    map
       ENTRY: ref $NML$PVB_ENTRY_BLOCK;

    local
         BUF_PTR,
         BUF_LEN,
         DATA_ID: block [1] field (DATA_ID_FIELDS), ! Data ID
         DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

    BUF_PTR = ..POINTER;
    DATA_ID = 0;
    DATA_ID[DI_PARMNO] = .ENTRY[PE_NUMBER]; ! Get parameter number
    DATA_ID[DI_TYPE] = 0;               ! This is a parameter
    DATA_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .ENTRY[PE_NUMBER]);

    if .DATA_TYPE[DT_CODED] eql 0       ! Not coded
    then begin
         PUTW (DATA_ID, BUF_PTR);       ! Write data id into buffer
         PUTB (.DATA_TYPE, BUF_PTR);    ! Write data type into buffer
         if .DATA_TYPE[DT_FTYPE] eql 0  ! Binary number
         then begin
              if .DATA_TYPE[DT_LENGTH] eql 0
              then begin                ! Binary image field
                   BUF_LEN = ch$rchar (ch$ptr (.ENTRY[PE_ADDRESS],,8)) + 1;
                   if .LENGTH geq .BUF_LEN
                   then BUF_PTR = ch$move (.BUF_LEN,
                                           ch$ptr (.ENTRY[PE_ADDRESS],,8),
                                           .BUF_PTR);
                   end
              else begin
                   BUF_LEN = .DATA_TYPE[DT_LENGTH];
                   if .DATA_TYPE[DT_LENGTH] leq %bpval/8
                   then begin           ! Data stored in value
                        if .LENGTH geq .BUF_LEN
                        then PUTN (.ENTRY[PE_DATA],
                                   BUF_PTR,
                                   .DATA_TYPE[DT_LENGTH]);
                        end
                   else begin           ! Data stored in buffer
                        BUF_LEN = .DATA_TYPE[DT_LENGTH];
                        if .LENGTH geq .BUF_LEN
                        then BUF_PTR = ch$move (.BUF_LEN,
                                                ch$ptr (.ENTRY[PE_ADDRESS],,8),
                                                .BUF_PTR);
                        end;
                   end;
              end
         else begin                     ! ASCII image field
              BUF_LEN = ch$rchar (ch$ptr (.ENTRY[PE_ADDRESS],,8)) + 1;
              if .LENGTH geq .BUF_LEN
              then BUF_PTR = ch$move (.BUF_LEN,
                                      ch$ptr (.ENTRY[PE_ADDRESS],,8),
                                      .BUF_PTR);
              end;
         end
    else begin                          ! Coded

         %( N.B. - We have to do special casing here for multiple coded
            fields. )%

         if .DATA_TYPE[DT_FTYPE] eql 0  ! Single field
         then begin
              PUTW (DATA_ID, BUF_PTR);  ! Write data id into buffer
              PUTB (.DATA_TYPE, BUF_PTR); ! Write data type into buffer
              BUF_LEN = .DATA_TYPE[DT_NUMBER];
              if .LENGTH geq .BUF_LEN
              then PUTN (.ENTRY[PE_DATA], BUF_PTR, .DATA_TYPE[DT_NUMBER]);
              end
         else selectone .DATA_TYPE[DT_NUMBER] of
                  set                   ! Multiple field
                  [CMN] :               ! Node format
                      begin
                      local PTR;

                      PTR = ch$ptr (.ENTRY[PE_ADDRESS],,8);
                      begin
                      literal DATA_TYPE = 1^7 + 1^6 + 2;
                      PUTW (DATA_ID, BUF_PTR); ! Write data id
                      PUTB (DATA_TYPE, BUF_PTR); ! Write data type
                      end;

                      BUF_LEN = 6 + 5;	! Assume node name of 6 chars
                      if .LENGTH geq .BUF_LEN
                      then
                        begin
                        !
                        ! Node address
                        !

                          begin
                          literal DATA_TYPE = 0^7 + 0^6 + 0^4 + 2;
                          local NODE_ADDRESS;

                          NODE_ADDRESS = GETW (PTR);
                          PUTB (DATA_TYPE, BUF_PTR); ! Write Data Type
                          PUTW (NODE_ADDRESS, BUF_PTR); ! Write address
                          end;

                        !
                        ! Node name
                        !

                          begin
                          literal DATA_TYPE = 0^7 + 1^6;
                          local NODE_NAME_LENGTH;

                          PUTB (DATA_TYPE, BUF_PTR); ! Write Data Type
                          NODE_NAME_LENGTH = GETB (PTR); ! Get I-length
                          PUTB (.NODE_NAME_LENGTH, BUF_PTR);
                          BUF_PTR = ch$move (.NODE_NAME_LENGTH,
                                             .PTR,
                                             .BUF_PTR);
                          BUF_LEN = .NODE_NAME_LENGTH + 5; ! Real length
                          end;
                        end;
                      end;

                  [CMV] :               ! Version format
                      begin
                      external          ! Version numbers defined in NMUSKD
                          NMLVER,       ! Major version
                          DECECO,       ! Minor version
                          USRECO;       ! Customer version

                      begin
                      literal DATA_TYPE = 1^7 + 1^6 + 3;
                      PUTW (DATA_ID, BUF_PTR); ! Write data id
                      PUTB (DATA_TYPE, BUF_PTR); ! Write data type
                      end;
                      BUF_LEN = 6;      ! Six bytes to write excluding
                                        ! data id and data type bytes

                      if .LENGTH geq .BUF_LEN
                      then
                          begin
                          literal DATA_TYPE = 0^7 + 0^6 + 0^4 + 1;

                          PUTB (DATA_TYPE, BUF_PTR); ! Write Data Type
                          PUTB (.NMLVER, BUF_PTR); ! Write version byte
                          PUTB (DATA_TYPE, BUF_PTR); ! Write Data Type
                          PUTB (.DECECO, BUF_PTR); ! Write version byte
                          PUTB (DATA_TYPE, BUF_PTR); ! Write Data Type
                          PUTB (.USRECO, BUF_PTR); ! Write version byte
                          end;

                      end;

                  [otherwise] :         ! Unknown multiple parameter
                      BUF_LEN = 0;
                  tes;
         end;

    .POINTER = .BUF_PTR;

    return .BUF_LEN;                    ! Return number of bytes written
    end;				! End of READ_PARAMETER_DATA
%routine ('LOGGING_ID_MATCH', EDB_QE, EID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular ENTITY_DB_BLOCK
!       for the LOGGING entity is the one being searched for when called
!       by NMU$QUEUE_SCAN as an exit routine.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the LOGGING entity data base block to be tested.
!	EID_PTR - Pointer to the entity id being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of LOGGING entity data base block if it matches the entity id;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    if ch$rchar (ch$ptr (EDB_QE [EDB_ENTITY_ID],, 8)) eql ch$rchar (.EID_PTR)
    then return .EDB_QE
    else return 0;

    end;				! End of NODE_ID_MATCH
%routine ('NODE_ID_MATCH', EDB_QE, EID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular ENTITY_DB_BLOCK
!       for the NODE entity is the one being searched for when called
!       by NMU$QUEUE_SCAN as an exit routine.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the NODE entity data base block to be tested.
!	EID_PTR - Pointer to the entity id being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of NODE entity data base block if it matches the entity id;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    local
         PTR;

    PTR = ch$ptr (EDB_QE[NDB_ENTITY_ID],,8);

    if GETW (PTR) eql GETW (EID_PTR)
    then return .EDB_QE
    else return 0;

    end;				! End of NODE_ID_MATCH
%routine ('PARM_NUM_MATCH', EDB_QE, EID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular ENTITY_DB_BLOCK
!	which holds the parameter number for a qualifier
!       is the one being searched for when called
!	by NMU$QUEUE_SCAN as an exit routine.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the entity data base block to be tested.
!	EID_PTR - Pointer to the entity id being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of entity data base entry if it matches the entity id;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    local
       PTR;

    PTR = .EID_PTR;
    if GETW (ch$ptr (EDB_QE[EDB_ENTITY_ID],,8)) eql GETW (.PTR)
    then
	return .EDB_QE;
    return 0;

    end;				! End of PARM_NUM_MATCH
%routine ('AREA_ID_MATCH', EDB_QE, EID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular ENTITY_DB_BLOCK
!       with entity type AREA is the one being searched for when called
!	by NMU$QUEUE_SCAN as an exit routine.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the entity data base block to be tested.
!	EID_PTR - Pointer to the entity id being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of entity data base entry if it matches the entity id;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    if ch$rchar (ch$ptr (EDB_QE[EDB_ENTITY_ID],,8)) eql ch$rchar (.EID_PTR)
    then
	return .EDB_QE;
    return 0;

    end;				! End of AREA_ID_MATCH
%routine ('NON_NODE_ID_MATCH', EDB_QE, EID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular ENTITY_DB_BLOCK
!       is the one being searched for when called by NMU$QUEUE_SCAN
!       as an exit routine.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the entity data base block to be tested.
!	EID_PTR - Pointer to the entity id being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of entity data base entry if it matches the entity id;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       EDB_QE: ref ENTITY_DB_BLOCK;

    return MATCH_ID (.EDB_QE, ch$ptr (EDB_QE[EDB_ENTITY_ID],,8), .EID_PTR);
    end;				! End of NON_NODE_ID_MATCH
%routine ('SVC_CKT_MATCH', NDB_QE, CKT_ID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular NODE_DB_BLOCK
!       contains the circuit id, passed as an argument, as the
!       SERVICE CIRCUIT parameter by NMU$QUEUE_SCAN as an exit routine.
!
! FORMAL PARAMETERS
!
!	NDB_QE  - Address of the NODE entity data base block to be tested.
!	CKT_ID_PTR - Pointer to the circuit entity id being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of NODE entity data base block if its SERVICE CIRCUIT
!          parameter matches the circuit entity id;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       NDB_QE: ref NODE_DB_BLOCK;

    bind
	PVB = NDB_QE[EDB_PARAMETER_VECTOR] : ref $NML$PVB_ENTRY_VECTOR (0);

    local
         ADR_AI_FIELD;

    ADR_AI_FIELD = 0;

    incr N from 0 to .NDB_QE[EDB_PARAMETER_COUNT] - 1
    do begin
       if .PVB[.N,PE_NUMBER] eql 110
       then begin
            ADR_AI_FIELD = .PVB[.N,PE_ADDRESS];
            exitloop;		! Found SERVICE CIRCUIT parameter
            end;
       end;

    if .ADR_AI_FIELD eql 0	! No SERVICE CIRCUIT parameter
    then return 0
    else return MATCH_ID (.NDB_QE, ch$ptr (.ADR_AI_FIELD,,8), .CKT_ID_PTR);

    end;				! End of SVC_CKT_MATCH
%routine ('HDR_ADR_MATCH', NDB_QE, HARDWARE_ADDR_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Makes determination as to whether a particular NODE_DB_BLOCK
!       contains the ETHERNET Address, passed as an argument, as the
!       HARDWARE ADDRESS parameter by NMU$QUEUE_SCAN as an exit routine.
!
! FORMAL PARAMETERS
!
!	NDB_QE  - Address of the NODE entity data base block to be tested.
!	HARDWARE_ADDR_PTR - Pointer to the ETHERNET Address being searched for.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of NODE entity data base block if its HARDWARE ADDRESS
!          parameter matches the ETHERNET Address
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       NDB_QE: ref NODE_DB_BLOCK;

    bind
	PVB = NDB_QE[EDB_PARAMETER_VECTOR] : ref $NML$PVB_ENTRY_VECTOR (0);

    local
         ADR_HI_FIELD;

    ADR_HI_FIELD = 0;

    incr N from 0 to .NDB_QE[EDB_PARAMETER_COUNT] - 1
    do begin
       if .PVB[.N,PE_NUMBER] eql 114
       then begin
            ADR_HI_FIELD = .PVB[.N,PE_ADDRESS];
            exitloop;		! Found HARDWARE ADDRESS parameter
            end;
       end;

    if .ADR_HI_FIELD eql 0	! No HARDWARE ADDRESS parameter
    then return 0
    else return MATCH_EA (.NDB_QE, ch$ptr (.ADR_HI_FIELD,,8), .HARDWARE_ADDR_PTR);

    end;				! End of HDR_ADR_MATCH
%routine ('MATCH_ID', EDB_QE, PTR1, PTR2) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Compares the entity id referenced by pointer 1 with the entity
!       id referenced by pointer 2.  No distinction is made between
!       upper and lower case when comparing the strings.  If the ids
!       match, the address of the entity data block is returned.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the entity data base block.
!	PTR1 - Pointer to the first entity id.
!	PTR2 - Pointer to the second entity id.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of entity data base entry if the strings match;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
	L;

    if (L = GETB (PTR1)) eql GETB (PTR2)
    then begin
         incr N from 1 to .L
         Do begin
            if GETB (PTR1) neq GETB (PTR2)
            then return 0;
            end;

         return .EDB_QE;
         end
    else return 0;

    end;				! End of MATCH_ID
%routine ('MATCH_EA', EDB_QE, PTR1, PTR2) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Compares the ETHERnet Address referenced by pointer 1 with the entity
!       id referenced by pointer 2. If the addresses
!       match, the address of the entity data block is returned.
!
! FORMAL PARAMETERS
!
!	EDB_QE  - Address of the entity data base block.
!	PTR1 - Pointer to the first ETHERnet Address.
!	PTR2 - Pointer to the second ETHERnet Address.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Address of entity data base entry if the strings match;
!	Zero (0), otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    if GETB (PTR1) eql 6
    then begin
         incr N from 1 to 6
         do begin
            if GETB (PTR1) neq GETB (PTR2)
            then return 0;
            end;

         return .EDB_QE;
         end
    else return 0;

    end;				! End of MATCH_ID
end                                     ! End of Module NMLVDB
eludom
! Local Modes:
! Mode:BLISS
! Auto Save Mode:1
! Comment Column:40
! Comment Rounding:+1
! End: