mirror of
https://github.com/PDP-10/stacken.git
synced 2026-02-28 17:09:15 +00:00
3412 lines
114 KiB
Plaintext
3412 lines
114 KiB
Plaintext
;TITLE NTMAN - Network Management Interface for DECnet-36
|
||
|
||
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
|
||
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
|
||
;
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976,1986,1988.
|
||
;ALL RIGHTS RESERVED.
|
||
|
||
SUBTTL Jim Halpin, Gunnar Lindell, & Tarl Neustaedter
|
||
|
||
SEARCH D36PAR,MACSYM
|
||
SALL
|
||
|
||
IFN FTOPS20,<
|
||
SEARCH PROLOG
|
||
TTITLE NTMAN,,< - Network Management interface for DECnet-36>
|
||
>
|
||
|
||
IFN FTOPS10,<
|
||
SEARCH F,S
|
||
TITLE NTMAN - Network Management interface for DECnet-36
|
||
.CPYRT<1976,1988>
|
||
$RELOC
|
||
>;END IFN FTOPS10
|
||
|
||
D36SYM ;SET UP D36 SPECIFIC PARAMETERS
|
||
|
||
;Declare all global entry points to NTMAN
|
||
ENTRY NTMAN ;TO FORCE LINK TO LOAD WITH REST OF DECNET
|
||
|
||
INTERN .NTMAN ; = NTMAN. JSYS/UUO entry point
|
||
INTERN NMXEVT ;Event logger
|
||
INTERN PRSCOU ;Hook for NSP event "Database reused"
|
||
|
||
IFN FTOPS20 <
|
||
INTERN EVRKIL ;Kill the event reader
|
||
INTERN NMLEVT ;Check if event reader should get PSI
|
||
>
|
||
|
||
SUBTTL Table of Contents
|
||
|
||
|
||
; Table of Contents for NTMAN
|
||
;
|
||
;
|
||
; Section Page
|
||
; 1. Table of Contents. . . . . . . . . . . . . . . . . . . 2
|
||
; 2. Data structures
|
||
; 2.1. Value definitions . . . . . . . . . . . . . . 3
|
||
; 2.2. BEGSTR NT . . . . . . . . . . . . . . . . . . 4
|
||
; 2.3. Byte pointers into NSP node block . . . . . . 5
|
||
; 2.4. Parameter and counter definitions . . . . . . 6
|
||
; 2.5. Event and logging definitions . . . . . . . . 12
|
||
; 3. NTMAN
|
||
; 3.1. Entry . . . . . . . . . . . . . . . . . . . . 13
|
||
; 3.2. Get pertinent data from user's data block . . 14
|
||
; 3.3. Dispatch to functions . . . . . . . . . . . . 15
|
||
; 4. Functions
|
||
; 4.1. .NTMAP - Map node name/number . . . . . . . . 16
|
||
; 4.2. .NTREX - Return local node number . . . . . . 17
|
||
; 4.3. .NTSET,.NTCLR - Parse and process a parameter 18
|
||
; 4.4. .NTZRO,.NTSZC - Zero counters . . . . . . . . 19
|
||
; 4.5. .NTSHO
|
||
; 4.5.1. Select parameters to return. . . . . 20
|
||
; 4.5.2. Return parameters to user. . . . . . 21
|
||
; 4.6. .NTRET
|
||
; 4.6.1. List node names. . . . . . . . . . . 22
|
||
; 4.6.2. List circuit and line names. . . . . 23
|
||
; 5. Entities
|
||
; 5.1. Convert entity names to entity ids. . . . . . 24
|
||
; 5.2. Circuit ID to name conversion . . . . . . . . 25
|
||
; 5.3. Convert name to Circuit-ID. . . . . . . . . . 26
|
||
; 6. Layers
|
||
; 6.1. Main interface to layer levels. . . . . . . . 27
|
||
; 6.2. Read/set NSP node blocks. . . . . . . . . . . 28
|
||
; 6.3. Read/set RTR circuit blocks . . . . . . . . . 29
|
||
; 6.4. Read/set node state . . . . . . . . . . . . . 30
|
||
; 6.5. Read/set executor node information. . . . . . 31
|
||
; 6.6. Read/set RTR node information . . . . . . . . 32
|
||
; 6.7. Find circuit which points to a node . . . . . 33
|
||
; 6.8. Set/clear node names. . . . . . . . . . . . . 34
|
||
; 6.9. Create/Destroy loopback nodes . . . . . . . . 35
|
||
; 6.10. Call the data link layer. . . . . . . . . . . 36
|
||
; 7. Events
|
||
; 7.1. Interface layer / NMX (NMXEVT). . . . . . . . 37
|
||
; 7.2. NMXEVT
|
||
; 7.2.1. EVGEC (Get EC block) . . . . . . . . 38
|
||
; 7.2.2. EVREC (Release Ec block) . . . . . . 39
|
||
; 7.2.3. EVFIL (Filter an event). . . . . . . 40
|
||
; 7.2.4. EVLOG (Log an event) . . . . . . . . 41
|
||
; 7.2.5. EVSIG (Log a signal) . . . . . . . . 45
|
||
; 7.3. .NTTEV function (Test event logger) . . . . . 46
|
||
; 7.4. .NTSLM function (Set global logging mask) . . 47
|
||
; 7.5. .NTPSI function (Set event PSI channel) . . . 48
|
||
; 7.6. .NTEVQ function (Pass queued event to user) . 49
|
||
; 8. User strings
|
||
; 8.1. Write parameter with nice . . . . . . . . . . 51
|
||
; 8.2. Write coded data. . . . . . . . . . . . . . . 52
|
||
; 8.3. Write ascii image data. . . . . . . . . . . . 53
|
||
; 8.4. Write numeric data. . . . . . . . . . . . . . 54
|
||
; 8.5. Read a number from user . . . . . . . . . . . 55
|
||
; 8.6. Read and write milliseconds . . . . . . . . . 56
|
||
; 8.7. Copy STRINGID from user to exec . . . . . . . 57
|
||
; 8.8. Copy STRINGID from exec to user . . . . . . . 58
|
||
; 8.9. Get and put user byte routines. . . . . . . . 59
|
||
; 8.10. Get and put single bytes into data strings. . 60
|
||
; 9. Miscellaneous
|
||
; 9.1. Error returns . . . . . . . . . . . . . . . . 61
|
||
; 9.2. Name/number conversion. . . . . . . . . . . . 62
|
||
; 10. Data base
|
||
; 10.1. Find an NSP node block. . . . . . . . . . . . 63
|
||
; 10.2. Find an existing NSP node block . . . . . . . 64
|
||
SUBTTL Data structures -- Value definitions
|
||
|
||
;AC definitions
|
||
TM=FREE0 ;A WORK AC. PRESERVED
|
||
NT=FREE1 ;POINTS TO THE TABLE FORMAT BLOCK
|
||
|
||
|
||
|
||
;Network management non-error code
|
||
XP NESUC%,1
|
||
|
||
;Function codes
|
||
.NTSLM==-4 ;Set global logging mask (TOPS-20 only)
|
||
.NTPSI==-3 ;SET PSI MASK (TOPS20 ONLY)
|
||
.NTMAP==-2 ;Map Node name/Node number
|
||
.NTREX==-1 ;Return local node ID
|
||
.NTSET==0 ;SET PARAMETER
|
||
.NTCLR==1 ;CLEAR PARAMETER
|
||
.NTZRO==2 ;ZERO COUNTERS
|
||
.NTSHO==3 ;SHOW SELECTED ITEMS
|
||
.NTSZC==4 ;SHOW AND ZERO COUNTERS
|
||
.NTRET==5 ;RETURN LIST OF ITEMS
|
||
.NTEVQ==6 ;REMOVE AN ITEM FROM THE EVENT QUEUE
|
||
|
||
.NTSUM==0 ;SUMMARY ;(FOR .NTSHO)
|
||
.NTSTA==1 ;STATUS
|
||
.NTCHA==2 ;CHARACTERISTICS
|
||
.NTCOU==3 ;COUNTERS
|
||
;Skip 4 to avoid possible confusion with EVENTS
|
||
.NTCST==5 ;CIRCUIT STATE
|
||
;Offsets to important locations in block
|
||
.NTQUA==5 ;BYTE POINTER TO FUNCTION QUALIFER
|
||
.NTSEL==4 ;SELECTION CRITERIA FOR FUNCTION
|
||
.NTQUA==5 ;QUALIFIER
|
||
.NTBPT==6 ;BYTE POINTER TO DATA STRING
|
||
.NTBYT==7 ;BYTE COUNT FOR DATA STRING
|
||
.NTERR==10 ;RETURN CODE, OR ERROR CODE
|
||
|
||
;Some Maximum Length Constants
|
||
MXNNLN==6 ;Maximum Node Name Length
|
||
MXHILN==6 ;Maximum Hexidecimal Image string Length
|
||
|
||
;Constants for Memory allocations
|
||
FHIBLK==4 ;Hexidecimal Image buffer
|
||
COUBLK==^D100 ;Counter Block, should have plenty of
|
||
;extra room, just incase some wierd layer
|
||
;invents some newer counters.
|
||
CIRBLK==^D100 ;For RETURN LIST OF ENTITY IDS function
|
||
LPNBLK==^D32 ;For return list of LOOP Nodes
|
||
NDBLEN==^D1024 ;For return of Home Area Nodes
|
||
|
||
;Some constants for NICE Data Type Fields
|
||
NT.CNM==200 ;Coded Non-Multiple (OR'ed into byte length)
|
||
NT.CM1==301 ;Coded Multiple, 1 fields long
|
||
NT.CM2==302 ;Coded multiple, 2 fields long
|
||
NT.CM3==303 ;Coded multiple, 3 fields long
|
||
NT.DU1==1 ;Decimal, Unsigned, 1 byte long
|
||
NT.DU2==2 ;Decimal, Unsigned, 2 bytes long
|
||
NT.AI==100 ;ASCII Image field
|
||
NT.HI==40 ;HEXIDECIMAL Image field
|
||
|
||
;Needed Parameter Numbers
|
||
NODSTA==0 ;Node State Parameter number value
|
||
|
||
;MACRO TO GIVE AN ERROR RETURN. THIS IS USED SIMPLY TO HIGHLIGHT THE FACT
|
||
;OF AN ERROR RETURN, AND DOES NOT PRECLUDE OTHER WAYS OF REACHING THE ROUTINES
|
||
;WHICH SET AN ERROR CODE. A JSP IS USED TO FACILITATE DEBUGGING.
|
||
|
||
DEFINE XERRRET(ROUTINE),<XJSP (CX,XCDSEC,ROUTINE)> ; Jump to error routine
|
||
; in Extended Section
|
||
|
||
DEFINE ERRRET(ROUTINE),<JSP CX,ROUTINE>
|
||
|
||
|
||
XSWAPCD ;Most of NTMAN is swappable ($HIGH on TOPS-10)
|
||
|
||
EXTERN DNGWDZ,DNGWZP,DNGWDS,DNFWDS,NMXTIM,NMXPRV ;D36COM
|
||
EXTERN IBBLK,D36IFG
|
||
EXTERN TIMBAS,DNGTIM ;D36COM
|
||
EXTERN RTRMXN
|
||
EXTERN RTN,RSKP,CHKBPT,KONNAM
|
||
IFN FTOPS10,<EXTERN GETWRD,GETWR1,PSIDVT>
|
||
|
||
;NMX Standard Interface Routines
|
||
EXTERN SCLNMX ;Session Control Layer
|
||
EXTERN ECLNMX ;End Communication Layer
|
||
EXTERN RTRNMX ;Routing layer
|
||
EXTERN DNDNMX ;Data Link Layer
|
||
SUBTTL Data structures -- BEGSTR NT
|
||
|
||
;Table to find and validate a call parameter or counter.
|
||
BEGSTR NT
|
||
FIELD TYP,4 ;DATA TYPE (ASCII, HEX,...)
|
||
XP NT.FC,1 ;CODED FORMAT
|
||
XP NT.FCM,2 ;CODED MULTIPLE (THIS MEANS SPECIAL CASING)
|
||
XP NT.FAI,3 ;ASCII IMAGE (8-BIT)
|
||
XP NT.FDU,4 ;DECIMAL, UNSIGNED. CANNOT BE ZERO.
|
||
XP NT.FDS,5 ;DECIMAL, SIGNED
|
||
XP NT.FH,6 ;HEX INTEGER.
|
||
XP NT.FHI,7 ;HEX, IMAGE.
|
||
XP NT.FOC,^D8 ;OCTAL.
|
||
;ABOVE ARE DATA TYPES AS DESCRIBED IN NM SPEC
|
||
; V3.0 PAGE 162.
|
||
;BELOW ARE DATA TYPES USED INTERNALLY ONLY TO
|
||
; THIS MODULE.
|
||
; THESE SHOULD BE SHIFTED DOWN IF NM SPECIFIES
|
||
; MORE DATA TYPES
|
||
XP NT.FDM,^D9 ;INTERNAL DATA TYPE ONLY. DECIMAL,MILLISECONDS.
|
||
; THIS GETS OUTPUT AS NT.FDU (SEE NMXWNM)
|
||
XP NT.FVN,^D10 ;INTERNAL DATA TYPE ONLY. VERSION NUMBER.
|
||
; THIS GETS OUTPUT AS NT.FCM (DU-1,DU-1,DU-1)
|
||
XP NT.FNE,^D11 ;INTERNAL DATA TYPE ONLY. NODE ENTITY ID.
|
||
; THIS GETS OUTPUT AS NT.FCM (DU-2,AI-6)
|
||
XP NT.FNN,^D12 ;INTERNAL DATA TYPE ONLY. ASCII NODE NAME
|
||
; THIS GET OUTPUT AS NT.FAI (AI-6)
|
||
XP NT.FCN,^D13 ;INTERNAL DATA TYPE ONLY. ASCII CIRCUIT NAME
|
||
; THIS GET OUTPUT AS NT.FAI (AI-16)
|
||
FIELD LEN,5 ;LENGTH
|
||
FIELD ROU,6 ;INDEX TO ROUTINE TO CALL
|
||
FIELD DEV,6 ;DEVICE APPLICABILITY
|
||
BIT D.R ;DMR-11
|
||
BIT D.N ;Ethernet (KLNI)
|
||
BIT D.C ;Computer Interconnect (KLPI)
|
||
BIT D.P ;DDP
|
||
BIT D.K ;KDP
|
||
BIT D.D ;DTE-20 (UGH)
|
||
FIELD QUA,15 ;Qualifier Parameter Number
|
||
|
||
NXTWRD ;FORCE NEXT WORD ALIGNMENT.
|
||
FIELD APL,4 ;APPLICABILITY RESTRICTIONS
|
||
BIT A.E ;EXECUTOR
|
||
BIT A.L ;LOOP NODES.
|
||
BIT A.R ;REMOTE NODES.
|
||
BIT A.H ;HOME AREA NODES ONLY.
|
||
FIELD INF,6 ;INFORMATION TYPE
|
||
BIT I.C ;CHARACTERISTICS (LISTED IN SPEC AS 'C')
|
||
BIT I.S ;STATUS (LISTED IN SPEC AS 'S')
|
||
BIT I.% ;SUMMARY (LISTED IN SPEC AS '*')
|
||
BIT I.K ;Circuit State.
|
||
BIT I.Q ;This parameter is Qualified
|
||
BIT I.N ;NONE. NOOP BIT, NOT NECESSARY
|
||
FIELD SET,2 ;SETTABILITY RESTRICTIONS
|
||
XP NTS.,0 ;0 MEANS READ AND WRITE
|
||
XP NTS.R,1 ;READ ONLY PARAMETER.
|
||
XP NTS.W,2 ;WRITE ONLY PARAMETER.
|
||
FIELD BUF,1 ;Buffer Field
|
||
XP NTB.,0 ;Parameter Value fits into a Word
|
||
XP NTB.B,1 ;Parameter value too big, go allocate a buffer
|
||
FIELD BSZ,10 ;Buffer size needed (if needed)
|
||
FIELD SEQ,13 ;SEQUENCE OR TYPE OF FIELD
|
||
ENDSTR
|
||
IFN <NT.LST-2>,<PRINTX ?LENGTH OF BEGSTR NT IS WRONG> ;TABLE LOGIC KNOWS LENGTH
|
||
|
||
;Bit positions for fields - will need for building tables.
|
||
TYP$==POS(NTTYP)
|
||
SEQ$==POS(NTSEQ)
|
||
SET$==POS(NTSET)
|
||
LEN$==POS(NTLEN)
|
||
ROU$==POS(NTROU)
|
||
QUA$==POS(NTQUA)
|
||
BSZ$==POS(NTBSZ)
|
||
BUF$==POS(NTBUF)
|
||
|
||
SUBTTL -- NMX dispatch table. Routines are indexes into this table.
|
||
|
||
NMXDSP:
|
||
|
||
PHASE 0 ;Make labels be relative offsets.
|
||
NMXMIN:! ;Lowest offset for NMXDSP
|
||
SCL:! XCDSEC,,SCLNMX ;Session Control Layer
|
||
ECL:! XCDSEC,,ECLNMX ;End Communication Layer
|
||
RTL:! XCDSEC,,RTRNMX ;Routing Layer
|
||
DLL:! XCDSEC,,DNDNMX ;Data Link Layer
|
||
NMXMAX:! ;Maximum value plus one
|
||
IFGE <NMXMAX-<1_WID(NTROU)>>,<PRINTX ?Too many Layer servers for width of NTROU>
|
||
DEPHASE
|
||
SUBTTL Data structures -- Parameter and counter definitions
|
||
DEFINE NODE$P,<
|
||
|
||
N(0 ,C,1 ,S%,ERH ,R,,RTL) ;State.
|
||
N(10 ,HI,6 ,S,E ,R,,DLL,,B,4) ;Physical Address
|
||
repeat 0,<
|
||
IFN FTOPS10,<
|
||
N(100 ,AI,31 ,C%,E ,,NMI,0) ;Identification
|
||
>; End IFN FTOPS10
|
||
> ;end repeat 0
|
||
N(500 ,NN,6 ,N,R ,W,,SCL) ;Name of node (set only)
|
||
N(501 ,CN,16 ,C%,L ,,,SCL) ;Circuit
|
||
N(502 ,DU,2 ,N,E ,W,,SCL) ;Address (set only)
|
||
N(510 ,DM,2 ,C,E ,,,SCL) ;Incoming timer
|
||
N(511 ,DM,2 ,C,E ,,,SCL) ;Outgoing timer
|
||
N(600 ,DU,2 ,S%,ER ,R,,ECL) ;Active links.
|
||
N(601 ,DM,2 ,S%,R ,R,,ECL) ;Delay
|
||
N(700 ,VN,3 ,C,E ,R,,ECL) ;NSP version
|
||
N(710 ,DU,2 ,C,E ,,,ECL) ;Maximum Links
|
||
N(720 ,DU,1 ,C,E ,,,ECL) ;Delay factor.
|
||
N(721 ,DU,1 ,C,E ,,,ECL) ;Delay weight.
|
||
N(722 ,DU,2 ,C,E ,,,ECL) ;Inactivity timer.
|
||
N(723 ,DU,2 ,C,E ,,,ECL) ;Retransmit factor.
|
||
N(810 ,C,1 ,S,RH ,R,,RTL) ;Type
|
||
N(820 ,DU,2 ,S,RH ,R,,RTL) ;Cost
|
||
N(821 ,DU,1 ,S,RH ,R,,RTL) ;Hops
|
||
N(822 ,CN,16 ,S%,R ,R,,RTL) ;circuit
|
||
N(830 ,NE,2 ,S%,R ,R,,RTL) ;Next Node
|
||
N(900 ,VN,3 ,C,E ,R,,RTL) ;Routing version
|
||
N(901 ,C,1 ,C,E ,R,,RTL) ;Type
|
||
N(910 ,DM,2 ,C,E ,,,RTL) ;Routing timer.
|
||
N(912 ,DM,2 ,C,E ,,,RTL) ;Broadcast Routing Timer
|
||
N(920 ,DU,2 ,C,E ,,,RTL) ;Maximum address.
|
||
N(921 ,DU,2 ,C,E ,,,RTL) ;Maximum Circuits.
|
||
N(922 ,DU,2 ,C,E ,,,RTL) ;Maximum cost.
|
||
N(923 ,DU,1 ,C,E ,,,RTL) ;Maximum hops.
|
||
N(924 ,DU,1 ,C,E ,,,RTL) ;Maximum visits.
|
||
N(926 ,DU,2 ,C,E ,,,RTL) ;Maximum Broadcast Non-Routers
|
||
N(927 ,DU,2 ,C,E ,,,RTL) ;Maximum Broadcast Routers
|
||
N(930 ,DU,2 ,C,E ,,,RTL) ;Maximum Buffers
|
||
N(931 ,DU,2 ,C,E ,R,,RTL) ;Buffer size.
|
||
N(932 ,DU,2 ,C,E ,,,RTL) ;Segment Buffer Size
|
||
>
|
||
|
||
DEFINE LINE$P,<
|
||
|
||
N(0 ,C,1 ,S%, ,,,DLL) ;State
|
||
N(1105 ,DU,2 ,C, ,R,,DLL) ;Receive Buffers
|
||
N(1110 ,C,1 ,C, ,R,,DLL) ;Controller
|
||
REPEAT 0,<
|
||
N(1111 ,C,1 ,C, ,R,,DLL) ;Duplex
|
||
> ;END REPEAT 0
|
||
N(1112 ,C,1 ,C, ,R,,DLL) ;Protocol
|
||
N(1160 ,HI,6 ,C, ,R,N,DLL,,B,4) ;Hardware Address
|
||
N(2500 ,DU,2 ,C, ,R,,DLL) ;Receive block size
|
||
>
|
||
|
||
DEFINE CIRC$P,<
|
||
|
||
N(0 ,C,1 ,K, ,,,RTL) ;State.
|
||
N(400 ,NN,6 ,S%, ,R,,SCL) ;Loopback Name
|
||
N(800 ,NE,2 ,%, ,R,,RTL,,B,1023) ;Adjacent node
|
||
N(801 ,NE,2 ,S, ,R,N,RTL) ;Designated Router
|
||
N(810 ,DU,2 ,SQ, ,R,,RTL,800) ;Block size
|
||
N(900 ,DU,1 ,C, ,,,RTL) ;Cost.
|
||
N(901 ,DU,1 ,C, ,,N,RTL) ;Maximum Routers
|
||
N(902 ,DU,1 ,C, ,,N,RTL) ;Router Priority
|
||
N(906 ,DM,2 ,C, ,,,RTL) ;Hello timer
|
||
N(1112 ,C,1 ,C, ,,,DLL) ;Circuit Type
|
||
N(907 ,DU,2 ,CQ, ,,,RTL,800) ;Listen timer
|
||
>
|
||
|
||
|
||
|
||
|
||
|
||
DEFINE XPAND(.RES,.PFX,.CHA),<
|
||
.RES=0
|
||
IFB <.CHA>,<.RES=-1>
|
||
IRPC .CHA,<IFNB <.CHA>,<.RES=.RES!.PFX'.CHA>>
|
||
>
|
||
|
||
DEFINE .M(MASK),<1_WID(MASK)>
|
||
|
||
;Macro to create primary table entry
|
||
DEFINE NTENT(.APL,.INF,.SET,.BFF,.SIZ,.SEQ),<
|
||
IFB <.SIZ>,<BSZ==0>
|
||
IFNB <.SIZ>,<BSZ==^D'.SIZ>
|
||
IFGE <^D'.SEQ-.M(NTSEQ)>,<PRINTX ?Parameter .SEQ will not fit in NTSEQ>
|
||
XPAND(APL,NTA.,.APL)
|
||
XPAND(INF,NTI.,.INF)
|
||
<APL&NTAPL>!
|
||
<INF&NTINF>!
|
||
<<NTS.'.SET>B<SET$>&NTSET>!
|
||
<<NTB.'.BFF>B<BUF$>&NTBUF>!
|
||
<<BSZ>B<BSZ$>&NTBSZ>!
|
||
<<^D'.SEQ>B<SEQ$>&NTSEQ>
|
||
>
|
||
|
||
;Define rightmost positions of fields, for ddt
|
||
NTNMSK==:<1B<POS(NTAPL)>!1B<POS(NTINF)>!1B<POS(NTSET)>!1B<POS(NTBUF)>!1B<POS(NTBSZ)>!1B<POS(NTSEQ)>>
|
||
NSSMSK==:<1B<POS(NTTYP)>!1B<POS(NTLEN)>!1B<POS(NTROU)>!1B<POS(NTDEV)>!1B<POS(NTQUA)>>
|
||
;Example - NTN$3M NODEP+3$10r$o/ 100.,10.,4.,0.,0.
|
||
;displays fields NTAPL, NTINF, NTSET, NTSEQ .
|
||
|
||
;Macro to define secondary entry (Format)
|
||
DEFINE STENT(.TYP,.LEN,.ROU,.DEV,.QUA),<
|
||
XPAND(DEV,NTD.,.DEV)
|
||
IFB <.QUA>,<QUA==0>
|
||
IFNB <.QUA>,<QUA==^D'.QUA>
|
||
IFGE <.ROU-NMXMAX>,<PRINTX ?Routine .ROU out of range>
|
||
IFGE <^D'.LEN-.M(NTLEN)>,<PRINTX ?Parameter .LEN will not fit in NTLEN>
|
||
<<NT.F'.TYP>B<TYP$>&NTTYP>!
|
||
<<^D'.LEN>B<LEN$>&NTLEN>!
|
||
<<.ROU>B<ROU$>&NTROU>!
|
||
<DEV&NTDEV>!
|
||
<<QUA>B<QUA$>&NTQUA>
|
||
>
|
||
|
||
;Define all the REAL stuff now.
|
||
|
||
DEFINE N(.SEQ,.TYP,.LEN,.INF,.APP,.SET,.DEV,.ROU,.QUA,.BFF,.SIZ),<
|
||
STENT(.TYP,.LEN,.ROU,.DEV,.QUA)
|
||
NTENT(.APP,.INF,.SET,.BFF,.SIZ,.SEQ)
|
||
>
|
||
|
||
|
||
DEFINE MAKTAB(.LAB,.STF),<
|
||
XLIST
|
||
.LAB: .STF
|
||
.LAB'L==:.-.LAB
|
||
LIST
|
||
>
|
||
|
||
MAKTAB(NODEP,NODE$P)
|
||
MAKTAB(LINEP,LINE$P)
|
||
MAKTAB(CIRCP,CIRC$P)
|
||
|
||
|
||
;Pointers to parameter data base.
|
||
PRMP: XWD <-NODEPL/NT.LST>,NODEP ;NODE PARAMETERS
|
||
XWD <-LINEPL/NT.LST>,LINEP ;LINE PARAMETERS
|
||
Z ;LOGGING PARAMETERS
|
||
XWD <-CIRCPL/NT.LST>,CIRCP ;CIRCUIT PARAMETERS
|
||
Z ;MODULE - WE DON'T HAVE ANY
|
||
Z ;EVENTS - CAN'T SET ANYTHING.
|
||
|
||
SUBTTL Data structures -- Event and logging definitions
|
||
|
||
RESVR
|
||
|
||
;Event queue variables
|
||
NMXEVQ: BLOCK QH.LEN ;Event queue header
|
||
NMXELO: BLOCK 1 ;Event queue contains a lost event
|
||
|
||
;Signal queue variables
|
||
NMXSIQ: BLOCK QH.LEN ;Signal queue header
|
||
|
||
;Macros to define global filter table
|
||
|
||
DEFINE $SFIL <> ;"Start filter table"
|
||
|
||
DEFINE $FIL(A,B) < ;"Filter table entry"
|
||
XWD A,B
|
||
REPEAT <B+1-A>,<XWD 37777,-1>
|
||
>
|
||
|
||
DEFINE $NOFIL(A,B) < ;;"Off filter table entry"
|
||
XWD A,B
|
||
REPEAT <B+1-A>,<EXP 0>
|
||
>
|
||
|
||
DEFINE $EFIL <EXP -1> ;"End filter table"
|
||
|
||
;Now generate filter table
|
||
RESDT ;Initialized data
|
||
|
||
NMXFIL: $SFIL
|
||
$FIL(2,6) ;Event classes 2 through 6 known by monitor
|
||
$NOFIL(^D96,^D96) ;LCG specific events - turned off
|
||
IFN FTDEBUG <
|
||
$FIL(^D480,^D480) ;Accept event class 480 while debugging
|
||
>
|
||
$EFIL
|
||
|
||
;Note: add more $FIL entries to declare more monitor event classes.
|
||
;The table will expand to
|
||
;
|
||
; NMXFIL: 2,,6
|
||
; REPEAT 5,< 37777,,777777> ;All 32 event types within
|
||
; -1 ; a class in BLISS bit meaning
|
||
; -1 is an end flag
|
||
|
||
SWAPCD
|
||
|
||
SUBTTL NTMAN -- Entry
|
||
|
||
;Called from DISP2A in UUOCON
|
||
;Call
|
||
; M[T6]/ UUO itself (Used for storing values in the AC later)
|
||
; T1/ Contents of the AC at UUO time
|
||
; P/ Pointer to a stack in the current section
|
||
;Return
|
||
; RET error, .NTERR and AC contain error code
|
||
; SKPRET success. AC unchanged
|
||
|
||
|
||
.NTMAN:
|
||
NTMAN:
|
||
IFN FTOPS20,<
|
||
MCENT ;ENTER MONITOR CONTEXT
|
||
UMOVE T1,1 ;GET ADDRESS OF BLOCK
|
||
>
|
||
SKIPL D36IFG ;Is DECNET initialized?
|
||
IFN FTOPS20,<
|
||
ITERR (NTMX3) ; -no, return error code
|
||
>
|
||
IFN FTOPS10,<
|
||
RET ; Just give error return
|
||
> ;end ifn ftops10
|
||
;** Note **
|
||
; If you change this TRVAR, you need to change the TRVAR in routine GENE32
|
||
; in LLINKS as well.
|
||
TRVAR <<NMXVAR,NX.LST>,<NFWBLK,NF.LST>> ;SET UP TRVAR
|
||
;** End note **
|
||
SETZM NMXVAR ;CLEAN FIRST WORD OF BLOCK
|
||
HRRI T2,1+NMXVAR ;GET POINTER TO SECOND WORD IN BLOCK
|
||
HRLI T2,NMXVAR ;POINT AT START OF BLOCK
|
||
BLT T2,NX.LST-1+NMXVAR ;CLEAN UNTIL END OF BLOCK
|
||
STOR T1,NXADR,+NMXVAR ;SAVE ADDRESS OF ARGUMENT BLOCK
|
||
SETZM NFWBLK ;CLEAN FIRST WORD OF BLOCK
|
||
HRRI T2,1+NFWBLK ;GET POINTER TO SECOND WORD IN BLOCK
|
||
HRLI T2,NFWBLK ;POINT AT START OF BLOCK
|
||
BLT T2,NF.LST-1+NFWBLK ;CLEAN UNTIL END OF BLOCK
|
||
IFN FTOPS10,STOR T6,NXUUO,+NMXVAR ;** TOPS10 CALLS US WITH M/ UUO EXECUTED
|
||
XCALL (XCDSEC,NMXPRV) ;MAKE SURE WE ARE PRIVED.
|
||
IFN FTOPS10,< ;Tops-10 wants error in NTMAN argument block
|
||
IFNSK.
|
||
CALL [ XERRRET NTEPRV] ;NOPE, GIVE THE NO PRIVS RETURN
|
||
ERRRET NTERXI ;RETURN ERROR CODE TO USER
|
||
ENDIF.
|
||
>
|
||
IFN FTOPS20,< ;While Tops-20 generates CAPX1 error
|
||
ITERR (CAPX1)
|
||
>
|
||
CALL GETBLK ;GET STUFF FROM USER PARAMETER BLOCK
|
||
ERRRET NTERXI ;DIDN'T MAKE IT. SOMETHING WRONG.
|
||
IFN FTXMON,<
|
||
XCALL (XCDSEC,NMXDIS) ;DISPATCH TO ROUTINES (IN NTMAN)
|
||
>
|
||
IFE FTXMON,<
|
||
DNCALL (NMXDIS)
|
||
>
|
||
ERRRET NTERXI ;ERROR EXIT OF SOME KIND. CHECK.
|
||
IFN FTDEBUG <
|
||
TMNE NXERR,+NMXVAR ;MAKE SURE NO ERROR CODE HAS MADE IT'S WAY HERE
|
||
BUG.(CHK,NTMSRF,NTMAN,SOFT,<Skipness of return fouled up>,,<
|
||
|
||
Cause: There is an error code stored in field NXERR after a return from
|
||
NTMAN with a skip return.
|
||
|
||
Action: Put a non-skip return in the routine giving the error call.
|
||
>,RTN)
|
||
>
|
||
LOAD T2,NXADR,+NMXVAR ;GET ADDRESS OF USER'S ARGUMENT BLOCK
|
||
MOVX T1,NESUC% ;ERROR CODE INDICATING SUCCESS.
|
||
UMOVEM T1,.NTERR(T2) ;PUT IN ERROR CODE SPOT OF ARGUMENT BLOCK
|
||
UMOVE T3,.NTBYT(T2) ;GET ORIGINAL NUMBER OF BYTES HE ALLOWED US
|
||
LOAD T1,NXDAT,+BP.BYT+NMXVAR ;GET NUMBER OF BYTES LEFT IN STRING
|
||
SUB T3,T1 ;GET NUMBER OF BYTES WE ACTUALLY DEPOSITED
|
||
TMNE NXWUS,+NMXVAR ;DID WE WRITE TO THE USER'S STRING?
|
||
UMOVEM T3,.NTBYT(T2) ;TELL USER HOW MANY BYTES WE GAVE HIM
|
||
IFN FTOPS20,MRETNG ;MAKE THE UUO DO A GOOD RETURN
|
||
IFN FTOPS10,RETSKP
|
||
|
||
NTERXI:
|
||
OPSTR <SKIPL T1,>,NXERR,+NMXVAR
|
||
BUG.(CHK,NTMNEC,NTMAN,SOFT,<No error code with error return>,,<
|
||
|
||
Cause: A routine has returned non-skip, but has not given
|
||
an error code by calling NTExxx. A return to the top level found
|
||
field NXERR zero.
|
||
|
||
Action: Determine which routine is failing, and make the error return
|
||
give an error code.
|
||
>)
|
||
IFN FTOPS10,<
|
||
LOAD T6,NXUUO,+NMXVAR ;GET UUO BACK - NEED FOR STOTAC
|
||
MCALL (RG,MSEC0,STOTAC##) ;PUT ERROR CODE IN AC
|
||
LOAD T1,NXERR,+NMXVAR ;GET ERROR CODE
|
||
CAXN T1,NEADC% ;WAS THIS AN ADDRESS CHECK?
|
||
RET ;YES, DON'T DO FURTHER DAMAGE.
|
||
> ;END IFN FTOPS10
|
||
LOAD T2,NXADR,+NMXVAR ;GET ADDRESS OF USER BLOCK
|
||
UMOVEM T1,.NTERR(T2) ;NOPE, SAFE TO GIVE HIM ERROR CODE
|
||
SETZ T1, ;0 BYTES
|
||
UMOVEM T1,.NTBYT(T2) ;TELL NML THAT WE DIDN'T GIVE HIM ANYTHING.
|
||
IFN FTOPS20,ITERR (NTMX1) ;GENERIC NETWORK MANAGEMENT ERROR
|
||
IFN FTOPS10,RET ;RETURN NON-SKIP, INDICATING UUO FAILED
|
||
SUBTTL NTMAN -- Get pertinent data from user's data block
|
||
|
||
;Called from NMXDIS
|
||
|
||
;GETBLK - Copy pertinent fields from user's argument block to NX block
|
||
;;Call
|
||
; NX/ Pointer to NX block
|
||
;Returns
|
||
; Non skip on failure - Address check
|
||
; Skip return on success
|
||
GETBLK:
|
||
SAVEAC P1 ;SO WE CAN HOLD SOME STUFF
|
||
LOAD T6,NXADR,+NMXVAR ;GETWRD UNDERSTANDS T6 AS ADDRESS.
|
||
MCALL (RG,MSEC1,GETWRD) ;GET FIRST WORD OF BLOCK
|
||
IFNSK.
|
||
XERRRET NTEADC ;NO GO. CAN'T HAPPEN
|
||
ENDIF.
|
||
CAIGE T1,.NTERR ;MAKE SURE BLOCK INCLUDES .NTERR
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
MCALL (RG,MSEC1,GETWR1) ;GET NEXT WORD IN BLOCK
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
CAXL T1,.NTNOD ;RANGE CHECK THE ENTITY TYPE
|
||
CAXLE T1,.NTARE
|
||
IFNSK.
|
||
XERRRET NTEINI ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
STOR T1,NXENT,+NMXVAR ;SAVE AS ENTITY TYPE
|
||
MCALL (RG,MSEC1,GETWR1) ;GET BYTE POINTER TO ENTITY ID
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
MOVE P1,T6 ;SAVE POINTER TO ARG BLOCK FOR A WHILE
|
||
MOVX T2,^D16 ;THIS COULD BE AS MUCH AS 16 BYTES
|
||
MCALL (RG,MSEC1,CHKBPT##) ;ASK IF THIS IS A GOOD BYTE POINTER
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
MOVE T6,P1 ;GET BACK POINTER TO OUR ARGUMENT LIST
|
||
STOR T1,NXEID,+BP.BPT+NMXVAR ;SAVE RESOLVED BYTE POINTER
|
||
MOVX T1,^D16 ;MAXIMUM LENGTH FOR AN ENTITY ID
|
||
STOR T1,NXEID,+BP.BYT+NMXVAR ;SAVE
|
||
MCALL (RG,MSEC1,GETWR1) ;GET FUNCTION TO BE PERFORMED
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
IFN FTDEBUG <
|
||
CAXL T1,.NTTEV
|
||
>
|
||
IFE FTDEBUG <
|
||
CAXL T1,.NTSLM ;RANGE CHECK FUNCTION
|
||
>
|
||
CAXLE T1,.NTEVQ
|
||
IFNSK.
|
||
XERRRET NTEUFO ;BAD FUNCTION
|
||
ENDIF.
|
||
STOR T1,NXFNC,+NMXVAR ;SAVE AWAY.
|
||
MCALL (RG,MSEC1,GETWR1) ;GET SELECTION CRITERIA
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
STOR T1,NXSEL,+NMXVAR ;STASH AWAY
|
||
MCALL (RG,MSEC1,GETWR1) ;GET FUNCTION QUALIFIER
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
;I DON'T KNOW WHAT TO DO WITH THIS. TOSS.
|
||
MCALL (RG,MSEC1,GETWR1) ;GET BYTE POINTER TO THE USER BUFFER
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
MOVE P1,T1 ;HANG ON TO BYTE POINTER FOR A WHILE
|
||
MCALL (RG,MSEC1,GETWR1) ;GET BYTE COUNT OF STRING
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
STOR T1,NXDAT,+BP.BYT+NMXVAR ;SAVE BYTE COUNT
|
||
UMOVEM T1,(T6) ;TRY TO MOVE IT BACK. (MAKE SURE WRITABLE)
|
||
IFN FTOPS10,ERJMP NTEADC ;DIDN'T WORK, MUST BE A HIGH SEGMENT.
|
||
MOVE T2,T1 ;NUMBER OF BYTES WE WANT TO CHECK
|
||
MOVE T1,P1 ;BYTE POINTER WE ARE GOING TO ASK ABOUT
|
||
MOVE P1,T6 ;SAVE OUR ARGUMENT LIST POINTER
|
||
MCALL (RG,MSEC1,CHKBPT##) ;ASK IF THIS BYTE POINTER IS ANY GOOD
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
STOR T1,NXDAT,+BP.BPT+NMXVAR ;SAVE FOR GETBYT
|
||
MOVE T6,P1 ;GET BACK POINTER TO THE USER ARG BLOCK
|
||
MCALL (RG,MSEC1,GETWR1) ;MAKE SURE .NTERR IS IN CORE
|
||
IFNSK.
|
||
XERRRET NTEADC ;NOPE, ADDRESS CHECK.
|
||
ENDIF.
|
||
UMOVEM T1,(T6) ;TRY TO PUT IT BACK.
|
||
IFN FTOPS10,ERJMP NTEADC ;DIDN'T WORK, MUST BE FIRST WORD IN HISEG
|
||
RETSKP ;RETURN SUCCESS TO CALLER
|
||
|
||
IFN FTOPS20,<
|
||
;GETWRD & GETWR1 - Get a word from user space
|
||
;Call
|
||
; T6/ address desired
|
||
;Return
|
||
; +2 always
|
||
|
||
GETWR1: AOJ T6, ;POINT TO NEXT WORD
|
||
GETWRD: UMOVE T1,(T6) ;GET WORD
|
||
RETSKP ;AND RETURN
|
||
|
||
|
||
|
||
> ;END IFN FTOPS20
|
||
SUBTTL NTMAN -- Dispatch to functions
|
||
|
||
XSWAPCD ;Section 6 Swapable Code
|
||
|
||
NMXDIS:
|
||
LOAD P1,NXENT,+NMXVAR ;GET ENTITY TYPE
|
||
LOAD T1,NXFNC,+NMXVAR ;GET FUNCTION CODE
|
||
IFE FTDEBUG <
|
||
MOVE T2,<-.NTSLM>+[ ;GET FLAG BITS FOR THIS FUNCTION
|
||
>
|
||
IFN FTDEBUG <
|
||
MOVE T2,<-.NTTEV>+[ ;GET FLAG BITS FOR THIS FUNCTION
|
||
NX%ECV ;.NTTEV (check entity)
|
||
>
|
||
NX%WRM ;.NTSLM (TOPS-20 only)
|
||
NX%WRM ;.NTPSI (TOPS-20 ONLY)
|
||
NX%WUS ;.NTMAP
|
||
NX%WUS ;.NTREX
|
||
NX%WRM!NX%ECV ;.NTSET
|
||
NX%WRM!NX%ZMC!NX%ECV ;.NTCLR
|
||
NX%WRM!NX%ZMC!NX%ECV ;.NTZRO
|
||
NX%WUS!NX%ECV ;.NTSHO
|
||
NX%WUS!NX%ZMC!NX%WRM!NX%ECV;.NTSZC
|
||
NX%WUS ;.NTRET
|
||
NX%WUS](T1) ;.NTDQE
|
||
STOR T2,NXFLG,+NMXVAR ;SAVE FLAGS WE JUST GOT
|
||
TXNN T2,NX%ECV ;SHOULD WE PARSE THE ENTITY?
|
||
JRST NMXDI2 ;NO, SKIP OVER
|
||
CALL ENTCVT ;CONVERT THE ENTITY TO AN ID
|
||
RET ;error...
|
||
LOAD T1,NXFNC,+NMXVAR ;GET FUNCTION CODE BACK AGAIN.
|
||
NMXDI2:
|
||
IFN FTDEBUG <
|
||
CAXL T1,.NTTEV
|
||
>
|
||
IFE FTDEBUG <
|
||
CAXL T1,.NTSLM ;RANGE CHECK FUNCTION
|
||
>
|
||
CAXLE T1,.NTEVQ ; CODE.
|
||
BUG.(CHK,NTMFUR,NTMAN,SOFT,<Function code out of range>,,<
|
||
|
||
Cause: While dispatching by function code, the function code is found
|
||
to be out of range. Since the function code the user supplies is
|
||
checked in GETBLK, this means that field NXFNC has been trashed
|
||
in the meantime.
|
||
>,NTEMPE)
|
||
CAXL P1,.NTNOD ;RANGE CHECK ENTITY
|
||
CAXLE P1,.NTARE ; TYPE.
|
||
BUG.(CHK,NTMEOR,NTMAN,SOFT,<Entity type out of range>,,<
|
||
|
||
Cause: While double checking the entity ID before dispatching
|
||
on it, the value was found to be illegal. Since the
|
||
value the user supplies is checked at GETBLK, this means that
|
||
field NXENT has been trashed.
|
||
>,NTEMPE)
|
||
IFN FTDEBUG <
|
||
CALLRET @.+1-.NTTEV(T1) ;DISPATCH TO APPROPRIATE ROUTINE.
|
||
>
|
||
IFE FTDEBUG <
|
||
CALLRET @.+1-.NTSLM(T1) ;DISPATCH TO APPROPRIATE ROUTINE.
|
||
>
|
||
IFN FTDEBUG <
|
||
IFIW <NTTEV&777777> ;.NTTEV - Test function
|
||
>
|
||
IFIW <NTSLM&777777> ;.NTSLM - Set global logging mask
|
||
IFIW <NTPSI&777777> ;.NTPSI - SET EVENT INTERRUPT (TOPS-20 ONLY)
|
||
IFIW <NODMAP&777777> ;.NTMAP - MAP NODE NUMBERS AND NAMES
|
||
IFIW <NODLOC&777777> ;.NTREX - RETURN ENTITY ID FOR EXECUTOR
|
||
IFIW <PRSPRM&777777> ;.NTSET - SET A PARAMETER
|
||
IFIW <PRSPRM&777777> ;.NTCLR - CLEAR A PARAMETER
|
||
IFIW <PRSCOU&777777> ;.NTZRO - ZERO COUNTERS
|
||
IFIW <SELITM&777777> ;.NTSHO - SHOW PARAMETERS/COUNTERS
|
||
IFIW <PRSCOU&777777> ;.NTSZC - SHOW AND ZERO COUNTERS
|
||
IFIW @<-.NTNOD>+[ ;.NTRET - LIST ENTITIES
|
||
IFIW <NMXLND&777777> ; .NTNOD - NODE
|
||
IFIW <NMXLCK&777777> ; .NTLIN - LINE
|
||
IFIW <NTEURC&777777> ; .NTLOG - DOESN'T EXIST
|
||
IFIW <NMXLCK&777777> ; .NTCKT - CIRCUIT
|
||
IFIW <NTEURC&777777> ; .NTMOD - Doesn't exist
|
||
IFIW <NTEURC&777777>](P1) ; .NTARE - Doesn't exist
|
||
IFIW <NTEVQ&777777> ;.NTEVQ - PASS A QUEUED EVENT TO USER
|
||
SUBTTL Functions -- .NTMAP - Map node name/number
|
||
|
||
;Called from NMXDIS
|
||
|
||
;Extract parameter from input string, if a number return node name,
|
||
; if a name, return node number (Address, or ID).
|
||
;Call
|
||
; NC/ Pointer to block of data copied from user.
|
||
|
||
NODMAP:
|
||
SAVEAC P1 ;NEED ACS FOR BYTE ROUTINES
|
||
CALL GET2BT ;GET NODE NUMBER
|
||
RET
|
||
STOR T1,NXNUM,+NMXVAR ;STORE ENTITY ID (MAYBE)
|
||
CALL GETSTR ;COPY SOME BYTES
|
||
RET
|
||
JE NXVAL,+NMXVAR,NODMA2 ;IF NO NAME, HE GAVE US AN ADDR
|
||
CALL NMXN2A ;CONVERT NAME IN NXVAL TO NUMBER
|
||
RET ;Error return
|
||
STOR T1,NXNUM,+NMXVAR ;STORE THE NODE ADDRESS AWAY.
|
||
|
||
NODMA2:
|
||
JE NXNUM,+NMXVAR,NTEPAM ;IF NO NODE ADDRESS YET, ILLEGAL.
|
||
LOAD T1,NXADR,+NMXVAR ;GET USER'S ARG BLOCK ADDRESS
|
||
S1XCT <
|
||
UMOVE T1,.NTBPT(T1) ;GET BYTE POINTER AGAIN
|
||
STOR T1,NXDAT,+BP.BPT+NMXVAR ;RESET EVERYTHING AGAIN
|
||
LOAD T1,NXADR,+NMXVAR ;ARG BLOCK ADDRESS AGAIN
|
||
ADDI T1,.NTBYT ;POINT TO BYTE COUNT
|
||
UMOVE T1,(T1) ;GET BYTE COUNT FOR DATA STRING
|
||
>
|
||
STOR T1,NXDAT,+BP.BYT+NMXVAR ;STASH AWAY FOR PUTBYT
|
||
LOAD T1,NXNUM,+NMXVAR ;GET NODE ADDRESS BACK
|
||
CALL NMXA2N ;CONVERT NODE ADDRESS TO NODE NAME
|
||
IFNSK.
|
||
LOAD T1,NXERR,+NMXVAR ;Get the error code (If any.)
|
||
CAXE T1,NF.URC ;Unrecognized Component?
|
||
RET ;No, it is a real error, report it
|
||
SETZRO NXVAL,+NMXVAR ;Otherwise, return #, without a name.
|
||
SETZRO NXERR,+NMXVAR ;Get rid of the error code
|
||
ENDIF.
|
||
NODMA3: LOAD T1,NXNUM,+NMXVAR ;GET NODE NUMBER
|
||
CALL PUT2BT ;PUT INTO DATA STRING
|
||
RET ;error...
|
||
XMOVEI P1,NX.VAL+NMXVAR ;POINTER TO STRINGID CONTAINING NODE NAME
|
||
CALLRET PUTSTR ;COPY STRING FROM NXVAL TO USER DATA STRING
|
||
SUBTTL Functions -- .NTREX - Return local node number
|
||
|
||
;Called from NMXDIS
|
||
|
||
NODLOC:
|
||
CALL LOCNID ;Get the Local Node Id
|
||
RET
|
||
CALL PUT2BT ;SEND TWO BYTES INTO THE OUTPUT STRING.
|
||
RET ;error
|
||
SETZ T1, ;NO NODE NAME (DON'T BOTHER)
|
||
CALLRET PUTBYT ;STORE AWAY IN USER STRING
|
||
|
||
; Get the Local Node Id
|
||
;
|
||
;Return
|
||
; RET ;Error return from ROUTER
|
||
; RETSKP ;Local Node ID (Address) in T1
|
||
;
|
||
LOCNID:
|
||
|
||
LOAD T1,IBADR,+IBBLK ;Get our node address
|
||
RETSKP ;Success....
|
||
|
||
|
||
LOCARE: LOAD T1,IBADR,+IBBLK ;Get our node address
|
||
ASH T1,-<^D10> ;Get just the area number
|
||
RETSKP
|
||
|
||
SUBTTL Functions -- .NTSET,.NTCLR - Parse and process a parameter
|
||
|
||
;Called from NMXDIS
|
||
|
||
;PRSPRM - Parse a parameter from the data string, and process
|
||
;CALL
|
||
; T1/ Function (From NXFNC)
|
||
;RETURN
|
||
; Non skip, on error, with code stored in NXERR
|
||
; Skip, no error, parameter has been processed
|
||
PRSPRM:
|
||
SAVEAC NT
|
||
MOVE NT,PRMP(P1) ;GET AOBJN POINTER TO NMXTAB
|
||
LOAD T1,NXENT,+NMXVAR ;Get the entity type
|
||
STOR T1,NFETY,+NFWBLK ;Store it in the Argument Block
|
||
MOVE T3,T1 ;Put Entity type into T3 for upcoming dispatch
|
||
LOAD T1,NXNUM,+NMXVAR ;Get the Converted Entity Id
|
||
STOR T1,NFEID,+NFWBLK ;And put it into the NFW Arg Block.
|
||
JE NXDAT,+BP.BYT+NMXVAR,TABCLR ;IF NO PARAMETER, TRY CLEAR ALL
|
||
CALL GET2BT ;GET DATA-ID FIELD.
|
||
RET ;error
|
||
STOR T1,NFPRM,+NFWBLK ;STORE SEQUENCE NUMBER
|
||
|
||
;Now search for sequence number in NMXTAB table.
|
||
TABSRC: JUMPGE NT,NTEUPT ;IF END OF TABLE, NO SUCH PARAMETER
|
||
LOAD T2,NTSEQ,(NT) ;GET AN ENTRY OUT OF THE TABLE.
|
||
CAME T1,T2 ;IS THIS THE ENTRY WE ARE LOOKING FOR ?
|
||
JRST [ADD NT,[1,,NT.LST] ;INCREMENT POINTER, DECREMENT COUNT
|
||
JRST TABSRC] ;AND TRY AGAIN
|
||
;NT now points to table entry describing this parameter or counter.
|
||
LOAD T1,NTSET,(NT) ;GET SETTABILITY RESTRICTIONS
|
||
CAXN T1,NTS.R ;IS IT READ ONLY?
|
||
ERRRET NTEOPF ;YEP - HE CAN'T BE WRITING THIS ONE
|
||
LOAD T1,NXENT,+NMXVAR ;GET TYPE OF ENTITY
|
||
CAXE T1,.NTNOD ;IS IT A NODE?
|
||
JRST TABSR1 ;NO, APPLICABILITY DOESN'T APPLY
|
||
LOAD T2,NXNTY,+NMXVAR ;GET TYPE OF NODE
|
||
MOVE T2,[NTA.E ;BIT INIDICATING EXECUTOR
|
||
NTA.R ; REMOTE
|
||
NTA.L]-1(T2) ; LOOPBACK
|
||
TDNN T2,NT.APL(NT) ;DOES THIS PARAMETER APPLY TO THIS NODE TYPE?
|
||
ERRRET NTEPNA ;NO, PARAMETER NOT APPLICABLE
|
||
JRST TABSR2 ;Skip over Line/Circuit Check
|
||
|
||
TABSR1: TXNN T1,<.NTLIN&.NTCKT> ;Is it a LINE or a CIRCUIT?
|
||
JRST TABSR2 ;No, don't bother checking Line type
|
||
LOAD T2,NXLTY,+NMXVAR ;Get the Line type
|
||
MOVE T2,[NTD.D ;Bit indicating DTE
|
||
NTD.K ; KDP
|
||
NTD.P ; DDP
|
||
NTD.C ; CI
|
||
NTD.N ; NI
|
||
NTD.R]-1(T2) ; DMR
|
||
TDNN T2,NT.DEV(NT) ;Does this Parameter apply to this Line Type?
|
||
ERRRET NTEPNA ;Parameter Not Applicable
|
||
|
||
TABSR2: JN NXZMC,+NMXVAR,TABSR3 ;IF ZEROING MONITOR CORE, DON'T GET VALUES
|
||
LOAD T1,NTTYP,(NT) ;FIND OUT WHAT KIND OF DATA WE ARE READING
|
||
CAXL T1,NT.FC ;IS IT LESSER THAN SIMPLE CODED?
|
||
CAXLE T1,NT.FCN ;OR GREATER THAN CIRCUIT NAME
|
||
TABSRE: BUG.(CHK,NTMBFP,NTMAN,SOFT,<Bad format type encountered>,,<
|
||
|
||
Cause: In the process of reading a value from the user string,
|
||
descriptor tables have returned an invalid format for this
|
||
item. The AC "NT" points to the descriptor for this item, and
|
||
field NTSEQ tells which item is being referred to.
|
||
|
||
Action: Fix the entry for this item to contain a valid format type.
|
||
>,NTEMPE)
|
||
CALL <-NT.FC>+@[ ;DISPATCH ACCORDING TO FORMAT TYPE
|
||
IFIW <NMXRNC&777777> ;ORDINARY CODED.
|
||
IFIW <TABSRE&777777> ;CODED MULTIPLE. ILLEGAL
|
||
IFIW <TABSRE&777777> ;ASCII IMAGE. ILLEGAL
|
||
IFIW <NMXRNU&777777> ;DECIMAL UNSIGNED.
|
||
IFIW <NMXRNS&777777> ;DECIMAL SIGNED.
|
||
IFIW <NMXRNU&777777> ;HEX INTEGER.
|
||
IFIW <NMXRHI&777777> ;HEX IMAGE. STRING ID.
|
||
IFIW <NMXRNU&777777> ;OCTAL - READ AS DECIMAL UNSIGNED
|
||
IFIW <NMXRNM&777777> ;MILLISECONDS (REALLY DECIMAL UNSIGNED)
|
||
IFIW <TABSRE&777777> ;VERSION NUMBER. ILLEGAL, READ-ONLY
|
||
IFIW <TABSRE&777777> ;NODE ENTITY ID. ILLEGAL, READ-ONLY
|
||
IFIW <NMXRNN&777777> ;NODE NAME (IN ASCII IMAGE FORMAT)
|
||
IFIW <NMXRCN&777777>](T1) ;CIRCUIT NAME. (IN ASCII IMAGE FORMAT)
|
||
RET ;PROPAGATE ERROR
|
||
MOVX T1,NF.SET ;Get the SET PARAMETER function code
|
||
SKIPA ;Skip
|
||
TABSR3: MOVX T1,NF.CLR ;Get the CLEAR PARAMETER function code
|
||
XMOVEI T2,NFWBLK ;Put address of the Arg Block in T2
|
||
LOAD T3,NTROU,(NT) ;GET ROUTINE FOR THIS PARAMETER
|
||
CALL NMXLAY ;HAVE THE LAYER DO THE REST.
|
||
JRST NTEERR ;Go report the error
|
||
JE NFBFF,+NFWBLK,RSKP ;If no buffer,we are finished
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the buffer address
|
||
CALL DNFWDS ;Deallocate it
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RETSKP ;FINISHED
|
||
|
||
;Logic for CLEAR ALL command
|
||
|
||
TABCLR: TMNN NXZMC,+NMXVAR ;ARE WE DOING A CLEAR?
|
||
ERRRET NTEPAM ;NOPE, PARAMETER MISSING
|
||
TABCL1: JUMPGE NT,RSKP ;DONE WHEN POSITIVE
|
||
LOAD T1,NTSET,(NT) ;GET SETTABILITY RESTRICTIONS
|
||
CAXE T1,NTS. ;ARE THERE ARE RESTRICTIONS?
|
||
JRST TABCL5 ;YES, IGNORE THIS PARAMETER
|
||
LOAD T1,NXENT,+NMXVAR ;GET ENTITY TYPE
|
||
CAXE T1,.NTNOD ;IS IT NODE?
|
||
JRST TABCL2 ;NOPE, APPLICABILITY DOESN'T APPLY
|
||
LOAD T1,NXNTY,+NMXVAR ;GET TYPE OF NODE
|
||
MOVE T1,[NTA.E
|
||
NTA.R
|
||
NTA.L]-1(T1) ;GET BITS REPRESENTING APPLICABILITY
|
||
TDNN T1,NT.APL(NT) ;DOES THIS APPLY TO THIS NODE?
|
||
JRST TABCL5 ;NOPE, BYPASS IT
|
||
|
||
TABCL2: TXNN T1,<.NTLIN&.NTCKT> ;Is it a LINE or a CIRCUIT?
|
||
JRST TABCL3 ;No, don't bother checking Line type
|
||
LOAD T2,NXLTY,+NMXVAR ;Get the Line type
|
||
MOVE T2,[NTD.D ;Bit indicating DTE
|
||
NTD.K ; KDP
|
||
NTD.P ; DDP
|
||
NTD.C ; CI
|
||
NTD.N ; NI
|
||
NTD.R]-1(T2) ; DMR
|
||
TDNN T2,NT.DEV(NT) ;Does this Parameter apply to this Line Type?
|
||
JRST TABCL5 ;NOPE, BYPASS IT
|
||
|
||
TABCL3: CALL TABSR3 ;Go CLEAR this parameter
|
||
RET ;Error
|
||
TABCL5: ADD NT,[1,,NT.LST] ;INCREMENT POINTER, DECREMENT COUNT
|
||
JRST TABCL1 ;AND DO THE NEXT PARAMETER
|
||
|
||
SUBTTL Counter Functions
|
||
;PRSCOU - Counter Functions Routine.
|
||
; All three JSYS Counter Functions dispatch to here. The
|
||
; NFWBLK Block is set up, a memory block is allocated,
|
||
; and the NMX function code is stored in T1.
|
||
; We then dispatch off of the Entity Type field to the
|
||
; routines which call the layers.
|
||
|
||
;Note: this routine is also called from LLINKS. NSP needs a little
|
||
; help to generate the NICE message of the NSP node counters on a
|
||
; "database reused" event.
|
||
;
|
||
;LLINKS sets up a NMXVAR and NFWBLK TRVAR's, so it mimics the higher
|
||
; layers of NTMAN.
|
||
|
||
PRSCOU:
|
||
LOAD T1,NXENT,+NMXVAR ;Get the Entity Type
|
||
STOR T1,NFETY,+NFWBLK ;Put entity Type into NFWBLK
|
||
LOAD T1,NXNUM,+NMXVAR ;Get the Entity ID (Already converted)
|
||
STOR T1,NFEID,+NFWBLK ;Copy it into NFWBLK
|
||
MOVX T1,COUBLK ;Get the size of a counter block
|
||
STOR T1,NFBLN,+NFWBLK ;Copy it into NFWBLK
|
||
CALL DNGWDS ;Get buffer of that length
|
||
ERRRET NTERES ;Resource Error
|
||
STOR T1,NFBUF,+NFWBLK ;Put Buffer Address into NFWBLK
|
||
SETONE NFBFF,+NFWBLK ;Flag that we sre sending a buffer to the layer
|
||
LOAD T2,NXFNC,+NMXVAR ;Get the JSYS function code
|
||
IFE FTDEBUG <
|
||
MOVE T1,<-.NTSLM>+[ ;GET FLAG BITS FOR THIS FUNCTION
|
||
>
|
||
IFN FTDEBUG <
|
||
MOVE T1,<-.NTTEV>+[ ;GET FLAG BITS FOR THIS FUNCTION
|
||
NF.ILG ;.NTTEV (check entity)
|
||
>
|
||
NF.ILG ;.NTSLM (TOPS-20 only)
|
||
NF.ILG ;.NTPSI (TOPS-20 ONLY)
|
||
NF.ILG ;.NTMAP
|
||
NF.ILG ;.NTREX
|
||
NF.ILG ;.NTSET
|
||
NF.ILG ;.NTCLR
|
||
NF.SZC ;.NTZRO
|
||
NF.COU ;.NTSHO
|
||
NF.SZC ;.NTSZC
|
||
NF.ILG ;.NTRET
|
||
NF.ILG](T2) ;.NTDQE
|
||
SKIPGE T1 ;Skip if Function code is alright
|
||
JRST [ LOAD T1,NFBUF,+NFWBLK ;Put the buffer address back into T1
|
||
CALL DNFWDS ;Return the block
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
BUG.(CHK,NTMICF,NTMAN,SOFT,<Non-counter function in PRSCOU>,,<
|
||
|
||
Cause: There is an illegal function in the PRSCOU routine. NXFNC
|
||
is wrong.
|
||
>,NTEMPE)]
|
||
|
||
LOAD T2,NXENT,+NMXVAR ;Get the Entity Type so we can dispatch
|
||
CALL <-.NTNOD>+@[ ;Dispatch according to Entity Type
|
||
IFIW <PRSNDC&777777> ;Node Counters
|
||
IFIW <PRSLNC&777777> ;Line Counters
|
||
IFIW <NTEUFO&777777> ;Logging Counters (There are none!)
|
||
IFIW <PRSCKC&777777> ;Circuit Counters
|
||
IFIW <NTEUFO&777777> ;Module Counters (None)
|
||
IFIW <NTEUFO&777777>](T2) ;Area Counters (None)
|
||
|
||
RET ;Error has been reported and buffer deallocated
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block Address
|
||
CALL DNFWDS ;Return the block
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RETSKP ;return success
|
||
|
||
SUBTTL PRSNDC - Process Node counters
|
||
;Show Node counters (and maybe Zero)
|
||
;Call
|
||
; T1/ Function Code (NF.COU or NF.SZC)
|
||
; NFWBLK is all set up for call to ECLNMX and RTRNMX
|
||
;Return
|
||
; RET on error, error code in T1
|
||
; RETSKP, via PRSCBK on success
|
||
PRSNDC:
|
||
SAVEAC <P1> ;Will store Function code here
|
||
MOVE P1,T1 ; so we have it for RTRNMX call
|
||
XMOVEI T2,NFWBLK ;And NF Block address in T2
|
||
CALL ECLNMX ;Call the End Communication Layer
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block Address
|
||
LOAD T2,NFBLN,+NFWBLK ;and the # of words written
|
||
CALL PRSCBK ;Go parse the counter block
|
||
RET
|
||
SETZRO NXNIL,+NMXVAR ;Make sure the No Information bit is clear
|
||
CALL LOCNID ;Get the Local node number
|
||
RET
|
||
LOAD T2,NFEID,+NFWBLK ;Get the Node Number back
|
||
CAME T1,T2 ;Is it our node number
|
||
RETSKP ;No, Return. ROUTER has EXECUTOR COUNTERS only
|
||
MOVX T1,COUBLK ;We have to reset the Buffer Length because
|
||
STOR T1,NFBLN,+NFWBLK ; ECLNMX returned bytes written there.
|
||
MOVE T1,P1 ;Put function code in T1
|
||
XMOVEI T2,NFWBLK ;And NF Block address in T2
|
||
CALL RTRNMX ;Call the End Communication Layer
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block Address
|
||
LOAD T2,NFBLN,+NFWBLK ;and the # of words written
|
||
CALLRET PRSCBK ;Go parse the counter block
|
||
|
||
SUBTTL PRSCKC - Process Circuit counters
|
||
;Show Circuit counters (and maybe Zero)
|
||
;Call
|
||
; T1/ Function Code (NF.COU or NF.SZC)
|
||
; NFWBLK is all set up for call to RTRNMX and DNDNMX
|
||
;Return
|
||
; RET on error, error code in T1
|
||
; RETSKP, via PRSCBK on success
|
||
PRSCKC:
|
||
SAVEAC <P1> ;Will store Function code here
|
||
MOVE P1,T1 ; so we have it for DNDNMX call
|
||
XMOVEI T2,NFWBLK ;And NF Block address in T2
|
||
CALL RTRNMX ;Call the End Communication Layer
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block Address
|
||
LOAD T2,NFBLN,+NFWBLK ;and the # of words written
|
||
CALL PRSCBK ;Go parse the counter block
|
||
RET
|
||
SETZRO NXNIL,+NMXVAR ;Make sure the No Information bit is clear
|
||
MOVX T1,COUBLK ;We have to reset the Buffer Length because
|
||
STOR T1,NFBLN,+NFWBLK ; ECLNMX returned bytes written there.
|
||
MOVE T1,P1 ;Put function code in T1
|
||
XMOVEI T2,NFWBLK ;And NF Block address in T2
|
||
CALL DNDNMX ;Call the End Communication Layer
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block Address
|
||
LOAD T2,NFBLN,+NFWBLK ;and the # of words written
|
||
CALLRET PRSCBK ;Go parse the counter block
|
||
|
||
SUBTTL PRSLNC - Process Line Counters
|
||
;Show (and maybe Zero) Line counters
|
||
;Call
|
||
; T1/ Function Code
|
||
; NFWBLK is all set up for call to DNDNMX
|
||
;Return
|
||
; RET on error
|
||
; RETSKP on success
|
||
|
||
PRSLNC:
|
||
XMOVEI T2,NFWBLK ;And NF Block address in T2
|
||
CALL DNDNMX ;Call the Data Link Layer
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block Address
|
||
LOAD T2,NFBLN,+NFWBLK ;and the # of words written
|
||
CALLRET PRSCBK ;Go parse the counter block
|
||
|
||
SUBTTL Parse Counter block and build NICE response
|
||
;PRSCBK - Parse the counter block passed back from a DECnet layer
|
||
;
|
||
;Call
|
||
; T1/ Counter Block Address
|
||
; T2/ Number of words written in block
|
||
;Return
|
||
; RET ;If error
|
||
; RETSKP ;If counter block handled OK
|
||
;
|
||
|
||
PRSCBK:
|
||
JN NXNIL,+NMXVAR,RSKP ;If Layer didn't know about him, ignore it.
|
||
JE NXWUS,+NMXVAR,RSKP ;IF NOT WRITING TO THE USER, RETURN
|
||
SAVEAC <P1,P2> ;P1<=Block Addr., P2<= # of words
|
||
MOVE P1,T1
|
||
MOVE P2,T2
|
||
COULOP: LOAD T1,KBWID,(P1) ;GET COUNTER SIZE
|
||
CAXN T1,40 ;IS IT SIZE 32.
|
||
MOVX T1,30 ;NICE WANTS IT TO GET A 30 (octal)
|
||
ASH T1,^D10 ;SHIFT IT INTO WIDTH FIELD OF HEADER FIELD
|
||
TXO T1,1_^D15 ;TURN ON BIT INDICATING A COUNTER HEADER
|
||
TMNE KBBMF,(P1) ;Check for a Bit Mask Field, skip if none
|
||
TXO T1,1_^D12 ;set "Bit Mask" bit
|
||
LOAD T2,KBTYP,(P1) ;GET SEQUENCE NUMBER OF PARAMETER OR COUNTER
|
||
IOR T1,T2 ;OR INTO HEADER DUO-BYTE
|
||
CALL PUT2BT ;PUT 2 BYTES OF HEADER INTO USER DATA STRING
|
||
RET ;error...
|
||
TMNE KBBMF,(P1) ;Skip over code that puts in Bit mask, if none
|
||
IFNSK.
|
||
LOAD T1,KBMSK,(P1) ;Get the Bit mask from the Counter Block
|
||
CALL PUT2BT ;Put 2 bytes of bit mask into user data string
|
||
RET ;error...
|
||
ENDIF.
|
||
NOBITM: LOAD T1,KBWID,(P1) ;Get the counter width
|
||
MOVX T2,1 ;we are going to calculate overflow value in T2
|
||
LSH T2,(T1) ;Shift over counter width times, decrement
|
||
SUBI T2,1 ; to get Max Counter value, and complement
|
||
SETCA T2,T2 ; it to get the bits that should not be set.
|
||
LOAD T1,KBVAL,(P1) ;Now get the 36-bit counter value returned
|
||
TDNE T1,T2 ;Skip if we do not have a counter overflow.
|
||
IFNSK.
|
||
SETCA T2,T2 ;Set the mask back to the Max Counter value
|
||
STOR T2,KBVAL,(P1) ;Put max value into counter block
|
||
;Now go and store the counter value
|
||
ENDIF.
|
||
STORCV: LOAD T2,KBWID,(P1) ;GET NUMBER OF BYTES FOR COUNTER AGAIN
|
||
LOAD T1,KBVAL,(P1) ;GET VALUE TO RETURN
|
||
ASH T2,-3 ;Right justify width
|
||
CAXL T2,1 ;MUST BE AT LEAST ONE BYTE
|
||
CAXLE T2,4 ;MAY BE AT MOST 4 BYTES
|
||
COULNE: BUG.(CHK,NTMBCL,NTMAN,SOFT,<Bad counter byte length>,,<
|
||
|
||
Cause: While generating output for a numeric field, there has been a
|
||
request to generate an illegal number of bytes.
|
||
>,NTEMPE)
|
||
CALL <-1>+@[IFIW <PUTBYT&777777> ;PUT A SINGLE BYTE
|
||
IFIW <PUT2BT&777777> ;PUT A DUO BYTE
|
||
IFIW <COULNE&777777> ;DO THREE BYTES. ILLEGAL
|
||
IFIW <PUT4BT&777777>](T2) ;4 BYTES.
|
||
RET ;error...
|
||
JE KBBMF,(P1),ADDTWO ;Skip over code for Bit Masks
|
||
SKIPA T1,[3] ;Three words if Bit Mask was included
|
||
ADDTWO: MOVX T1,2 ;Only two words if no bit mask
|
||
ADD P1,T1 ;Move the address pointer down the block
|
||
SUB P2,T1 ;decrement the count of words in buffer
|
||
JUMPG P2,COULOP ;do more counters if any left
|
||
SKIPE P2 ;Count is zero, OK
|
||
BUG.(CHK,NTMCBL,NTMAN,SOFT,<Bad Counter Block length>,,<
|
||
|
||
Cause: A DECnet Layer has returned an invalid length for a
|
||
Counter Block.
|
||
>,NTEMPE)
|
||
|
||
RETSKP
|
||
|
||
SUBTTL Functions -- .NTSHO -- Select parameters to return
|
||
;SELITM - Select items from list of parameters for an entity, and
|
||
; write their values to the user string
|
||
;Call
|
||
; P1/ Type of entity
|
||
;Return
|
||
; RET ;on error, NXERR contains code
|
||
; RETSKP ;success, all info for this entity in string
|
||
;
|
||
|
||
SELITM:
|
||
SAVEAC <P1,P2,P3,NT> ;GET SOME WORK REGISTERS
|
||
LOAD T1,NXSEL,+NMXVAR ;GET SELECTION CRITERIA
|
||
CAXL T1,.NTSUM ;RANGE CHECK SELECTION CRITERIA
|
||
CAXLE T1,.NTCST ;CIRCUIT STATE IS HIGHEST.
|
||
BUG.(CHK,NTMSOR,NTMAN,SOFT,<Selection criteria is out of range>,,<
|
||
|
||
Cause: The criteria is out of range for selecting items to return (for .NTSHO)
|
||
dependent on the selection criteria.
|
||
|
||
Action: Fix the check in GETBLK or find out who is trashing field NXSEL
|
||
>,NTEUFO)
|
||
CAXN T1,.NTCOU ;IS THIS SHOW COUNTERS?
|
||
JRST PRSCOU ;Yes, jump to Counter Processing Routine
|
||
MOVE NT,PRMP(P1) ;NOPE, GET POINTER TO PARAMETERS
|
||
MOVE P1,<-.NTSUM>+[NTI.% ;SUMMARY BIT
|
||
NTI.S ;STATUS BIT
|
||
NTI.C ;CHARACTERISTICS BIT
|
||
NTI.N ;NOOP (COUNTERS NOT HANDLED HERE)
|
||
NTI.N ;NOOP (EVENTS NOT HANDLED HERE)
|
||
NTI.K](T1) ;CIRCUIT STATE BIT
|
||
LOAD T1,NXNTY,+NMXVAR ;GET NODE TYPE (REMOTE, EXECUTOR...)
|
||
CAXL T1,0 ;RANGE CHECK NODE TYPE (LOWEST IS NONE)
|
||
CAXLE T1,NX.LPN ;LOOPBACK IS HIGHEST YET.
|
||
BUG.(CHK,NTMNTR,NTMAN,SOFT,<Node type is out of range>,,<
|
||
|
||
Cause: It is necessary to know the node type (executor,remote, or loop)
|
||
to select entries to return (for function .NTSHO). Other entities
|
||
(circuit, lines) should have this field zero. This field is set by
|
||
ENTCVT.
|
||
>,NTEMPE)
|
||
MOVE P2,[NTAPL ;NO NODE TYPE, DO THEM ALL
|
||
NTA.E ;BIT INDICATING APPLIES TO EXECUTOR NODE
|
||
NTA.R ;APPLIES TO REMOTE NODES
|
||
NTA.L](T1) ;APPLIES TO LOOPBACK NODES
|
||
|
||
LOAD T1,NXLTY,+NMXVAR ;GET LINE TYPE (CI, NI, DTE,...)
|
||
CAXL T1,0 ;RANGE CHECK LINE TYPE (LOWEST IS NONE)
|
||
CAXLE T1,NX.DMR ;DMR IS HIGHEST.
|
||
BUG.(CHK,NTMLTR,NTMAN,SOFT,<Line type is out of range>,,<
|
||
|
||
Cause: To determine entries to return (for function .NTSHO),
|
||
it is necessary to know the Line type (CI,NI,DTE,...).
|
||
Other entities (Nodes,Modules) should have this field
|
||
zero. This field is set by ENTCVT.
|
||
>,NTEMPE)
|
||
MOVE P3,[NTDEV ;NO LINE TYPE, DO THEM ALL
|
||
NTD.D ;APPLIES TO DTE'S
|
||
NTD.K ;APPLIES TO KDP'S
|
||
NTD.P ;DDP'S
|
||
NTD.C ;CI'S
|
||
NTD.N ;NI'S
|
||
NTD.R](T1) ;DMR'S
|
||
|
||
SELIT4: JUMPGE NT,RSKP ;WHEN DONE, RETURN SUCCESS
|
||
LOAD T2,NXENT,+NMXVAR ;Get the Entity Type
|
||
CAXE T2,.NTNOD ;Is it a NODE Entity?
|
||
IFSKP.
|
||
CALL LOCARE ;Yes, go get Home Area number
|
||
JRST NTEERR
|
||
LOAD T2,NXNUM,+NMXVAR ;Get the Node address from the user
|
||
TXZ T2,RN%NOD ;Get just the AREA Number
|
||
LSH T2,-^D10 ; Right justify
|
||
CAMN T1,T2 ;Is the requested node in the Home Area?
|
||
IFSKP. ;No, Check if parameter is for Home Area only
|
||
MOVX T1,NTA.H ;Put Home Area Only flag into T1
|
||
TDNE T1,NT.APL(NT) ;Check Parameter applicabilty
|
||
JRST SELIT6
|
||
ENDIF.
|
||
ENDIF.
|
||
TDNE P1,NT.INF(NT) ;DOES THIS MATCH OUR SELECTION CRITERIA?
|
||
TDNN P2,NT.APL(NT) ;AND DOES THIS APPLY TO US?
|
||
SKIPA ;NOPE. SKIP OVER IT
|
||
TDNN P3,NT.DEV(NT) ;Does it apply to this device?
|
||
JRST SELIT6 ;NOPE. SKIP OVER IT
|
||
MOVX T1,NTI.Q ;Get the 'Qualified Parameter' bit flag
|
||
TDNE T1,NT.INF(NT) ;Skip if this parameter is not qualified
|
||
IFSKP.
|
||
CALL SHOPRM ;Go SHOW QUALIFIED PARAMETER
|
||
RET ;Error return...
|
||
ELSE.
|
||
CALL SHOQUP ;YEP. DO THIS PARAMETER
|
||
RET ;error, punt...
|
||
ENDIF.
|
||
SELIT6: ADD NT,[1,,NT.LST] ;POINT TO NEXT ITEM ON LIST
|
||
JRST SELIT4 ;GO TRY FOR THIS NEW ITEM
|
||
SUBTTL Functions -- Get the Qualifier values, for a Qualified Parameter
|
||
;SHOQUP - Show qualified Parameter.
|
||
|
||
SHOQUP: SAVEAC <P1,P2,P3,P4,NT>
|
||
LOAD T1,NXENT,+NMXVAR ;Get the Entity Type Back
|
||
MOVE P1,NT ;Save the Qualified Parameter table entry
|
||
MOVE NT,PRMP(T1) ;Get the pointer to top of the parameter table
|
||
LOAD T1,NTQUA,(P1) ;Get the Qualifier Parameter Number
|
||
|
||
SHOQU1: JUMPGE NT,NTEMPE ;If we hit the end of table, we have an error
|
||
LOAD T2,NTSEQ,(NT) ;Get a Sequence number
|
||
CAME T1,T2 ;Is it our Qualifier????
|
||
IFNSK.
|
||
ADD NT,[1,,NT.LST] ;NO! Get next entry in table
|
||
JRST SHOQU1 ;And loop until we find it....
|
||
ENDIF.
|
||
MOVE T1,NT ;Get the Table Entry address for the Qualifier
|
||
CALL SETNFB ;Set up the NF Block
|
||
RET ;error
|
||
MOVX T1,NF.RED ;Set up READ function code
|
||
XMOVEI T2,NFWBLK ;And the argument block goes into T2
|
||
LOAD T3,NTROU,(NT) ;GET ROUTINE FOR THIS PARAMETER
|
||
CALL NMXLAY ;CALL LAYER-LEVEL ROUTINE TO DO PARAMETER
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
JE NFBFF,+NFWBLK,ONEQUA ;Jump if only One qualifier, (i.e no buffer)
|
||
LOAD P2,NFBUF,+NFWBLK ;Get the buffer address back into P2
|
||
MOVE P4,P2 ;Keep the head of the buffer address in P4
|
||
LOAD P3,NFBLN,+NFWBLK ;And the number of words written...
|
||
JUMPE P3,SHOQU3 ;Jump if no values returned
|
||
SETZRO NFBFF,+NFWBLK ;indicate no buffer present.
|
||
SHOQU2: MOVE T1,(P2) ;Get the first Qualifier value
|
||
STOR T1,NFBUF,+NFWBLK ;Put the value into the Buffer/value field
|
||
CALL NMXWTY ;Write qualifier value to user buffer
|
||
IFNSK.
|
||
MOVE T1,P4 ;Get the buffer address back into T1
|
||
CALL DNFWDS ;And return buffer
|
||
RET
|
||
ENDIF.
|
||
EXCH NT,P1 ;Get the Qualified parameter table entry
|
||
MOVE T1,NT ;Put the Parameter Table Entry address into T1
|
||
CALL SETNFB ;Set up the Interface Block
|
||
IFNSK.
|
||
MOVE T1,P4 ;Get the buffer address back into T1
|
||
CALL DNFWDS ;Deallocate it.
|
||
RET ;error return, buffer has been deallocated
|
||
ENDIF.
|
||
MOVE T1,(P2) ;Get the first Qualifier value again
|
||
STOR T1,NFQUA,+NFWBLK ;Store it in the Qualifier Field
|
||
SETONE NFQUF,+NFWBLK ;Flag we are sending a qualifier
|
||
MOVX T1,NF.RED ;Set up READ function code
|
||
XMOVEI T2,NFWBLK ;And the argument block goes into T2
|
||
LOAD T3,NTROU,(NT) ;GET ROUTINE FOR THIS PARAMETER
|
||
CALL NMXLAY ;CALL LAYER-LEVEL ROUTINE TO DO PARAMETER
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
IFNSK.
|
||
STOR P4,NFBUF,+NFWBLK ;Put buffer back in NFWBLK
|
||
SETONE NFBFF,+NFWBLK ;NTEERR will deallocate buffer for us
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
ENDIF.
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
CALL NMXWTY ;WRITE STRING OUT TO USER IN APPROPRIATE FORMAT
|
||
IFNSK.
|
||
MOVE T1,P4 ;Get the buffer address back into T1
|
||
CALL DNFWDS ;Deallocate it.
|
||
RET ;error return, buffer has been deallocated
|
||
ENDIF.
|
||
EXCH NT,P1 ;Get the Qualifier parameter table entry
|
||
AOJ P2, ;Increment the buffer pointer
|
||
SOJG P3,SHOQU2 ;Jump if more qualifiers
|
||
SHOQU3: MOVE T1,P4 ;Get the buffer address back
|
||
CALL DNFWDS ;Deallocate the buffer
|
||
RETSKP
|
||
|
||
ONEQUA: JN NXNIL,+NMXVAR,RSKP ;Return if layer didn't know about Qualifier
|
||
CALL NMXWTY ;Write qualifier value to user string
|
||
RET ;Error return...
|
||
EXCH NT,P1 ;Get the Qualified Parameter table entry
|
||
LOAD P1,NFBUF,+NFWBLK ;Save the Qualifier value
|
||
MOVE T1,NT ;Now put it into T1
|
||
CALL SETNFB ;Set up the NFWBLK
|
||
RET
|
||
STOR P1,NFQUA,+NFWBLK ;Store it in the Qualifier Field
|
||
SETONE NFQUF,+NFWBLK ;Flag we are sending a qualifier
|
||
JRST SHOPR1 ;And jump into SHOPRM
|
||
|
||
SUBTTL Functions -- .NTSHO -- Return parameters to user
|
||
;SHOPRM - Process a parameter, and put into user data string
|
||
|
||
SHOPRM: SAVEAC <P1,P2,NT,TM> ;SAVE A BUNCH OF ACS (TRASHED IN CM HANDLING)
|
||
MOVE T1,NT ;Put the Parameter Table Entry address into T1
|
||
CALL SETNFB ;Set up the Interface Block
|
||
RET
|
||
SHOPR1: MOVX T1,NF.RED ;Set up READ function code
|
||
XMOVEI T2,NFWBLK ;And the argument block goes into T2
|
||
LOAD T3,NTROU,(NT) ;GET ROUTINE FOR THIS PARAMETER
|
||
CALL NMXLAY ;CALL LAYER-LEVEL ROUTINE TO DO PARAMETER
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
SETONE NXNIL,+NMXVAR ;Indicate no info returned, but no error
|
||
ENDIF.
|
||
CALL NMXWTY ;WRITE STRING OUT TO USER IN APPROPRIATE FORMAT
|
||
RET ; error return
|
||
JE NFBFF,+NFWBLK,RSKP ;If no buffer,we are finished
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the buffer address
|
||
CALL DNFWDS ;Deallocate it
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RETSKP ;FINISHED
|
||
|
||
|
||
;Setup NMX Interface Block
|
||
;Call:
|
||
; T1/ Address of a Parameter Table Entry
|
||
;Return
|
||
;
|
||
; RET error return
|
||
; RETSKP NFWBLK/ All set up for a call to a DECnet Layer
|
||
;
|
||
SETNFB: SAVEAC <NT> ;Preserve NT
|
||
MOVE NT,T1 ;Put parameter table entry address here
|
||
SETZM NFWBLK ;CLEAN FIRST WORD OF BLOCK
|
||
HRRI T2,1+NFWBLK ;GET POINTER TO SECOND WORD IN BLOCK
|
||
HRLI T2,NFWBLK ;POINT AT START OF BLOCK
|
||
BLT T2,NF.LST-1+NFWBLK ;CLEAN UNTIL END OF BLOCK
|
||
LOAD T1,NXNUM,+NMXVAR ;Get the converted Entity Id
|
||
STOR T1,NFEID,+NFWBLK ;Put it int the argument block
|
||
LOAD T1,NTSEQ,(NT) ;Get the parameter type (number) from the table
|
||
STOR T1,NFPRM,+NFWBLK ;and into the argument block
|
||
LOAD T1,NXENT,+NMXVAR ;We need the Entity type
|
||
STOR T1,NFETY,+NFWBLK ;save it...
|
||
JE NTBUF,(NT),SETNF1 ;Does this Parameter require a buffer
|
||
LOAD T1,NTBSZ,(NT) ;Yes, get the size needed from table
|
||
STOR T1,NFBLN,+NFWBLK ;Put it into the argument block
|
||
CALL DNGWDS ;Go allocate the block
|
||
ERRRET NTERES ;No memory available, resource error
|
||
STOR T1,NFBUF,+NFWBLK ;Put the buffer addr into the arg block
|
||
SETONE NFBFF,+NFWBLK ;And tell Layer to expect a buffer
|
||
RETSKP
|
||
|
||
SETNF1: SETZRO NFBFF,+NFWBLK ;No buffer in this case.
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the buffer address
|
||
RETSKP
|
||
|
||
SUBTTL Functions -- .NTRET -- List node names
|
||
;NMXLND - List a series of node names. Function .NTRET
|
||
;Call
|
||
; NMXVAR/ NX block
|
||
;Return
|
||
; RET ;On error, error code loaded into NXERR,+NMXVAR
|
||
; RETSKP ;Success, with user's data string containing list
|
||
|
||
NMXLND:
|
||
SAVEAC <P1,P2,NT> ;I NEED A LOT OF ACS
|
||
MOVX T1,.NTNOD ;Get the NODE ENTITY TYPE code
|
||
STOR T1,NFETY,+NFWBLK ;Put it into the Arg Block
|
||
SETZ NT, ;FLAG NOTHING SPECIAL YET
|
||
LOAD P1,NXSEL,+NMXVAR ;FIND OUT WHAT KIND OF LIST HE WANTS
|
||
STOR P1,NFSEL,+NFWBLK ;Put it into the NF Block
|
||
CAXL P1,.NTSGN ;Range Check the Selection Criteria
|
||
CAXLE P1,.NTKNO ;If not between SIGNIFICANT & KNOW
|
||
JRST NTEUFO ; it is an error
|
||
JRST <-.NTSGN>+@[
|
||
IFIW <NTEUFO&777777> ;SIGNIFICANT nodes not supported
|
||
IFIW <NMXLAD&777777> ;ADJACENT nodes
|
||
IFIW <NMXLLN&777777> ;LOOP Nodes
|
||
IFIW <NMXLAC&777777> ;ACTIVE Nodes
|
||
IFIW <NMXLNA&777777>](P1) ;KNOWN Nodes
|
||
|
||
|
||
NMXLNA: CALL GETEBY ;Get the Area Number user wants
|
||
RET ;Error return
|
||
STOR T1,NFEID,+NFWBLK ;Put it into the Argument Block
|
||
MOVE NT,T1 ;And save it in a register for now
|
||
CALL LOCARE ;Get the local Node Id
|
||
RET ;Error Return
|
||
CAME T1,NT ;Does user want the Home Area????
|
||
JRST NMXLFA ;No, go ask Session Control
|
||
MOVX T1,NDBLEN ;Length of a Node Bffer
|
||
CALL DNGWZP ;Get a Zeroed Buffer (Low Priority)
|
||
JRST NTERES ;Resource Error
|
||
STOR T1,NFBUF,+NFWBLK ;Put it into the arg block
|
||
SETONE NFBFF,+NFWBLK ;Tell the layers we are giving them a buffer
|
||
MOVX T1,NDBLEN ;Get the buffer length
|
||
STOR T1,NFBLN,+NFWBLK ;So the layer knows how long it is.
|
||
MOVX T1,NF.RET ;Get the function code
|
||
XMOVEI T2,NFWBLK ;and the Arg Block address
|
||
CALL SCLNMX ;Ask Session Control for KNOWN NODES
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;and go report the error
|
||
JRST NMXLA2 ;Return OK, No Data....
|
||
ENDIF.
|
||
MOVX T1,NF.RET ;Get the function code
|
||
XMOVEI T2,NFWBLK ;and the Arg Block address
|
||
CALL RTRNMX ;Ask Routing Layer for KNOWN NODES
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;and go report the error
|
||
JRST NMXLA2 ;Return OK, No Data....
|
||
ENDIF.
|
||
|
||
LOAD P2,NFBUF,+NFWBLK ;Get the buffer address into P2
|
||
ADDI P2,1 ;START AT NODE NUMBER 1
|
||
NMXLN2: LOAD T1,NFBUF,+NFWBLK ;Get Buffer address
|
||
ADDI T1,<NDBLEN-1> ;Find the end of the buffer
|
||
CAMLE P2,T1 ;HAVE WE PASSED THE MAXIMUM NODE NUMBER?
|
||
IFNSK.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block
|
||
CALL DNFWDS ;Free up memory
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
JRST RSKP ;Yes, we are all done
|
||
ENDIF.
|
||
MOVE T1,(P2) ;Get the contents of this cell
|
||
SKIPN T1 ;Are the contents zero???
|
||
AOJA P2,NMXLN2 ;If so increment index, and loop
|
||
CALL PUT2BT ;PUT NODE NUMBER IN DATA STRING
|
||
RET
|
||
SETZ T1, ;NO NAME FOLLOWING, SO A ZERO STRINGID HEAD
|
||
CALL PUTBYT ;PUT BYTE IN DATA STRING
|
||
RET
|
||
AOJA P2,NMXLN2 ;GO DO ANOTHER NODE
|
||
|
||
;Ask Session Control for KNOWN NODES in a Specific area, other than
|
||
;the Home area.
|
||
NMXLFA:
|
||
LOAD T1,NXDAT,+BP.BPT+NMXVAR ;Get the Byte pointer to the user buffer
|
||
STOR T1,NFBPT,+NFWBLK ;Put it into the Arg block
|
||
LOAD T1,NXDAT,+BP.BYT+NMXVAR ;Get the number of bytes in the user buf.
|
||
STOR T1,NFBLN,+NFWBLK ;Send it to Session control
|
||
SETONE NFUBF,+NFWBLK ;Flag it is a user buffer
|
||
MOVX T1,NF.RET ;Get the function code
|
||
XMOVEI T2,NFWBLK ;and the Arg Block address
|
||
CALL SCLNMX ;Ask Session Control for Known Nodes
|
||
JRST NTEERR ;Report error and deallocate buffer
|
||
SETZRO NFUBF,+NFWBLK ;Get rid of the User buffer flag
|
||
LOAD T1,NFBPT,+NFWBLK ;Get the byte pointer back
|
||
STOR T1,NXDAT,+BP.BPT+NMXVAR ;Put it back where NTMAN expects it
|
||
LOAD T1,NFBLN,+NFWBLK ;And the updated count
|
||
STOR T1,NXDAT,+BP.BYT+NMXVAR ;And save it again
|
||
RETSKP ;return success
|
||
;Ask Session Control for LOOP NODES
|
||
|
||
NMXLLN: MOVX T1,LPNBLK ;Get the size of a LOOP NODE Block
|
||
STOR T1,NFBLN,+NFWBLK ;Copy it into NFWBLK
|
||
CALL DNGWDS ;Get buffer of that length
|
||
ERRRET NTERES ;Resource Error
|
||
STOR T1,NFBUF,+NFWBLK ;Put Buffer Address into NFWBLK
|
||
SETONE NFBFF,+NFWBLK ;Flag that we sre sending a buffer to the layer
|
||
MOVX T1,.NTNOD ;Get the NODE ENTITY TYPE code
|
||
STOR T1,NFETY,+NFWBLK ;Put it into the Arg Block
|
||
MOVX T1,NF.RET ;Get the function code
|
||
XMOVEI T2,NFWBLK ;and the Arg Block address
|
||
CALL SCLNMX ;Ask Session Control for LOOP NODES
|
||
JRST NTEERR ;Report error and Deallocate buffer
|
||
LOAD NT,NFBUF,+NFWBLK ;Get the Buffer address back
|
||
LOAD P2,NFBLN,+NFWBLK ;Get the number of words written into buffer
|
||
JUMPE P2,NMXLN6 ;Jump if no Loop nodes returned...
|
||
NMXLN5: MOVE T1,(NT) ;Get the name
|
||
CALL NMXS2A ;Convert Node name to ASCII and save in NMXVAR
|
||
SETZ T1, ;NO NUMBER
|
||
CALL PUT2BT ;PUT TWO BYTES IN STREAM INDICATING NO NUMBER
|
||
RET
|
||
XMOVEI P1,NX.VAL+NMXVAR ;POINT TO THE WHERE THE NODE STRING IS
|
||
CALL PUTSTR ;COPY THE STRING TO THE USER
|
||
RET
|
||
SOSLE P2 ;Decrement count of Circuits and skip if done
|
||
AOJA NT,NMXLN5 ;Increment Buffer pointer and do next Node
|
||
NMXLN6: LOAD T1,NFBUF,+NFWBLK ;Get the Buffer Address
|
||
CALL DNFWDS ;Return the block
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RETSKP ;return success
|
||
|
||
;Ask Routing Layer for ACTIVE or ADJACENT NODES.
|
||
|
||
NMXLAD:
|
||
NMXLAC: SAVEAC <P1,P2>
|
||
MOVX T1,NDBLEN ;Length of a Node Bffer
|
||
CALL DNGWZP ;Get a Zeroed Buffer (Low Priority)
|
||
JRST NTERES ;Resource Error
|
||
STOR T1,NFBUF,+NFWBLK ;Put it into the arg block
|
||
SETONE NFBFF,+NFWBLK ;Tell the layers we are giving them a buffer
|
||
MOVX T1,NDBLEN ;Get the buffer length
|
||
STOR T1,NFBLN,+NFWBLK ;So the layer knows how long it is.
|
||
MOVX T1,NF.RET ;Get the function code
|
||
XMOVEI T2,NFWBLK ;and the Arg Block address
|
||
CALL RTRNMX ;Ask Session Control for Known Nodes
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;and go report the error
|
||
JRST NMXLA2 ;Return OK, No Data....
|
||
ENDIF.
|
||
LOAD P1,NFBUF,+NFWBLK ;Get the buffer address
|
||
LOAD P2,NFBLN,+NFWBLK ;And the number of node numbers written
|
||
JUMPE P2,NMXLA2 ;Jump if the count is zero
|
||
NMXLA1: MOVE T1,(P1) ;Get a node number
|
||
CALL PUT2BT
|
||
RET
|
||
SETZ T1,
|
||
CALL PUTBYT
|
||
RET
|
||
AOJ P1,
|
||
SOJG P2,NMXLA1
|
||
NMXLA2: LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block
|
||
CALL DNFWDS ;Free up memory
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RETSKP ;return success
|
||
|
||
SUBTTL Functions -- .NTRET -- List circuit and line names
|
||
;NMXLCK - Return a list of line/circuit names
|
||
;Call
|
||
; NMXVAR/ NX block
|
||
; P1/ Entity Type (LINE or CIRCUIT)
|
||
;Return
|
||
; RET ;ON ERROR, NXERR,+NMXVAR CONTAINING ERROR CODE
|
||
; RETSKP ;WITH LIST OF NAMES IN USER DATA STRING
|
||
|
||
NMXLCK:
|
||
SAVEAC <P1,P2,NT>
|
||
STOR P1,NFETY,+NFWBLK ;Put entity Type into NFWBLK
|
||
LOAD T1,NXSEL,+NMXVAR ;Get the Selector
|
||
STOR T1,NFSEL,+NFWBLK ;Copy it into NFWBLK
|
||
MOVX T1,CIRBLK ;Get the size of a return-circuits block
|
||
STOR T1,NFBLN,+NFWBLK ;Copy it into NFWBLK
|
||
CALL DNGWDS ;Get buffer of that length
|
||
ERRRET NTERES ;Resource Error
|
||
STOR T1,NFBUF,+NFWBLK ;Put Buffer Address into NFWBLK
|
||
SETONE NFBFF,+NFWBLK ;Flag that we sre sending a buffer to the layer
|
||
MOVX T1,NF.RET ;Set up the function code
|
||
XMOVEI T2,NFWBLK ;Get the buffer address into T2
|
||
CAXE P1,.NTLIN ;Is the Entity Type a LINE??
|
||
IFSKP.
|
||
CALL DNDNMX ;Go ask DNADLL for the circuit ids
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
JRST NMXLC5 ;No data returned, but no error...
|
||
ENDIF.
|
||
ELSE.
|
||
CALL RTRNMX ;Go ask Router for the circuit ids
|
||
IFNSK.
|
||
SKIPE T1 ;Is there 'error' return zero??
|
||
JRST NTEERR ;No. Report error and deallo buffer if there
|
||
JRST NMXLC5 ;No data returned, but no error...
|
||
ENDIF.
|
||
ENDIF.
|
||
LOAD NT,NFBUF,+NFWBLK ;Get back the buffer address
|
||
LOAD P2,NFBLN,+NFWBLK ;and the number of words returned
|
||
JUMPLE P2,NMXLC5 ;If none (or less than none), do nothing.
|
||
NMXLC4: MOVE T1,(NT) ;Get the Circuit Id
|
||
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;DATA STORAGE AREA
|
||
CALL NMXC2N ;CONVERT CIRCUIT-ID TO NAME
|
||
JRST NTEMPE ;ERROR!
|
||
XMOVEI P1,NX.VAL+NMXVAR ;POINT TO THE CIRCUIT NAME STRINGID
|
||
CALL PUTSTR ;PUT THIS STRING IN THE USER'S BUFFER
|
||
RET ;error
|
||
SOSLE P2 ;Decrement count of Circuits and skip if done
|
||
AOJA NT,NMXLC4 ;Increment Buffer pointer and do next circuit
|
||
NMXLC5: LOAD T1,NFBUF,+NFWBLK ;Get the Buffer Address
|
||
CALL DNFWDS ;Return the block
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RETSKP ;return success
|
||
|
||
SUBTTL Entities -- Convert entity names to entity ids
|
||
|
||
;Called from NMXDIS
|
||
|
||
ENTCVT: SETZRO NXNTY,+NMXVAR ;NO NODE AS OF YET
|
||
SETZRO NXLTY,+NMXVAR ;NO LINE AS OF YET
|
||
CALLRET @.+1-.NTNOD(P1)
|
||
IFIW <NODCVT&777777> ;CONVERT NODE TYPE
|
||
IFIW <LINCVT&777777> ;LINE TYPE
|
||
IFIW <NTEURC&777777> ;LOGGING. PUNT, WE DON'T DO THESE
|
||
IFIW <CIRCVT&777777> ;SAME AS LINE
|
||
IFIW <NTEURC&777777> ;MODULE - ILLEGAL
|
||
IFIW <NTEURC&777777> ;ILLEGAL.
|
||
|
||
|
||
;Called from ENTCVT
|
||
|
||
NODCVT:
|
||
SAVEAC <P1> ;NEED FOR TEMP BYTE STORAGE
|
||
CALL GETEBY ;GET ENTITY STRING BYTE
|
||
RET
|
||
MOVE P1,T1 ;SAVE THE BYTE FOR A WHILE
|
||
CALL GETEBY ;GET ANOTHER BYTE
|
||
RET
|
||
ASH T1,^D8 ;SHIFT HIGH-ORDER BYTE OVER
|
||
IOR P1,T1 ;INCLUDE LOW ORDER BYTE
|
||
JUMPN P1,NODCVX ;IF WE HAVE AN ADDRESS, WE ARE OK
|
||
CALL GETSTI ;NO ADDRESS, I MUST HAVE A NAME
|
||
RET
|
||
CALL NMXN2A ;CONVERT THE NAME TO AN ADDRESS.
|
||
JRST NODCV2 ;NO SUCH NAME, MUST BE LOOPBACK
|
||
MOVE P1,T1 ;Need the address in P1 now.
|
||
JRST NODCV0
|
||
|
||
NODCVX: MOVE T1,P1 ;Get the node number back
|
||
ASH T1,-<^D10> ;Get just the AREA Number
|
||
JUMPN T1,NODCV0 ;Jump if AREA is non-zero
|
||
CALL LOCARE ;Get the Local Area Number
|
||
RET
|
||
ASH T1,^D10 ;Shift it over to the right position
|
||
IOR P1,T1 ;And or it into the node number
|
||
NODCV0: STOR P1,NXNUM,+NMXVAR ;SAVE IN ARGUMENT BLOCK
|
||
CALL LOCNID ;Get our Node address, returned in T1
|
||
RET ;Error, give up...
|
||
LOAD T2,NXNUM,+NMXVAR ;Get back the address we are working on
|
||
CAME T2,T1 ;IS THIS US?
|
||
JRST NODCV1 ;NOPE
|
||
MOVX T1,NX.EXN ;THIS IS THE EXECUTOR NODE
|
||
STOR T1,NXNTY,+NMXVAR ;DECLARE TYPE OF NODE
|
||
RETSKP ;WE'RE DONE, RETURN
|
||
NODCV1: MOVX T1,NX.REN ;THIS IS A REMOTE NODE
|
||
STOR T1,NXNTY,+NMXVAR ;DECLARE THAT THIS IS A NODE, AND WHAT TYPE
|
||
RETSKP
|
||
|
||
;Come here only for loop nodes after a fail return from NMXN2A. The latter
|
||
; routine will have written an error code into NXERR that needs to be cleared.
|
||
NODCV2: SETZRO NXERR,+NMXVAR ;Clear error code from NMXN2A
|
||
LOAD T2,NXFNC,+NMXVAR ;GET THE FUNCTION CODE WE ARE TO DO
|
||
CAXE T2,.NTSET ;Is this a set?
|
||
IFNSK.
|
||
MOVX T1,.NTNOD ;Get the Node Entity type code
|
||
STOR T1,NFETY,+NFWBLK ;Put it into the Arg block
|
||
MOVX T1,NF.CKL ;Check Loopback Node function
|
||
XMOVEI T2,NFWBLK ;Get the Argument Block
|
||
CALL SCLNMX ;Go ask Session Control if Loopback Node Exists
|
||
JRST NTEERR ;No it doesn't, go handle error
|
||
ENDIF.
|
||
LOAD T1,NFEID,+NFWBLK ;Get the Node Name back from the Block
|
||
STOR T1,NXNUM,+NMXVAR ;SAVE THE NODNAME IN NXNUM
|
||
MOVX T1,NX.LPN ;THIS IS A LOOPBACK NODE
|
||
STOR T1,NXNTY,+NMXVAR ;SAVE THE NODE TYPE
|
||
RETSKP
|
||
|
||
;Called from ENTCVT
|
||
|
||
LINCVT:
|
||
CALL GETSTI ;COPY MULTIPLE BYTES (INTERNAL LIMIT 16)
|
||
RET ;error...
|
||
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO LINE NAME WE COPIED
|
||
CALL NMXN2C ;CONVERT NAME TO LINE-ID
|
||
RET ; error, pass the code back
|
||
SETONE LILXC,+T1 ;Flag that it is a Line Id (not circuit)
|
||
STOR T1,NXNUM,+NMXVAR ;SAVE AWAY LINE ID
|
||
LOAD T2,LIDEV,+T1 ;Get the Device Type Back
|
||
STOR T2,NXLTY,+NMXVAR ;AND INTO THE NMX BLOCK
|
||
STOR T1,NFEID,+NFWBLK ;Put the Line Id into argument block
|
||
LOAD T1,NXENT,+NMXVAR ;Get the entity type
|
||
STOR T1,NFETY,+NFWBLK ;Store it in Arg block
|
||
MOVX T1,NF.CET ;Check Entity Function code into T1
|
||
XMOVEI T2,NFWBLK ;And the Argument Block address into T2
|
||
CALL DNDNMX ;Have the Data Link Layer Verify Line Id
|
||
JRST NTEERR ;Save the error code
|
||
RETSKP ;Return success if not
|
||
|
||
|
||
;Called from ENTCVT
|
||
|
||
CIRCVT:
|
||
CALL GETSTI ;COPY MULTIPLE BYTES (INTERNAL LIMIT 16)
|
||
RET ;error...
|
||
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO LINE NAME WE COPIED
|
||
CALL NMXN2C ;CONVERT NAME TO LINE-ID
|
||
RET ; error, pass the code back
|
||
SETZRO LILXC,+T1 ;Flag that it is a Circuit Id (not Line)
|
||
STOR T1,NXNUM,+NMXVAR ;SAVE AWAY LINE ID
|
||
LOAD T2,LIDEV,+T1 ;Get the Device Type Back
|
||
STOR T2,NXLTY,+NMXVAR ;AND INTO THE NMX BLOCK
|
||
STOR T1,NFEID,+NFWBLK ;Put the Line Id into argument block
|
||
LOAD T1,NXENT,+NMXVAR ;Get the entity type
|
||
STOR T1,NFETY,+NFWBLK ;Store it in Arg block
|
||
MOVX T1,NF.CET ;Check Entity Function code into T1
|
||
XMOVEI T2,NFWBLK ;And the Argument Block address into T2
|
||
CALL DNDNMX ;Have the Data Link Layer Verify Line Id
|
||
JRST NTEERR ;Save the error code
|
||
RETSKP ;Return Success
|
||
|
||
SUBTTL Entities -- Circuit ID to name conversion
|
||
;NMXC2N - Convert circuit ID to name
|
||
;Call
|
||
; T1/ Circuit ID
|
||
; T2/ Local byte pointer to use in returning bytes
|
||
; Area must be large enough to receive 16 bytes.
|
||
;Return
|
||
; +1/ No such circuit ID
|
||
; +2/ Data area has stringid for circuit name
|
||
;
|
||
|
||
NMXC2N::
|
||
SAVEAC <P1,P2> ;SOME SCRATCH ACS
|
||
DMOVE P1,T1 ;SAVE BOTH ARGUMENTS FOR THIS CALL
|
||
SETZ T6, ;NUMBER OF BYTES DEPOSITED
|
||
IDPB T6,P2 ;FIRST BYTE IS COUNT OF BYTES FOLLOWING
|
||
MOVE T5,P2 ;SAVE BYTE POINTER TO COUNT BYTE
|
||
LOAD T1,LIDEV,+P1 ;GET THE TYPE OF DEVICE
|
||
CAXLE T1,LD.MAX ;IN RANGE OF DEVICES WE KNOW?
|
||
BUG.(CHK,NTMKOR,NTMAN,SOFT,<Controller out of range in Circuit-id>,,<
|
||
|
||
Cause: The controller field in a line-id is out of range. The value
|
||
LD.MAX defines the number of controllers known by D36PAR, and
|
||
thus by NTMAN. The most likely cause of this bug is a trashed
|
||
AC.
|
||
Note:
|
||
|
||
A controller is any device driver to which a router will interface.
|
||
It is currently used to define the name of a Circuit/Line,
|
||
under the assumption that each Kontroller will control only
|
||
a single line type.
|
||
|
||
>,RTN)
|
||
;WE KNOW THAT ALL DEVICE NAMES ARE AT MOST 4 BYTES LONG, AND THUS FIT IN A WORD
|
||
HRLI T2,(POINT 7,) ;WE STORE THE DATA IN 7 BIT BYTES INTERNALLY
|
||
HRRI T2,KONNAM(T1) ;GET POINTER TO DEVICE NAME
|
||
NMXC20: ILDB T1,T2 ;GET A BYTE FROM THE DEVICE NAME
|
||
JUMPE T1,NMXC21 ;END OF STRING, FALL THROUGH
|
||
IDPB T1,P2 ;SAVE IT IN OUR DESTINATION DATA STRING
|
||
AOJA T6,NMXC20 ;INCREMENT NUMBER OF BYTES DEPOSITED
|
||
NMXC21: MOVEI T1,"-" ;SEPERATOR
|
||
IDPB T1,P2 ;STORE IT
|
||
AOJ T6, ;COUNT UP CHARACTER
|
||
LOAD T1,LIKON,+P1 ;GET THE KONTROLLER NUMBER
|
||
PUSHJ P,NMXC28 ;OUTPUT NUMBER IN DECIMAL
|
||
IFN FTOPS10,<
|
||
LOAD T1,LIDEV,+P1 ;GET THE DEVICE TYPE
|
||
CAXN T1,LD.ETH ;IS IT AN ETHERNET?
|
||
JRST NMXC22 ;YES, WE ARE DONE
|
||
>; END IFN FTOPS10
|
||
MOVEI T1,"-"
|
||
IDPB T1,P2 ;STORE THE SEPARATOR
|
||
AOJ T6, ;INCREMENT NUMBER OF BYTES
|
||
LOAD T1,LIUNI,+P1 ;GET THE UNIT NUMBER
|
||
PUSHJ P,NMXC28 ;OUTPUT THE NUMBER IN DECIMAL
|
||
JN LILXC,+P1,NMXC22 ;Jump if we are not dealing with a CIRCUIT
|
||
LOAD T1,LIDEV,+P1 ;GET THE DEVICE TYPE
|
||
CAXE T1,LD.CIP ;IS IT A CI?
|
||
JRST NMXC22 ;NO, WE ARE DONE
|
||
MOVEI T1,"." ;OUTPUT SEPERATOR
|
||
IDPB T1,P2 ;STORE IT
|
||
AOJ T6, ;AND INCREMENT COUNT
|
||
LOAD T1,LIDRP,+P1 ;GET THE DROP NUMBER (PORT ON THE CI)
|
||
PUSHJ P,NMXC28 ;AND OUTPUT IT IN DECIMAL
|
||
NMXC22: CAIL T6,^D16 ;DID WE DO THIS IN 16 BYTES?
|
||
BUG.(HLT,NTMCNO,NTMAN,SOFT,<Circuit name overrun>,,<
|
||
|
||
Cause: More than 16 bytes of data have been returned into a 16 byte field.
|
||
The data beyond the buffer has been trashed.
|
||
|
||
Action: Examine the algorithm above to determine why more bytes than
|
||
expected were returned. Fix the above code to check for overrun
|
||
while it is producing the bytes, so that this halt does not occur.
|
||
>)
|
||
DPB T6,T5 ;STORE NUMBER OF BYTES WE GAVE
|
||
RETSKP
|
||
|
||
NMXC28: IDIVI T1,^D10 ;SEPERATE INTO DIGITS
|
||
JUMPE T1,NMXC29 ;COMPLETED THE SEPARATION, START OUTPUTTING.
|
||
PUSH P,T2 ;SAVE DIGIT ON STACK
|
||
PUSHJ P,NMXC28 ;RECURSE
|
||
POP P,T2 ;GET BACK DIGIT
|
||
NMXC29: ADDI T2,"0" ;MAKE IT INTO AN ASCII DIGIT
|
||
IDPB T2,P2 ;DEPOSIT INTO STRING
|
||
AOJ T6, ;INCREMENT NUMBER OF BYTES GIVEN
|
||
RET ;RETURN
|
||
SUBTTL Entities -- Convert name to Circuit-ID.
|
||
;NMXN2C - Convert a string to line id
|
||
;Call
|
||
; T1/ Byte pointer to name
|
||
;Return
|
||
; +1, No such circuit
|
||
; +2, t1/ Circuit ID
|
||
|
||
NMXN2C:
|
||
SAVEAC <P1,P2> ;WORK REGISTERS
|
||
MOVE P1,T1 ;SAVE BYTE POINTER TO NAME
|
||
MOVE T6,[POINT 7,T2] ;BYTE POINTER TO COPY NAME
|
||
MOVEI T5,5 ;MAX OF 5 BYTES (ONE WORD)
|
||
ILDB T4,P1 ;GET NUMBER OF BYTES IN THIS STRINGID
|
||
SETZB T2,P2 ;CLEAR OUT DESTINATION, AND CIRCUIT ID
|
||
NMXN20: SOJL T4,NTEINI ;TERMINATED TOO SOON. INVALID
|
||
ILDB T1,P1 ;GET A BYTE
|
||
CAIL T1,140 ;IS IT LOWER CASE?
|
||
SUBI T1,40 ;YES, MAKE IT UPPER CASE
|
||
CAIN T1,"-" ;DID IT INCLUDE THE DASH?
|
||
JRST NMXN21 ;YES, STOP HERE.
|
||
IDPB T1,T6 ;SAVE IN COPYING STRING
|
||
SOJG T5,NMXN20 ;GET ANOTHER BYTE
|
||
ERRRET NTEINI ;ILLEGAL NAME, GIVE UNRECOGNIZED COMPONENT
|
||
NMXN21: MOVEI T1,LD.MAX ;MAXIMUM KONTROLLER DEVICE NUMBER
|
||
NMXN22: CAMN T2,KONNAM(T1) ;IS THIS THE CONTROLLER WE CARE ABOUT?
|
||
JRST NMXN23 ;YES, EXIT
|
||
SOJGE T1,NMXN22 ;TRY FOR NEXT KONTROLLER DEVICE NUMBER
|
||
ERRRET NTEINI ;ILLEGAL NAME
|
||
NMXN23: STOR T1,LIDEV,+P2 ;STORE IN CIRCUIT ID WE ARE BUILDING
|
||
CALL NMXN28 ;GET A NUMBER FROM THE STRING
|
||
STOR T1,LIKON,+P2 ;STORE AS KONTROLLER NUMBER IN CIRCUIT ID
|
||
CALL NMXN28 ;GET THE NEXT NUMBER FROM THE STRING
|
||
STOR T1,LIUNI,+P2 ;SAVE UNIT NUMBER
|
||
CALL NMXN28 ;GET NEXT NUMBER (IF ANY)
|
||
STOR T1,LIDRP,+P2 ;SAVE AS DROP NUMBER (PORT ON CI)
|
||
MOVE T1,P2 ;GET THE CIRCUIT ID WE JUST BUILT
|
||
RETSKP ;RETURN SUCCESS.
|
||
|
||
NMXN28: SETZ T1, ;CLEAR DESTINATION NUMBER
|
||
NMXN29: SOJL T4,RTN ;NO MORE BYTES, RETURN
|
||
ILDB T2,P1 ;GET NEXT DIGIT
|
||
CAIL T2,"0" ;RANGE
|
||
CAILE T2,"9" ; CHECK
|
||
RET ;NOT A DIGIT
|
||
SUBI T2,"0" ;CONVERT TO NUMBER
|
||
IMULI T1,^D10 ;SHIFT ORIGINAL NUMBER
|
||
ADD T1,T2 ;ADD IN CURRENT DIGIT
|
||
JRST NMXN29 ;AND GET ANOTHER DIGIT
|
||
|
||
SUBTTL Layers -- Main interface to layer levels
|
||
;NMXLAY - Call layer-level routine, to get/set value.
|
||
;CALL
|
||
; T1/ NMX Function Code
|
||
; T2/ NFWBLK - NMX Interface argument block
|
||
; T3/ Routine Index value from Parameter Table Entry (NTROU)
|
||
; NMXVAR/ NX block
|
||
; NT/ Pointer to STENT part of NT block
|
||
;Return
|
||
; RET ;on error, NXERR has code
|
||
; RETSKP ;
|
||
;
|
||
NMXLAY:
|
||
SETZRO NXNIL,+NMXVAR ;CLEAR THE "I DIDN'T DO ANYTHING" FLAG
|
||
CAXGE T3,NMXMAX ;RANGE CHECK
|
||
CAXGE T3,NMXMIN
|
||
BUG.(CHK,NTMDVI,NTMAN,SOFT,<NMXDSP value illegal>,,<
|
||
|
||
Cause: There will be a call to a "layer" to obtain or set a value for
|
||
an item. The routine value in the descriptor block pointed
|
||
to by NT is illegal.
|
||
|
||
Action: Examine the data structure pointed to by NT. In all probability
|
||
this is caused by a trashed NT, since the descriptor block
|
||
generation macros are supposed to range check this value.
|
||
|
||
Note: A "layer" is any routine described at NMXDSP.
|
||
>,NTEMPE)
|
||
CALLRET @NMXDSP(T3) ;CALL LAYER-LEVEL ROUTINE
|
||
|
||
SUBTTL Events -- Interface layer / NMX (NMXEVT)
|
||
|
||
;NMXEVT is the interface routine between a layer and the event logger.
|
||
;
|
||
;Context: interrupt or scheduler level
|
||
XRESCD
|
||
;
|
||
;Arguments:
|
||
; T1/ function code
|
||
; T2/ function dependent argument
|
||
;
|
||
;Returns (depends on function):
|
||
; +1 indicates that the function could not be successfully completed
|
||
; +2 success
|
||
|
||
XRESCD
|
||
NMXEVT:
|
||
|
||
;Verify the function code
|
||
CAIL T1,EV.GEC ;Function code within range?
|
||
CAILE T1,EV.SIG
|
||
BUG.(CHK,NTMEFO,NTMAN,SOFT,<Event function out of range>,,<
|
||
|
||
Cause: The event function supplied by a DECnet layer to NMXEVT was
|
||
out of range.
|
||
|
||
Action: Make callers of NMXEVT supply the correct function code
|
||
>,RTN)
|
||
|
||
;Dispatch to appropriate routine
|
||
CALLRET <-EV.GEC>+@[ ;Dispatch according to function code
|
||
IFIW <EVGEC&777777> ;Get EC block
|
||
IFIW <EVREC&777777> ;Release EC block
|
||
IFIW <EVFIL&777777> ;Filter an event
|
||
IFIW <EVLOG&777777> ;Log an event
|
||
IFIW <EVSIG&777777>](T1) ;Log a signal
|
||
|
||
SUBTTL Events -- NMXEVT -- EVGEC (Get EC block)
|
||
|
||
;EVGEC allocates an EC block
|
||
;
|
||
;Input: none
|
||
;Return: +1 if no memory, no EC block allocated
|
||
; +2 with T1/ address of EC block
|
||
|
||
;Resident...
|
||
|
||
EVGEC: MOVX T1,EC.LEN ;Length of EC block
|
||
CALLRET DNGWDZ ;Get chunk of zero words and propagate return
|
||
; from memory allocator
|
||
|
||
SUBTTL Events -- NMXEVT -- EVREC (Release Ec block)
|
||
|
||
;EVREC releases an EC block
|
||
;
|
||
;Input: T2/ address of EC block
|
||
;Returns: +2 always
|
||
|
||
;Resident...
|
||
|
||
EVREC:
|
||
|
||
;Unless ECCNT is non-zero (i.e. there is a NE block on queue pointing back
|
||
; to this EC block) it is OK to release the memory. In the case of ECCNT
|
||
; non-zero, the ECDEL bit is set to indicate to NTEVQ that the EC block
|
||
; should be deallocated when ECCNT goes to zero.
|
||
MOVE T1,T2 ;T1 := ^EC
|
||
OPSTR <SKIPG>,ECCNT,(T1) ;ECCNT greater than zero?
|
||
IFSKP. ; -yes
|
||
SETONE ECDEL,(T1) ; Set ECDEL flag
|
||
ELSE. ; -no, all OK
|
||
CALL DNFWDS ; Deallocate memory
|
||
ENDIF.
|
||
RETSKP
|
||
|
||
SUBTTL Events -- NMXEVT -- EVFIL (Filter an event)
|
||
|
||
;EVFIL filters an event
|
||
;
|
||
;Input: T2/ event code in the following format:
|
||
; FIELD CCL,13 Event class
|
||
; FIELD CTY,5 Event type
|
||
; FILLER 18
|
||
;
|
||
;Returns: +1 Event should be thrown away
|
||
; +2 Event should be logged
|
||
|
||
;Resident...
|
||
|
||
EVFIL: SAVEAC <P1>
|
||
MOVE P1,T2 ;P1 := event class and type
|
||
LOAD T1,FACCL,+P1 ;Get event class
|
||
CALL NTFFIL ;Find filter
|
||
RET ; -not there, throw away event
|
||
LOAD T2,FACTY,+P1 ;Get event type
|
||
MOVX T3,1 ;Load a 1 into test word
|
||
LSH T3,(T2) ; and shift into position
|
||
TDNN T3,NMXFIL(T1) ;Is bit set in filter mask?
|
||
RET ; -no, throw away
|
||
RETSKP ;-yes, keep event
|
||
|
||
;NTFFIL - find index of event class in filter table (NMXFIL)
|
||
;
|
||
;Call with: T1/ event class
|
||
;Returns: +1/ did not find event class in table
|
||
; +2/ T1/ index of filter in table
|
||
;
|
||
NTFFIL: ;Ac usage: T1/ event class, T2/ moving index
|
||
SETZ T2, ;Start at index 0 in table
|
||
DO. ;Loop over all event classes
|
||
SKIPGE NMXFIL(T2) ; At end of list?
|
||
RET ; -yes, return 'not found'
|
||
HLRZ T3,NMXFIL(T2) ; Get low bound
|
||
HRRZ T4,NMXFIL(T2) ; and high bound
|
||
CAML T1,T3 ; Is event class in interval?
|
||
CAMLE T1,T4
|
||
IFNSK. ; -no, step to next event class interval
|
||
SUB T4,T3 ; Find out # of entries to step over
|
||
ADDI T4,2 ; Dont forget the interval word
|
||
ADD T2,T4 ; Add to current index
|
||
LOOP. ; and loop back
|
||
ELSE. ; -yes, in interval
|
||
MOVE T4,T1 ; Calculate matching index
|
||
SUB T4,T3
|
||
AOJ T4,
|
||
ADD T4,T2
|
||
MOVE T1,T4 ; and put it in T1
|
||
EXIT. ; Exit DO loop to exit routine
|
||
ENDIF.
|
||
ENDDO.
|
||
RETSKP ; Return 'found'
|
||
|
||
SUBTTL Events -- NMXEVT -- EVLOG (Log an event)
|
||
|
||
;EVLOG logs an event
|
||
;
|
||
;Input: T2/ NE block
|
||
; Note: The NE block must contain a valid pointer to the EC block
|
||
;
|
||
;Returns: +2 always
|
||
|
||
;Resident...
|
||
|
||
EVLOG: SAVEAC <P1,P2> ;Ac usage: P1/ NE block, P2/ EC block
|
||
MOVE P1,T2 ;P1 := ^NE
|
||
LOAD P2,NEECP,(P1) ;P2 := ^EC
|
||
CALL DNGTIM ;Get system time
|
||
STOR T1,NETIM,(P1) ;Store for future conversion to julian time
|
||
D36OFF ;Turn off interrupts
|
||
CALL EVLOG1 ;Call coroutine that does the work
|
||
IFNSK. ; No-skip means event lost; deallocate it
|
||
D36ON ; First turn on interrupts
|
||
MOVE T1,P1 ; Get ^NE
|
||
CALL EVRNE ; Call EVRNE to release NE block
|
||
RETSKP ; Always success return
|
||
ENDIF.
|
||
D36ON ;Skip means NE block now on queue
|
||
MCALL (RG,MSEC1,PSIDVT) ;Give a PSI if someone wiating
|
||
RETSKP
|
||
|
||
;EVLOG1 - EVLOG worker routine
|
||
;
|
||
;Called with D36OFF
|
||
;
|
||
;Input:
|
||
; P1/ ^NE block
|
||
; P2/ ^EC block
|
||
;
|
||
;Output:
|
||
; +1 lost event, deallocate it
|
||
; +2 do not deallocate event
|
||
;
|
||
;Local AC use:
|
||
; T4/ count of entries on queue
|
||
|
||
EVLOG1:
|
||
|
||
; if ECLOS gtr 0 then lose_event
|
||
JN ECLOS,(P2),EVLOGL ;If ECLOS non-zero, lose this one too
|
||
|
||
; if NMXECN = NMXELN then lose_event
|
||
LOAD T4,QHCNT,+NMXEVQ ;Get current # of entries in queue
|
||
CAIL T4,NMXELN ;Compare with max length of queue
|
||
JRST EVLOGL ;Lose event
|
||
|
||
; if ECCNT geq ECMAX
|
||
LOAD T1,ECCNT,(P2)
|
||
OPSTR <CAMGE T1,>,ECMAX,(P2)
|
||
IFSKP. ; ... then
|
||
SKIPE NMXELO ; if NMXELO = true
|
||
JRST EVLOGL ; then lose event
|
||
CALL EVLOGM ; else lose event and make lost event
|
||
ELSE. ; ... else
|
||
CAIE T4,<NMXELN-1> ; if queue length = queue max - 1
|
||
IFSKP. ; then
|
||
SKIPE NMXELO ; and NMXELO is false
|
||
ANSKP.
|
||
CALL EVLOGM ; lose event and make lost
|
||
ENDIF.
|
||
ENDIF.
|
||
;Queue NE block
|
||
ENDQUE P1,NMXEVQ,NE.NXT,T1
|
||
;Increment ECCNT
|
||
INCR ECCNT,(P2)
|
||
;Return with queued block
|
||
RETSKP
|
||
|
||
;EVLOG support routines
|
||
;
|
||
|
||
;Resident...
|
||
|
||
;EVLOGL - called to lose event and return
|
||
EVLOGL: INCR ECLOS,(P2) ;Increment # of lost events
|
||
RET ;No-skip to deallocate NE block
|
||
|
||
;EVLOGM - called to remake event to "lost event"
|
||
; The event will then be queued as an "ordinary event"
|
||
EVLOGM: INCR ECLOS,(P2) ;Increment # of lost events
|
||
SETZRO NECCL,(P1) ;Event class := 0
|
||
SETZRO NECTY,(P1) ;Event type := 0
|
||
SETONE NEETP,(P1) ;Entity type := no entity
|
||
SETZRO NEDLN,(P1) ;Data length := 0
|
||
SETOM NMXELO ;And now is NMXELO true
|
||
RET
|
||
|
||
;EVRNE - release NE block. Called on "lost event" or when event is copied
|
||
; to user (NTEVQ).
|
||
;
|
||
; T1/ ^NE block
|
||
|
||
;Resident...
|
||
|
||
EVRNE: LOAD T2,NECBK,(T1) ;Get callback address
|
||
SKIPN T2 ;Was one supplied?
|
||
IFNSK. ; -no, use default
|
||
CALLRET DNFWDS ; DECnet deallocator
|
||
ELSE.
|
||
CALL (T2) ; -yes, call users routine
|
||
JFCL ; Ignore no-skip
|
||
ENDIF.
|
||
RET ;Return
|
||
|
||
SUBTTL Events -- NMXEVT -- EVSIG (Log a signal)
|
||
|
||
;EVSIG signals an event
|
||
;
|
||
;Input: T2/ NE block
|
||
;
|
||
;Returns: +2 always
|
||
|
||
;Resident...
|
||
|
||
EVSIG: SAVEAC <P1,P2> ;Ac usage: P1/ NE block, P2/ EC block
|
||
MOVE P1,T2 ;P1 := ^NE
|
||
LOAD P2,NEECP,(P1) ;P2 := ^EC
|
||
CALL DNGTIM ;Get system time
|
||
STOR T1,NETIM,(P1) ;Store for future conversion to julian time
|
||
;Turn off interrupts
|
||
D36OFF
|
||
;Verify that there is room in the signal queue
|
||
LOAD T1,QHCNT,+NMXSIQ ;Get current count
|
||
CAIL T1,NMXSLN ; and compare with max allowed
|
||
BUG.(INF,NTMSQF,NTMAN,SOFT,<Signal queue full>,,<
|
||
|
||
Cause: The signal queue was full when a new signal was logged.
|
||
This might be caused by a malfunctioning NMLT20 that does not
|
||
read the signals from the signal queue, or it may be caused by
|
||
a DECnet device driver going bad. A signal is used to tell
|
||
NMLT20 that a device needs attention/reload.
|
||
|
||
Action: Restart NMLT20, or turn off malfunctioning DECnet device.
|
||
If necessary, reload any devices by hand
|
||
>,EVSIG2)
|
||
|
||
;If no BUGCHK, come here and insert event into signal queue
|
||
ENDQUE P1,NMXSIQ,NE.NXT,T1
|
||
EVSIG1: D36ON ;Turn on interrupts
|
||
MCALL (RG,MSEC1,PSIDVT) ;Give a PSI if someone waiting
|
||
RETSKP
|
||
|
||
EVSIG2: D36ON ;Turn on interrupts
|
||
MOVE T1,P1 ;Get pointer to NE block
|
||
CALL EVRNE ;Release NE block
|
||
RETSKP
|
||
|
||
;End of resident code
|
||
XSWAPCD
|
||
|
||
IFN FTDEBUG <
|
||
SUBTTL Events -- .NTTEV function (Test event logger)
|
||
|
||
;Called from NMXDIS
|
||
|
||
;The .NTTEV function tests the event logger and uses the ET structure
|
||
|
||
NTTEV: SAVEAC <P1,P2,MB,MS>
|
||
|
||
; P1/ ^NE block, P2/ ^EC block, MS/ ^ET block, MB/ count of events to do
|
||
|
||
;Get ET block
|
||
MOVX T1,ET.LEN
|
||
CALL DNGWDZ
|
||
ERRRET NTERES
|
||
MOVE MS,T1
|
||
|
||
;Copy from user argument block to our ET block
|
||
;
|
||
;T1/ ^user argument
|
||
;T2/ rolling index
|
||
UMOVE T1,1
|
||
UMOVE T1,.NTSEL(T1)
|
||
SETZ T2,
|
||
DO.
|
||
CAIL T2,ET.LEN ;Through copying?
|
||
EXIT. ; -yes,exit
|
||
MOVE T3,T1
|
||
ADD T3,T2
|
||
UMOVE T4,(T3) ;Get user word
|
||
ERJMP [ MOVE T1,MS ;On illegal read, return MS block
|
||
CALL DNFWDS
|
||
ERRRET NTEADC ;Give "address check"
|
||
]
|
||
MOVE T3,MS
|
||
ADD T3,T2
|
||
MOVEM T4,(T3) ;Store in ET block
|
||
AOJ T2,
|
||
LOOP.
|
||
ENDDO.
|
||
LOAD MB,ETCNT,(MS) ;Get count of events to do
|
||
|
||
;Get EC block
|
||
MOVX T1,EV.GEC ;Get EC block
|
||
CALL NMXEVT
|
||
IFNSK.
|
||
MOVE T1,MS
|
||
CALL DNFWDS
|
||
ERRRET NTERES
|
||
ENDIF.
|
||
MOVE P2,T1
|
||
MOVX T1,2 ;Allow 2 events on queue
|
||
STOR T1,ECMAX,(P2)
|
||
|
||
;Get NE block
|
||
NEGET: MOVX T1,NE.LEN
|
||
ADDI T1,<44/4> ;Add data string
|
||
CALL DNGWDZ
|
||
IFNSK.
|
||
MOVX T1,EV.REC ;Release EC block
|
||
MOVE T2,P2
|
||
CALL NMXEVT
|
||
JFCL
|
||
MOVE T1,MS
|
||
CALL DNFWDS
|
||
ERRRET NTERES
|
||
ENDIF.
|
||
MOVE P1,T1 ;P1 := ^NE
|
||
|
||
;At this point all blocks are allocated, and the user arguments have been
|
||
; copied to our ET block
|
||
|
||
;Copy data to NE block
|
||
STOR P2,NEECP,(P1) ;Store EC pointer
|
||
LOAD T1,ETCCL,(MS) ;Get event class
|
||
STOR T1,NECCL,(P1)
|
||
LOAD T1,ETCTY,(MS) ;Get event type
|
||
STOR T1,NECTY,(P1)
|
||
LOAD T1,NXENT,+NMXVAR ;Get entity type
|
||
STOR T1,NEETP,(P1)
|
||
LOAD T1,NXNUM,+NMXVAR ;Get entity ID
|
||
STOR T1,NEEID,(P1)
|
||
LOAD T1,ETDLN,(MS) ;Get data length
|
||
STOR T1,NEDLN,(P1)
|
||
XMOVEI T1,NE.DAT(P1) ;Get address of data string
|
||
AOJ T1,
|
||
STOR T1,NEDAT,(P1)
|
||
;Copy the string also
|
||
LOAD T1,ETDLN,(MS) ;Get string length
|
||
MOVSI T2,(POINT 8,0) ;Byte pointer
|
||
TDO T2,[1B12] ;Make it global...
|
||
XMOVEI T3,ET.DAT(MS) ;Get source address
|
||
DMOVE T4,T1 ;Duplicate T1-T2
|
||
LOAD T6,NEDAT,(P1) ;Get destination address
|
||
EXTEND T1,[MOVSLJ] ;"Move string left justified"
|
||
JFCL ;Ignore error
|
||
|
||
;Now log or signal the event
|
||
MOVX T1,EV.SIG ;Assume signal
|
||
OPSTR <SKIPE>,ETSIG,(MS)
|
||
IFSKP. ;No, it was "ordinary" event
|
||
SETZ T2, ;Clear word to receive argument
|
||
LOAD T1,NECCL,(P1) ;Get event class
|
||
STOR T1,FACCL,+T2
|
||
LOAD T1,NECTY,(P1) ;Get event type
|
||
STOR T1,FACTY,+T2
|
||
MOVX T1,EV.FIL ;Filter the event
|
||
CALL NMXEVT
|
||
IFNSK. ;Throw away this event
|
||
MOVE T1,P1
|
||
CALL DNFWDS ;Release NE block
|
||
ELSE.
|
||
MOVX T1,EV.LOG ;Log event
|
||
MOVE T2,P1
|
||
CALL NMXEVT
|
||
JFCL
|
||
ENDIF.
|
||
ELSE.
|
||
MOVE T2,P1
|
||
CALL NMXEVT
|
||
JFCL
|
||
ENDIF.
|
||
|
||
;Check count
|
||
SOJG MB,NEGET ;More to do?
|
||
|
||
;No, deallocate EC and ET blocks
|
||
MOVX T1,EV.REC
|
||
MOVE T2,P2
|
||
CALL NMXEVT
|
||
JFCL
|
||
|
||
;And ET block too
|
||
MOVE T1,MS
|
||
CALL DNFWDS
|
||
|
||
;Everything done, return success
|
||
RETSKP
|
||
|
||
>
|
||
|
||
SUBTTL Events -- .NTSLM function (Set global logging mask)
|
||
|
||
;Called from NMXDIS
|
||
|
||
;The .NTSLM function sets/changes the global logging masks in NTMAN.
|
||
;The event class to set is in word .NTSEL, and the new filter in word .NTQUA.
|
||
|
||
NTSLM: SAVEAC <P1>
|
||
UMOVE P1,1 ;P1 := user ^argblk
|
||
UMOVE T1,.NTSEL(P1) ;Get event class
|
||
CALL NTFFIL ;Find the filter
|
||
ERRRET NTEPNA ;Say 'parameter not applicable'
|
||
;Index of matching entry is now in T1
|
||
UMOVE T2,.NTQUA(P1) ;Get event filter
|
||
TXZ T2,17B3 ;Clear bits 0-3 (BLISS bits 33-36)
|
||
MOVEM T2,NMXFIL(T1) ;Store new filter
|
||
RETSKP ;Give success return
|
||
SUBTTL Events -- .NTPSI function (Set event PSI channel)
|
||
|
||
;Called from NMXDIS
|
||
|
||
;The .NTPSI sets the PSI channel for "events available" interrupts. TOPS-10
|
||
; uses another mechanism to set event interrupts, so the following routine is
|
||
; Tops-20 only.
|
||
;
|
||
; The PSI channel is in word .NTSEL
|
||
|
||
NTPSI:
|
||
|
||
IFN FTOPS10,<ERRRET NTEUFO> ;NOT IN TOPS10
|
||
|
||
IFN FTOPS20,<
|
||
SKIPN T1,EVRFRK ;SOMEONE ALREADY DOING THIS?
|
||
IFSKP.
|
||
HRRZS T1 ;YES, GET HIS ID
|
||
CAME T1,FORKX ;IS HE RESETTING?
|
||
S1XCT <ITERR (NTMX2)>;Return "Event facility already in use"
|
||
ENDIF.
|
||
LOAD T1,NXSEL,+NMXVAR ;Get users PSI channel from .NTSEL
|
||
CAME T1,[-1] ;DOES HE STILL WANT TO BE NOTIFIED?
|
||
IFSKP.
|
||
SETZM EVRFRK ;NO, NO MORE EVENT READER
|
||
ELSE.
|
||
CAIL T1,0 ;YES, CHECK FOR
|
||
CAILE T1,^D36 ; LEGAL PSI CHANNEL
|
||
ERRRET NTEMPE ; -not legal, give 'management program error'
|
||
AOS T1 ;FIX IT FOR INTERNAL USE
|
||
HRLM T1,EVRFRK ;SET IT UP
|
||
MOVE T1,FORKX ;GET USER
|
||
HRRM T1,EVRFRK ;SET IT UP
|
||
SKIPE NMXEVQ ;IS THERE ANYTHING IN THE QUEUE ?
|
||
CALL NMLEVT ;YES. GIVE INTERRUPT.
|
||
ENDIF.
|
||
RETSKP
|
||
|
||
|
||
;KILL THE EVENT READER (CALLED FROM .RESET AND KSELF)
|
||
;RETURNS: +1
|
||
|
||
;Resident ? (To be checked in future/GL)
|
||
XRESCD
|
||
|
||
XRENT EVRKIL
|
||
HRRZ T1,EVRFRK ;GET THE EVENT LOGGER
|
||
CAMN T1,FORKX ;IS IT US?
|
||
SETZM EVRFRK ;YES, NO MORE EVENT READER
|
||
RET ;NO, NOTHING TO DO
|
||
|
||
;GIVE THE EVENT READER A PSI
|
||
;CALLED FROM LV8CHK
|
||
|
||
;This must be resident
|
||
|
||
XRESCD
|
||
NMLEVT: SETZM NMLPSI ;CLEAR THE FLAG
|
||
HLRZ T1,EVRFRK ;GET PSI CHANNEL
|
||
JUMPE T1,RTN ;IF THERE IS ONE.
|
||
SOS T1 ;THERE IS. MAKE IT REAL.
|
||
HRRZ T2,EVRFRK ;GET EVENT READER FORK
|
||
XCALLRET (MSEC1,PSIRQ) ;LET HIM KNOW
|
||
|
||
;ASSERT EVENT PSI FOR SCHEDULER TO CATCH
|
||
;MAY BE CALLED AT ANY LEVEL.
|
||
;CALL PSIDVT
|
||
;RETURNS +1 ALWAYS
|
||
XRESCD ;MUST BE RESIDENT
|
||
|
||
PSIDVT: SETOM NMLPSI ;SET FLAG FOR SCHEDULER.
|
||
RET
|
||
|
||
;No more resident code
|
||
XSWAPCD
|
||
|
||
|
||
>;END IFN FTOPS20
|
||
|
||
SUBTTL Events -- .NTEVQ function (Pass queued event to user)
|
||
|
||
;Called from NMXDIS
|
||
|
||
;Writes next event to user buffer. If there are no events on queue,
|
||
; a zero length is indicated to the user.
|
||
|
||
;Must be resident since D36OFF is done
|
||
XRESCD
|
||
|
||
NTEVQ: SAVEAC <P1,P2> ;Ac usage: P2/ ^NE block
|
||
|
||
;Turn off interrupts and call routine to get next event.
|
||
D36OFF
|
||
CALL NTEVQN ;Pull next event off queues
|
||
IFNSK. ;No-skip indicates no event on queue
|
||
D36ON ; Turn on interrupts
|
||
RETSKP ; Do success return, higher layer will write
|
||
ENDIF. ; 0 into the "number of bytes returned" field
|
||
D36ON ;Turn on interrupts on success return
|
||
JRST NTEVQ1 ;Proceed in swappable code
|
||
|
||
XSWAPCD
|
||
;Come here with T1/ ^NE block
|
||
NTEVQ1: MOVE P2,T1 ;P2 := ^NE
|
||
|
||
;Now "build" a NQ block in the users buffer, i.e.
|
||
; B:2 event class and type
|
||
; 3*B:2 julian day, second and millisecond
|
||
; B:2 entity type
|
||
; B:n entity ID
|
||
; B:m m bytes of event data
|
||
|
||
;Event class and type
|
||
LOAD T1,NECCL,(P2) ;Get event class
|
||
ASH T1,6 ;Shift over to make room for type
|
||
OPSTR <IOR T1,>,NECTY,(P2) ;Or in event type
|
||
CALL PUT2BT ;Put to user
|
||
RET ;error...
|
||
|
||
;Julian day, second and millisecond
|
||
LOAD T1,NETIM,(P2) ;Get system time stored
|
||
STKVAR <SEC,MSC> ;Two local variables
|
||
CALL NMXTIM ;Convert to julian time
|
||
MOVEM T2,SEC ;Save julian seconds
|
||
MOVEM T3,MSC ;Save julian milliseconds
|
||
CALL PUT2BT ;Put julian 1/2day to user
|
||
RET ;error...
|
||
MOVE T1,SEC
|
||
CALL PUT2BT ;Put julian seconds to user
|
||
RET ;error...
|
||
MOVE T1,MSC
|
||
CALL PUT2BT ;Put julian milliseconds to user
|
||
RET ;error...
|
||
|
||
;Now put entity type and entity ID
|
||
LOADE T1,NEETP,(P2) ;Get entity type
|
||
CALL PUTBYT ;Put to user
|
||
RET ;error...
|
||
|
||
LOADE T1,NEETP,(P2) ;Get entity type again
|
||
CAXE T1,.NTNOD ;Is it node?
|
||
IFSKP. ; -yes
|
||
LOAD T1,NEEID,(P2) ; Get entity ID (node number)
|
||
CALL PUT2BT ; Put # in user buffer
|
||
RET ;error...
|
||
SETZ T1, ; Zero length node name
|
||
CALL PUTBYT ; Put length byte to user
|
||
RET ;error...
|
||
ELSE. ; -no, not node entity
|
||
CAXE T1,.NTCKT ; Is it circuit
|
||
CAXN T1,.NTLIN ; or a line?
|
||
IFNSK. ; -yes, it was
|
||
LOAD T1,NEEID,(P2) ; Get entity ID
|
||
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;Where to store circuit/line string
|
||
CALL NMXC2N ; Convert id to a name
|
||
JRST NTEMPE ; Error!
|
||
XMOVEI P1,NX.VAL+NMXVAR ; Load pointer to string containing name
|
||
CALL PUTSTR ; Copy string to user space
|
||
RET ;error...
|
||
ELSE. ; -not circuit or line ID
|
||
AOJ T1, ; Maybe 'NO ENTITY' (elevenish -1)
|
||
TRNE T1,<<377_8>+377> ; Is it?
|
||
BUG.(CHK,NTMORE,NTMAN,SOFT,<Unrecognized entity type>,,<
|
||
|
||
Cause: An event was received from a DECnet layer, and the entity type
|
||
is not legal.
|
||
|
||
Action: Find the routine that logged the event, and change it to
|
||
a legal entity type.
|
||
>,NTEMPE)
|
||
ENDIF.
|
||
ENDIF.
|
||
|
||
;Now copy data string to user buffer
|
||
SAVEAC <MB>
|
||
LOAD NT,NEDLN,(P2) ;Count in NT
|
||
LOAD MB,NEDAT,(P2) ;Address of string to MB
|
||
MOVE P1,[POINT 8,(MB)] ;Do it this way to get intersection copy
|
||
DO.
|
||
SOSGE NT ;Any more bytes?
|
||
EXIT. ; -no
|
||
ILDB T1,P1 ;Get next byte
|
||
CALL PUTBYT ; and give it to user
|
||
RET ;error...
|
||
LOOP.
|
||
ENDDO.
|
||
|
||
;Now the NE block has been copied to the user buffer, deallocate the NE block
|
||
; and then return successfully
|
||
MOVE T1,P2 ;EVRNE wants pointer in T1
|
||
CALL EVRNE
|
||
RETSKP
|
||
|
||
;NTEVQN - extract next event from queue
|
||
;
|
||
;Called with D36OFF, so must be resident
|
||
XRESCD
|
||
;
|
||
;Returns: +1 No events on queue
|
||
; +2 T1/ ^NE block
|
||
|
||
NTEVQN: SAVEAC <P1,P2> ;P1/ ^NE block, P2/ ^EC block
|
||
|
||
;Try dequeue an event from the signal queue
|
||
DEQUE T1,NMXSIQ,NE.NXT,NTEVQM ;Dequeue into T1
|
||
RETSKP ;Success, return
|
||
|
||
;NTEVQM - try to extract event from the event queue
|
||
NTEVQM: DEQUE P1,NMXEVQ,NE.NXT,RTN ;Just return if nothing available
|
||
|
||
;Come here with P1/ ^NE block
|
||
LOAD P2,NEECP,(P1) ;P2 := ^EC
|
||
|
||
;Is this an events lost?
|
||
LOAD T1,NECCL,(P1) ;Get event class
|
||
LOAD T2,NECTY,(P1) ; and event type
|
||
SKIPN T1 ;Is event class = 0
|
||
SKIPE T2 ; and event type = 0
|
||
SKIPA ; -no, skip next instruction
|
||
SETZM NMXELO ; -yes, flag no "events lost" on queue any more
|
||
;Decrement ECCNT by one; and if it went to zero there may be things to do
|
||
DECR ECCNT,(P2)
|
||
OPSTR <SKIPE>,ECCNT,(P2) ;Did it go to zero?
|
||
IFSKP. ; -yes
|
||
;Code may go here to generated "events were lost event"
|
||
;
|
||
SETZRO ECLOS,(P2) ;No more lost events now
|
||
;If ECDEL is set, then deallocate the EC block
|
||
OPSTR <SKIPN>,ECDEL,(P2) ;Set?
|
||
IFSKP. ; -yes
|
||
MOVE T2,P2
|
||
CALL EVREC
|
||
JFCL
|
||
ENDIF.
|
||
ENDIF.
|
||
;Put NE address in T1, and return skip to indicate that there was an event
|
||
MOVE T1,P1
|
||
RETSKP
|
||
|
||
;End of resident code
|
||
XSWAPCD
|
||
|
||
SUBTTL User strings -- Write parameter with nice
|
||
;NMXWTY - Write a parameter to the user data string, including NICE
|
||
; headers such as DATA ID and DATA TYPE
|
||
;Call
|
||
; NT/ Pointer to STENT part of NT block
|
||
; NXVAL,+NMXVAR/ Value obtained from NMXLAY
|
||
;
|
||
;Return
|
||
; RET ;On error, NXERR has error code
|
||
; RETSKP ;when done, maybe with stuff in user string
|
||
;
|
||
|
||
NMXWTY:
|
||
JN NXNIL,+NMXVAR,RSKP ;If Layer didn't know about him, ignore it.
|
||
JE NXWUS,+NMXVAR,RSKP ;IF NOT WRITING TO THE USER, RETURN
|
||
SETZ T1, ;START OFF WITH A CLEAN HEADER DUO-BYTE
|
||
LOAD T2,NTSEQ,(NT) ;GET SEQUENCE NUMBER OF PARAMETER
|
||
IOR T1,T2 ;OR INTO HEADER DUO-BYTE
|
||
CALL PUT2BT ;PUT 2 BYTES OF HEADER INTO USER DATA STRING
|
||
RET ;error...
|
||
NMXWT3: LOAD T1,NTTYP,(NT) ;GET DATA TYPE OF THIS PARAMETER
|
||
CAXL T1,NT.FC ;IS IT LESSER THAN SIMPLE CODED?
|
||
CAXLE T1,NT.FCN ;OR GREATER THAN ASCII CIRCUIT NAME?
|
||
BUG.(CHK,NTMFOR,NTMAN,SOFT,<Format out of range>,,<
|
||
|
||
Cause: While formatting output for a show, the format block for
|
||
this item has been found to have an illegal format type.
|
||
>,NTEMPE)
|
||
CALLRET @.+1-NT.FC(T1)
|
||
IFIW <NMXWCD&777777> ;ORDINARY CODED. HANDLE AS INTEGER
|
||
IFIW <RSKP&777777> ;CODED MULTIPLE IS HANDLED AT ANOTHER LEVEL
|
||
IFIW <RSKP&777777> ;ASCII IMAGE. HANDLED AT ANOTHER LEVEL
|
||
IFIW <NMXWNU&777777> ;DECIMAL UNSIGNED
|
||
IFIW <NMXWNU&777777> ;DECIMAL SIGNED.
|
||
IFIW <NMXWNU&777777> ;HEXADECIMAL INTEGER.
|
||
IFIW <NMXWHI&777777> ;HEX IMAGE. BYTE STRING
|
||
IFIW <NMXWNU&777777> ;OCTAL
|
||
IFIW <NMXWNM&777777> ;MILLISECONDS
|
||
IFIW <NMXWVN&777777> ;VERSION NUMBER
|
||
IFIW <NMXWNE&777777> ;NODE ENTITY ID
|
||
IFIW <NMXWNN&777777> ;NODE NAME
|
||
IFIW <NMXWCN&777777> ;WRITE CIRCUIT NAME
|
||
|
||
SUBTTL User strings -- Write coded data
|
||
;NMXWCD - Write coded info to user data string
|
||
;Call
|
||
; NT/ Pointer to format block
|
||
;Return
|
||
; RET ;Error, code is in NXERR
|
||
; RETSKP ;data type byte and data are in user string
|
||
;
|
||
|
||
NMXWCD:
|
||
SAVEAC <P1,P2> ;GET SOME WORK AREA
|
||
LOAD T1,NTLEN,(NT) ;GET SIZE OF FIELD
|
||
CAIE T1,1 ;WE ONLY HAVE SINGLE BYTE CODEDS. (**HACK**)
|
||
BUG.(CHK,NTMBCF,NTMAN,SOFT,<Bad coded field on output>,,<
|
||
|
||
Cause: Output for a SHOW is being formatted, and there has been a request
|
||
to generate a CODED field of more than one byte. This can't be
|
||
done.
|
||
|
||
Action: Look at the descriptor block pointed to by NT. Check to see if
|
||
this item is supposed to be a multiple byte coded. If not, fix
|
||
the item's entry. If it is correct, you are going to have to write
|
||
the code to handle multiple byte codeds.
|
||
>,NTEMPE)
|
||
TXO T1,NT.CNM ;INDICATE CODED NON MULTIPLE (PP 148 OF NM)
|
||
CALL PUTBYT ;DEPOSIT DATA TYPE BYTE IN USER STRING
|
||
RET ;error
|
||
LOAD T1,NFBUF,+NFWBLK ;GET THE CODED VALUE TO OUTPUT
|
||
CALLRET PUTBYT ;PUT THE BYTE IN THE OUTPUT STRING, AND RETURN
|
||
|
||
|
||
|
||
SUBTTL User strings -- Write ascii image data
|
||
;NMXWNN - Write ASCII image Node Name data to user data string
|
||
;Call
|
||
; NT/ Pointer to format block
|
||
; NF.BUF contains sixbit node name
|
||
;Return
|
||
; RET ;Error, code is in NXERR
|
||
; RETSKP ;Data type byte and data are in user string
|
||
|
||
NMXWNN:
|
||
SAVEAC <P1,P2>
|
||
MOVX T1,NT.AI ;Non-coded, ASCII image data
|
||
CALL PUTBYT ;Store data type byte
|
||
RET ; -error
|
||
MOVE P1,[POINT 6,NF.BUF+NFWBLK] ;Byte pointer to stringid with value
|
||
|
||
;Make a first pass over sixbit string since we need the count first
|
||
MOVE T1,P1 ;Get byte pointer
|
||
MOVEI T2,6 ;Max 6 chars in a node name
|
||
DO. ;LOOP
|
||
ILDB T3,T1 ; Get next byte
|
||
SKIPE T3 ; Empty?
|
||
SOJG T2,TOP. ; or out of bytes?
|
||
ENDDO. ; - yes, come here with T1 = remaining bytes
|
||
MOVEI T1,6 ;Get max # of bytes again
|
||
SUB T1,T2 ; and get # of bytes to write
|
||
MOVE P2,T1 ;Remember # of bytes to write
|
||
CALL PUTBYT ;Output that
|
||
RET ; -error
|
||
DO. ;LOOP again
|
||
SOSGE P2 ; Any more bytes to do?
|
||
EXIT. ; -no, all done
|
||
ILDB T1,P1 ; Get byte
|
||
ADDI T1,^O40 ; and make ASCII
|
||
CALL PUTBYT ; Dump it to user
|
||
RET ; -error
|
||
LOOP. ; And go back
|
||
ENDDO.
|
||
RETSKP
|
||
|
||
|
||
NMXWCN:
|
||
SAVEAC <P1,P2> ;GET SOME WORK AREA
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the returned Circuit/Line Id word
|
||
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;A temporary place to write CN
|
||
CALL NMXC2N ;Convert Circuit Id to Name
|
||
JRST NTEMPE ;Weird error!!!!!!!!!!!!!
|
||
MOVX T1,NT.AI ;NON-CODED, ASCII IMAGE DATA
|
||
CALL PUTBYT ;STORE DATA TYPE BYTE
|
||
RET ;error
|
||
MOVE P1,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO STRINGID WITH VALUE
|
||
ILDB T1,P1 ;GET FIRST BYTE, WHICH IS SIZE
|
||
MOVE P2,T1 ;COPY SIZE, TO COUNT DOWN BYTES
|
||
NMXWC2: CALL PUTBYT ;PUT IT IN USER DATA STRING
|
||
RET
|
||
ILDB T1,P1 ;GET NEXT BYTE
|
||
SOJGE P2,NMXWC2 ;DECREMENT COUNT, IF ANY BYTES LEFT, DO THEM
|
||
RETSKP ;DO A GOOD RETURN
|
||
|
||
|
||
SUBTTL User strings -- Write hexidecimal image data
|
||
;NMXWHI - Write HEXIDECIMAL image data to user data string
|
||
;Call
|
||
; NT/ Pointer to format block
|
||
; NFWBLK/ Argument Block returned from Layer
|
||
; NFBPT/ Byte pointer to start of Hexidecimal number
|
||
; NFBYT/ number of bytes in number
|
||
;Return
|
||
; RET ;Error, code is in NXERR
|
||
; RETSKP ;data type byte and data are in user string
|
||
|
||
NMXWHI:
|
||
SAVEAC <P1,P2,P3> ;GET HOME WORK AREA
|
||
MOVX T1,NT.HI ;NON-CODED, HEXIDECIMAL IMAGE DATA
|
||
CALL PUTBYT ;STORE DATA TYPE BYTE
|
||
RET ;Error return
|
||
LOAD P3,NFBUF,+NFWBLK ;Get the buffer address into P1
|
||
MOVE P1,[POINT 8,(P3)] ;Point at the buffer.
|
||
MOVEI P2,6 ;Get the number of bytes in the number
|
||
MOVE T1,P2 ;copy size and...
|
||
NMXWH2: CALL PUTBYT ;PUT IT IN USER DATA STRING
|
||
RET
|
||
ILDB T1,P1 ;GET NEXT BYTE
|
||
SOJGE P2,NMXWH2 ;DECREMENT COUNT, IF ANY BYTES LEFT, DO THEM
|
||
RETSKP ;DO A GOOD RETURN
|
||
|
||
SUBTTL User strings -- Write numeric data
|
||
;NMXWNU - Write a numeric value to the user data string
|
||
;CALL
|
||
; NMXVAR/ NX block
|
||
; NT/ Pointer to STENT part of NT block
|
||
; NFBUF,+NFWBLK/ Integer to deposit
|
||
;RETURN
|
||
; RET ;On error, NXERR contains code
|
||
; RETSKP ;Integer has been placed in data string
|
||
;
|
||
|
||
NMXWNU: LOAD T2,NTLEN,(NT) ;GET LENGTH IN BYTES OF THIS NUMBER
|
||
LOAD T1,NTTYP,(NT) ;GET FORMAT OF THIS NUMBER
|
||
CAXL T1,NT.FDU ;MAKE SURE THIS IS IN NUMERIC RANGE
|
||
CAXLE T1,NT.FOC ;BETWEEN DECIMAL UNSIGNED AND OCTAL.
|
||
BUG.(CHK,NTMINT,NTMAN,SOFT,<Invalid numeric type>,,<
|
||
|
||
Cause: When generating output for a numeric field, something other than
|
||
Decimal, Hexadecimal or Octal was requested.
|
||
>,NTEMPE)
|
||
MOVE T1,<-NT.FDU>+[ ;GET NICE TYPE.
|
||
0_3 ;DECIMAL UNSIGNED IS FORMAT 0
|
||
1_3 ;DECIMAL SIGNED IS FORMAT 1
|
||
2_3 ;HEXADECIMAL NUMBER IS FORMAT 2
|
||
-1 ;HEX IMAGE DOESN'T COME HERE.
|
||
3_3](T1) ;OCTAL NUMBER IS FORMAT 3
|
||
IOR T1,T2 ;OR IN SIZE OF FIELD
|
||
CALL PUTBYT ;PUT THIS BYTE IN USER DATA AS DATA TYPE
|
||
RET
|
||
NMXWCO: LOAD T2,NTLEN,(NT) ;GET NUMBER OF BYTES FOR COUNTER AGAIN
|
||
LOAD T1,NFBUF,+NFWBLK ;GET VALUE TO RETURN
|
||
CAXL T2,1 ;MUST BE AT LEAST ONE BYTE
|
||
CAXLE T2,4 ;MAY BE AT MOST 4 BYTES
|
||
NMXWCE: BUG.(CHK,NTMBDL,NTMAN,SOFT,<Bad multiple byte length>,,<
|
||
|
||
Cause: While generating output for a numeric field, there has been
|
||
a request to generate an illegal number of bytes.
|
||
>,NTEMPE)
|
||
CALLRET @.(T2)
|
||
IFIW <PUTBYT&777777> ;PUT A SINGLE BYTE
|
||
IFIW <PUT2BT&777777> ;PUT A DUO BYTE
|
||
IFIW <NMXWCE&777777> ;DO THREE BYTES. ILLEGAL
|
||
IFIW <PUT4BT&777777> ;4 BYTES.
|
||
|
||
SUBTTL Write out NSP or Routing Version numbers
|
||
;NMXWVN - Write out NSP or Routing Version numbers
|
||
;
|
||
NMXWVN:
|
||
SAVEAC <P1> ;We are going to put the Version # word here
|
||
MOVX T1,NT.CM3 ;Going to build a CM-3 Data Type Field
|
||
CALL PUTBYT ;Put it into the string
|
||
RET ;Error
|
||
MOVX T1,NT.DU1 ;Now we are building a DU-1 header
|
||
CALL PUTBYT ;Put it into the string
|
||
RET
|
||
LOAD P1,NFBUF,+NFWBLK ;Get the value from the Argument Block
|
||
LOAD T1,VNVER,+P1 ;Get the Version number
|
||
CALL PUTBYT
|
||
RET
|
||
MOVX T1,NT.DU1 ;Now we are building a DU-1 header
|
||
CALL PUTBYT ;Put it into the string
|
||
RET
|
||
LOAD T1,VNECO,+P1 ;Get the ECO number
|
||
CALL PUTBYT
|
||
RET
|
||
MOVX T1,NT.DU1 ;Now we are building a DU-1 header
|
||
CALL PUTBYT ;Put it into the string
|
||
RET
|
||
LOAD T1,VNUCO,+P1 ;And finally the User ECO number
|
||
CALLRET PUTBYT ;Write out that byte and we are done
|
||
|
||
SUBTTL Write out Node Entity Id
|
||
;NMXWNE - We come here to write out the value of parameters which are
|
||
; Node Ids, such as ADJACENT NODE, DESIGNATED ROUTER, ect...
|
||
; We have already received the Node Address part of the parameter
|
||
; from the Routing Layer. Before we write out anything to the
|
||
; user buffer, we will check to see if there is enough room in the
|
||
; buffer for the entire node entity (assuming a six character name).
|
||
; If not we give up right away, subtract two from the byte count,
|
||
; because the parameter nmuber has already been stored, and report
|
||
; a resource error. Then, we will try to get a Node Name from Session
|
||
; Control. We will then write out a Coded Multiple entry,
|
||
; depending on what we have.
|
||
|
||
NMXWNE: SAVEAC <P1,P2> ;
|
||
JE NFBFF,+NFWBLK,ONENDE ;If no buffer, Write one Node Entity
|
||
LOAD P2,NFBLN,+NFWBLK ;Get the number of entity Ids in buffer
|
||
JUMPE P2,RSKP ;If none, then return skip
|
||
LOAD P1,NFBUF,+NFWBLK ;Get the buffer address
|
||
NMXWN1: MOVE T1,(P1) ;Put the Node Number into P1
|
||
CALL WRTNDE ;Write out the Node Id to user buffer
|
||
RET ;Error return
|
||
AOJ P1, ;Update the buffer pointer
|
||
SOSG P2 ;Skip if more node numbers in buffer
|
||
RETSKP
|
||
LOAD T1,NTSEQ,(NT) ;Get the Parameter Number again
|
||
CALL PUT2BT ;Need to put it into user buffer for each
|
||
RET ;entry
|
||
JRST NMXWN1 ;Loop until done.
|
||
|
||
ONENDE: LOAD T1,NFBUF,+NFWBLK ;Get the node number into T1
|
||
CALL WRTNDE ;Write out the Node Id to user buffer
|
||
RET ;Error return
|
||
RETSKP
|
||
|
||
;
|
||
; Write Out a Node Entity Id to the user Buffer
|
||
;CALL
|
||
; T1/ Node Number
|
||
;
|
||
;
|
||
WRTNDE: SAVEAC <P1,P2> ;
|
||
MOVE P1,T1 ;Get the Node Address
|
||
CALL GETNDN ;Try to get Node Name from SCLINK
|
||
JRST NONAME ;No name mapped in SCLINK
|
||
CALL NMXS2A ;Convert SIXBIT name to ASCII, store it
|
||
MOVX T1,NT.CM2 ;Get the CM-2 header
|
||
CALL PUTBYT
|
||
RET
|
||
MOVX T1,NT.DU2 ;Get the DU-2 Header byte
|
||
CALL PUTBYT ;
|
||
RET
|
||
MOVE T1,P1 ;Get the Node address back
|
||
CALL PUT2BT ;Put it into the User string
|
||
RET
|
||
MOVX T1,NT.AI ;Get the AI-6 header byte
|
||
CALL PUTBYT ;
|
||
RET
|
||
XMOVEI P1,NX.VAL+NMXVAR ;Get address of ASCII Image string
|
||
CALL PUTSTR ;Write it to the user buffer
|
||
RET
|
||
RETSKP
|
||
|
||
NONAME: MOVX T1,NT.CM1 ;Get the CM-1 header
|
||
CALL PUTBYT
|
||
RET
|
||
MOVX T1,NT.DU2 ;Get the DU-2 Header byte
|
||
CALL PUTBYT ;
|
||
RET
|
||
MOVE T1,P1 ;Get the Node address back
|
||
CALL PUT2BT ;Put it into the User string
|
||
RET
|
||
RETSKP
|
||
|
||
|
||
|
||
GETNDN: TRVAR <<NFNBLK,NF.LST>> ;Need a brand new Argument Block here
|
||
SETZM NFNBLK ;CLEAN FIRST WORD OF BLOCK
|
||
HRRI T2,1+NFNBLK ;GET POINTER TO SECOND WORD IN BLOCK
|
||
HRLI T2,NFNBLK ;POINT AT START OF BLOCK
|
||
BLT T2,NF.LST-1+NFNBLK ;CLEAN UNTIL END OF BLOCK
|
||
STOR T1,NFEID,+NFNBLK ;Store the node number back into the block
|
||
MOVX T1,.NTNOD ;We need the Entity Type (Node)
|
||
STOR T1,NFETY,+NFNBLK ;Store the Entity Type
|
||
MOVX T1,NF.A2N ;Function code into T1
|
||
XMOVEI T2,NFNBLK ;Argument Block
|
||
CALL SCLNMX ;Map Node address into Node Name
|
||
RET
|
||
LOAD T1,NFBUF,+NFNBLK ;Get the node name into T1
|
||
RETSKP
|
||
|
||
SUBTTL User strings -- Read a number from user
|
||
;NMXRNU - Read an integer from data string, and put into NXVAL
|
||
;
|
||
|
||
NMXRNU:
|
||
LOAD T1,NTLEN,(NT) ;GET SIZE OF FIELD
|
||
CALL NMXRBY ;READ BYTES
|
||
RET ;error
|
||
JUMPE T1,NTEIPV ;ILLEGAL TO SET QUANTITY TO ZERO
|
||
STOR T1,NFBUF,+NFWBLK ;SAVE VALUE IN NF BLOCK
|
||
SETZRO NFBFF,+NFWBLK ;And Flag that there is no buffer
|
||
RETSKP ;RETURN SUCCESS
|
||
|
||
NMXRNC: LOAD T1,NTLEN,(NT) ;GET SIZE OF CODED FIELD
|
||
CALL NMXRBY ;READ BYTES
|
||
RET ;Error
|
||
STOR T1,NFBUF,+NFWBLK ;SAVE VALUE IN NF BLOCK
|
||
SETZRO NFBFF,+NFWBLK ;And Flag that there is no buffer
|
||
RETSKP
|
||
|
||
|
||
NMXRCN:
|
||
CALL GETSTR ;Go read the string into Monitor Core
|
||
RET ;error
|
||
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;Pointer to beginging of circuit name
|
||
CALL NMXN2C ;Convert Name to Line ID
|
||
RET ;error
|
||
STOR T1,NFBUF,+NFWBLK ;Put Line ID into the NF Block
|
||
SETZRO NFBFF,+NFWBLK ;No buffer being used
|
||
RETSKP
|
||
|
||
NMXRNN: CALL GETSTR ;Go read the string into Monitor Core
|
||
RET ;error
|
||
SETZ T1 ;Start off with a clear Node Name
|
||
MOVE T4,[POINT 6,NF.BUF+NFWBLK] ;Destination Byte Pointer for SIXBIT name
|
||
MOVE T3,[POINT 8,NX.VAL+NMXVAR] ;Pointer to String Containing name
|
||
ILDB T2,T3 ;Get Number of bytes in Node Name
|
||
JUMPLE T2,NTEIPV ;No Name, return error...
|
||
CAXLE T2,MXNNLN ;Make sure name is not longer than six
|
||
JRST NTEIPV ;Error...
|
||
NMXRN2: ILDB T5,T3 ;GET A BYTE FROM THE NODE NAME STRINGID
|
||
CAIL T5,^O140 ;IS IT LOWER CASE
|
||
SUBI T5,^O40 ;MAKE IT UPPER CASE
|
||
SUBI T5,^O40 ;MAKE IT SIXBIT
|
||
IDPB T5,T4 ;STORE IT IN THE SIXBIT NODE NAME
|
||
SOJG T2,NMXRN2 ;LOOP UNTIL ENTIRE NAME COPIED.
|
||
SETZRO NFBFF,+NFWBLK ;Make sure Layer knows that is no buffer
|
||
RETSKP
|
||
|
||
NMXRHI:
|
||
SAVEAC <P1>
|
||
MOVX T1,FHIBLK ;Get the size of the Buffer we need
|
||
STOR T1,NFBLN,+NFWBLK ;Put it into the argument block
|
||
CALL DNGWDS ;Go allocate the block
|
||
ERRRET NTERES ;No memory available, resource error
|
||
MOVE P1,T1 ;Put buffer address into P1
|
||
STOR T1,NFBUF,+NFWBLK ;Put the buffer addr into the arg block
|
||
SETONE NFBFF,+NFWBLK ;And tell Layer to expect a buffer
|
||
|
||
CALL GETSTR ;Go read the string into Monitor Core
|
||
RET ;error
|
||
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;Pointer to beginging of Hex String
|
||
MOVE T2,[POINT 8,(P1)] ;Pointer to Buffer to go to DECnet Layer
|
||
STOR T2,NFBPT,+NFWBLK ;Save Virgin Pointer for the DECnet Layer
|
||
ILDB T3,T1 ;Get the Length of the string
|
||
JUMPLE T3,NTEIPV ;Negative or zero, Invalid Parameter Value
|
||
CAXLE T3,MXHILN ;And it must be less than or equal to 6
|
||
JRST NTEIPV ;error
|
||
STOR T3,NFBYT,+NFWBLK ;Send the number of bytes to the DECnet Layer
|
||
NMXRH1: ILDB T4,T1 ;Get a byte from user
|
||
IDPB T4,T2 ;Put it into Buffer
|
||
SOJG T3,NMXRH1 ;Loop until entire string is copied
|
||
RETSKP
|
||
|
||
|
||
; I have commented out this routine (except for RETSKP) because
|
||
; there are currently NO Decimal Signed Parameters maintained
|
||
; by DECnet Layers in the Monitor.
|
||
;
|
||
NMXRNS:
|
||
; LOAD T1,NTLEN,(NT) ;GET SIZE OF FIELD
|
||
; CALL NMXRBY ;READ THE BYTES
|
||
; RET ;Error
|
||
; JUMPE T1,NTEIPV ;ZERO IS AN ILLEGAL NUMBER
|
||
; LOAD T2,NTLEN,(NT) ;GET SIZE AGAIN
|
||
; IMULI T2,^D8 ;CONVERT TO NUMBER OF BITS
|
||
; SETO T3, ;POSSIBLE SIGN EXTENSION
|
||
; ASH T3,(T2) ;SHIFT TO BECOME ONLY THE SIGN BITS
|
||
; TDNE T3,T1 ;IS THE SIGN BIT ON?
|
||
; IOR T1,T3 ;YES, TURN ON ALL THE SIGN BITS
|
||
; STOR T1,NFBUF,+NFWBLK ;SAVE VALUE IN NF BLOCK
|
||
; SETZRO NFBFF,+NFWBLK ;And Flag that there is no buffer
|
||
RETSKP
|
||
|
||
|
||
|
||
NMXRBY: CAXL T1,1 ;RANGE CHECK NUMBER OF BYTES TO READ
|
||
CAXLE T1,4 ;TO ENSURE ONLY 1,2, AND 4
|
||
NMXRBE: BUG.(CHK,NTMILN,NTMAN,SOFT,<Illegal number size>,,<
|
||
|
||
Cause: When going to read a numeric value from the user's string,
|
||
the format descriptor block for this item has specified an illegal
|
||
number of bytes to read.
|
||
>,NTEMPE)
|
||
CALLRET @.(T1) ;DISPATCH
|
||
IFIW <GETBYT&777777> ;GET A SINGLE BYTE
|
||
IFIW <GET2BT&777777> ;GET 2 BYTES OF INTEGER
|
||
IFIW <NMXRBE&777777> ;
|
||
IFIW <GET4BT&777777> ;GET 4 BYTES
|
||
SUBTTL User strings -- Read and write milliseconds
|
||
;NMXWNM - Write milliseconds
|
||
;Call
|
||
; NMXVAR/ NX block
|
||
; NT/ Pointer to NT begstr
|
||
;Return
|
||
; see NMXWNU
|
||
|
||
NMXWNM: LOAD T1,NFBUF,+NFWBLK ;GET VALUE WE ARE GOING TO WRITE OUT
|
||
IDIVI T1,TIMBAS ;CONVERT TO SECONDS
|
||
STOR T1,NFBUF,+NFWBLK ;PUT BACK WHERE IT CAME FROM
|
||
LOAD T1,NTLEN,(NT) ;GET THE LENGTH WE ARE GOING TO STORE
|
||
; IOR T1,0_3 ;NICE CODE INDICATING DECIMAL UNSIGNED
|
||
CALL PUTBYT ;PUT THE NICE HEADER IN
|
||
RET ;error...
|
||
JRST NMXWCO ;AND JOIN COMMON CODE
|
||
|
||
;NMXRNM - Read seconds, store milliseconds
|
||
;Call
|
||
; NMXVAR/ NX block
|
||
; NT/ Pointer to NT begstr
|
||
|
||
NMXRNM: CALL NMXRNU ;READ THE NUMBER AS DECIMAL UNSIGNED
|
||
RET ;error...
|
||
MOVX T1,TIMBAS ;CONVERSION FACTOR
|
||
OPSTRM <IMULB T1,>,NFBUF,+NFWBLK ;CONVERT TO MILLISECONDS
|
||
RETSKP ;AND RETURN SUCCESSFULLY
|
||
|
||
|
||
|
||
SUBTTL User strings -- Copy STRINGID from user to exec
|
||
|
||
;GETSTR - Copy a number of bytes (String) to a place in monitor core.
|
||
;Call
|
||
; NMXVAR/ NX block
|
||
;Return
|
||
; Non-skip on address check, error already in NXERR
|
||
; Skip if successfull, string starting at NXVAL
|
||
|
||
GETSTR: XMOVEI T1,NX.DAT+NMXVAR ;GET POINTER TO DATA BP BLOCK
|
||
JRST GETST0 ;JUMP INTO MAIN CODE
|
||
GETSTI: XMOVEI T1,NX.EID+NMXVAR ;GET POINTER TO ENITITY ID BP BLOCK
|
||
GETST0: SAVEAC <P1,P2,NT> ;SAVE SOME DATA ACS
|
||
MOVE P2,T1 ;SAVE POINTER
|
||
MOVE P1,[POINT 8,NX.VAL+NMXVAR] ;PUT STRING IN VALUE PART OF NX
|
||
MOVE T2,P2 ;GET POINTER TO BP BLOCK
|
||
CALL DNGUBT ;GET A SINGLE BYTE
|
||
RET ;error...
|
||
IDPB T1,P1 ;PUT BYTE AWAY IN DESTINATION STRING
|
||
CAXLE T1,^D32 ;WILL THIS STRING FIT IN NXVAL?
|
||
ERRRET NTEPVL ;NOPE. PARAMETER TOO LONG
|
||
MOVE NT,T1 ;SAVE NUMBER OF BYTES TO DO
|
||
GETST1: SOJL NT,RSKP ;AT END, RETURN SUCCESS
|
||
MOVE T2,P2 ;GET POINTER TO BP BLOCK
|
||
CALL DNGUBT ;GET A BYTE
|
||
RET ;error...
|
||
IDPB T1,P1 ;PUT BYTE AWAY.
|
||
JRST GETST1 ;DO ANOTHER BYTE
|
||
SUBTTL User strings -- Copy STRINGID from exec to user
|
||
;PUTSTR - Copy string from exec space to user data string
|
||
;Call
|
||
; P1/ Full word pointer to stringid in exec space
|
||
;Return
|
||
; RET on address check
|
||
; RETSKP with string in user address space
|
||
|
||
PUTSTR: SAVEAC <NT,P2> ;SAVE AN AC FOR BYTE COUNT
|
||
MOVX P2,<POINT 8,(P1)> ;MAKE AN 8-BIT BYTEPOINTER TO STRING
|
||
ILDB T1,P2 ;GET BYTE COUNT (FIRST BYTE)
|
||
MOVE NT,T1 ;SAVE BYTE COUNT FOR LATER
|
||
CALL PUTBYT ;PUT BYTE IN USER'S OUTPUT STRING
|
||
RET ;error...
|
||
PUTST1: SOJL NT,RSKP ;RETURN WHEN DONE
|
||
ILDB T1,P2 ;GET ANOTHER BYTE
|
||
CALL PUTBYT ;PUT IN USER DATA STRING
|
||
RET ;error...
|
||
JRST PUTST1 ;DO ANOTHER BYTE
|
||
SUBTTL User strings -- Get and put user byte routines.
|
||
;CALL
|
||
; T1/ integer to deposit
|
||
;RETURN
|
||
; RET on error, code in NXERR
|
||
; RETSKP with number deposited/loaded from/to T1
|
||
|
||
PUTBYT: XMOVEI T2,NX.DAT+NMXVAR ;POINTER TO BYTE POINTER/COUNT STRUCTURE
|
||
JRST DNPUBT ;PUT THE BYTE IN THE STREAM.
|
||
|
||
PUT4BT: SAVEAC <P1,P2> ;P1 IS OUR DATA, P2 IS THE NUMBER OF BYTES
|
||
XMOVEI T2,NX.DAT+NMXVAR ;POINTER TO BYTE POINTER/COUNT STRUCTURE.
|
||
MOVX P2,4 ;DO 4 BYTES
|
||
JRST PUTMBT ;PUT MULTIPLE BYTES
|
||
PUT2BT: SAVEAC <P1,P2> ;P1 IS DATA, P2 IS COUNT OF BYTES
|
||
XMOVEI T2,NX.DAT+NMXVAR ;POINTER TO BYTE POINTER/COUNT STRUCTURE.
|
||
MOVX P2,2 ;WE ARE DOING 2 BYTES
|
||
;; JRST PUTMBT ;PUT MULTIPLE BYTES
|
||
PUTMBT:
|
||
MOVE P1,T1 ;SAVE ORIGINAL BYTES
|
||
PUTMB1: LDB T1,[POINT 8,P1,35] ;GET BOTTOM BYTE
|
||
CALL DNPUBT ;STORE IT IN USER'S DATA STRING
|
||
RET ;error...
|
||
SOJLE P2,RSKP ;IF DONE, RETURN SUCCESS.
|
||
ASH P1,-10 ;DROP (INTO BIT BUCKET) THE BYTE WE JUST PUT
|
||
JRST PUTMB1 ;AND PUT ANOTHER BYTE IN USER'S STRING
|
||
|
||
GETEBY:
|
||
XMOVEI T2,NX.EID+NMXVAR ;POINTER TO BP FOR ENTITY ID
|
||
CALLRET DNGUBT ;AND GET A BYTE FROM IT.
|
||
GETBYT:
|
||
XMOVEI T2,NX.DAT+NMXVAR ;POINTER TO BYTE POINTER/COUNT STRUCTURE
|
||
CALLRET DNGUBT ;AND GO GET THE BYTE
|
||
GET2BT:
|
||
SAVEAC P1 ;WE ARE GOING TO ACCUMULATE BYTES HERE
|
||
XMOVEI T2,NX.DAT+NMXVAR ;POINTER TO BYTE POINTER/COUNT STRUCTURE.
|
||
CALL DNGUBT ;GET A BYTE OUT OF STREAM
|
||
RET ;error...
|
||
MOVE P1,T1 ;SAVE WHILE WE GET HIGH ORDER BYTE
|
||
CALL DNGUBT ;GET SECOND BYTE
|
||
RET ;error...
|
||
ASH T1,8 ;SINCE THIS IS HIGH ORDER, MAKE ROOM FOR LOW
|
||
IOR T1,P1 ;OR IT IN, MAKING A 2-BYTE AC
|
||
RETSKP ;RETURN WITH 2 BYTES IN T1
|
||
GET4BT:
|
||
SAVEAC P1 ;THIS IS WHERE WE ACCUMULATE INCOMING BYTES
|
||
XMOVEI T2,NX.DAT+NMXVAR ;POINTER TO BYTE POINTER/COUNT STRUCTURE.
|
||
CALL DNGUBT ;GET A BYTE OUT OF USER STREAM
|
||
RET ;error...
|
||
MOVE P1,T1 ;COPY BYTE INTO SAFE AC
|
||
ROT P1,-10 ;NEXT BYTE IS HIGHER ORDER THAN THIS
|
||
CALL DNGUBT ;GET BYTE NUMBER 2
|
||
RET ;error...
|
||
IOR P1,T1 ;ACCUMULATE THIS BYTE IN
|
||
ROT P1,-10 ;LET NEXT BYTE COME IN ABOVE THIS ONE
|
||
CALL DNGUBT ;GET BYTE NUMBER 3
|
||
RET ;error...
|
||
IOR P1,T1 ;ACCUMULATE IT IN
|
||
ROT P1,-10 ;NEXT BYTE IS THE HIGHEST ORDER BYTE
|
||
CALL DNGUBT ;GET THE LAST (4TH) BYTE
|
||
RET ;error...
|
||
IOR T1,P1 ;INCLUDE STUFF WE HAVE BEEN ACCUMULATING
|
||
ROT T1,30 ;ROTATE SO WE HAVE A REAL NUMBER
|
||
RETSKP ;RETURN WITH THE ENTIRE NUMBER IN T1
|
||
SUBTTL User strings -- Get and put single bytes into data strings.
|
||
;Call
|
||
; T1/ Byte to be put, or byte returned.
|
||
; T2/ Pointer to BP block
|
||
;Return
|
||
; RET on error, error code in NXERR
|
||
; RETSKP T1 deposited/loaded
|
||
;
|
||
;Note - These assume the caller has verified the byte pointer by calling
|
||
;CHKIND, to avoid the possibility of an indirect loop, and to insure that
|
||
;the destination byte stream is in core.
|
||
;For reasons of efficiency, T2 is guaranteed to be preserved.
|
||
|
||
|
||
DNPUBT:
|
||
OPSTRM <SOS T3,>,BPBYT,(T2) ;DECREMENT COUNT OF AVAILABLE BYTES
|
||
JUMPL T3,NTERES ;PARAMETERS TOO LONG
|
||
TMNE NXMCX,+NMXVAR ;Writing to monitor context?
|
||
IFSKP. ; -no
|
||
S1XCT <XCTBU [IDPB T1,(T2)]> ;deposit the byte in user context
|
||
ELSE. ; -yes,
|
||
IDPB T1,(T2) ; just a single deposit
|
||
ENDIF.
|
||
|
||
RETSKP
|
||
|
||
DNGUBT:
|
||
OPSTRM <SOS T3,>,BPBYT,(T2) ;DECREMENT COUNT OF BYTES PERMITTED
|
||
JUMPL T3,NTEPAM ;PARAMETER MISSING
|
||
S1XCT <
|
||
XCTBU [ILDB T1,(T2)] ;DO THE ILDB
|
||
>
|
||
RETSKP ;GOT THE BYTE IN T1 - RETURN SUCCESS
|
||
|
||
|
||
SUBTTL Miscellaneous -- Error returns
|
||
;;Error returns. Put error code in AC and .NTERR in user's block,
|
||
;and return non-skip.
|
||
|
||
DEFINE NMXERR(CODE),<
|
||
MOVX T1,^D'CODE ;ERROR CODE
|
||
JRST NTEERR ;AND DO ERROR
|
||
>
|
||
|
||
NTEUFO: NMXERR(-1) ;UNRECOGNIZED FUNCTION OR OPTION
|
||
NTEIMF: NMXERR(-2) ;INVALID MESSAGE FORMAT
|
||
NTEPRV: NMXERR(-3) ;PRIVILEGE VIOLATION.
|
||
NTEMPE: NMXERR(-5) ;MANAGEMENT PROGRAM ERROR
|
||
NTEUPT: NMXERR(-6) ;UNRECOGNIZED PARAMETER TYPE
|
||
NTEURC: NMXERR(-8) ;UNRECOGNIZED COMPONENT
|
||
NTEINI: NMXERR(-9) ;INVALID IDENTIFICATION
|
||
; NELCE%==-10 ;LINE COMMUNICATION ERROR
|
||
; NECWS%==-11 ;COMPONENT IN WRONG STATE
|
||
NTERES: NMXERR(-15) ;RESOURCE ERROR
|
||
NTEIPV: NMXERR(-16) ;INVALID PARAMETER VALUE
|
||
NTENRM: NMXERR(-20) ;NO ROOM (OR SLOT ALREADY TAKEN)
|
||
NTEPNA: NMXERR(-22) ;PARAMETER NOT APPLICABLE
|
||
NTEPVL: NMXERR(-23) ;PARAMETER VALUE TOO LONG
|
||
NTEOPF: NMXERR(-25) ;OPERATION FAILURE
|
||
NTEFNS: NMXERR(-26) ;FUNCTION NOT SUPPORTED
|
||
NTEIPG: NMXERR(-27) ;INVALID PARAMETER GROUPING
|
||
NTEPAM: NMXERR(-29) ;PARAMETER MISSING
|
||
NTEADC: NMXERR(-47) ;ADDRESS CHECK
|
||
|
||
NTEERR: STOR T1,NXERR,+NMXVAR ;Save the error code the Layer sent back
|
||
JE NFBFF,+NFWBLK,RTN ;If no buffer, return now
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the Counter Block
|
||
CALL DNFWDS ;Free up memory
|
||
SETZRO NFBUF,+NFWBLK ;Get rid of the address
|
||
SETZRO NFBFF,+NFWBLK ;and the flag
|
||
RET ;Return non-skip
|
||
|
||
SUBTTL Miscellaneous -- Name/number conversion.
|
||
;NMXA2N - Address to name conversion
|
||
;Call
|
||
; T1/ Node address
|
||
;Return
|
||
; RET ;No such node, illegal, ect.
|
||
; RETSKP, name in NXVAL ;on success
|
||
|
||
NMXA2N: SETZRO NFBUF,+NFWBLK ;SCLINK doesn't like anything in here....
|
||
STOR T1,NFEID,+NFWBLK ;Store the Node Address in the Argument block
|
||
MOVX T1,.NTNOD ;NODE ENTITY TYPE
|
||
STOR T1,NFETY,+NFWBLK ;Put it into the block
|
||
MOVX T1,NF.A2N ;Function code into T1
|
||
XMOVEI T2,NFWBLK ;Argument Block address
|
||
CALL SCLNMX ;CONVERT NODE ADDRESS TO NODE NAME
|
||
IFNSK.
|
||
SKIPE T1 ;Is it a zero error code?
|
||
JRST NTEERR ;No, It is a real error then...
|
||
SETZRO NXVAL,+NMXVAR ;SET BYTE COUNT AND NODE NAME TO 0
|
||
RETSKP ;And do an error return
|
||
ENDIF.
|
||
LOAD T1,NFBUF,+NFWBLK ;Get the SIXBIT Node Name
|
||
CALL NMXS2A ;Convert name and store it in NMXVAR block
|
||
RETSKP ;RETURN SUCCESS
|
||
|
||
;Convert SIXBIT Node Name to ASCII Node Name and save in NMXVAR Block
|
||
;Call
|
||
; T1/ SIXBIT Node Name
|
||
;Return
|
||
; RET always, ASCII Node Name stored in NXVAL,+NMXVAR
|
||
|
||
NMXS2A: SETZ T2, ;START OFF WITH ZERO BYTES RETURNED
|
||
MOVE T3,[POINT 6,T1] ;POINTER TO THE NODE NAME RETURNED
|
||
MOVEI T4,6 ;MAXIMUM NUMBER OF CHARACTERS TO CHECK
|
||
NMXS21: SOSL T4
|
||
IFNSK.
|
||
ILDB T5,T3 ;GET A BYTE FROM THE NAME
|
||
JUMPE T5,NMXS22 ;IF ZERO BYTE, END OF NAME
|
||
AOJA T2,NMXS21 ;ELSE KEEP COUNTING.
|
||
ENDIF.
|
||
NMXS22: MOVE T4,[POINT 6,T1] ;BYTE POINTER TO THE NODE NAME
|
||
MOVE T3,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO WHERE WE WANT NAME
|
||
IDPB T2,T3 ;START OFF STRINGID WITH NUMBER OF CHARACTERS
|
||
NMXS23: ILDB T5,T4 ;GET A BYTE FROM THE NAME
|
||
ADDI T5,^O40 ;MAKE IT ASCII
|
||
IDPB T5,T3 ;STORE IT IN NMXVAR IN STRINGID FORMAT
|
||
SOJG T2,NMXS23 ;AND CONTINUE COPYING UNTIL DONE.
|
||
RET
|
||
|
||
;NMXN2A - Name to address conversion
|
||
;Call
|
||
; NXVAL+NMXVAR/ Stringid for node name. Max 6 chars.
|
||
;Return
|
||
; RET ;Unknown name. NTEURC.
|
||
; RETSKP ;T1 contains node address.
|
||
|
||
NMXN2A: SETZ T1, ;START OFF WITH A CLEAN NODE NAME
|
||
MOVE T6,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO STRINGID WITH NAME
|
||
MOVE T5,[POINT 6,NF.EID+NFWBLK] ;BYTE POINTER TO CREATE SIXBIT NAME
|
||
ILDB T4,T6 ;GET COUNT OF BYTES
|
||
JUMPE T4,RTN ;IF NOTHING, ERROR
|
||
NMXN2B: ILDB T3,T6 ;GET A BYTE FROM THE NODE NAME
|
||
CAIL T3,^O140 ;IS IT LOWER CASE
|
||
SUBI T3,^O40 ;MAKE IT UPPER CASE
|
||
SUBI T3,^O40 ;MAKE IT SIXBIT
|
||
IDPB T3,T5 ;STORE IT IN THE NODE NAME
|
||
SOJG T4,NMXN2B ;AND LOOP UNTIL BYTES EXHAUSTED.
|
||
|
||
MOVX T1,.NTNOD ;NODE ENTITY TYPE
|
||
STOR T1,NFETY,+NFWBLK ;Send it to Session Control Layer
|
||
MOVX T1,NF.N2A ;Get the Function Code
|
||
XMOVEI T2,NFWBLK ;And the address of the Argument Block
|
||
CALL SCLNMX ;CONVERT NODE NAME TO NODE ADDRESS
|
||
JRST NTEERR ;SESSION CONTROL CAN'T FIND THE NAME. ERROR.
|
||
LOAD T1,NFBUF,+NFWBLK ;Put the address into T1
|
||
RETSKP ;SUCCESS. T1 CONTAINS NODE ADDRESS.
|
||
|
||
|
||
|
||
XLIST
|
||
LIT
|
||
LIST
|
||
IFN FTOPS10, .XCMSY
|
||
IFN FTOPS20, TNXEND
|
||
IFN FTOPS10,<
|
||
RESDT
|
||
NTMLOW::!
|
||
XRESCD
|
||
>; END IFN FTOPS10
|
||
END
|