Trailing-Edge
-
PDP-10 Archives
-
BB-X116A-BB_1984
-
ntman.mac
There are 26 other files named ntman.mac in the archive. Click here to see a list.
;DNET:NTMAN.MAC[10,36,MON,NEW], 05-Oct-1983 03:21:15, Edit by TARL
;MCO 10994 - Fixes to MCO 10988
;DNET:NTMAN.MAC[10,36,MON,NEW], 29-Sep-1983 20:54:32, Edit by TARL
;MCO 10988 - Add interface to DLL via KONDSP functions KF.xxx
;DNET:NTMAN.MAC[10,36,MON,NEW], 22-Sep-1983 23:20:34, Edit by TARL
;MCO 10971 - Grand Re-merge of the -10/-20 sources
;TITLE NTMAN - Network Management Interface for DECnet-36
SUBTTL Tarl Neustaedter
SEARCH D36PAR,MACSYM
SALL
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
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<
COPYRIGHT (C) 1984 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
>
>;END IFN FTOPS10
D36SYM ;SET UP D36 SPECIFIC PARAMETERS
$RELOC
ENTRY NTMAN ;TO FORCE LINK TO LOAD WITH REST OF DECNET
SUBTTL Table of Contents
SUBTTL Table of Contents
; Table of Contents for NTMAN
;
;
; Section Page
; 1. Table of Contents. . . . . . . . . . . . . . . . . . . 3
; 2. Data structures
; 2.1. Value definitions . . . . . . . . . . . . . . 4
; 2.2. BEGSTR NT . . . . . . . . . . . . . . . . . . 5
; 2.3. BEGSTRs NQ,EL . . . . . . . . . . . . . . . . 6
; 2.4. Byte pointers into NSP node block . . . . . . 7
; 2.5. Parameter and counter definitions . . . . . . 8
; 3. NTMAN
; 3.1. Entry . . . . . . . . . . . . . . . . . . . . 14
; 3.2. Get pertinent data from user's data block . . 15
; 3.3. Dispatch to functions . . . . . . . . . . . . 16
; 4. Functions
; 4.1. .NTPSI - Set event PSI. . . . . . . . . . . . 17
; 4.2. .NTMAP - Map node name/number . . . . . . . . 18
; 4.3. .NTREX - Return local node number . . . . . . 19
; 4.4. .NTSET,.NTCLR - Parse and process a parameter 20
; 4.5. .NTZRO,.NTSZC - Zero counters . . . . . . . . 21
; 4.6. .NTSHO
; 4.6.1. Select parameters to return. . . . . 22
; 4.6.2. Return parameters to user. . . . . . 23
; 4.7. .NTRET
; 4.7.1. List node names. . . . . . . . . . . 24
; 4.7.2. List circuit and line names. . . . . 25
; 4.8. .NTEVQ - Pass queued event to user. . . . . . 26
; 5. Entities
; 5.1. Convert entity names to entity ids. . . . . . 27
; 5.2. Circuit ID to name conversion . . . . . . . . 28
; 5.3. Convert name to Circuit-ID. . . . . . . . . . 29
; 6. Layers
; 6.1. Main interface to layer levels. . . . . . . . 30
; 6.2. Read/set NSP node blocks. . . . . . . . . . . 31
; 6.3. Read/set RTR circuit blocks . . . . . . . . . 32
; 6.4. Read/set node state . . . . . . . . . . . . . 33
; 6.5. Read/set logging masks. . . . . . . . . . . . 34
; 6.6. Read/set for executor node. . . . . . . . . . 35
; 6.7. Read/set RTR node information . . . . . . . . 36
; 6.8. Find circuit which points to a node . . . . . 37
; 6.9. Set/clear node names. . . . . . . . . . . . . 38
; 6.10. Create/Destroy loopback nodes . . . . . . . . 39
; 7. Events
; 7.1. Event receiver. . . . . . . . . . . . . . . . 40
; 7.2. Mask out unwanted events. . . . . . . . . . . 41
; 8. User strings
; 8.1. Write parameter with nice . . . . . . . . . . 42
; 8.2. Write coded data. . . . . . . . . . . . . . . 43
; 8.3. Write ascii image data. . . . . . . . . . . . 44
; 8.4. Write numeric data. . . . . . . . . . . . . . 45
; 8.5. Read a number from user . . . . . . . . . . . 46
; 8.6. Read and write milliseconds . . . . . . . . . 47
; 8.7. Copy STRINGID from user to exec . . . . . . . 48
; 8.8. Copy STRINGID from exec to user . . . . . . . 49
; 8.9. Get and put user byte routines. . . . . . . . 50
; 8.10. Get and put single bytes into data strings. . 51
; 9. Miscellaneous
; 9.1. String compare which handles upper/lower case 52
; 9.2. Error returns . . . . . . . . . . . . . . . . 53
; 9.3. Name/number conversion. . . . . . . . . . . . 54
; 10. Data base
; 10.1. Find NMX per-entity data base . . . . . . . . 55
; 10.2. Find an NSP node block. . . . . . . . . . . . 56
; 10.3. Find an existing NSP node block . . . . . . . 57
; 11. Data Base
; 11.1. NMXNMI - Get node software ID.. . . . . . . . 58
SUBTTL Data structures -- Value definitions
;AC definitions
TM=FREE0 ;A WORK AC. PRESERVED
NT=FREE2 ;POINTS TO THE TABLE FORMAT BLOCK
;Network managment circuit states
XP NCK.ON,0 ;CIRCUIT/LINE STATE ON
XP NCK.OF,1 ;STATE OFF
XP NCK.SR,2 ;SERVICE
XP NCK.CL,3 ;CLEARED
;Network management non-error code
XP NESUC%,1
;Entity types
.NTNOD==0 ;NODE ENTITY
.NTLIN==1 ;LINE
.NTCKT==3 ;CIRCUIT
;Function codes
.NTPSI==-3 ;SET PSI MASK (TOPS20 ONLY)
.NTSET==0 ;FOR SPECIAL CASE CHECK
.NTEVQ==6 ;REMOVE AN ITEM FROM THE EVENT QUEUE
;Qualifiers for functions
.NTLOP==-3 ;LOOP
.NTACT==-2 ;ACTIVE ITEMS
.NTKNO==-1 ;KNOWN ITEMS ;(FOR .NTRET)
.NTSUM==0 ;SUMMARY ;(FOR .NTSHO)
.NTCOU==3 ;COUNTERS
;Offsets to important locations in block
.NTBPT==6 ;BYTE POINTER TO DATA STRING
.NTBYT==7 ;BYTE COUNT FOR DATA STRING
.NTERR==10 ;RETURN CODE, OR ERROR CODE
XP .NQMXS,44 ;MAXIMUM EVENT STRING LENGTH IN BYTES.
;MACRO TO CALL A ROUTINE, KNOWING THAT THE ROUTINE CAN RETURN NON-SKIP
;MEANING AN ERROR. THIS ERROR WOULD SIMPLY POPJ ALL THE WAY BACK TO THE
;TOP. NOTE THAT THE BOTTOM LEVEL MUST HAVE SET AN ERROR CODE IN NXERR.
DEFINE ECALL(ROUTINE),<
CALL ROUTINE
RET
>
;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 ERRRET(ROUTINE),<JSP CX,ROUTINE>
$LOW
NMXLST: BLOCK 1 ;LOST EVENT FLAG
NMXIDN: BLOCK 1 ;POINTER TO EXECUTOR IDENTIFICATION IF SET
NMXNDQ::BLOCK QH.LEN ;QUEUE HEADER FOR NMX NODE BLOCKS
NMXEVQ::BLOCK QH.LEN ;QUEUE HEADER FOR EVENT BLOCKS
$HIGH ;RELOC TO HIGHSEG (RSCOD PSECT ON TOPS-20)
EXTERN DNGWDZ,DNGWDS,DNGEBL,DNFEBL,DNFWDS,NMXTIM,NMXPRV ;D36COM
EXTERN TIMBAS,DNGTIM ;D36COM
EXTERN RTRMXN,RTRNRV,RTRADR,RTNLID,RTNGLS,RTRNMX,RTNSLS,RTRCBQ ;RTR
EXTERN RTNGLB,RTRKBA ;RTR
EXTERN RTN,RSKP,CHKBPT,KONNAM
EXTERN SCTN2A,SCTA2N,SCTAND ;SCT
IFN FTOPS10,<EXTERN GETWRD,GETWR1,PSIDVT>
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 TO INCLUDE COUNTERS AS DATA TYPES
; 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.FCO,^D10 ;COUNTER (NOT REAL DATA TYPE, SPECIAL CASED)
XP NT.FCB,^D11 ;BIT MAPPED COUNTER (DITTO ABOVE, POWER OF 2)
FIELD LEN,5 ;LENGTH
FIELD ROU,6 ;INDEX TO ROUTINE TO CALL
FIELD APL,3 ;APPLICABILITY RESTRICTIONS (NOTE - THIS REALLY)
BIT A.E ;EXECUTOR (BELONGS IN NEXT )
BIT A.L ;LOOP NODES (WORD, BUT WE RAN )
BIT A.R ;REMOTE NODES. (OUT OF SPACE. )
FIELD IDX,18 ;VALUE TO PASS TO DATA ROUTINE
;NOTE THAT THE FOLLOWING ENTRIES ARE ONLY IN THE PRIMARY TABLE,
; THEY ARE NOT INCLUDED IN CODED MULTIPLE SUB-ENTRIES
NXTWRD ;FORCE NEXT WORD ALIGNMENT.
FIELD SEQ,12 ;SEQUENCE OR TYPE OF FIELD
FIELD INF,4 ;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.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 DFL,18 ;DEFAULT VALUE. USUALLY ZERO
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)
SUBTTL Data structures -- BEGSTRs NQ,EL
BEGSTR NQ
WORD NXT ;POINTER TO NEXT EVENT IN QUEUE
FIELD CCL,13 ;EVENT CLASS
FIELD CTY,5 ;EVENT TYPE
WORD TIM ;TIME STAMP
HWORD ETP ;ENTITY TYPE
WORD EID ;ENTITY ID
WORD STR,<.NQMXS/4> ;PLACE TO SAVE STRING PASSED TO US.
ENDSTR
SUBTTL Data structures -- Byte pointers into NSP node block
;Define byte pointers for parameters in the node block.
NSPLKM: POINTR(NN.LKM(T1),NNLKM) ;BYTE POINTER. POINT T1 TO NODE BLOCK.
NSPDLX: POINTR(NN.DLY(T1),NNDLY) ;DITTO.
;Counters
NSPTMC: POINTR(NN.TMC(T1),NNTMC)
NSPRBC: POINTR(NN.RBC(T1),NNRBC)
NSPXBC: POINTR(NN.XBC(T1),NNXBC)
NSPRMC: POINTR(NN.RMC(T1),NNRMC)
NSPXMC: POINTR(NN.XMC(T1),NNXMC)
NSPRCC: POINTR(NN.RCC(T1),NNRCC)
NSPXCC: POINTR(NN.XCC(T1),NNXCC)
NSPLKC: POINTR(NN.LKC(T1),NNLKC)
NSPCRC: POINTR(NN.CRC(T1),NNCRC)
;NMX dispatch table. Routines are indexes into this table.
NMXDSP:
PHASE 0 ;Make labels be relative offsets.
NMXMIN:! ;Lowest offset for NMXDSP
NSP:! IFIW NMXNSP ;Call NMX's NSP NMX server
EXE:! IFIW NMXEXE ;Call for EXECUTOR node
XND:! IFIW NMXXND ;Call for RTR node stuff
CIR:! IFIW NMXCIR ;Single entry for Circuit of a node
RTL:! IFIW NMXRTL ;Line block entries.
RTD:! IFIW NMXRTD ;Special case of rtl. Return node name.
NMC:! IFIW NMXNMC ;Call SCTAND
RTS:! IFIW NMXRTS ;Router state setting/reading.
RTB:! IFIW NMXRTB ;Router substate reading
NMS:! IFIW NMXNMS ;Network management state setting/reading
NMI:! IFIW NMXNMI ;Get Identification string
LLP:! IFIW NMXLLP ;Loopback type
DLL:! IFIW NMXDLL ;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%,ER ,R,NMS,0) ;State.
N(100 ,AI,31 ,C%,E ,,NMI,0) ;Identification
N(500 ,AI,6 ,N,R ,W,NMC,0) ;Name of node (set only)
N(501 ,AI,16 ,C%,L ,,LLP,0) ;Circuit
N(510 ,DM,2 ,C,E ,,EXE,SCTINT##, %SCINT##) ;Incoming timer
N(511 ,DM,2 ,C,E ,,EXE,SCTOTT##, %SCOTT##) ;Outgoing timer
N(600 ,DU,2 ,S%,ER ,R,NSP,NSPLKC) ;Active links.
N(601 ,DM,2 ,S%,R ,R,NSP,NSPDLX) ;Delay
N(700 ,CM,3 ,C,E ,R) ;NSP version
CMENT(DU,1 ,EXE,NSPVER##) ; Version number
CMENT(DU,1 ,EXE,NSPECO##) ; ECO number
CMENT(DU,1 ,EXE,NSPUEC##) ; User ECO number
N(720 ,DU,1 ,C,E ,,EXE,NSPDLY##, %NSDLY##) ;Delay factor.
N(721 ,DU,1 ,C,E ,,EXE,NSPWGT##, %NSWGT##) ;Delay weight.
N(722 ,DU,2 ,C,E ,,EXE,NSPINA##, %NSINA##) ;Inactivity timer.
N(723 ,DU,2 ,C,E ,,EXE,NSPRTH##, %NSRTH##) ;Retransmit factor.
N(820 ,DU,2 ,S,R ,R,XND,RTNCST##) ;Cost
N(821 ,DU,1 ,S,R ,R,XND,RTNHOP##) ;Hops
N(822 ,AI,16 ,S%,R ,R,CIR,0) ;circuit
N(900 ,CM,3 ,C,E ,R) ;Routing version
CMENT(DU,1 ,EXE,RTRVER##) ; Version number
CMENT(DU,1 ,EXE,RTRECO##) ; ECO number
CMENT(DU,1 ,EXE,RTRCUS##) ; User ECO number
N(901 ,C,1 ,C,E ,R,EXE,RTRTYP##) ;Type
N(910 ,DM,2 ,C,E ,,EXE,RTRTM1##, %RTTM1##) ;Routing timer.
N(920 ,DU,2 ,C,E ,R,EXE,RTRMXN##) ;Maximum address.
N(922 ,DU,2 ,C,E ,,EXE,RTRMXC##, %RTMXC##) ;Maximum cost.
N(923 ,DU,1 ,C,E ,,EXE,RTRMXH##, %RTMXH##) ;Maximum hops.
N(924 ,DU,1 ,C,E ,,EXE,RTRMXV##, %RTMXV##) ;Maximum visits.
N(931 ,DU,2 ,C,E ,R,EXE,RTRBSZ##) ;Buffer size.
>
DEFINE LINE$P,<
N(0 ,C,1 ,S%, ,,DLL,0, NCK.OF) ;State
N(1 ,C,1 ,S%, ,R,DLL,0) ;Substate
N(1110 ,C,1 ,C, ,,DLL,0) ;Controller
N(1112 ,C,1 ,C, ,,DLL,0) ;Protocol
>
DEFINE CIRC$P,<
N(0 ,C,1 ,S%, ,,RTS,, NCK.OF) ;State.
N(1 ,C,1 ,S%, ,R,RTB,) ;Substate
N(800 ,CM,2 ,S%, ,R) ;Adjacent node
CMENT(DU,2 ,RTL,RTLNAD##) ; Node address
CMENT(AI,6 ,RTD,RTLNAD##) ; Node Name.
N(810 ,DU,2 ,S, ,R,RTL,RTLBSZ##) ;Block size
N(900 ,DU,1 ,C, ,,RTL,RTLCST##, 1) ;Cost.
N(906 ,DM,2 ,C, ,,RTL,RTLTM3##, %RTTM3##) ;Hello timer
N(907 ,DM,2 ,C, ,,RTL,RTLTM4##, %RTTM4##) ;Listen timer
>
DEFINE NODE$C,<
N(0 ,CO,2 ,, ,,NSP,0) ;seconds since last zeroed
N(600 ,CO,4 ,, ,,NSP,NSPRBC) ;Bytes received
N(601 ,CO,4 ,, ,,NSP,NSPXBC) ;Bytes sent
N(610 ,CO,4 ,, ,,NSP,NSPRMC) ;Messages received.
N(611 ,CO,4 ,, ,,NSP,NSPXMC) ;Messages sent
N(620 ,CO,2 ,, ,,NSP,NSPRCC) ;Connects received.
N(621 ,CO,2 ,, ,,NSP,NSPXCC) ;Connects sent
N(630 ,CO,2 ,, ,,NSP,NSPTMC) ;Response timeouts
N(640 ,CO,2 ,, ,,NSP,NSPCRC) ;Recv connect resource errors
N(900 ,CO,1 ,,E ,,EXE,RTRCAP##) ;Aged packet loss
N(901 ,CO,2 ,,E ,,EXE,RTRCNU##) ;Node unreachable packet loss
N(902 ,CO,1 ,,E ,,EXE,RTRCNO##) ;Node out-of-range packet loss
N(903 ,CO,1 ,,E ,,EXE,RTRCOP##) ;Oversised packet loss
N(910 ,CO,1 ,,E ,,EXE,RTRCPF##) ;Packet format error
N(920 ,CO,1 ,,E ,,EXE,RTRCPR##) ;Partial routing update loss
N(930 ,CO,1 ,,E ,,EXE,RTRCVR##) ;Verification reject
>
DEFINE LINE$C,< ;Line counters
N(1100 ,CO,1 ,, ,,DLL,0) ;Remote process errors
N(1101 ,CO,1 ,, ,,DLL,0) ;Local process errors
>
DEFINE CIRC$C,< ;Circuit counters
N(0 ,CO,2 ,, ,,RTL,0) ;Seconds since last zeroed.
N(800 ,CO,4 ,, ,,RTL,RTLCAP##) ;Arriving packets received
N(801 ,CO,4 ,, ,,RTL,RTLCDP##) ;Departing packets sent
N(802 ,CO,2 ,, ,,RTL,RTLCAL##) ;Arriving congestion loss
N(810 ,CO,4 ,, ,,RTL,RTLCTR##) ;Transit packets received
N(811 ,CO,4 ,, ,,RTL,RTLCTS##) ;Transit packest sent
N(812 ,CO,2 ,, ,,RTL,RTLCTL##) ;Transit congestion loss
N(820 ,CO,1 ,, ,,RTL,RTLCCD##) ;Line down
N(821 ,CO,1 ,, ,,RTL,RTLCIF##) ;Initialization failure
N(1000 ,CO,4 ,, ,,RTL,RTLBYR##) ;Bytes received
N(1001 ,CO,4 ,, ,,RTL,RTLBYS##) ;Bytes sent
N(1010 ,CO,4 ,, ,,RTL,RTLDBR##) ;Data blocks received
N(1011 ,CO,4 ,, ,,RTL,RTLDBS##) ;Data blocks sent
>
DEFINE DEFLAB(LABEL),<CM.'LABEL>
..LBL==0 ;Start off at CM.1
DEFINE NLABEL,<..LBL=..LBL+1
DEFLAB(\..LBL)>
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(.SEQ,.INF,.SET,.DFL),<
IFGE <^D'.SEQ-.M(NTSEQ)>,<PRINTX ?Parameter .SEQ will not fit in NTSEQ>
XPAND(INF,NTI.,.INF)
DFL==.DFL
<<^D'.SEQ>B<SEQ$>&NTSEQ>!
<INF&NTINF>!
<<NTS.'.SET>B<SET$>&NTSET>!
<DFL&NTDFL>
>
;Define rightmost positions of fields, for ddt
NTN==:<1B<POS(NTSEQ)>!1B<POS(NTINF)>!1B<POS(NTSET)>!1B<POS(NTDFL)>>
NSS==:<1B<POS(NTTYP)>!1B<POS(NTLEN)>!1B<POS(NTROU)>!1B<POS(NTAPL)>!1B<POS(NTIDX)>>
;Example - NTN$3M NODEP+3$10r$o/ 100.,10.,4.,0.,0.
;displays fields NTSEQ, NTINF, NTSET, NTDFL .
;Macro to define secondary entry (Format)
DEFINE STENT(.TYP,.LEN,.ROU,.IDX,.APL),<
IFGE <.ROU-NMXMAX>,<PRINTX ?Routine .ROU out of range [.IDX]>
IFGE <^D'.LEN-.M(NTLEN)>,<PRINTX ?Parameter .LEN will not fit in NTLEN>
XPAND(APL,NTA.,.APL)
<APL&NTAPL>!
<<NT.F'.TYP>B<TYP$>&NTTYP>!
<<^D'.LEN>B<LEN$>&NTLEN>!
<<.ROU>B<ROU$>&NTROU>!
.IDX
>
DEFINE N(.SEQ,.TYP,.LEN,.INF,.APP,.SET,.ROU,.IDX,.DFL),<
IFN LASTLN,<PRINTX ?NMXPHE Phase error in previous CM (This .SEQ, .TYP, .LEN).
PRINTX [SEQ=.SEQ, TYP=.TYP, LEN=.LEN, INF=.INF, APP=.APP, SET=.SET]
LASTLN=0>
IFN <NT.F'.TYP-NT.FCM>,<IFB <.ROU>,<
PRINTX ?NMXILD Illegal to default unless multiple (.SEQ,.TYP,.LEN)
PRINTX [SEQ=.SEQ, TYP=.TYP, LEN=.LEN, INF=.INF, APP=.APP, SET=.SET]
>
>
IFE <NT.F'.TYP-NT.FCM>,<IFNB <.ROU>,<
PRINTX ?NMXMDM Must default in multiple (.SEQ,.TYP,.LEN)
PRINTX [SEQ=.SEQ, TYP=.TYP, LEN=.LEN, INF=.INF, APP=.APP, SET=.SET]
>
LASTLN==.LEN ;;NUMBER OF FIELDS TO FOLLOW.
NLABEL : ;;DEFINE LABEL FOR THESE CM ENTRIES
>
>
DEFINE CMENT(.TYP,.LEN,.ROU,.IDX),<
LASTLN=LASTLN-1 ;DECREMENT NUMBER YET TO GO.
STENT(.TYP,.LEN,.ROU,.IDX,)
>
LASTLN=0
;Define all the coded multiple subentries - Should all go in a
; contiguous block, with labels pointing at each sub-group
CMBLK:
NODE$P
LINE$P
CIRC$P
..LBL=0 ;RE-SET LABEL NAMES, SO WE GET THE SAME
; LABELS THE SECOND TIME THROUGH.
;Define all the REAL stuff now.
DEFINE N(.SEQ,.TYP,.LEN,.INF,.APP,.SET,.ROU,.IDX,.DFL),<
IDX=.IDX
IFE <NT.F'.TYP-NT.FCM>,<IDX=DEFLAB(\<..LBL+1>)
..LBL=..LBL+1
>
STENT(.TYP,.LEN,.ROU,IDX,.APP)
NTENT(.SEQ,.INF,.SET,.DFL)
>
DEFINE CMENT(.TYP,.LEN,.ROU,.IDX),<> ;ALREADY DEFINED ALL THESE.
DEFINE MAKTAB(.LAB,.STF),<
XLIST
.LAB::.STF
.LAB'L==:.-.LAB
LIST
>
MAKTAB(NODEP,NODE$P)
MAKTAB(NODEC,NODE$C)
MAKTAB(LINEP,LINE$P)
MAKTAB(LINEC,LINE$C)
MAKTAB(CIRCP,CIRC$P)
MAKTAB(CIRCC,CIRC$C)
;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.
CNTP:: XWD <-NODECL/NT.LST>,NODEC ;NODE PARAMETERS
XWD <-LINECL/NT.LST>,LINEC ;LINE PARAMETERS
Z ;LOGGING PARAMETERS
XWD <-CIRCCL/NT.LST>,CIRCC ;CIRCUIT PARAMETERS
Z ;MODULE - WE DON'T HAVE ANY
Z ;EVENTS - CAN'T SET ANYTHING.
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
>
SEC1 ;DO THE UUO IN SECTION 1
TRVAR <<NMXVAR,NX.LST>> ;SET UP TRVAR
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
IFN FTOPS10,STOR T6,NXUUO,+NMXVAR ;** TOPS10 CALLS US WITH M/ UUO EXECUTED
CALL GETBLK ;GET STUFF FROM USER PARAMETER BLOCK
ERRRET NTERXI ;DIDN'T MAKE IT. SOMETHING WRONG.
CALL NMXDIS ;DISPATCH TO ROUTINES (IN NTMAN)
ERRRET NTERXI ;ERROR EXIT OF SOME KIND. CHECK.
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: We have come back from NTMAN with aa skip return, but there
is an error code stored in field NXERR.
Cure: Find out who is giving the error code (or trashing NXERR) and
make him give a non-skip return.
>,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: Some routine has returned non-skip, but has not given
an error code by calling NTExxx. This means that we returned
to top level, and field NXERR was zero.
Cure: 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
CALL 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:
CALL NMXPRV ;MAKE SURE WE ARE PRIVED.
ERRRET NTEPRV ;NOPE, GIVE THE NO PRIVS RETURN
SAVEAC P1 ;SO WE CAN HOLD SOME STUFF
LOAD T6,NXADR,+NMXVAR ;GETWRD UNDERSTANDS T6 AS ADDRESS.
CALL GETWRD ;GET FIRST WORD OF BLOCK
ERRRET NTEADC ;NO GO. CAN'T HAPPEN
CAIGE T1,.NTERR ;MAKE SURE BLOCK INCLUDES .NTERR
ERRRET NTEADC ;NOPE, ADDRESS CHECK.
CALL GETWR1 ;GET NEXT WORD IN BLOCK
ERRRET NTEADC ;ADDRESS CHECK
CAXL T1,.NTNOD ;RANGE CHECK THE ENTITY TYPE
CAXLE T1,.NTCOU
ERRRET NTEINI ;BAD ENTITY TYPE
STOR T1,NXENT,+NMXVAR ;SAVE AS ENTITY TYPE
CALL GETWR1 ;GET BYTE POINTER TO ENTITY ID
ERRRET NTEADC
MOVE P1,T6 ;SAVE POINTER TO ARG BLOCK FOR A WHILE
MOVX T2,^D16 ;THIS COULD BE AS MUCH AS 16 BYTES
CALL CHKBPT ;ASK IF THIS IS A GOOD BYTE POINTER
ERRRET NTEADC ;NOPE - BAD BYTE POINTER
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
CALL GETWR1 ;GET FUNCTION TO BE PERFORMED
ERRRET NTEADC ;SIGH.
CAXL T1,.NTPSI ;RANGE CHECK FUNCTION
CAXLE T1,.NTEVQ
ERRRET NTEUFO ;BAD FUNCTION
STOR T1,NXFNC,+NMXVAR ;SAVE AWAY.
CALL GETWR1 ;GET SELECTION CRITERIA
ERRRET NTEADC
STOR T1,NXSEL,+NMXVAR ;STASH AWAY
CALL GETWR1 ;GET FUNCTION QUALIFIER
ERRRET NTEADC
;I DON'T KNOW WHAT TO DO WITH THIS. TOSS.
CALL GETWR1 ;GET BYTE POINTER TO FUNCTION QUALIFIER
ERRRET NTEADC
MOVE P1,T1 ;HANG ON TO BYTE POINTER FOR A WHILE
CALL GETWR1 ;GET BYTE COUNT OF STRING
ERRRET NTEADC
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
CALL CHKBPT ;ASK IF THIS BYTE POINTER IS ANY GOOD
ERRRET NTEADC ;NOPE.
STOR T1,NXDAT,+BP.BPT+NMXVAR ;SAVE FOR GETBYT
MOVE T6,P1 ;GET BACK POINTER TO THE USER ARG BLOCK
CALL GETWR1 ;MAKE SURE .NTERR IS IN CORE
ERRRET NTEADC ;I'LL BE DAMMNED. IT WASN'T.
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
SUBTTL NTMAN -- Dispatch to functions
NMXDIS:
LOAD P1,NXENT,+NMXVAR ;GET ENTITY TYPE
LOAD T1,NXFNC,+NMXVAR ;GET FUNCTION CODE
MOVE T2,<-.NTPSI>+[ ;GET FLAG BITS FOR THIS FUNCTION
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
ECALL ENTCVT ;CONVERT THE ENTITY TO AN ID
LOAD T1,NXFNC,+NMXVAR ;GET FUNCTION CODE BACK AGAIN.
NMXDI2:
CAXL T1,.NTPSI ;RANGE CHECK FUNCTION
CAXLE T1,.NTEVQ ; CODE.
BUG.(CHK,NTMFUR,NTMAN,SOFT,<Function code out of range>,,<
Cause: We are going to dispatch by function code, and we have
found that the function code is 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,.NTCKT ; TYPE.
BUG.(CHK,NTMEOR,NTMAN,SOFT,<Entity type out of range>,,<
Cause: We are double checking the entity ID, before dispatching
on it, and we have found the value to be illegal. Since the
value the user supplies is checked at GETBLK, this means that
field NXENT has been trashed.
>,NTEMPE)
CALLRET @.+1-.NTPSI(T1) ;DISPATCH TO APPROPRIATE ROUTINE.
IFIW NTLPSI ;.NTPSI - SET EVENT INTERRUPT (TOPS-20 ONLY)
IFIW NODMAP ;.NTMAP - MAP NODE NUMBERS AND NAMES
IFIW NODLOC ;.NTREX - RETURN ENTITY ID FOR EXECUTOR
IFIW PRSPRM ;.NTSET - SET A PARAMETER
IFIW PRSPRM ;.NTCLR - CLEAR A PARAMETER
IFIW PRSCOU ;.NTZRO - ZERO COUNTERS
IFIW SELITM ;.NTSHO - SHOW PARAMETERS/COUNTERS
IFIW PRSCOU ;.NTSZC - SHOW AND ZERO COUNTERS
IFIW @<-.NTNOD>+[ ;.NTRET - LIST ENTITIES
IFIW NMXLND ; .NTNOD - NODE
IFIW NMXLCK ; .NTLIN - LINE
IFIW NTEURC ; .NTLOG - DOESN'T EXIST
IFIW NMXLCK](P1); .NTCKT - CIRCUIT
IFIW GETEVT ;.NTEVQ - PASS A QUEUED EVENT TO USER
SUBTTL Functions -- .NTPSI - Set event PSI
NTLPSI:
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?
JRST NTEMPE ;NO, ONLY ONE EVENT READER IS ALLOWED
ENDIF.
MOVE T1,.NTSEL(Q1) ;GET USER'S PSI CHANNEL
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
JRST NTEMPE ;ILLEGAL
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
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
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
CALL PSIRQ ;LET HIM KNOW
RET ;DONE.
;ASSERT EVENT PSI FOR SCHEDULER TO CATCH
;MAY BE CALLED AT ANY LEVEL.
;CALL PSIDVT
;RETURNS +1 ALWAYS
; RESCD ;MUST BE RESIDENT
PSIDVT::SETOM NMLPSI ;SET FLAG FOR SCHEDULER.
RET
>;END IFN FTOPS20
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
ECALL GET2BT ;GET NODE NUMBER
STOR T1,NXNUM,+NMXVAR ;STORE ENTITY ID (MAYBE)
ECALL GETSTR ;COPY SOME BYTES
JE NXVAL,+NMXVAR,NODMA2 ;IF NO NAME, HE GAVE US AN ADDR
CALL NMXN2A ;CONVERT NAME IN NXVAL TO NUMBER
ERRRET NTEURC ;SAY THAT IT FOULED UP.
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
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
CAMLE T1,RTRMXN ;MAKE SURE IN RANGE.
ERRRET NTEURC ;HE GAVE US A BAD NODE NUMBER
CALL NMXA2N ;CONVERT NODE ADDRESS TO NODE NAME
TRN
NODMA3: LOAD T1,NXNUM,+NMXVAR ;GET NODE NUMBER
ECALL PUT2BT ;PUT INTO DATA STRING
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:
CAXE P1,.NTNOD ;THIS FUNCTION ONLY VALID FOR NODE ENTITY
ERRRET NTEUFO ;ERROR "FUNCTION ILLEGAL FOR THIS ENTITY"
MOVE T1,RTRADR ;GET OUR NODE ADDRESS
ECALL PUT2BT ;SEND TWO BYTES INTO THE OUTPUT STRING.
SETZ T1, ;NO NODE NAME (DON'T BOTHER)
CALLRET PUTBYT ;STORE AWAY IN USER STRING
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
JE NXDAT,+BP.BYT+NMXVAR,TABCLR ;IF NO PARAMETER, TRY CLEAR ALL
ECALL GET2BT ;GET DATA-ID FIELD.
STOR T1,NXPRM,+NMXVAR ;STORE SEQUENCE NUMBER (THIS WILL BE CHANGED
; LATER, WHEN WE FIND THE ENTRY IN NMXTAB)
ASH T1,-^D15 ;SHIFT SO 11-ISH BIT 15 IS IN BOTTOM
LOAD T2,NXCXP,+NMXVAR ;DOES BLOCK SAY PARAMETER OR COUNTER
CAME T2,T1 ;DO WE MATCH FUNCTION WITH DATA STREAM?
ERRRET NTEPNA ;NOPE - ILLEGAL DATA STREAM.
LOAD T1,NXPRM,+NMXVAR ;GET SEQUENCE NUMBER IN SCRATCH AC.
;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.
STOR T2,NXPRM,+NMXVAR ;SAVE VALUE TO PASS TO CALLED ROUTINE.
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 T1,NXNTY,+NMXVAR ;GET TYPE OF NODE
MOVE T1,[NTA.E ;BIT INIDICATING EXECUTOR
NTA.R ; REMOTE
NTA.L]-1(T1) ; LOOPBACK
TDNN T1,NT.APL(NT) ;DOES THIS PARAMETER APPLY TO THIS NODE TYPE?
ERRRET NTEPNA ;NO, PARAMETER NOT APPLICABLE
TABSR1: JN NXZMC,+NMXVAR,TABSR2 ;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.FDM ;OR GREATER THAN DECIMAL MILLISECONDS
TABSRE: BUG.(CHK,NTMBFP,NTMAN,SOFT,<Bad format type encountered>,,<
Cause: We are 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 should tell you which item is being referred to.
Cure: Fix the entry for this item to contain a valid format type.
>,NTEMPE)
CALL <-NT.FC>+@[ ;DISPATCH ACCORDING TO FORMAT TYPE
IFIW NMXRNC ;ORDINARY CODED.
IFIW TABSRE ;CODED MULTIPLE. ILLEGAL
IFIW GETSTR ;ASCII IMAGE. WILL ALSO BE STRINGID
IFIW NMXRNU ;DECIMAL UNSIGNED.
IFIW NMXRNS ;DECIMAL SIGNED.
IFIW NMXRNU ;HEX INTEGER.
IFIW GETSTR ;HEX IMAGE. STRING ID.
IFIW NMXRNU ;OCTAL - READ AS DECIMAL UNSIGNED
IFIW NMXRNM](T1);MILLISECONDS (REALLY DECIMAL UNSIGNED)
RET ;PROPAGATE ERROR
TABSR2: CALLRET NMXLAY ;HAVE THE LAYER DO THE REST.
;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: ECALL NMXLAY ;CALL THE LAYER TO CLEAR THIS PARAMETER
TABCL5: ADD NT,[1,,NT.LST] ;INCREMENT POINTER, DECREMENT COUNT
JRST TABCL1 ;AND DO THE NEXT PARAMETER
SUBTTL Functions -- .NTZRO,.NTSZC - Zero counters
;Called from NMXDIS
;Call
; T1/ Functions (from NXFNC)
;Return
; RET Error, code stored in NXERR
; RETSKP Counters have been processed
PRSCOU:
SAVEAC NT
MOVE NT,CNTP(P1) ;GET FORMAT POINTER FOR COUNTERS FOR ENTITY
SETONE NXCXP,+NMXVAR ;INDICATE COUNTERS ARE BEING DONE
PRSCO1: JUMPGE NT,RSKP ;WHEN DONE, RETURN SUCCESS
ECALL PUTPRM ;DO THIS PARAMETER
ADD NT,[1,,NT.LST] ;INCREMENT BOTH SIDES
JRST PRSCO1 ;TRY FOR SOME MORE.
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,NT> ;GET SOME WORK REGISTERS
LOAD T1,NXSEL,+NMXVAR ;GET SELECTION CRITERIA
SKIPL T1 ;IF NEGATIVE
CAXLE T1,.NTCOU ;OR GREATER THAN HIGHEST VALUE
ERRRET NTEUFO ;GIVE AN ERROR
CAXE T1,.NTCOU ;IS THIS SHOW COUNTERS?
JRST [MOVE NT,PRMP(P1) ;NOPE, GET POINTER TO PARAMETERS
JRST SELIT2] ;AND JOIN COMMON CODE
SETONE NXCXP,+NMXVAR ;NOTE THAT WE ARE DOING COUNTERS
MOVE NT,CNTP(P1) ;GET POINTER TO COUNTER LIST
SELIT2:
CAXL T1,.NTSUM ;RANGE CHECK SELECTION CRITERIA
CAXLE T1,.NTCOU ;COUNTERS IS HIGHEST.
BUG.(CHK,NTMSOR,NTMAN,SOFT,<Selection criteria is out of range>,,<
Cause: We are going to select items to return (for .NTSHO) depending
on the selection criteria, and we have found the criteria to
be out of range.
Cure: Fix the check in GETBLK or find out who is trashing field NXSEL
>,NTEMPE)
MOVE P1,<-.NTSUM>+[NTI.% ;SUMMARY BIT
NTI.S ;STATUS BIT
NTI.C ;CHARACTERISTICS BIT
NTINF](T1) ;COUNTERS (DO ALL OF THEM)
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: We are going to select entries to return (for function .NTSHO)
and we need to know the node type (executor,remote, or loop) to
decide. 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
SELIT4: JUMPGE NT,RSKP ;WHEN DONE, RETURN SUCCESS
TDNE P1,NT.INF(NT) ;DOES THIS MATCH OUR SELECTION CRITERIA?
TDNN P2,NT.APL(NT) ;AND DOES THIS APPLY TO US?
JRST SELIT6 ;NOPE. SKIP OVER IT
ECALL PUTPRM ;YEP. DO THIS PARAMETER
SELIT6: ADD NT,[1,,NT.LST] ;POINT TO NEXT ITEM ON LIST
JRST SELIT4 ;GO TRY FOR THIS NEW ITEM
SUBTTL Functions -- .NTSHO -- Return parameters to user
;PUTPRM - Process a parameter/counter, and put into user data string
;Also called by PRSCOU, for function .NTSZC and .NTZRO
PUTPRM: SAVEAC <P1,P2,NT,TM> ;SAVE A BUNCH OF ACS (TRASHED IN CM HANDLING)
LOAD T1,NTIDX,(NT) ;GET INDEX TO PASS TO LOWER LEVEL
STOR T1,NXPRM,+NMXVAR ;SAVE IN NX BLOCK
LOAD T1,NTTYP,(NT) ;GET TYPE OF PARAMETER
CAXN T1,NT.FCM ;IS THIS PARAMETER TYPE 'CODED MULTIPLE'?
JRST PUTPR1 ;YES, SPECIAL CASE IT.
ECALL NMXLAY ;CALL LAYER-LEVEL ROUTINE TO DO PARAMETER
ECALL NMXWTY ;WRITE STRING OUT TO USER IN APPROPRIATE FORMAT
RETSKP ;FINISHED
;HANDLE CODED MULTIPLES HERE.
PUTPR1:
MOVE P2,NT ;SAVE NT FOR A WHILE
LOAD T1,NTLEN,(P2) ;GET NUMBER OF POSSIBLE CM ENTRIES
MOVN T1,T1 ;MAKE IT A NEGATIVE NUMBER (FOR JUMPGE)
LOAD NT,NTIDX,(P2) ;GET POINTER TO CM STENT TABLE
HRL NT,T1 ;NOW WE HAVE A NT TYPE POINTER IN NT
SETZ P1, ;NO ENTRIES HAVE BEEN FOUND YET.
PUTPR2: ECALL NMXLAY ;CALL THE LAYER, FIND OUT ABOUT PARAMETER
JN NXNIL,+NMXVAR,PUTPR4 ;IF THE LAYER DIDN'T KNOW ABOUT IT, TRY NEXT
JE NXWUS,+NMXVAR,PUTPR4 ;IF NOT WRITING, SKIP OVER WRITE CODE
JUMPN P1,PUTPR3 ;IF FIRST THING FOUND, OUTPUT CM HEADER
EXCH P2,NT ;TEMPORARILY GET BACK REAL NT POINTER
ECALL NMXWTY ;WRITE OUT CM HEADER TO USER STRING
EXCH P2,NT ;GET BACK NT POINTER TO CM TABLE
SETZ T1, ;ZILP, WILL HAVE REAL VALUE AT PUTPR5
ECALL PUTBYT ;RESERVE A BYTE. (DATA TYPE OF CM+NUMBER)
LOAD TM,NXDAT,+BP.BPT+NMXVAR ;GET POINTER TO DATA TYPE - CHANGED LATER
PUTPR3: AOJ P1, ;INCREMENT NUMBER OF FIELD WE HAVE PROCESSED
ECALL NMXWT3 ;OUTPUT DATA TYPE BYTE, AND DATA
PUTPR4: AOBJN NT,PUTPR2 ;TRY ANOTHER CM ENTRY.
PUTPR5: SKIPN T1,P1 ;GET NUMBER OF FIELDS WE SENT
RETSKP ;NONE OF THEM WERE AVAILABLE (NXNIL IS SET)
TXO T1,<1_7>!<1_6> ;DATA TYPE IS CODED, AND IT IS MULTIPLE
XCTBU [DPB T1,TM] ;REPLACE BYTE WE SENT EARLIER.
SETZRO NXNIL,+NMXVAR ;CLEAR THE "NOTHING DONE" BIT.
RETSKP ;FINISHED, GOOD RETURN
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
SETZ NT, ;FLAG NOTHING SPECIAL YET
LOAD P1,NXSEL,+NMXVAR ;FIND OUT WHAT KIND OF LIST HE WANTS
CAXN P1,.NTLOP ;DID HE WANT LOOP NODES?
JRST NMXLLN ;YEP, GIVE HIM THOSE
CAXN P1,.NTACT ;DOES HE WANT ACTIVE NODES?
JRST NMXLNA ;YEP, GIVE HIM ALL REACHABLE NODES
CAXE P1,.NTKNO ;DOES HE WANT ALL KNOWN NODES?
ERRRET NTEUFO ;NOPE - WHAT DOES HE WANT???
SETO NT, ;FLAG SOMETHING SPECIAL - DO ALL NODES
NMXLNA: MOVX P2,1 ;START AT NODE NUMBER 1
NMXLN2: CAMLE P2,RTRMXN ;HAVE WE PASSED THE MAXIMUM NODE NUMBER?
JRST NMXLLN ;YES, DO LOOPBACK NODES NOW.
JUMPE NT,NMXLN3 ;IF ONLY ACTIVE NODES, SKIP OVER SOME CODE
MOVE T1,P2 ;COPY NODE ADDRESS WE WANT TO KNOW ABOUT
CALL SCTA2N ;ASK SCLINK IF HE EVER HEARD OF THIS NODE
JRST NMXLN3 ;NOPE, ENQUIRE FURTHER
JRST NMXLN4 ;SCT KNOWS ABOUT IT, GO PUT IT INTO LIST
NMXLN3: MOVE T1,P2 ;COPY NODE NUMBER
CALL RTNLID ;ASK RTR IF NODE IS REACHABLE
AOJA P2,NMXLN2 ;NOPE. TRY FOR NEXT NODE
NMXLN4: MOVE T1,P2 ;COPY NODE NUMBER
ECALL PUT2BT ;PUT NODE NUMBER IN DATA STRING
SETZ T1, ;NO NAME FOLLOWING, SO A ZERO STRINGID HEAD
ECALL PUTBYT ;PUT BYTE IN DATA STRING
AOJA P2,NMXLN2 ;GO DO ANOTHER NODE
NMXLLN: MOVE P2,SCTLNL## ;GET POINTER TO LOOPBACK NODE NAME LIST
NMXLN5: JUMPE P2,RSKP ;WHEN DONE, RETURN SUCCESS
LOAD T1,LNNAM,(P2) ;GET THE NAME
ECALL NMXA21 ;CONVERT FROM SIXBIT TO 8BIT STRINGID
SETZ T1, ;NO NUMBER
ECALL PUT2BT ;PUT TWO BYTES IN STREAM INDICATING NO NUMBER
XMOVEI P1,NX.VAL+NMXVAR ;POINT TO THE WHERE THE NODE STRING IS
ECALL PUTSTR ;COPY THE STRING TO THE USER
LOAD P2,LNNXT,(P2) ;GET NEXT LOOPBACK NODE BLOCK POINTER
JRST NMXLN5 ;AND LOOP
SUBTTL Functions -- .NTRET -- List circuit and line names
;NMXLCK - Return a list of line/circuit names
;Call
; NMXVAR/ NX block
;Return
; RET ;ON ERROR, NXERR,+NMXVAR CONTAINING ERROR CODE
; RETSKP ;WITH LIST OF NAMES IN USER DATA STRING
NMXLCK:
SAVEAC P2 ;GET A SCRATCH REGISTER
MOVE P2,RTRCBQ ;GET POINTER TO CIRCUIT BLOCKS (SINCE WE ARE
; ONLY LOOKING AT THE BLOCKS, WE CAN DO THIS
; WITHOUT ANY INTERLOCK. THE CIRCUIT BLOCKS
; NEVER GET REMOVED, SO A ONCE-VALID POINTER
; IS ALWAYS VALID).
NMXLC1: JUMPE P2,RSKP ;IF END OF LIST, WE HAVE FINISHED
LOAD P1,NXSEL,+NMXVAR ;GET SELECTOR
CAXN P1,.NTKNO ;TELL ABOUT ALL KNOWN ITEMS?
JRST NMXLC4 ;YES, JUST LIST IT
LOAD T1,RCLID,(P2) ;GET THE LINE ID FOR THIS CIRCUIT
CALL RTNGLS ;ASK RTR FOR THE LINE STATE
BUG.(CHK,NTMBLI,NTMAN,SOFT,<Bad Line id>,,<
Cause: Router has given us an error return when we asked for the state
of a circuit. The only valid error return from this routine is
due to the circuit not existing.
Cure: None known.
>,NTEMPE)
CAXN P1,.NTLOP ;IS HE ASKING FOR SERVICE STATE?
CAXE T1,NCK.SR ;YES, IS THIS IN SERVICE STATE?
TRNA ;NO.
JRST NMXLC4 ;IT'S THE RIGHT FLAVOR. GO LIST IT.
CAXN P1,.NTACT ;IS HE ASKING FOR ACTIVE STATE?
CAXE T1,NCK.ON ;IS THIS LINE ACTIVE?
JRST NMXLC7 ;NO, ABANDON ALL HOPE FOR THIS LINE
NMXLC4: LOAD T1,RCLID,(P2) ;GET THE LINE ID AGAIN.
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;DATA STORAGE AREA
ECALL NMXC2N ;CONVERT CIRCUIT-ID TO NAME
XMOVEI P1,NX.VAL+NMXVAR ;POINT TO THE CIRCUIT NAME STRINGID
ECALL PUTSTR ;PUT THIS STRING IN THE USER'S BUFFER
NMXLC7: LOAD P2,RCNXT,(P2) ;GET POINTER TO NEXT CIRCUIT
JRST NMXLC1 ;GO TRY FOR NEXT LINE
SUBTTL Functions -- .NTEVQ - Pass queued event to user
;Called from NMXDIS
GETEVT::
SAVEAC <P1,P2,NT> ;NEED FOR POINTER TO NMX BLOCK
D36OFF ;#AVOID RACES
DEQUE P2,NMXEVQ,NQ.NXT,GETEVX ;#PULL AN EVENT BLOCK OFF THE QUEUE
D36ON ;#ALLOW THE REST OF THE WORLD TO RUN AGAIN
CALL GETEV1 ;CALL REST OF CODE AS SUBROUTINE TO TRAP RETURN
JRST NMXEP2 ;SOMETHING FAILED, RETURN THE BLOCK
RETSKP ;SUCCESS RETURN
GETEV1: LOAD T1,NQCCL,(P2) ;GET EVENT CLASS
ASH T1,6 ;SHIFT IT OVER TO MAKE ROOM FOR TYPE
OPSTR <ADD T1,>,NQCTY,(P2) ;ADD IN EVENT TYPE
ECALL PUT2BT
LOAD T1,NQTIM,(P2) ;GET TIME EVENT OCCURRED
CALL NMXTIM ;GET THE TIMESTAMP
STKVAR <SEC,MSC> ;SET UP A STKVAR TO HOLD TWO WORDS
MOVEM T2,SEC ;SAVE SECONDS
MOVEM T3,MSC ;SAVE MILLISECONDS
ECALL PUT2BT ;GIVE THE USER THE JULIAN-HALF-DAY
MOVE T1,SEC ;GET BACK SECONDS
ECALL PUT2BT
MOVE T1,MSC ;GET BACK MILLISECONDS
ECALL PUT2BT
LOAD T1,NQETP,(P2) ;ENTITY TYPE (NODE, LINE, CIRCUIT)
ECALL PUT2BT ;SPEC SAYS THIS IS A 2-BYTE FIELD.
LOAD T1,NQETP,(P2) ;GET ENTITY TYPE AGAIN
CAXN T1,.NTNOD ;IS IT A NODE?
JRST NMXPNO ;YES, PUT NODE ID INTO STRING
CAXE T1,.NTCKT ;IS IT A CIRCUIT?
CAXN T1,.NTLIN ;OR A LINE?
JRST NMXPCK ;PUT A CIRCUIT/LINE ID
AOJ T1, ;BUMP IT UP BY ONE
TRNE T1,<<377_8>+377> ;DO WE NOW HAVE ELEVENISH 0?
BUG.(CHK,NTMURE,NTMAN,SOFT,<Unrecognized entity type>,,<
Cause: We have received an event from a DECnet layer, and the entity
type is not legal.
Cure: Find the routine which generated the event, and cause it to
supply a legal entity type.
>,NTEMPE)
;NO ENTITY TYPE. FALL THROUGH TO DATA STRING
NMXEPP: MOVE P1,[POINT 8,NQ.STR(P2)] ;BYTE POINTER TO DATA STRING
ILDB NT,P1 ;GET NUMBER OF BYTES TO COPY
JUMPE NT,NMXEP2 ;IF NOTHING TO COPY, FALL THROUGH.
NMXEP1: ILDB T1,P1 ;GET NEXT DATA BYTE
ECALL PUTBYT ;STORE BYTE IN USER DATA STREAM
SOJG NT,NMXEP1 ;AND COPY MORE BYTES UNTIL DONE
NMXEP2: SKIPE T1,NMXLST ;WAS THERE A LOST EVENT?
JRST NMXEP3 ;YES, QUEUE A LOST EVENT.
MOVE T1,P2 ;POINTER TO THE NQ BLOCK
CALL DNFEBL ;FREE THE QUEUED EVENT BLOCK
RETSKP ;AND RETURN SUCCESS.
NMXEP3: SETZM NMXLST ;ZERO FLAG OF LOST EVENTS
STOR T1,NQTIM,(P2) ;STORE THE ORIGINAL TIMESTAMP IN LOST BLOCK
SETZRO <NQCTY,NQCCL,NQETP,NQEID,NQSTR>,(P2) ;ZERO FOR LOST EVENT
D36OFF ;AVOID ANYONE TOUCHING THE QUEUE
ENDQUE P2,NMXEVQ,NQ.NXT,T1 ;QUEUE THE LOST BLOCK UP
D36ON ;AND LET THE WORLD BACK IN.
RETSKP ;AND RETURN
NMXPNO:
LOAD T1,NQEID,(P2) ;GET ENTITY ID (NODE NUMBER)
ECALL PUT2BT ;PUT IT IN USER STRING AS TWO BYTES
SETZ T1, ;BYTE INDICATING HOW MANY BYTES FOR NAME
ECALL PUTBYT ;SINGLE BYTE INDICATING NO NAME
JRST NMXEPP ;AND FINISH OFF THE EVENT RETURNING
NMXPCK:
LOAD T1,NQEID,(P2) ;GET ENTITY ID (LINE/CIRCUIT ID)
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;WHERE TO STORE CIRCUIT NAME STRING
ECALL NMXC2N ;CONVERT THE ID TO A NAME
XMOVEI P1,NX.VAL+NMXVAR ;POINTER TO STRING CONTAINING THE NAME
ECALL PUTSTR ;COPY THE ENTITY NAME TO USER BLOCK
JRST NMXEPP ;FINISH OFF COPYING THE EVENT BLOCK
GETEVX: D36ON ;#ALLOW INTERRUPTS
JRST NTEOPF ;OPERATION FAILURE (NO EVENTS TO RETURN)
SUBTTL Entities -- Convert entity names to entity ids
;Called from NMXDIS
ENTCVT: SETZRO NXNTY,+NMXVAR ;NO NODE AS OF YET
CALLRET @.+1-.NTNOD(P1)
IFIW NODCVT ;CONVERT NODE TYPE
IFIW LINCVT ;LINE TYPE
IFIW NTEURC ;LOGGING. PUNT, WE DON'T DO THESE
IFIW LINCVT ;SAME AS LINE
IFIW NTEURC ;MODULE - ILLEGAL
IFIW NTEURC ;ILLEGAL.
;Called from ENTCVT
NODCVT:
SAVEAC <P1> ;NEED FOR TEMP BYTE STORAGE
ECALL GETEBY ;GET ENTITY STRING BYTE
MOVE P1,T1 ;SAVE THE BYTE FOR A WHILE
ECALL GETEBY ;GET ANOTHER BYTE
ASH T1,^D8 ;SHIFT HIGH-ORDER BYTE OVER
IOR T1,P1 ;INCLUDE LOW ORDER BYTE
JUMPN T1,NODCV0 ;IF WE HAVE AN ADDRESS, WE ARE OK
ECALL GETSTI ;NO ADDRESS, I MUST HAVE A NAME
CALL NMXN2A ;CONVERT THE NAME TO AN ADDRESS.
JRST NODCV2 ;NO SUCH NAME, MUST BE LOOPBACK
NODCV0: STOR T1,NXNUM,+NMXVAR ;SAVE IN ARGUMENT BLOCK
CAME T1,RTRADR ;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
NODCV2: LOAD T2,NXFNC,+NMXVAR ;GET THE FUNCTION CODE WE ARE TO DO
CAXE T2,.NTSET ;IS THIS A SET?
CALL SCTCKL## ;NO, MAKE SURE THE LOOPBACK NODE EXISTS
TRNA ;ACCEPTABLE
ERRRET NTEURC ;UNRECOGNIZED COMPONENT
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:
ECALL GETSTI ;COPY MULTIPLE BYTES (INTERNAL LIMIT 16)
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO LINE NAME WE COPIED
ECALL NMXN2C ;CONVERT NAME TO LINE-ID
STOR T1,NXNUM,+NMXVAR ;SAVE AWAY LINE ID
RETSKP
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,<Kontroller out of range in Circuit-id>,,<
Cause: The Kontroller field in a line-id is out of range. The value
LD.MAX defines the number of Kontrollers known by D36PAR, and
thus by NTMAN. The most likely cause of this bug is a trashed
AC.
Note: A Kontroller is any device driver to which 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
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
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: We have returned more than 16 bytes of data into a 16 byte field.
The data beyond the buffer has been trashed.
Cure: Examine the algorithm above to determine why we returned more
bytes than we expected. While you are at it, fix the above
code to check for overrun while it is producing the bytes, so
that we don't have this embarrasing halt.
>)
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
CALL RTNGLS ;GET THE LINE STATE (JUST TO VERIFY CIRCUIT)
ERRRET NTEURC ;NO SUCH CIRCUIT
MOVE T1,P2 ;GET THE CIRCUIT AGAIN.
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
; NMXVAR/ NX block
; NT/ Pointer to STENT part of NT block
;Return
; RET ;on error, NXERR has code
; RETSKP ;NXNIL will be set if this layer does not
; ; know about this entity.
NMXLAY:
SETZRO NXNIL,+NMXVAR ;CLEAR THE "I DIDN'T DO ANYTHING" FLAG
LOAD T1,NTDFL,(NT) ;GET DEFAULT VALUE, IF ANY
TMNE NXZMC,+NMXVAR ;ARE WE CLEARING/ZEROING?
STOR T1,NXVAL,+NMXVAR ;YES, SET DEFAULT AS VALUE TO SET
LOAD T1,NTROU,(NT) ;GET ROUTINE FOR THIS PARAMETER
CAXGE T1,NMXMAX ;RANGE CHECK
CAXGE T1,NMXMIN
BUG.(CHK,NTMDVI,NTMAN,SOFT,<NMXDSP value illegal>,,<
Cause: We are going to call a "layer" to obtain or set a value for
an item. The routine value in the descriptor block pointed
to by NT is illegal.
Cure: 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(T1) ;CALL LAYER-LEVEL ROUTINE
SUBTTL Layers -- Read/set NSP node blocks
;Called from NMXLAY through NMXDSP+NSP
;NMXNSP - NMX's handler of some NSP parameters. Will extract anything
; NSP keeps in it's node block
NMXNSP::
LOAD T1,NXNUM,+NMXVAR ;GET NUMBER OF ENTITY (NODE ADDRESS)
CALL SRHNOD ;SEARCH FOR THE NODE
JRST NMXNIL ;NOT KNOWN HERE, BUT DO REST OF THE STUFF
LOAD T2,NXPRM,+NMXVAR ;GET PARAMETER PASSED TO US (POINTER TO BPT)
JUMPE T2,NSPNM2 ;IS IT SECONDS SINCE LAST ZEROED?
TMNN NXWRM,+NMXVAR ;AM I WRITING THE MONITOR'S DATA?
JRST [LDB T3,(T2) ;GET VALUE FROM ENTITY
JRST NSPNM1] ;AND JOIN COMMON CODE BELOW
LOAD T4,NXVAL,+NMXVAR ;GET VALUE SENT BY PROGRAM
D36OFF ;#DON'T ALLOW RACES
LDB T3,(T2) ;#GET ORIGINAL VALUE
DPB T4,(T2) ;#STORE NEW VALUE (PROBABLY ZERO)
D36ON ;#ALLOW RACES AGAIN.
NSPNM1: STOR T3,NXVAL,+NMXVAR ;SAVE OLD VALUE IN ARG BLOCK
RETSKP
NSPNM2: SAVEAC P1 ;POINTER TO NN BLOCK
MOVE P1,T1 ;SAVE FOR LATER USE
CALL DNGTIM ;GET CURRENT TIME STAMP
JN NXZMC,+NMXVAR,NSPNM3 ;IF ZEROING, SPECIAL CODE
OPSTR <SUB T1,>,NNSLZ,(P1) ;GET OFFSET IN MILLISECONDS
IDIVI T1,TIMBAS ;AND CONVERT TO SECONDS
STOR T1,NXVAL,+NMXVAR ;SAVE FOR NMXLAY
RETSKP
NSPNM3: LOAD T2,NNSLZ,(P1) ;GET OLD TIME STAMP
STOR T1,NNSLZ,(P1) ;STORE CURRENT TIME STAMP
SUB T1,T2 ;GET OFFSET
IDIVI T1,TIMBAS ;CONVERT TO SECONDS
STOR T1,NXVAL,+NMXVAR ;SAVE FOR NMXLAY
RETSKP
SUBTTL Layers -- Read/set RTR circuit blocks
;NMXRTL - call RTR to do line stuff
;Call
; NT/ Pointer to format block
; NMXVAR/ NX Block
;Return
; RET ;if invalid line id in NXNUM
; RETSKP ;With value set or loaded into NXVAL
NMXRTL::
LOAD T1,NXNUM,+NMXVAR ;GET LINE ID
LOAD T2,NTIDX,(NT) ;GET POINTER TO BYTE POINTER IN RTR
XMOVEI T3,+NMXVAR ;COPY OF NX FOR RTR
CALL RTRNMX ;ASK RTR DO DO SOME NMX STUFF
ERRRET NTEURC ;BAD LINE ID
STOR T1,NXVAL,+NMXVAR ;SAVE FOR CALLER TO PICK UP
RETSKP ;RETURN SUCCESS
;NMXRTD - Special case of NMXRTL, re-formatting the output to look nice
; to NML.
NMXRTD: ECALL NMXRTL ;DO THE ACTUAL WORK.
LOAD T1,NXVAL,+NMXVAR ;GET NODE ADDRESS
CALL NMXA2N ;CONVERT ADDRESS TO NAME
CALLRET NMXNIL ;FLAG WE DIDN'T DO ANYTHING
RETSKP ;AND RETURN "SUCCESS" (WE DIDN'T FAIL)
;NMXRTS - Call router to do stuff with circuit state
;Call
;Return
; Ret ;If state cannot be set or other error
; RETSKP ;Success.
NMXRTS: LOAD T1,NXNUM,+NMXVAR ;GET LINE ID TO SET STATE OF
JN NXWRM,+NMXVAR,NMXRT2 ;IF SETTING LINE STATE, OTHER CODE
CALL RTNGLS ;ASK WHAT THE LINE STATE IS
BUG.(CHK,NTMXNL,NTMAN,SOFT,<ROUTER doesn't know about a line>,,<
Cause: We have asked router for the state of a circuit, and router has
given us a failure return. The only valid failure is for a non-existant
circuit, and we are supposed to check the circuit ID for existance
at ENTCVT before getting here.
>,NTEMPE)
STOR T1,NXVAL,+NMXVAR ;SAVE STATE FOR USER
RETSKP ;RETURN SUCCESS
NMXRT2: LOAD T2,NXVAL,+NMXVAR ;GET LINE STATE TO SET TO
CAXL T2,NCK.ON ;RANGE CHECK THE REQUESTED
CAXLE T2,NCK.SR ;STATE (OR ELSE ROUTER BUGCHKS)
ERRRET NTEIPV ;INVALID PARAMETER VALUE
CALL RTNSLS ;ASK ROUTER TO SET THE CIRCUIT STATE
ERRRET NTEOPF ;SAY THAT THE OPERATION FAILED.
RETSKP ;SUCCESS, RETURN
NMXRTB: LOAD T1,NXNUM,+NMXVAR ;GET LINE ID OF CIRCUIT WE ARE GOING TO READ
TMNE NXWRM,+NMXVAR ;MAKE SURE WE ARE READING
BUG.(CHK,NTMSSB,NTMAN,SOFT,<Setting a circuit substate>,,<
Cause: Setting a substate is illegal - This entry should be READ-ONLY
in the descriptor block, and we should have caught this before.
Action: Make the entry in the descriptor block be READ ONLY.
>,NTEMPE)
CALL RTNGLB ;ASK ROUTER FOR SUBSTATE (IF APPLICABLE)
CALLRET NMXNIL ;FLAG WE DIDN'T DO ANYTHING
STOR T1,NXVAL,+NMXVAR ;SAVE SUBSTATE FOR USER
RETSKP ;AND SAY WE DIDN'T FAIL.
SUBTTL Layers -- Read/set node state
;Read a state for any node, and set node on for executor
;Call
; NXNUM,+NMXVAR/ node number
; NXNTY,+NMXVAR/ node type
; NXVAL,+NMXVAR/ state to be set to, or place to return value
;Return
; RET ;on error, with error code in NXERR
; RETSKP ;Success, with state in NXVAL if read.
NMXNMS:
; JN NXWRM,+NMXVAR,NTEFNS ;WE DON'T SUPPORT SETTING NODE STATE
LOAD T1,NXNTY,+NMXVAR ;WHAT KIND OF NODE IS THIS?
CAXN T1,NX.EXN ;IS IT THE EXECUTOR NODE?
JRST NMXNS2 ;YES, DO SPECIAL STUFF
LOAD T1,NXNUM,+NMXVAR ;NODE WHICH WE ARE ASKING ABOUT
CALL RTNLID ;ASK ROUTER WHAT HE THINKS ABOUT THIS NODE
SKIPA T1,[5] ;UNREACHABLE. RETURN CODE
MOVX T1,4 ;REACHABLE.
STOR T1,NXVAL,+NMXVAR ;SAVE FOR NICE TO PRINT OUT
RETSKP ;VOILA!
NMXNS2:
SETZRO NXVAL,+NMXVAR ;STATE IS ON, WHICH IS THE ONLY SUPPORTED STATE
;FOR THE EXECUTOR NODE.
RETSKP
SUBTTL Layers -- Read/set executor node information
;Called through NMXDSP+EXE
NMXEXE::LOAD T2,NTIDX,(NT) ;GET INDEX, IN THIS CASE, POINTER TO WORD
; CALLRET NMXVAL ;HAVE POINTER, JUST DO THE FUNCTION
NMXVAL:
;All is OK, do the requested function
LOAD T1,NXVAL,+NMXVAR ;STORE NEW VALUE WITH EXCHANGE
TMNN NXWRM,+NMXVAR ;WRITE VALUE?
SKIPA T1,(T2) ;NO, READ, RETURN WITH OLD VALUE
EXCH T1,(T2) ;RETURN OLD VALUE IN T1
STOR T1,NXVAL,+NMXVAR ;SAVE VALUE FOR POSTERITY
RETSKP ;SUCCESS RETURN
SUBTTL Layers -- Read/set RTR node information
;NMXXND - Do NMX functions for all RTR nodes. This information is entirely
; in RTR, so we extract information from the routing vector.
NMXXND::
LOAD T1,NXNUM,+NMXVAR ;GET NODE NUMBER
CALL RTNLID ;FIND OUT IF IT IS REACHABLE
JRST NMXNIL ;FLAG WE DIDN'T DO ANTYING
LOAD T2,NXNUM,+NMXVAR ;GET NODE NUMBER AGAIN.
TMNN NXWUS,+NMXVAR ;MAKE SURE WE ARE WRITING USER'S STRING
BUG.(CHK,NTMBCX,NTMAN,SOFT,<Bad call to NMXXND>,,<
Cause: We have called a "layer" which handles information in Router's
routing vector. All the information in this vector is supposed
to be read only, but we have been called for a set or clear.
Cure: Look at the descriptor block pointed to by NT, and determine
which item caused this layer to be called. Then fix the item's
entry to indicate that this is a read-only parameter.
>,NTEMPE)
ADD T2,RTRNRV ;ADD IN ADDRESS OF VECTOR, GETTING REAL ADDRESS
LOAD T3,NXPRM,+NMXVAR ;GET ADDRESS OF BYTE POINTER TO FIELD
LDB T1,(T3) ;GET VALUE ITSELF
STOR T1,NXVAL,+NMXVAR ;SAVE FOR CALLER.
RETSKP ;HAVE THE VALUE, RETURN
SUBTTL Layers -- Find circuit which points to a node
;Called from NMXLAY through NMXDSP+CIR
;NMXCIR - Get Circuit pointing to this node
NMXCIR::
LOAD T1,NXNUM,+NMXVAR ;GET NODE NUMBER
CAMN T1,RTRADR ;EXECUTOR NODE?
JRST NMXNIL ;YUP, DON'T LET HIM TRY FOR THIS.
CALL RTNLID ;GET LINE POINTING TO THIS NODE
JRST NMXNIL ;SORRY, NO PATH TO NODE.
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;POINTER TO VALUE AREA
CALLRET NMXC2N ;CONVERT CIRCUIT ID TO NAME
;VALUE IS NOW IN NXVAL, RETURN
SUBTTL Layers -- Set/clear node names
;Called from NMXLAY through NMXDSP+NMC
NMXNMC::SETZ T1, ;START OFF WITH A CLEAR NODE NAME
JN NXZMC,+NMXVAR,NMXNM2 ;IF WE ARE CLEARING, THIS IS GOOD ENOUGH.
MOVE T4,[POINT 6,T1] ;DESTINATION BYTE POINTER FOR SIXBIT NAME
MOVE T3,[POINT 8,NX.VAL+NMXVAR] ;POINTER TO STRINGID CONTAINING NAME
ILDB T2,T3 ;GET NUMBER OF BYTES IN NODE NAME
JUMPE T2,NMXNM2 ;IF NO BYTES, FALL INTO CLEAR CODE
NMXNM0: 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,NMXNM0 ;LOOP UNTIL ENTIRE NAME COPIED.
NMXNM2: LOAD T2,NXNUM,+NMXVAR ;GET NODE ADDRESS
CALL SCTAND ;SET THE NODE NAME FOR THIS NODE
ERRRET NTENRM ;NAME ALREADY TAKEN.
RETSKP ;SUCCESS
SUBTTL Layers -- Create/Destroy loopback nodes
;Called from NMXLAY through NMXDSP+LLP
;Loopback nodes
NMXLLP: JN NXZMC,+NMXVAR,NMXLL1 ;IF WE ARE CLEARING, DON'T LOOK FOR CIRCUIT
JE NXWRM,+NMXVAR,NMXLL2 ;IF WE ARE READING, DON'T TRY TO SET STUFF
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO CIRCUIT NAME
ECALL NMXN2C ;CONVERT IT TO LINE ID
SKIPA T2,T1 ;COPY TO WHERE SCTANL EXPECTS IT
NMXLL1: SETZ T2, ;CLEAR THE CIRCUIT
LOAD T1,NXNUM,+NMXVAR ;GET NODE NAME
CALL SCTANL## ;ADD LOOPBACK NODE NAME
ERRRET NTENRM ;NAME ALREADY TAKEN, OR NO ROOM
RETSKP ;DONE.
NMXLL2: LOAD T1,NXNUM,+NMXVAR ;GET THE NODE NAME
CALL SCTN2L## ;CONVERT THE NAME TO CIRCUIT BLOCK POINTER
ERRRET NTEURC ;UNRECOGNIZED COMPONENT
MOVE T2,[POINT 8,NX.VAL+NMXVAR] ;VALUE AREA TO USE
CALLRET NMXC2N ;CONVERT CIRCUIT ID TO NAME
SUBTTL Layers -- Call the data link layer
;Called from NMXLAY through NMXDSP+DLL
NMXDLL:
LOAD T1,NXNUM,+NMXVAR ;GET ENTITY ID (LINE ID)
LOAD T5,LIDEV,+T1 ;STORE KONTROLLER FOR LATER
CALL RTRKBA ;CONVERT TO POINTER TO CIRCUIT BLOCK
BUG.(CHK,NTMILI,NTMAN,SOFT,<Invalid Line ID>,,<
Cause: We have called NMXDLL to perform a function for a line, and the
previously validated line id is bad. The probable cause is
something trashing NMXVAR+NXNUM
>,NTEMPE)
LOAD T4,NXFLG,+NMXVAR ;GET FLAGS FOR FUNCTION
MOVX T1,KF.RED ;ASSUME READ
TXNE T4,NX%WRM ;ARE WE WRITING TO THE MONITOR?
MOVX T1,KF.SET ;YES, ASSUME SET
TXNE T4,NX%ZMC ;ARE WE DOING A CLEAR?
MOVX T1,KF.CLR ;YES, CLEAR FUNCTION
LOAD T3,NTSEQ,(NT) ;GET PARAMETER NUMBER
TXNE T4,NX%CXP ;IS THIS A COUNTER?
IOR T3,1_^D15 ;YES, MARK IT AS SUCH FOR DLL
LOAD T4,NXVAL,+NMXVAR ;GET VALUE FOR SET (IF ANY)
CALL @KONDSP##(T5) ;CALL THE KONTROLLER
JRST NMXDL1 ;HANDLE ERROR RETURN
STOR T1,NXVAL,+NMXVAR ;STORE IN CASE IT WAS A READ
RETSKP ;RETURN SUCCESS
NMXDL1: JUMPN T1,NTEOPF ;IF ANY KIND OF ERROR CODE, FLAG THE ERROR
NMXNIL: SETONE NXNIL,+NMXVAR ;SET FLAG SAYING "I DIDN'T DO ANYTHING"
RETSKP ;AND RETURN SUCCESS
SUBTTL Events -- Event receiver
;Receive an event, from some module.
;Call
; T1/ Pointer to NE begstr to put on queue
; This should be obtained with a CALL DNGEBL
;Return
; RET always.
NMXEVT::
SAVEAC <P1,P2> ;SAVE AN AC TO BLOCK
MOVE P2,T1 ;SAVE POINTER TO EVENT BLOCK
CALL DNGEBL ;GET A BLOCK FOR THIS EVENT
JRST NMXEQF ;EVENT BLOCKS USED UP - QUEUE MUST BE FULL
MOVE P1,T1 ;SAVE POINTER TO OUR EVENT BLOCK
CALL DNGTIM ;GET CURRENT TIME OF DAY
STOR T1,NQTIM,(P1) ;STASH AWAY FOR LATER USERS
LOAD T1,NECCL,(P2) ;GET EVENT CLASS
LOAD T2,NECTY,(P2) ;GET EVENT TYPE
LOAD T3,NEETP,(P2) ;GET ENTITY TYPE
LOAD T4,NEEID,(P2) ;GET ENTITY ID
STOR T1,NQCCL,(P1) ;STORE AWAY IN OUR BLOCK
STOR T2,NQCTY,(P1) ;STORE IN OUR BLOCK
STOR T3,NQETP,(P1) ;STORE ENTITY TYPE
STOR T4,NQEID,(P1) ;STORE ENTITY ID
LOAD T5,NEDAT,(P2) ;GET FULLWORD POINTER TO DATA STRING
LOAD T4,NEDLN,(P2) ;LENGTH OF DATA STRING
CAXL T4,.NQMXS ;MAKE SURE IT WILL FIT
BUG.(CHK,NTMESL,NTMAN,SOFT,<Event string too long>,,<
Cause: We have received an event from a DECnet layer, and the
length of the data string is too long to fit in our storage
block.
Cure: Either increase the size of .NQMXS or persuade the DECnet layer
to return a smaller string.
>,NMXEVE)
MOVE T3,[POINT 8,(T5)] ;MAKE A BYTE POINTER TO HIS STRING
MOVE T2,[POINT 8,NQ.STR(P1)] ;MAKE A BYTE POINTER TO OUR STRING
IDPB T4,T2 ;FIRST BYTE OF STRING IS DATA LENGTH
NMXEV1: JUMPE T4,NMXEV2 ;IF NO BYTES LEFT, STOP COPYING
ILDB T1,T3 ;GET A BYTE FROM HIS STRING
IDPB T1,T2 ;STORE IT INTO OUR STRING
SOJG T4,NMXEV1 ;GO DO MORE BYTES
NMXEV2: D36OFF ;TURN OFF INTERRUPTS.
ENDQUE P1,NMXEVQ,NQ.NXT,T1 ;QUEUE THIS BLOCK UP
D36ON ;LET THEM COME BACK IN
CALL PSIDVT ;NOTIFY THE WORLD ABOUT AN EVENT
RETSKP ;RETURN.
NMXEQF:
CALL DNGTIM ;GET CURRENT TIME OF DAY
D36OFF ;TURN OFF DECNET
SKIPN NMXLST ;HAVE WE ALREADY LOST AN EVENT?
MOVEM T1,NMXLST ;NOPE, FLAG WHEN WE LOST THIS ONE
NMXEVF: D36ON ;TURN DECNET BACK ON.
NMXEVE: MOVE T1,P2 ;RETURN BLOCK OF CORE TO FREE POOL
RET ;RETURN ERROR
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
; NXNIL,+NMXVAR/ if on, return immediatley, don't do anything.
;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
JE NXCXP,+NMXVAR,NMXWT2 ;SKIP OVER COUNTER ONLY CODE IF PARAMETER
LOAD T1,NTLEN,(NT) ;GET COUNTER SIZE
CAXN T1,4 ;IS IT SIZE 4?
MOVX T1,3 ;NICE WANTS IT TO GET A 3
ASH T1,^D13 ;SHIFT IT INTO WIDTH FIELD OF HEADER FIELD
TXO T1,1_^D15 ;TURN ON BIT INDICATING A COUNTER HEADER
NMXWT2: LOAD T2,NTSEQ,(NT) ;GET SEQUENCE NUMBER OF PARAMETER OR COUNTER
IOR T1,T2 ;OR INTO HEADER DUO-BYTE
ECALL PUT2BT ;PUT 2 BYTES OF HEADER INTO USER DATA STRING
NMXWT3: LOAD T1,NTTYP,(NT) ;GET DATA TYPE OF THIS PARAMETER
CAXL T1,NT.FC ;IS IT LESSER THAN SIMPLE CODED?
CAXLE T1,NT.FCB ;OR GREATER THAN BIT MAPPED COUNTER?
BUG.(CHK,NTMFOR,NTMAN,SOFT,<Format out of range>,,<
Cause: We are formatting output for a show, and the format block for
this item has an illegal format type.
>,NTEMPE)
CALLRET @.+1-NT.FC(T1)
IFIW NMXWCD ;ORDINARY CODED. HANDLE AS INTEGER
IFIW RSKP ;CODED MULTIPLE IS HANDLED AT ANOTHER LEVEL
IFIW NMXWAI ;ASCII IMAGE. STRINGID
IFIW NMXWNU ;DECIMAL UNSIGNED
IFIW NMXWNU ;DECIMAL SIGNED.
IFIW NMXWNU ;HEXADECIMAL INTEGER.
IFIW NMXWAI ;HEX IMAGE. BYTE STRING
IFIW NMXWNU ;OCTAL
IFIW NMXWNM ;MILLISECONDS
IFIW NMXWCN ;COUNTER
IFIW NMXWCN ;BIT MAPPED COUNTERS
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: We are formatting output for a SHOW, and we have been requested
to generate a CODED field of more than one byte. We currently
don't know how to do this.
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,1_7 ;INDICATE CODED NON MULTIPLE (PP 148 OF NM)
ECALL PUTBYT ;DEPOSIT DATA TYPE BYTE IN USER STRING
LOAD T1,NXVAL,+NMXVAR ;GET THE CODED VALUE TO OUTPUT
CALLRET PUTBYT ;PUT THE BYTE IN THE OUTPUT STRING, AND RETURN
SUBTTL User strings -- Write ascii image data
;NMXWAI - Write ASCII image data 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
NMXWAI:
SAVEAC <P1,P2> ;GET SOME WORK AREA
MOVX T1,<1_6> ;NON-CODED, ASCII IMAGE DATA
ECALL PUTBYT ;STORE DATA TYPE BYTE
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
NMXWA2: ECALL PUTBYT ;PUT IT IN USER DATA STRING
ILDB T1,P1 ;GET NEXT BYTE
SOJGE P2,NMXWA2 ;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
; NXVAL,+NMXVAR/ 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: We are generating output for a numeric field, and we have been
asked to generate something other than Decimal, Hexadecimal or Octal.
>,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
ECALL PUTBYT ;PUT THIS BYTE IN USER DATA AS DATA TYPE
NMXWCN: LOAD T2,NTLEN,(NT) ;GET NUMBER OF BYTES FOR COUNTER AGAIN
LOAD T1,NXVAL,+NMXVAR ;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: We are generating output for a numeric field, and we have been
asked to generate an illegal number of bytes.
>,NTEMPE)
CALLRET @.(T2)
IFIW PUTBYT ;PUT A SINGLE BYTE
IFIW PUT2BT ;PUT A DUO BYTE
IFIW NMXWCE ;DO THREE BYTES. ILLEGAL
IFIW PUT4BT ;4 BYTES.
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
ECALL NMXRBY ;READ BYTES
JUMPE T1,NTEIPV ;ILLEGAL TO SET QUANTITY TO ZERO
STOR T1,NXVAL,+NMXVAR ;SAVE VALUE IN NX BLOCK
RETSKP ;RETURN SUCCESS
NMXRNC: LOAD T1,NTLEN,(NT) ;GET SIZE OF CODED FIELD
ECALL NMXRBY ;READ BYTES
STOR T1,NXVAL,+NMXVAR ;SAVE VALUE IN NX BLOCK
RETSKP
NMXRNS:
LOAD T1,NTLEN,(NT) ;GET SIZE OF FIELD
ECALL NMXRBY ;READ THE BYTES
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,NXVAL,+NMXVAR ;SAVE IN NX BLOCK
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: We are going to read a numeric value from the user's string, and
the format descriptor block for this item has specified an illegal
number of bytes to read.
>,NTEMPE)
CALLRET @.(T1) ;DISPATCH
IFIW GETBYT ;GET A SINGLE BYTE
IFIW GET2BT ;GET 2 BYTES OF INTEGER
IFIW NMXRBE
IFIW GET4BT ;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,NXVAL,+NMXVAR ;GET VALUE WE ARE GOING TO WRITE OUT
IDIVI T1,TIMBAS ;CONVERT TO SECONDS
STOR T1,NXVAL,+NMXVAR ;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
ECALL PUTBYT ;PUT THE NICE HEADER IN
JRST NMXWCN ;AND JOIN COMMON CODE
;NMXRNM - Read seconds, store milliseconds
;Call
; NMXVAR/ NX block
; NT/ Pointer to NT begstr
NMXRNM: ECALL NMXRNU ;READ THE NUMBER AS DECIMAL UNSIGNED
MOVX T1,TIMBAS ;CONVERSION FACTOR
OPSTRM <IMULB T1,>,NXVAL,+NMXVAR ;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
ECALL DNGUBT ;GET A SINGLE BYTE
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
ECALL DNGUBT ;GET A BYTE
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
ECALL PUTBYT ;PUT BYTE IN USER'S OUTPUT STRING
PUTST1: SOJL NT,RSKP ;RETURN WHEN DONE
ILDB T1,P2 ;GET ANOTHER BYTE
ECALL PUTBYT ;PUT IN USER DATA STRING
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
ECALL DNPUBT ;STORE IT IN USER'S DATA STRING
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.
ECALL DNGUBT ;GET A BYTE OUT OF STREAM
MOVE P1,T1 ;SAVE WHILE WE GET HIGH ORDER BYTE
ECALL DNGUBT ;GET SECOND BYTE
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.
ECALL DNGUBT ;GET A BYTE OUT OF USER STREAM
MOVE P1,T1 ;COPY BYTE INTO SAFE AC
ROT P1,-10 ;NEXT BYTE IS HIGHER ORDER THAN THIS
ECALL DNGUBT ;GET BYTE NUMBER 2
IOR P1,T1 ;ACCUMULATE THIS BYTE IN
ROT P1,-10 ;LET NEXT BYTE COME IN ABOVE THIS ONE
ECALL DNGUBT ;GET BYTE NUMBER 3
IOR P1,T1 ;ACCUMULATE IT IN
ROT P1,-10 ;NEXT BYTE IS THE HIGHEST ORDER BYTE
ECALL DNGUBT ;GET THE LAST (4TH) BYTE
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
XCTBU [IDPB T1,(T2)] ;DEPOSIT THE BYTE
RETSKP
DNGUBT::
OPSTRM <SOS T3,>,BPBYT,(T2) ;DECREMENT COUNT OF BYTES PERMITTED
JUMPL T3,NTEPAM ;PARAMETER MISSING
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::JN NXERR,+NMXVAR,RTN ;IF AN ERROR IS ALREADY THERE, LEAVE IT
; ALONE. IT IS MORE INTERESTING THAN
; ANY FOLLOW-UP ERRORS.
TRACE NMX,<Failure in an NTMAN. uuo>
STOR T1,NXERR,+NMXVAR ;SAVE IN OUR COPIED BLOCK
RET ;NON SKIP RETURN. WILL POP ALL THE WAY BACK
; TO THE TOP, AND RETURN AS AN ERROR.
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: CALL SCTA2N ;CONVERT NODE ADDRESS TO NODE NAME
JRST [SETZRO NXVAL,+NMXVAR;SET BYTE COUNT AND NODE NAME TO 0
RET] ;AND RETURN AN ERROR
NMXA21: 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
SOJGE T4,[ILDB T5,T3 ;GET A BYTE FROM THE NAME
JUMPE T5,.+1 ;IF ZERO BYTE, END OF NAME
AOJA T2,.] ;ELSE KEEP COUNTING.
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
NMXA22: 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,NMXA22 ;AND CONTINUE COPYING UNTIL DONE.
RETSKP ;RETURN SUCCESS
;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,T1] ;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.
CALL SCTN2A ;CONVERT NODE NAME TO NODE ADDRESS
RET ;SESSION CONTROL CAN'T FIND THE NAME. ERROR.
RETSKP ;SUCCESS. T1 CONTAINS NODE ADDRESS.
SUBTTL Data base -- Find an NSP node block
;FNDNOD - Find an NMX Node Block, if fail, make a new one
;
;Call: T1/ Network Node Address of node
; CALL FNDNOD
; Error Return if no resources
; Normal Return with pointer to node block in T1
;Changes T1,T2,T3,T4
;Note that the new node block goes on the end of the queue of node
;blocks. This causes the blocks which we hear about soonest to be at
;the beginning of the queue. These are the nodes we are most likely
;to converse with, so having them at the beginning of the queue is a
;convenience for DDT if nothing else.
FNDNOD::SAVEAC P1
MOVE P1,T1 ;SAVE THE ARG
CALL SRHNOD ;FIRST, SEARCH FOR AN EXISTING ONE
JRST MAKND1 ;CAN'T FIND IT, TRY TO MAKE ONE
RETSKP ;FOUND IT, SUCCESS RETURN
MAKND1: MOVEI T1,NN.LEN ;LENGTH OF A NMX NODE BLOCK
CALL DNGWDZ ;ZERO SO MANY ZEROED WORDS
RET ;CAN'T, ERROR RETURN
STOR P1,NNNOD,(T1) ;STORE NODE ID IN NEW NODE BLOCK
MOVE P1,T1 ;SAVE ADDRESS OF NODE BLOCK
CALL DNGTIM ;GET A TIMESTAMP
STOR T1,NNSLZ,(P1) ;STORE AS LAST TIME BLOCK WAS ZEROED
ENDQUE P1,NMXNDQ,NN.NXT,T2
;Some initialization for NSP
MOVEI T2,TIMBAS ;MACRO/LINK CAN'T MULTIPLY EXTERNAL RIGHT
IMULI T2,5 ;ESTIMATE 5 SECOND FOR INITIAL DELAY
STOR T2,NNDLY,(P1) ;ZERO IS NOT GOOD FOR CONNECT CONFIRM!
;SEE UPDELAY ABOUT THIS
MOVE T1,P1 ;RETURN PTR TO BLOCK IN T1
RETSKP
SUBTTL Data base -- Find an existing NSP node block
;SRHNOD - Search for an existing NMX Node Block
;
;Call: T1/ Network Node Id
; CALL SRHNOD
; Error Return if not found
; Normal Return with pointer to it in T1
;Changes T1,T2,T3
;This must save T5 and T6 if it evers changes them, since SCMUUO calls it.
SRHNOD::MOVE T2,T1 ;COPY NODE ID TO T2
LOAD T1,QHBEG,+NMXNDQ ;GET HEAD OF NMX NODES LIST
FNDND1: JUMPE T1,RTN ;LIST IS EMPTY, ERROR RETURN
OPSTR <CAMN T2,>,NNNOD,(T1) ;IS THIS THE NODE WE'RE LOOKING FOR?
RETSKP ;YES, SUCCESS RET WITH PTR IN T1
LOAD T1,QPNXT,+NN.NXT(T1) ;NO, GET THE NEXT ENTRY IN LIST
JRST FNDND1 ;AND TRY IT
SUBTTL Data Base -- NMXNMI - Get node software ID.
;Copy system name
;Call
; T1/ Local byte pointer to destination of string
;Return
; RET ;hopefully never.
; RETSKP ;Always
NMXNMI::
SAVEAC <P1,P2> ;SAVE AN AC FOR BYTE COUNT
JN NXWRM,+NMXVAR,NMXNI3 ;IF SETTING, USE ALTERNATE CODE
MOVE T1,[POINT 8,NX.VAL+NMXVAR] ;BYTE POINTER TO RECEIVE STRING
MOVSI T2,(POINT 7,(P2)) ;BYTE POINTER TO STRING
SKIPN P2,NMXIDN ;DO WE HAVE A LOCALLY SET ID?
IFN FTOPS10,XMOVEI P2,CONFIG## ;NO, DEFAULT TO MONITOR NAME
IFN FTOPS20,XMOVEI P2,VTSVN## ;NO, DEFAULT TO SYSTEM NAME
SETZ P1, ;ASSUME A ZERO LENGTH STRING
IDPB P1,T1 ;STORE LENGTH (TEMP, WILL BE REPLACED)
MOVE T4,T1 ;COPY BYTE POINTER TO LENGTH
NMXNI0: CAIL P1,^D32 ;IF WE ARE ABOUT TO RUN OVER
JRST NMXNI1 ;FINISH THE STRING
ILDB T3,T2 ;GET NEXT BYTE FROM CONFIG
JUMPE T3,NMXNI1 ;IF END OF ASCIZ STRING, END
IDPB T3,T1 ;SAVE BYTE IN DESTINATION STRING
AOJA P1,NMXNI0 ;GO GET ANOTHER BYTE
NMXNI1: DPB P1,T4 ;STORE SIZE IN BEGINNING OF BYTE STRING
RETSKP ;RETURN SUCCESS
NMXNI3: JN NXZMC,+NMXVAR,NMXNI7 ;IF CLEARING, RETURN BLOCK OF CORE
SKIPE P2,NMXIDN ;GET POINTER TO CURRENT STRING, IF ANY
JRST NMXNI4 ;HAVE CURRENT STRING, DON'T GET ANOTHER BLOCK
MOVEI T1,<^D32/5>+1 ;GET ENOUGH SPACE TO STORE 32 CHARACTERS
CALL DNGWDS ;GET THE SPACE
ERRRET NTERES ;NOT ENOUGH RESOURCES
MOVE P2,T1 ;SAVE POINTER
MOVEM P2,NMXIDN ;AND SAVE FOR LATER
NMXNI4: MOVE T3,[POINT 8,NX.VAL+NMXVAR] ;POINTER TO SOURCE STRING
MOVSI T2,(POINT 7,(P2)) ;DESTINATION BYTE POINTER
ILDB P1,T3 ;SAVE BYTE COUNT TO DECREMENT ON.
CAXL P1,^D32 ;WILL IT FIT IN DESTINATION BLOCK?
BUG.(CHK,NTMBSS,NTMAN,SOFT,<Bad string size in NMXNI4>,,<
Cause: We are going to copy an identification string from NMXVAR into
a freecore block, and the string claims to be longer than will
fit in either block.
Cure: Find out how this byte (length) got trashed.
>,NTEMPE)
NMXNI5: ILDB T1,T3 ;GET A BYTE FROM SOURCE
IDPB T1,T2 ;STORE IN DESTINATION STRING
SOJG P1,NMXNI5 ;AND LOOP
IDPB P1,T2 ;TERMINATE STRING WITH A ZERO BYTE
RETSKP
NMXNI7: SKIPE T1,NMXIDN ;GET POINTER TO ID STRING
CALL DNFWDS ;FREE THE CORE
SETZM NMXIDN ;CLEAR THE POINTER TO OBSOLETE CORE
RETSKP ;AND RETURN SUCCESS
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
LIT
IFN FTOPS10, .XCMSY
IFN FTOPS20, TNXEND
END