Trailing-Edge
-
PDP-10 Archives
-
bb-h240e-bm_decnet-20_v4_0_dist
-
tools/dntatl.mac
There are 9 other files named dntatl.mac in the archive. Click here to see a list.
; UPD ID= 57, SNARK:<6.1.UTILITIES>DNTATL.MAC.44, 12-Dec-84 16:08:13 by PALMIERI
;Fix local DECnet
; UPD ID= 52, SNARK:<6.1.UTILITIES>DNTATL.MAC.43, 21-Nov-84 15:52:12 by GLINDELL
;Redefine DELAY bit
; UPD ID= 45, SNARK:<6.1.UTILITIES>DNTATL.MAC.42, 16-Nov-84 15:03:10 by GLINDELL
;Add support for DELAY bit
;
; UPD ID= 29, SNARK:<6.1.UTILITIES>DNTATL.MAC.38, 22-Aug-84 13:39:22 by NICHOLS
;Fix /NODE:n so that route-through messages are properly recognised.
; UPD ID= 28, SNARK:<6.1.UTILITIES>DNTATL.MAC.35, 19-Aug-84 18:29:47 by NICHOLS
;Fix /NODE:n/RTRCTL so that router control is typed even if no NSP records are.
;Tell user how many records were skipped at end of file, just before close.
; UPD ID= 26, SNARK:<6.1.UTILITIES>DNTATL.MAC.33, 19-Aug-84 18:08:06 by NICHOLS
;Rearrange selection switch processing so that each message is only parsed
;once. Add the /[NO]NSPCTL switch.
; UPD ID= 13, SNARK:<6.1.UTILITIES>DNTATL.MAC.28, 22-Jun-84 13:58:25 by GROSSMAN
;Increase DECnet buffer size to prevent program from blowing up on Ethernet
; packets.
;SNARK:<6.1.UTILITIES>DNTATL.MAC.14 2-Apr-84 17:37:04, Edit by NICHOLS
;Add input and output circuit typeout
;WORK:<NICHOLS>DNTATL.MAC.56 1-Feb-84 21:16:06, Edit by NICHOLS
;Fix date/time typout
;WORK:<NICHOLS>DNTATL.MAC.23 24-Jan-84 15:59:49, Edit by NICHOLS
;Add code to handle Phase IV router header and its pad byte
;SNARK:<6.1.UTILITIES>DNTATL.MAC.4 20-Jan-84 11:36:24, Edit by NICHOLS
;Add Phase IV NI routing for ROUTER data messages.
TITLE DNTATL - Format a DECnet-20 Trace
SUBTTL W. G. Nichols
OPDEF OPEN [050000,,0] ;GET AROUND KEVIN'S BAD MACSYM
OPDEF CLOSE [070000,,0] ;DITTO
SEARCH D36PAR,MONSYM,MACSYM,SCNMAC
XP FTLIST,0 ;NON-0 TO DISABLE XLISTS
XP FTNSCAN,0 ;NON-0 FOR HOUK'S NEW SCAN
XP FTOPS10,0 ;NON-0 FOR TOPS-10 VERSION
XP FTOPS20,1 ;NON-0 FOR TOPS-20 VERSION
.REQUEST REL:SCAN
PRGID='DNTATL' ;NAME OF THIS PROGRAM
PRGABR='DNT' ;3 CHR ABBREVIATION USED FOR PROG.
DNTWHO==0
DNTVER==1 ;MAJOR VERSION
DNTMIN==0 ;MINOR VERSION
DNTEDT==2 ;EDIT NUMBER
HSGAD==600000 ;STARTING ADDR OF HISEG
TWOSEG HSGAD ;WE'LL HAVE A SHARABLE HI-SEG
; RELOC ; HSGAD
;Note that these BEGSTRs are copied in MSGTRC, the program which
;makes the trace file.
FTSHOW==0
BEGSTR FH ;File Header
WORD LNG ;Length of this header
FIELD FLG,9 ;Flags to indicate what kind of entry
FIELD TYP,9 ;Entry Type
XP TYP.FH,1 ; Entry type of header record
HWORD MGL ;Length of a message block
WORD UPT ;UPTIME corresponding to UDT below
WORD UDT ;Universal Date/Time corresp to UPTIME
WORD PVR ;Trace program version number (loc 137)
WORD MVR ;Monitor Version (location 137)
WORD CFG,5 ;CONFIG string from this monitor
ENDSTR
BEGSTR MH ;Message Header
WORD LNG ;Length of the entire entry
FIELD FLG,6 ;Flags to indicate what kind of entry
FIELD IOL,3 ;Input, output or local
XP IOL.IN,1 ;Input (avoid zero for error detection)
XP IOL.OT,2 ;Output message
XP IOL.LO,3 ;Local message
FIELD TYP,9 ;Entry Type
XP TYP.MH,2 ; Entry type of message record
HWORD LST ;Cumulative number of messages lost
WORD UPT ;UPTIME as of entry (reliable time stamp)
WORD UDT ;Universal date/time (readable time stamp)
WORD OMB ;Original MB pointer
WORD ILN ;Input line ID (or zero if none)
WORD OLN ;Output line ID (or zero if none)
ENDSTR
;The format of an ACKNUM field
;This structure is expected to be used to pull apart a value held
;in a register.
BEGSTR AK
FILLER 20 ;ONLY THE RIGHTMOST 16 BITS COUNT
FIELD PNT, 1 ;FLAG SET IF FIELD IS PRESENT
FIELD QAL, 3 ;QUALIFIER:
AK$QAK==0 ; 0 IS ACK
AK$QNK==1 ; 1 IS NAK, 2 & 3 ARE RESERVED
AK$CAK==2 ; 2 IS CROSS-SUB CHANNEL ACK
AK$CNK==3 ; 3 IS CROSS-SUB CHANNEL NAK
FIELD NUM, 12 ;THE ACK NUMBER, WE KNOW THIS IS RT-JUSTIFIED
ENDSTR ; NEGATIVE IF HIGH BIT OF BYTE IS SET
; SEE LOADE MACRO (E IS AS IN HRRE)
;This structure is expected to be used to pull apart a value held
;in a register.
BEGSTR LS ;THE LSFLAGS FIELD OF A LINK SERVICE MESSAGE
FILLER 28 ;ONLY THE RIGHTMOST 8 BITS COUNT
FIELD ZRO,4 ;MUST BE ZERO
FIELD INT,2 ;INTERPRETATION
LS.INR==0 ;NORMAL DATA REQUEST
LS.IOT==1 ;OTHER DATA REQUEST (2 & 3 RESERVED)
FIELD MOD,2 ;THE ON/OFF INDICATOR
LS.MNC==0 ;NO CHANGE, CODE USES JUMPE
LS.MOF==1 ;TURN SUBLINK OFF (IGNORED ON "OTHER")
LS.MON==2 ;TURN SUBLINK ON (IGNORED ON "OTHER")
LS.MRS==3 ;RESERVED
ENDSTR
;This structure is expected to be used to pull apart a value held
;in a register.
BEGSTR SV ;THE SERVICES FIELD OF A CI OR CC MSG
FIELD FL1,32 ;FILLER 1, CHECK FOR ALL ZEROES
FIELD OPT,2 ;THE FLOW CONTROL OPTION, SEE FCM.xx
FIELD FL2,2 ;FILLER 2, CHECK FOR BEING "01"
SV$FL2==1 ;MAGIC NUMBER THAT SVFL2 MUST BE
ENDSTR
;This structure us expected to be used to pull apart a value held
; in a register.
BEGSTR SG ;The SEGNUM field of a DATA message
FILLER 20 ;Only 16 bits used
FILLER 1
FIELD DLY,1 ;ACK DELAY allowed
FILLER 2
FIELD NUM,12 ;The segment number
ENDSTR
SUBTTL Macros
DEFINE SMEAR(ac,start,end,value),<
MOVX ac,value
MOVEM ac,start
MOVE ac,[XWD start,start+1]
BLT ac,end
>
DEFINE $LIST,< LIST
SALL
>
DEFINE $XLIST,<IFE FTLIST,<XLIST
>>
$LIST
DEFINE VRSN. (PROG),<
BYTE (3) PROG'WHO (9) PROG'VER (6) PROG'MIN (18) PROG'EDT
>
.JBVER=137 ;JOBDAT LOC FOR VERSION NUMBER
LOC .JBVER
VRSN. DNT
RELOC
SUBTTL Accumulator Definitions
FLAG=0 ;FLAGS, CONTINUOUS THROUGH ALL CALLS
;ZEROED BEFORE EACH CALL TO .TSCAN
;SEE BIT DEFINITIONS BELOW
T1=1 ;WORK... T1 AND T2 MUST BE 1 & 2
T2=2
T3=3 ;AND T3 AND T4 MUST BE 3 & 4
T4=4 ;FOR COMPATIBILITY WITH SCAN & WILD
T5=5
T6=6 ;T6 IS USED AS INDEX FOR MSD BYTE PTRS
N=7 ;SAME AS IN SCAN
C=10 ;SAME AS IN SCAN
MBO=11 ;OFFSET TO SUBTRACT FROM PTRS INTO MSG BLK
MS=12 ;POINTER TO CURRENT MSD IN MSG BLK
P1=13 ;PRESERVED ACs
P2=14
; ??=15
CX=16 ;SUPER-TEMP FOR MACROS
.SAC==CX ; ALTERNATE NAME FOR CX FOR SOME MACROS
P=17 ;STACK POINTER
SUBTTL Compile-Time Variables
OPDEF CALL [PUSHJ P,]
OPDEF RET [POPJ P,]
OPDEF RETSKP [JRST RSKP]
OPDEF CALLRET [JRST]
;CHANNEL ASSIGNMENTS
XP F.FIN,1 ;CHANNEL FOR INPUT FILE.
XP F.FOUT,2 ;CHANNEL FOR OUTPUT FILE.
;DEFAULT DEVICE NAMES
XP INDFT,'DSK ' ;DEFAULT INPUT DEVICE
XP OUTDFT,'DSK ' ;DEFAULT OUTPUT DEVICE.
;Block lengths
XP %XPBSZ,^D2000 ;MAX BUFFER SIZE DECnet USES
XP LN$PDL,^D100 ;LENGTH OF PUSH DOWN LIST
XP FOPLEN,^D7 ;LENGTH OF NON-PRIV FILOP. BLOCK
XP PTHLNG,^D9 ;LENGTH OF A PATH BLOCK
XP LN$ENT,^D9 ;LENGTH OF EXTENDED ENTER BLOCK
XP LN$LKP,^D9 ;LENGTH OF EXTENDED LOOKUP BLOCK
; MSG$ is followed by the three letter error code, one of the
; indicators ERR, WRN, or INF for which class of message, an
; optional S to save all accumulators, and the message text.
; it will force out any TTY buffers, issue the file name if
; not yet done, then issue the message correctly prefixed.
DEFINE MSG$(code$,level$,savef$,text$),<
$XLIST
E..'code$:!
IFIDN <savef$><S>,< PUSH P,T1
PUSH P,T2
PUSH P,T3
PUSH P,T4>
LEVL$$=="%"
IFIDN <level$><ERR>,<LEVL$$=="?">
MOVE T1,[XWD PRGABR,''code$'']
MOVE T2, [XWD LEVL$$,[ASCIZ "text$"] ]
$LIST
CALL .ERMSG## ;;TYPE THE ERROR MESSAGE.
$XLIST
IFIDN <savef$><S>,< POP P,T4
POP P,T3
POP P,T2
POP P,T1>
$LIST
SALL
>
DEFINE ERROR(code,text,label),<
IFNB <label>,<JRST [>
IFB <label>,<CALL [>
IF2,<IFN .TYTTY,<PRINTX ?ERROR macro requires that .TYTTY be zero>>
SKIPE TYPDEV ;;SKIP IF NO OUTPUT FILE BEING USED
OUT F.FOUT, ;;SYNCH ERROR MSG IF OUT DEV IS TTY
PUSH P,TYPDEV
SETZM TYPDEV ;;DIRECT .TCHAR OUTPUT TO TTY NOW
MSG$(code,ERR,S,<text>)
CALL .TCRLF##
POP P,TYPDEV
IFNB <label>,<JRST label>
IFB <label>,<RET>
]
>
DEFINE FMTERR(text,label),<
IFNB <label>,<JRST [>
IFB <label>,<CALL [>
CALL .TCRLF##
WRTSTR <?Format error: text>
IFNB <label>,<JRST label>
IFB <label>,<RET>
]
>
;Macros for writing to the output file
DEFINE WRTSTR(string),<
CALL [ JSP T1,.TSTRG##
ASCIZ `string`]
>
SUBTTL General Impure Storage
;Locations which are set at start-up time and never cleared.
RELOC ;INTO THE LOWSEG
;The stack:
PLIST: BLOCK LN$PDL+1
CCLF1: BLOCK 1 ;1 IF CCL ENTRY, 0 IF NORMAL
INICOR: BLOCK 1 ;SIZE OF CORE BEFORE ANY EXPANSION
INIFF: BLOCK 1 ;INITIAL SETTING OF .JBFF
TYPDEV: BLOCK 1 ;OUTPUT DEVICE TYPE
.TYTTY==0 ;TTY, MUST BE ZERO (ERROR MACRO USES SKIPE)
.TYFIL==1 ;OUTPUT TO FILE (OUTPUT DEVICE)
.TYBUF==2 ;OUTPUT TO TEMP BUFFER
SUBTTL Not-File-Specific Switch Definitions
SCMFWA:! ;START OF FS.NFS SWITCHES CLEARED TO -1
SCNLLA: BLOCK 1 ;PUT CHOSEN LOCAL LINK ADDRESS HERE
SCNRLA: BLOCK 1 ;PUT CHOSEN REMOTE LINK ADDRESS HERE
SCNNOD: BLOCK 1 ;PUT CHOSEN NODE ADDRESS HERE
SCNRTR: BLOCK 1 ;NON-ZERO TO INCLUDE ROUTER CONTROL MSGS
SCNNSP: BLOCK 1 ;NON-ZERO TO INCLUDE NSP CONTROL MSGS
SCNDAT: BLOCK 1 ;NON-ZERO TO INCLUDE DATA PORTION OF MSGS
SCMLWA==.-1
SCNLEN==.FXLEN ;LENGTH OF A SCAN SPEC INCLUDING LOCAL LOAD
SCNFWA:! ;START OF SCAN AREA CLEARED TO 0
SCNIN: BLOCK SCNLEN ;PLACE TO PUT INPUT SPEC
SCNOUT: BLOCK SCNLEN ;PLACE TO PUT OUTPUT SPEC
;Trace Record Collection Areas
RHDRLN: BLOCK 1 ;LENGTH OF ROUTER HDR ON THIS MSG
; -1 IF MSG IS ROUTER CONTROL
LSTCNT: BLOCK 1 ;LAST LOST COUNT WE SAW (MHLST FIELD)
SKPCNT: BLOCK 1 ;NUMBER OF RECS SKIPPED FOR SELECTION SWITCHES
FILHDR: BLOCK FH.LEN ;BLOCK TO HOLD FILE HEADER RECORD
MSGHDR: BLOCK MH.LEN ;BLOCK TO HOLD MESSAGE HEADER RECORD
MSGBLK: BLOCK MB.LEN ;BLOCK TO HOLD MESSAGE BLOCK
USERDA: BLOCK <%XPBSZ+3>/4 ;USER DATA GOES HERE
SEQBFR: BLOCK <%XPBSZ+3>/4 ;BUILD A SEQUENTIAL MSG HERE
SEQPTR: BLOCK 1 ;BYTE PTR INTO SEQBFR
SEQCNT: BLOCK 1 ;LENGTH OF REST OF SEQUENTIAL MESSAGE
SEQLEN: BLOCK 1 ;INITIAL LENGTH OF SEQUENTIAL MESSAGE
TMPWDS==<%XPBSZ+3>*2
TMPBUF: BLOCK TMPWDS ;BUILD OUTPUT RECORD HERE BEFORE DECIDING
TMPPTR: BLOCK 1 ; WHETHER OR NOT WE REALLY WANT IT,
TMPCNT: BLOCK 1 ; DUE TO SELECTION SWITCHES
RTROFF: BLOCK 1 ;PLACE TO STORE OFFSET TO FIRST RTR HDR BYTE
CURDNA: BLOCK 1 ;PLACE TO STORE CURRENT MSG'S DEST NODE ADDR
CURSNA: BLOCK 1 ;PLACE TO STORE CURRENT MSG'S SOURCE NODE ADDR
CURDLA: BLOCK 1 ;PLACE TO STORE CURRENT MSG'S DEST LINK ADDR
CURSLA: BLOCK 1 ;PLACE TO STORE CURRENT MSG'S SOURCE LINK ADDR
;Input I/O areas
FOPLKP: BLOCK FOPLEN ;ARG BLK FOR FILOP. LOOKUP
OPNIN=FOPLKP+.FOIOS ;ALLOW OLD NAMES
LKPBLK: BLOCK LN$LKP+1 ;LOOKUP BLK FOR INPUT FILE.
LKPBLE=.-1
LKPPTH: BLOCK PTHLNG ;PATH BLK FOR LKPBLK
LKPPTE=.-1 ;LIMIT OF BLT SMEARING
;INPUT BUFF RING HDR IS IN .WILD
;Output I/O areas
IFN FTOPS20,<
.FOIOS==1 ;OUTPUT BLOCK IN FILOP BLOCK
.FOBRH==3 ;BUFFER RING HEADERS IN FILOP BLOCK
.BFPTR==1 ;BUFFER RING HEADER POINTER WORD
.BFCTR==2 ;BUFFER RING HEADER COUNTER WORD
IO.ERR==740000 ;IO ERRORS MASK
IO.EOF==20000 ;END OF FILE ERROR FLAG
.IOASC==0 ;ASCIZ MODE I/O
.IOBIN==14 ;BINARY MODE I/O
>;END IFN FTOPS20
FOPENT: BLOCK FOPLEN ;ARG BLK FOR FILOP. ENTER
OPNOUT=FOPENT+.FOIOS ;ALLOW USE OF OLD NAMES
ENTBLK: BLOCK LN$ENT+1 ;ENTER BLOCK FOR OUTPUT FILE.
ENTBLE=.-1
ENTPTH: BLOCK PTHLNG ;PATH BLOCK FOR .STOPB AND ENTBLK
ENTPTE=.-1 ;LIMIT OF BLT SMEARING
H.FIN: BLOCK 3 ;BUFFER HEADER FOR INPUT.
H.FOUT: BLOCK 3 ;BUFFER HEADER FOR OUTPUT.
SCNLWA==.-1 ;LAST OF WORK AREA CLEARED TO 0
;Now put the rest in the High Segment
RELOC
SUBTTL SCAN Switch Tables.
DEFINE ND(name,value),<IFNDEF name,name=:value> ;DM NEEDS THIS
;Define the defaults for switches:
; First arg is 3-chr abbrieviation used for this switch.
; Second arg is maximum allowed value.
; Third arg is absent default (AD.xxx)
; (not used by SCAN, for application use only).
; Fourth arg is present default (PD.xxx)
; (used by SCAN unless FS.VRQ specified)
; Name Max Absent Present
; xxx MX.xxx AD.xxx PD.xxx
; ---- ------ ------ -------
lall
DM LLA, 177777, 0, 0 ;/LLA (LOCAL LINK ADDRESS)
DM RLA, 177777, 0, 0 ;/RLA (REMOTE LINK ADDRESS)
DM NOD, ^D1024, 0, 0 ;/NODE
sall
; See SCNMAC.MAC for definition of macros used here.
;
; An asterisk before a switch name in this table means that
; this switch has abbreviation priority over any other
; switches in the list.
;
;REMEMBER to update HLPSTR when updating the switches
DEFINE SWTCHS,<
$XLIST
SP LLA,SCNLLA,.SWOCT##,LLA,FS.NFS!FS.VRQ
SP RLA,SCNRLA,.SWOCT##,RLA,FS.NFS!FS.VRQ
SP NODE,SCNNOD,.SWDEC##,NOD,FS.NFS!FS.VRQ
SN NSPCTL,SCNNSP,FS.NFS
SN RTRCTL,SCNRTR,FS.NFS
SN DATA,SCNDAT,FS.NFS
$LIST
>;END OF SWTCHS
;Now build the tables.
DOSCAN (SWT)
SUBTTL HLPSTR - The HELP string
HLPSTR: ASCIZ \
The commands are in the traditional SCAN format:
output-file-spec = input-file-spec /switches
The input to DNTATL is the file output by DNSNUP which contains DECnet message
blocks in internal format. The output from DNTATL is a text file representing
those messages and their DECnet headers. The user data portion of the messages
are put out first in octal bytes, then in ASCII.
The default for all switches is to output everything.
The switches are:
NODE:n Show only those messages to or from Node n. Only the low
order 10 bits of the node address (intra-area node number)
are compared. /NODE:n accepts only a single decimal number.
LLA:n Show only those messages whose Local Link Address is n.
RLA:n Show only those messages whose Remote Link Address is n.
[NO]NSPCTL [Don't] show NSP Control messages.
[NO]RTRCTL [Don't] show Router Control messages.
Iff /NODE, /LLA, /RLA or /NONSPCTL are specified, /NORTRCTL is default.
[NO]DATA [Don't] show data part of messages.
To find the Link Address of a logical link, first run DNTATL (perhaps with
/NODE:n) to find the interesting series of messages. Note the DLA
(Destination Link Address) of an input message or the SLA (Source Link
Address) of an output message. This is the Local Link Address to be used with
the /LLA:n switch. The Remote Link Address is the same with source and
destination reversed.
\
SUBTTL Startup
DNTATL:
IFN FTOPS10,<
TDZA T1,T1 ;NON-CCL ENTRY
MOVEI T1,1 ;CCL ENTRY
MOVEM T1,CCLF1 ;STORE FOR LATER
>;END IFN FTOPS10
RESET ;CLEAR ALL I/O
SETZM TYPDEV ;DIRECT .TCHAR OUTPUT TO TTY NOW
IFN FTOPS10,<
HRRZ T1,.JBREL ;GET FIRST-TIME CORE SIZE
MOVEM T1,INICOR
HRRZ T1,.JBFF ;GET INITIAL .JBFF
MOVEM T1,INIFF ;SAVE FOR LATER
>;END IFN FTOPS10
MOVE P,[IOWD LN$PDL,PLIST] ;STACK
;Fall through to next page
SUBTTL Call .ISCAN
;From previous page
;.ISCAN--SUBROUTINE TO INITIALIZE COMMAND SCANNER
;CALL AC1=XWD LENGTH,BLOCK
;
; BLOCK+0=PROTOCOL VERSION WORD: <MAJOR>,,<MINOR>
; BLOCK+1=0 OR IOWD PTR TO A LIST OF LEGAL MONITOR COMMANDS
; IF 0, NO RESCAN IS DONE
; BLOCK+2=RH 0 OR SIXBIT CCL NAME
; IF 0, NO CCL MODE
; LH 0 OR ADDRESS OF STARTING OFFSET
; BLOCK+3=RH 0 OR ADDRESS OF CHARACTER TYPEOUT ROUTINE
; IF 0, OUTCHR WILL BE DONE FROM T1
; LH 0 OR ADDRESS OF CHARACTER INPUT ROUTINE
; MUST SAVE ALL ACS, CHAR IN P4
; BLOCK+4=0 OR POINTER (XWD LEN,BLOCK) TO INDIRECT FILE BLOCK
; .FXDEV NE 0 TO USE BLOCK
; BLOCK+5=RH 0 OR ADDRESS OF MONRET ROUTINE
; LH 0 OR ADDRESS OF PROMPT ROUTINE
; CALLED WITH CHAR IN RH(T1), LH(T1) HAS
; 0 FOR FIRST LINE, -1 FOR CONTINUATION LINES
; BLOCK+6=LH FLAGS
; RH (FUTURE)
;VALUE AC1=INDEX IN TABLE OF COMMANDS IF FOUND(0,1,...), ELSE -1
IFN FTNSCAN,<MOVE T1,[4,,[12,,%%FXVE> ;MAJOR,,MINOR SCAN VERSION
IFE FTNSCAN,<MOVE T1,[3,,[IOWD 1,[PRGABR]>
CCLF1,,PRGABR
0,,TYPOUT]]
CALL .ISCAN##
;Fall through to next page
SUBTTL Driving Loop
DNTLOP: RELEASE F.FIN, ;RELEASE INPUT CHANNEL
RELEASE F.FOUT, ;RELEASE OUTPUT CHANNEL
SETZM TYPDEV ;DIRECT .TCHAR OUTPUT TO TTY NOW
CALL $SCAN ;GET FILE SPECS FROM .TSCAN
JRST DNTLOP ;ERROR, TRY AGAIN
CALL $DFALT ;DEFAULT THE NAMES & EXTENSIONS
CALL $OPEN ;OPEN INPUT & OUTPUT FILES
JRST DNTLOP ;ERROR, TRY AGAIN
MOVEI T1,.TYFIL ;DIRECT .TCHAR
MOVEM T1,TYPDEV ; OUTPUT TO FILE NOW
CALL REDHDR ;READ TRACE FILE'S HEADER
JRST DNTCLS ;END OF FILE OR ERROR
DNTFMT: CALL REDMSG ;READ NEXT RECORD INTO MSG BLK
JRST DNTCLS ;END OF FILE OR ERROR
CALL FMTMSG ;FORMAT & OUTPUT THIS RECORD
JRST DNTCLS ;ERROR WRITING OUTPUT FILE
JRST DNTFMT ;GO GET NEXT RECORD
DNTCLS: MOVEI T1,.TYFIL ;DIRECT OUTPUT
MOVEM T1,TYPDEV ; TO FILE (OUTPUT DEVICE) FOR TYPSKP
CALL TYPSKP ;ADMIT TO ANY REMAINING SKIPPED MESSAGES
CALL $CLOSE ;CLOSE INPUT & OUTPUT FILES
JRST DNTLOP ;SEE IF USER WANTS MORE
SUBTTL Routines for SCAN's input from TTY
;.TSCAN--SUBROUTINE FOR TRADITIONAL COMMAND SCANNER
;ARGS AC1=XWD LENGTH,BLOCK
; BLOCK+0=0 OR IOWD POINTER TO LIST OF SWITCH NAMES
; (IOWD XXXXXL,XXXXXN)
; BLOCK+1=LH ADDRESS OF DEFAULT SWITCH TABLE (XXXXXD)
; RH ADDRESS OF PROCESSOR SWITCH TABLE (XXXXXM)
; BLOCK+2=LH ADDRESS OF (FUTURE)
; RH ADDRESS OF SWITCH POINTERS FOR STORING (XXXXXP)
; BLOCK+3=LH TYPE OF HELP (0=NONE, 1=STRING, 2=SUBROUTINE)
; IF GT 77, NAME OF PROGRAM IN WHOLE WORD
; IF -1 IN WORD, USE JOB TABLE
; RH LOCATION OF HELP
; BLOCK+4=LH 0 OR SUBROUTINE TO CLEAR ALL ANSWERS
; RH 0 OR SUBROUTINE TO CLEAR FILE ANSWERS
; BLOCK+5=LH SUBROUTINE TO ALLOCATE INPUT FILE AREA
; RH SUBROUTINE TO ALLOCATE OUTPUT FILE AREA
; BOTH RETURN T1=START OF AREA, T2=LENGTH
; BLOCK+6=LH 0 OR SUBROUTINE TO MEMORIZE STICKY DEFAULTS
; RH 0 OR SUBROUTINE TO APPLY STICKY DEFAULTS
; BLOCK+7=LH 0 OR SUBROUTINE TO CLEAR STICKY DEFAULTS
; RH FLAGS TO CONTROL SCAN:
; 1B18=MORE THAN ONE OUTPUT SPEC POSSIBLE
; 1B19=ALLOW INPUT SWITCHES ON OUTPUT AND VV
; BLOCK+10=LH (FUTURE)
; RH 0 OR ROUTINE TO STORE SWITCH VALUES
; ;ENTERRED WITH T1=VALUE, T2=POINTER
; ;NON-SKIPS IF SCAN SHOULD NOT STORE
; ;SKIPS IF SCAN SHOULD STORE (T1-2 OK)
;Back here after each command is complete
$SCAN:
IFN FTNSCAN,<MOVE T1,[12,,[12,,%%FXVE> ;MAJOR,,MINOR SCAN VERSION
IFE FTNSCAN,<MOVE T1,[11,,[IOWD SWTL, SWTN>
SWTD,,SWTM
0,,SWTP
1,,HLPSTR ;HELP IS STRING,,ADDR OF STRING
SCNCLA,,SCNCLF
SCNAIN,,SCNAOT
FILSTK,,APLSTK
CLRSTK,,0
0,,0 ] ]
CALL .TSCAN## ;SCAN THE LINE
; Check SWITCH.INI
IFN FTNSCAN,<MOVE T1,[5,,[12,,%%FXVE> ;MAJOR,,MINOR SCAN VERSION
IFE FTNSCAN,<MOVE T1,[4,,[IOWD SWTL,SWTN>
SWTD,,SWTM
0,,SWTP
PRGID]] ;get help from HLP:PRGID
CALL .OSCAN## ;GET OPTIONS IF ANY
RETSKP ;SUCCESS RETURN.
;Routine to allocate output spec area
SCNAOT: SMEAR T1,SCNOUT,SCNOUT+SCNLEN-1,0
MOVEI T1,SCNOUT ;POINT TO AREA
MOVEI T2,SCNLEN ; AND LENGTH
RET ;RETURN
;Routine to allocate input spec area
SCNAIN: SMEAR T1,SCNIN,SCNIN+SCNLEN-1,0
MOVEI T1,SCNIN ;POINT TO AREA
MOVEI T2,SCNLEN ; AND LENGTH
RET ;RETURN
;Routine to clear SCAN results
SCNCLA: SMEAR T1,SCNFWA,SCNLWA,0 ;CLEAR AREA
SMEAR T1,SCMFWA,SCMLWA,-1 ; AND SWITCHES
RET
SCNCLF:
CLRSTK:
APLSTK:
FILSTK: RET
SUBTTL $DFALT -- Default the SCAN Blocks
$DFALT:
;Default the input file spec
IFN FTNSCAN,<
MOVE T4,.FXFLD+SCNIN ;GET THE 'FIELDS-SPECIFIED' WORD
HRLOI T1,'MSG' ;DEFAULT EXTENSION IS .MSG
TXNN T4,FX.UEX ;USER SPECIFY AN EXTENSION?
MOVEM T1,.FXEXT+SCNIN ;NO, SPECIFY .MSG
;Default the output file spec
MOVE T4,.FXFLD+SCNOUT ;GET THE 'FIELDS-SPECIFIED' WORD
HRLOI T1,'TXT' ;DEFAULT EXTENSION IS .TXT
TXNN T4,FX.UEX ;USER SPECIFY AN EXTENSION?
MOVEM T1,.FXEXT+SCNOUT ;NO, SPECIFY .TXT
>;END IFN FTNSCAN
;Default the /RTRCTL switch from the other switches
SKIPL SCNRTR ;HAS USER SPECIFIED /RTRCTL OR /NORTRCTL?
JRST DFALT1 ;YES, DON'T OVERRIDE USER
MOVE T1,SCNLLA ;NO, ARE OTHER RESTRICTION
AND T1,SCNRLA ; SWITCHES
AND T1,SCNNOD ; USED?
SKIPE SCNNSP ;USER SAY /NONSPCTL?
AOJE T1,DFALT1 ;NO, JUMP IF ALL OTHERS WERE -1 (DEFAULT)
SETZM SCNRTR ;AT LEAST ONE RESTRICTION, SAY /NORTRCTL
DFALT1: RET
SUBTTL $OPEN -- Open Input & Output Devices
;.STOPB -- ROUTINE TO TURN SCAN BLOCK INTO OPEN/LOOKUP BLOCKS
; WILD-CARDS ARE ILLEGAL
;CALL: MOVEI T1,SCAN BLOCK
; LH(T1)=LENGTH IF .GT. 24
; MOVEI T2,OPEN BLOCK (3 WORDS)
; MOVEI T3,LOOKUP BLOCK (6 WORDS OR MORE)
; LH(T3)=LENGTH IF .GT. 6
; MOVEI T4,PATH BLOCK (9 WORDS)
; PUSHJ P,.STOPB
; ERROR RETURN IF WILD-CARDS
; SKIP RETURN IF SETUP OK
;USES T1-4
$OPEN: MOVEI T1,LN$LKP ;GET LENGTH OF A LOOKUP BLOCK
MOVEM T1,LKPBLK+0 ;STORE IN LENGTH WORD
MOVEI T1,SCNIN ;PTR TO SCAN BLK
MOVEI T2,OPNIN ;PTR TO OPEN BLK
MOVX T3,<LN$LKP,,LKPBLK> ;LENGTH,,PTR TO LOOKUP BLOCK
MOVEI T4,LKPPTH ;PTR TO LOOKUP'S PATH BLK
CALL .STOPB##
ERROR WNI,<Wildcards not supported>,RTN
MOVEI T1,LN$ENT ;GET LENGTH OF AN ENTER BLOCK
MOVEM T1,ENTBLK+0 ;STORE IN LENGTH WORD
MOVEI T1,SCNOUT ;PTR TO SCAN BLK
MOVEI T2,OPNOUT ;PTR TO OPEN BLK
MOVX T3,<LN$ENT,,ENTBLK> ;LENGTH,,PTR TO ENTER BLOCK
MOVEI T4,ENTPTH ;PTR TO ENTER'S PATH BLK
CALL .STOPB##
ERROR WNO,<Wildcards not supported>,RTN
MOVX T1,.IOBIN ;INPUT FILE IN BINARY MODE
MOVEM T1,OPNIN
MOVEI T1,H.FIN ;GET IBUF ADDR FROM SCAN
MOVEM T1,FOPLKP+.FOBRH
OPEN F.FIN,OPNIN ;OPEN INPUT FILE
ERROR COI,<Cannot Open Input Device>,RTN
LOOKUP F.FIN,LKPBLK
ERROR CFI,<Cannot Find Input File>,RTN
MOVX T1,.IOASC ;OUTPUT FILE IN ASCII MODE
MOVEM T1,OPNOUT
MOVSI T1,H.FOUT ;GET OBUF ADDR
MOVEM T1,FOPENT+.FOBRH
OPEN F.FOUT,OPNOUT ;OPEN OUTPUT FILE
ERROR COO,<Cannot Open Output Device>,RTN
ENTER F.FOUT,ENTBLK
ERROR CFO,<Cannot Find Output File>,RTN
RETSKP
$CLOSE: CLOSE F.FIN, ;CLOSE INPUT FILE
CLOSE F.FOUT, ;CLOSE OUTPUT FILE
RET ;NOTHING MORE FOR NOW
SUBTTL REDHDR -- Read Header from Input File
REDHDR: CALL INBYT ;GET LENGTH OF HEADER RECORD
RET ;PROPOGATE ERROR RETURN
CAIE T1,FH.LEN ;IS IT THE LENGTH WE'RE EXPECTING?
ERROR BLN,<Header in trace file is of unexpected length>,RTN
STOR T1,FHLNG,+FILHDR ;'TIS RIGHT LENGTH, STORE IT
MOVE T1,[XWD -<FH.LEN-1>,FILHDR+1] ;PTR TO HEADER RECORD STORAGE
; (MINUS LENGTH FIELD ALREADY STORED)
CALL REDBLK ;READ A BLOCK FROM INPUT FILE
RET ;PROPOGATE ERROR RETURN
LOAD T1,FHTYP,+FILHDR ;GET TYPE OF THIS RECORD
CAIE T1,TYP.FH ;IS THIS A HEADER RECORD?
ERROR BHT,<First record in file not a header record>,RTN
LOAD T1,FHMGL,+FILHDR ;GET LENGTH OF A MSG BLK FROM HEADER
CAIE T1,MB.LEN ;IS IT WHAT WE THINK IT SHOULD BE?
ERROR MLW,<Message Block Length is wrong in Header Record>,RTN
WRTSTR <Trace from monitor >
MOVEI T1,FILHDR+FH.CFG ;PTR TO CONFIG STRING FROM HEADER
CALL .TSTRG## ;WRITE ASCIZ STRING TO OUTPUT FILE
CALL .TCRLF##
WRTSTR <Monitor version >
LOAD T1,FHMVR,+FILHDR ;GET MONITOR VERSION FROM FILE HEADER
CALL .TVERW## ;TYPE OUT A VERSION WORD
WRTSTR <, DNSNUP version >
LOAD T1,FHPVR,+FILHDR ;GET PROGRAM VERSION FROM FILE HEADER
CALL .TVERW## ;TYPE OUT A VERSION WORD
WRTSTR <, DNTATL version >
MOVE T1,.JBVER ;GET MY VERSION FROM JOBDAT
CALL .TVERW## ;TYPE OUT A VERSION WORD
CALL .TCRLF## ;WRITE A CRLF
WRTSTR <DNTATL switches: >
MOVEI T1,[ASCIZ "/RTRCTL"]
SKIPN SCNRTR ;TEST THE /RTRCTL VALUE
MOVEI T1,[ASCIZ "/NORTRCTL"]
CALL .TSTRG##
MOVEI T1,[ASCIZ "/NSPCTL"]
SKIPN SCNNSP ;TEST THE /NSPCTL VALUE
MOVEI T1,[ASCIZ "/NONSPCTL"]
CALL .TSTRG##
MOVEI T1,[ASCIZ " /DATA"]
SKIPN SCNDAT ;TEST THE /DATA VALUE
MOVEI T1,[ASCIZ " /NODATA"]
CALL .TSTRG##
WRTSTR < /NODE:>
MOVE T1,SCNNOD ;PICK UP THE /NODE VALUE
CALL .TDECW## ; WHICH IS IN DECIMAL
WRTSTR < /LLA:>
MOVE T1,SCNLLA ;PICK UP THE LOCAL LINK ADDRESS
CALL .TOCTW## ; WHICH IS IN OCTAL
WRTSTR < /RLA:>
MOVE T1,SCNRLA ;PICK UP THE REMOTE LINK ADDRESS
CALL .TOCTW## ; WHICH IS IN OCTAL
CALL .TCRLF
WRTSTR <Trace started >
LOAD T1,FHUDT,+FILHDR ;GET INTERNAL DATE & TIME FROM FILE HDR
CALL .TTADL ;TYPE IT OUT, LONG FORM
WRTSTR <, UPTIME >
LOAD T1,FHUPT,+FILHDR ;GET UPTIME FROM FILE HDR
CALL .TJIFY ;TYPE IT OUT TOO
CALL .TCRLF## ;WRITE A CRLF
RETSKP ;SUCCESS RETURN
SUBTTL REDMSG -- Read Message from Input File
;Returns:
; MBO/ Offset to be subtracted from ptrs into message block
; to point into MSGBLK
; MS/ Pointer to current MSD in MSGBLK
REDMSG: SAVEAC P1
;Read in the record header
MOVE T1,[XWD -<MH.LEN>,MSGHDR] ;AOBJN PTR TO MSG RECORD HEADER
CALL REDBLK ;READ A BLOCK FROM INPUT FILE
RET ;PROPOGATE ERROR RETURN
LOAD T1,MHTYP,+MSGHDR ;GET TYPE OF THIS RECORD
CAIE T1,TYP.MH ;IS IT A MESSAGE?
ERROR BMT,<Expected a message record, didn't get one>,RTN
;Read in the message block
MOVE T1,[XWD -<MB.LEN>,MSGBLK] ;AOBJN PTR TO MESSAGE BLOCK
CALL REDBLK ;READ A BLOCK FROM INPUT FILE
RET ;PROPOGATE ERROR RETURN
;Read in the user data block (if there is one)
LOAD T1,MHLNG,+MSGHDR ;GET LENGTH OF THIS WHOLE RECORD
SUBI T1,<MH.LEN+MB.LEN> ;SUBTRACT LENGTHS OF RECORD HDR & MSG BLK
JUMPLE T1,REDMG1 ;JUMP IF NO USER DATA TO READ
MOVNS T1 ;MAKE NEGATIVE FOR AOBJN PTR
HRLZ T1,T1 ;PUT IN LH FOR AOBJN PTR
HRRI T1,USERDA ;POINT TO USER DATA RECORD
CALL REDBLK ;READ USER DATA INTO USER DATA RECORD
RET ;PROPOGATE ERROR RETURN
REDMG1:
;Set up MBO & MS to point to original msg blk and first MSD therein
LOAD MBO,MHOMB,+MSGHDR ;PICK UP ORIGINAL ADDRESS OF MSG BLK
SUBI MBO,MSGBLK ;OFFSET FROM MHMBO ADDR TO MSGBLK
LOAD MS,MBFMS,+MSGBLK ;PICK UP PTR TO FIRST MSD
JUMPE MS,REDNMG ;RETURN NO MESSAGE IF NO MSDs
SUB MS,MBO ;MUST BE FULL-WORD SUBTRACT FOR EXT ADDR
CALL MSGLEN ;GET LENGTH OF THIS MESSAGE
JRST REDNMG ;RETURN NO MESSAGE
MOVEM T1,SEQLEN ;STORE LENGTH OF WHOLE MESSAGE
MOVEM T1,SEQCNT ;INITIALIZE 'REST OF MSG' COUNTER
MOVE P1,[POINT 8,SEQBFR] ;POINT TO PLACE WHERE WE'LL REBUILD MSG
MOVEM P1,SEQPTR ;INITIALIZE BYTE PTR TO SEQUENTIAL MSG
REDMG2: CALL RED1BY ;GET A BYTE OF MSG FROM MSG BLK
RETSKP ;ALL DONE WHEN NO MORE
IDPB T1,P1 ;STORE IN SEQUENTIAL MSG
JRST REDMG2 ;GET NEXT BYTE
REDNMG: SETZM SEQLEN ;NO MSG, ZERO THE LENGTH
SETZM SEQCNT ; AND THE GETnBY LENGTH
RETSKP ;SUCCESS RETURN (NOT A FILE ERROR)
SUBTTL FMTMSG - Format a DECnet Message
;The message will have been read into MSGHDR and MSGBLK by REDMSG
;before this routine is called.
;Returns +1 on error writing output file, else +2
FMTMSG: CALL INITBF ;INITIALIZE TEMP OUTPUT BUFFER HEADER
SETZM CURSLA ;INITIALIZE CURSLA AND CURDLA TO ZERO
SETZM CURDLA ; SO CHKCUR CAN TELL IF THIS MSG USES THEM
MOVEI T1,.TYBUF ;DIRECT SCAN'S OUTPUT
MOVEM T1,TYPDEV ; TO TEMP BUFFER
CALL FMTMSS ;CALL FORMATTING SUBR
RET ;ERROR RETURN, NO RECORD OUTPUT
SKIPE TMPCNT ;DECIDED TO IGNORE THIS MESSAGE ALREADY?
CALL CHKCUR ;NO, CHECK MORE SELECTION SWITCHES
JRST FMTMSN ;FAILED THE TESTS, IGNORE IT
MOVEI T1,.TYFIL ;DIRECT SCAN'S OUTPUT DIRECTLY TO FILE
MOVEM T1,TYPDEV ; SO IT'LL BE BEFORE RECORD FROM TEMP BUF
CALL TYPSKP ;TELL USER IF WE SKIPPED ANY RECORDS
CALL TYPTBF ;OUTPUT MESSAGE RECORD STORED IN TMPBUF
RETSKP ;SUCCESS RETURN
FMTMSN: CALL INITBF ;REINITIALIZE TEMP OUTPUT BUFFER
AOS SKPCNT ;COUNT ONE MORE MESSAGE SKIPPED FOR TYPSKP
RETSKP ;RETURN WITH NO ERROR
;IGNMSG - FMTMSS will return through IGNMSG to ignore a partially built record
;when a record fails to satisify a selection switch.
IGNMSG: SETZM TMPCNT ;THIS MAKES FMTMSG IGNORE THIS MESSAGE
RETSKP
SUBTTL CHKCUR - Check current message against selection switches
;Checks the current record, as evidenced in the CURxxx cells set up by FMTMSS,
;against the selection switches SCNxxx.
;Returns +1 on failure to meet selection criteria, +2 on success
CHKCUR: SKIPN CURSLA ;DID THIS MESSAGE HAVE A SOURCE LINK ADDR,
SKIPE CURDLA ; OR A DESTINATION LINK ADDR?
TRNA ;YES (NOTE THAT CI WILL ONLY HAVE SLA)
RETSKP ;NO, CALL IT A MATCH RIGHT AWAY
;YES, CHECK IT AGAINST THE NSP HEADER
SKIPGE T1,SCNNOD ;DO WE HAVE A /NODE SWITCH?
IFSKP. ;YES,
MOVE T2,CURSNA ;GET SOURCE (REMOTE) NODE ADDRESS
ANDI T2,1777 ;ONLY THE INTRA-AREA NUMBER IS INTERESTING
CAMN T1,T2 ;THIS MESSAGE MATCH THE CRITERION?
IFSKP. ;NO
MOVE T2,CURDNA ;GET DEST (REMOTE) NODE ADDRESS
ANDI T2,1777 ;ONLY THE INTRA-AREA NUMBER IS INTERESTING
CAME T1,T2 ;THIS MESSAGE MATCH THE CRITERION?
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
ENDIF.
LOAD T1,MHIOL,+MSGHDR ;GET INPUT,OUTPUT,LOCAL CODE
JRST .+1(T1) ;CHECK ACCORDING TO DIRECTION
RET ;ZERO IS ILLEGAL CODE
JRST CHKCR1 ;INPUT
JRST CHKCR2 ;OUPTUT
JRST CHKCR3 ;LOCAL
CHKCR1: ;INPUT MESSAGE
SKIPGE T1,SCNRLA ;DO WE HAVE A /RLA SWITCH?
IFSKP. ;YES,
CAME T1,CURSLA ;MATCH SOURCE (REMOTE) LINK ADDRESS?
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
SKIPGE T1,SCNLLA ;DO WE HAVE A /LLA SWITCH?
IFSKP. ;YES,
CAME T1,CURDLA ;MATCH DEST (LOCAL) LINK ADDRESS?
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
RETSKP ;MATCH
CHKCR2: ;OUTPUT MESSAGE
SKIPGE T1,SCNRLA ;DO WE HAVE A /RLA SWITCH?
IFSKP. ;YES,
CAME T1,CURDLA ;MATCH DEST (REMOTE) LINK ADDRESS?
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
SKIPGE T1,SCNLLA ;DO WE HAVE A /LLA SWITCH?
IFSKP. ;YES,
CAME T1,CURSLA ;MATCH SOURCE (LOCAL) LINK ADDRESS?
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
RETSKP ;MATCH
CHKCR3: ;LOCAL MESSAGE
SKIPGE T1,SCNRLA ;DO WE HAVE A /RLA SWITCH?
IFSKP. ;YES,
CAME T1,CURSLA ;MATCH SOURCE LINK ADDRESS
CAMN T1,CURDLA ; OR DEST LINK ADDRESS?
TRNA ;YES
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
SKIPGE T1,SCNLLA ;DO WE HAVE A /LLA SWITCH?
IFSKP. ;YES,
CAME T1,CURSLA ;MATCH SOURCE LINK ADDRESS
CAMN T1,CURDLA ; OR DEST LINK ADDRESS?
TRNA ;YES
RET ;NO, IGNORE THIS MESSAGE
ENDIF.
RETSKP ;MATCH
SUBTTL TYPSKP - Tell user about skipped messages
;TYPSKP - called when FMTMSG is about to output a temp buffer to the real
;output device to tell the user how many messages were skipped due to
;congestion in DNSNUP or due to selection switches given to DNTATL.
;Only returns +1
TYPSKP: LOAD T1,MHLST,+MSGHDR ;GET NEW CUMULATIVE LOST COUNT
CAMG T1,LSTCNT ;SAME AS WE HAD BEFORE?
JRST TYPSK1 ;YES, NO PROBLEM
CALL .TCRLF##
WRTSTR <**********************************************************>
CALL .TCRLF##
WRTSTR <******** >
LOAD T1,MHLST,+MSGHDR ;GET CUMULATIVE TOTAL AGAIN
SUB T1,LSTCNT ;GET NUMBER WE JUST LOST
ADDM T1,LSTCNT ;STORE NEW CUMULATIVE LOST COUNT
PUSH P,T1 ;SAVE LOST COUNT
CALL .TDECD ;OUTPUT IN DECIMAL
WRTSTR < message>
POP P,T2 ;RESTORE LOST COUNT
MOVEI T1,"S"+40 ;LOWER CASE
CAIE T2,1 ;PRETTY-PRINT
CALL .TCHAR## ; THE PLURALS
WRTSTR < lost due to congestion in DNSNUP>
CALL .TCRLF##
WRTSTR <**********************************************************>
CALL .TCRLF##
;Now check for messages skipped due to selection switches
TYPSK1: SKIPG SKPCNT ;HAVE WE SKIPPED ANY RECORDS?
RET ;NO, SUCCESS RETURN NOW
CALL .TCRLF## ;MAKE A LITTLE
CALL .TCRLF## ; ROOM FOR THE SKIP MESSAGE
WRTSTR <*** Skipped > ;YES, TELL USER ABOUT IT
MOVE T1,SKPCNT ;GET NUMBER WE SKIPPED
CALL .TDECD ;DECIMAL
WRTSTR < message>
MOVE T2,SKPCNT ;GET NUMBER WE SKIPPED AGIAN
MOVEI T1,"S"+40 ;LOWER CASE
CAIE T2,1 ;PRETTY-PRINT
CALL .TCHAR## ; THE PLURALS
WRTSTR < due to selection switches ***>
CALL .TCRLF##
SETZM SKPCNT ;START SKIP COUNT ANEW NOW
RET ;SUCCESS RETURN
;FMTMSS - A subroutine of FMTMSG which builds output records and tests them
;against the selection switches as it builds. If a record fails a criterion,
;it returns through IGNMSG which reinitializes the pointers to the temp
;buffer, thus ignoring the whole record.
FMTMSS: CALL .TCRLF## ;SOME SPACE
CALL .TCRLF## ; BETWEEN MESSAGES
LOAD T1,MHUDT,+MSGHDR ;GET INTERNAL DATE & TIME
CALL .TTADS ;TYPE IT OUT, SHORT FORM
WRTSTR <, Uptime: >
LOAD T1,MHUPT,+MSGHDR ;GET UPTIME STAMP FROM MSG HEADER
CALL .TJIFY ;TYPE OUT TIME FROM JIFFIES
CALL .TTABC## ;A TAB
LOAD T1,MHIOL,+MSGHDR ;GET INPUT,OUTPUT,LOCAL CODE
CAXE T1,IOL.IN ;IS THIS AN INPUT MESSAGE?
JRST FMTMS2 ;NO, MUST BE OUTPUT OR LOCAL
WRTSTR <Input >
CALL FMTCNT ;TYPE OUT MSG'S BYTE COUNT
RET ;PROPOGATE ERROR
JRST FMTMS5 ;END OF INPUT CODE
FMTMS2: CAXN T1,IOL.OT ;IS THIS AN OUTPUT MESSAGE?
JRST FMTMS3 ;YES
WRTSTR <Local > ;NO, MUST BE LOCAL
JRST FMTMS4 ;CONTINUE
FMTMS3: WRTSTR <Output >
FMTMS4: CALL FMTCNT ;TYPE OUT MSG'S BYTE COUNT
RET ;PROPOGATE ERROR
LOAD T1,NMCNT,+MSGBLK ;GET # OF TIMES MSG WAS SENT
CAIG T1,1 ;IF FIRST TRANSMISSION OR
JRST FMTMS5 ; WE DON'T KNOW, DON'T SAY ANYTHING
WRTSTR <, Transmission #>
LOAD T1,NMCNT,+MSGBLK ;GET # OF TIMES MSG WAS SENT AGAIN
CALL .TDECD ;TYPE SEND COUNT IN DECIMAL
FMTMS5: CALL .TCRLF##
;Fall through to next page
;Handle the Router header (from previous page)
LOAD T1,MHIOL,+MSGHDR ;GET INPUT,OUTPUT,LOCAL CODE
CAXN T1,IOL.LO ;IS THIS A LOCAL MESSAGE?
IFSKP. ;IF NOT, TYPE OUT CIRCUIT ID
WRTSTR < Circuit: >
LOAD T1,MHILN,+MSGHDR ;GET LINE ID (DNSNUP SETS UP ILN = OLN)
CALL .TCKT
CALL .TCRLF
ENDIF.
;Fall through to next page
;Handle the Router header (from previous page)
MOVEI T1,1 ;PEEK AT FIRST BYTE OF MSG
CALL GTO1BY ;PEEK AT FIRST BYTE OF THE ROUTER HDR
FMTERR No router header,RSKP
SETZM RTROFF ;ASSUME NO PAD BYTE
TRZN T1,200 ;IS THIS A PAD BYTE?
IFSKP.
MOVEM T1,RTROFF ;SAVE PAD COUNT
MOVE P1,T1 ;COPY PAD COUNT
DO.
CALL GET1BY ;EAT A PAD BYTE
FMTERR No router header,RSKP
SOJG P1,TOP. ;LOOP OVER ALL PAD BYTES
ENDDO.
MOVEI T1,1 ;PEEK AT FIRST BYTE OF MSG
ADD T1,RTROFF ;ADD IN OFFSET TO START OF RTR HDR
CALL GTO1BY ;PEEK AT FIRST BYTE OF THE ROUTER HDR
FMTERR No router header,RSKP
ENDIF.
;See if this is a local message w/o a ROUTER header
TXNE T1,RM%EVL ;IF EVOLUTION BIT IS ON
JRST PH2TST ; WE KNOW ITS A PHASE II MSG
MOVEI T2,3 ;MAKE LOW-2-BIT MASK
AND T2,T1 ;ISOLATE LOW 2 BITS
JRST @[ z NORHDR ;PHASE II OR LOCAL W/O RTR HDR
z PH3CTL ;PHASE III CONTROL HDR
z PH3DAT ;PHASE III DATA MESSAGE
z PH3CTL](T2) ;PHASE III CONTROL HDR
PH2TST: TXNE T1,RM%MB1 ;EVOLUTION WAS ON, HOW ABOUT MB1?
JRST PH2RTR ;OFF, THERE IS NO ROUTING HDR
NORHDR: LOAD T1,MHIOL,+MSGHDR ;GET INPUT,OUTPUT,LOCAL CODE
CAXN T1,IOL.LO ;IS THIS AN INPUT MESSAGE?
JRST NSPHDR ;YES, SKIP ROUTER HEADER PRONOUNCEMENT
WRTSTR < Phase II message without routing header>
CALL .TCRLF##
JRST NSPHDR ;TYPE OUT NSP AND BEYOND
PH2RTR: WRTSTR < Phase II routing not supported by DNTATL>
CALL .TCRLF##
CALLRET FMTOCT ;OUTPUT PHASE II AS STRING
PH3CTL: WRTSTR < Phase III/IV routing control message>
SKIPN SCNRTR ;USER WANT TO SEE ROUTER CONTROL MSGS?
CALLRET IGNMSG ;NO, IGNORE RECORD
CALL .TCRLF## ;YES
CALLRET FMTOCT ;OUTPUT AS STRING
;Here if we have a Phase III/IV data message
PH3DAT: WRTSTR < Phase III/IV data message, control byte: >
CALL GET1BY ;EAT BYTE WE'VE BEEN PEEKING AT
FMTERR No router header,RSKP
CALL .TOCTW
CALL .TCRLF
TXNE T1,4 ;IS THIS PHASE IV FROM ETHERNET?
JRST PH4DAT ;YES
WRTSTR < Dest node: >
CALL GET2BY ;DEST ADDR IS 2 BYTES
FMTERR No destination node address,RSKP
MOVEM T1,CURDNA ;STORE FOR SELECTION CHECK
CALL .TNODE ;TYPE NODE ADDRESS IN DECIMAL
WRTSTR <, Source node: >
CALL GET2BY ;SOURCE ADDR IS 2 BYTES
FMTERR No destination node address,RSKP
MOVEM T1,CURSNA ;STORE FOR SELECTION CHECK
CALL .TNODE ;TYPE NODE ADDRESS IN DECIMAL
WRTSTR <, Visits: >
CALL GET1BY ;VISIT COUNT IS 1 BYTE
FMTERR No visit count,RSKP
CALL .TDECD ;TYPE VISIT COUNT IN DECIMAL
CALL .TCRLF##
JRST NSPHDR ;GO OUTPUT NSP HEADER
PH4DAT: WRTSTR < Dest area: > ;LINE UP DEST WITH SOURCE FIELDS
CALL GET1BY
FMTERR No destination area,RSKP
CALL .TDECD
WRTSTR <, Dest subarea: > ;LINE UP DEST WITH SOURCE FIELDS
CALL GET1BY
FMTERR No destination subarea,RSKP
CALL .TDECD
WRTSTR <, Dest node: > ;LINE UP DEST WITH SOURCE FIELDS
CALL GET2BY ;EAT 4 BYTES
FMTERR No destination node address,RSKP
CALL GET2BY ; OF ROUTER HIORD
FMTERR No destination node address,RSKP
CALL GET2BY ;DEST ADDR IS 2 BYTES
FMTERR No destination node address,RSKP
MOVEM T1,CURDNA ;STORE FOR SELECTION CHECK
CALL .TNODE ;TYPE NODE ADDRESS IN DECIMAL
CALL .TCRLF
WRTSTR < Source area: >
CALL GET1BY
FMTERR No source area,RSKP
CALL .TDECD
WRTSTR <, Source subarea: >
CALL GET1BY
FMTERR No source subarea,RSKP
CALL .TDECD
WRTSTR <, Source node: >
CALL GET2BY ;EAT 4 BYTES
FMTERR No destination node address,RSKP
CALL GET2BY ; OF ROUTER HIORD
FMTERR No destination node address,RSKP
CALL GET2BY ;SOURCE ADDR IS 2 BYTES
FMTERR No source node address,RSKP
MOVEM T1,CURSNA ;STORE FOR SELECTION CHECK
CALL .TNODE ;TYPE NODE ADDRESS IN DECIMAL
CALL .TCRLF##
WRTSTR < Next Level Two: >
CALL GET1BY ;NL2 IS 1 BYTE
FMTERR No NL2 field,RSKP
CALL .TDECD
WRTSTR <, Visits: >
CALL GET1BY ;VISIT COUNT IS 1 BYTE
FMTERR No visit count field,RSKP
CALL .TDECD ;TYPE VISIT COUNT IN DECIMAL
WRTSTR <, Service Class: >
CALL GET1BY ;SERVICE CLASS
FMTERR No service class field,RSKP
CALL .TDECD
WRTSTR <, Protocol type: >
CALL GET1BY ;PROTOCOL TYPE
FMTERR No protocol type field,RSKP
CALL .TDECD
CALL .TCRLF##
JRST NSPHDR ;GO OUTPUT NSP HEADER
;Output length of message
FMTCNT: MOVE T1,SEQLEN ;GET LENGTH OF MESSAGE
CALL .TDECD ;DECIMAL
WRTSTR < bytes>
RETSKP
;Output the rest of the message as a user data field (image with count)
FMTUDA: CALL .TCRLF##
WRTSTR < User Data Length: >
CALL GET1BY ;GET LENGTH (FIRST BYTE)
SETZ T1, ;NO MORE DATA, TELL USER WE HAVE ZERO
PUSH P,T1 ;SAVE VALUE WE'RE TYPING
CALL .TDECD ;THERE IS A LENGTH, TYPE IN DECIMAL
POP P,T1 ;RECOVER VALUE WE TYPED
SKIPN SCNDAT ;USER SAY /NODATA?
RETSKP ;YES, LEAVE NOW
JUMPE T1,RSKP ;NO, LEAVE NOW IF LENGTH WAS ZERO
WRTSTR <, Data: > ;WE HAVE DATA, ANNONCE THE FACT
CALLRET FMTSTR ;TYPE REST AS AS A STRING
;FMTCDA is same as FMTUDA, except length is rest of message instead of
;contents of first byte
FMTCDA: WRTSTR <, Connect Data Length: >
MOVE T1,SEQCNT ;GET REMAINING LENGTH OF MESSAGE
CALL .TDECD ;THERE IS A LENGTH, TYPE IN DECIMAL
SKIPG SEQCNT ;ANY USER DATA TO TYPE?
RETSKP ;NO, LEAVE NOW
WRTSTR <, Data: > ;WE HAVE DATA, ANNONCE THE FACT
CALLRET FMTSTR ;TYPE REST AS AS A STRING
;Output the rest of the message as octal bytes and as ASCII
FMTSTR: CALL FMTOCT ;FIRST OUTPUT IN OCTAL
RET
CALL .TCRLF## ;MAKE SOME ROOM BETWEEN OCTAL & ASCII
CALL FMTASC ;THEN IN ASCII
RET
RETSKP
;Here to put out the string in octal bytes
FMTOCT: SAVEAC P1
SKIPG SEQCNT ;ANYTHING THERE?
RETSKP ;NO, SUCCESS NOW
PUSH P,SEQCNT ;SAVE REMAINING LENGTH OF MSG
PUSH P,SEQPTR ; AND BYTE PTR TO IT
FMTST1: MOVEI P1,^D20 ;WE'LL PUT (P1) BYTES ON A LINE
CALL .TCRLF## ;START WITH A FRESH LINE FOR P1'S COUNT
FMTST2: CALL GET1BY ;GET A BYTE FROM CURRENT MSG
JRST FMTST5 ;DONE WHEN NO MORE BYTES TO READ
PUSH P,T1 ;SAVE OUR BYTE
TRNE T1,700 ;NEED ANY FILLER?
JRST FMTST4 ;NO, BIG NUMBER
TRNE T1,70 ;YES, NEED 2 FILLERS?
JRST FMTST3 ;NO, MEDIUM NUMBER
CALL .TSPAC## ;YES, LITTLE NUMBER
FMTST3: CALL .TSPAC## ;FILL FOR MEDIUM NUMBER
FMTST4: POP P,T1 ;RESTORE OUR BYTE
CALL .TOCTW## ;TYPE OUT BYTE IN OCTAL
SOJLE P1,FMTST1 ;NEXT LINE IF THIS LINE FILLED
CALL .TSPAC## ;NO, THEN TYPE A SPACE
JRST FMTST2 ;LOOP UNTIL DONE
FMTST5: POP P,SEQPTR ;RESTORE BYTE PTR TO MSG
POP P,SEQCNT ; AND ITS LENGTH
RETSKP
;Here to put out the string in ASCII
FMTASC: SAVEAC P1
SKIPG SEQCNT ;ANYTHING THERE?
RETSKP ;NO, SUCCESS NOW
FMTST6: CALL GET1BY ;GET A BYTE FROM CURRENT MSG
JRST FMTST8 ;ONE MORE CRLF, THEN SUCCESS
ANDI T1,177 ;TURN OFF THE PARITY BIT FOR COMPARES
CAIL T1,40 ;PRINTING CHAR?
JRST FMTST7 ;YES
CAIE T1,15 ;MAYBE NOT, IS IT A CR
CAIN T1,12 ; OR LF
JRST FMTST7 ;YES
CAIN T1,11 ;OR TAB
JRST FMTST7 ;YES
PUSH P,T1 ;NO, SAVE CHAR
MOVEI T1,"^" ;PRINT A 'CONTROL' SIGNAL
CALL .TCHAR##
POP P,T1 ;RESTORE OUR CHAR
ADDI T1,100 ;DECONTROL IT
FMTST7: CALL .TCHAR## ;TYPE OUT BYTE IN ASCII
JRST FMTST6 ;LOOP UNTIL DONE
FMTST8: CALL .TCRLF## ;BACK TO LEFT MARGIN
RETSKP ;SUCCESS
;Handle the NSP header
;
;Call: SEQBFR set up by REDMSG for GETnBY
; CALL NSPHDR
; Error Return
; Normal Return
NSPHDR: SAVEAC P1
CALL GET1BY ;GET NSP MESSAGE TYPE FIELD
FMTERR No NSP message type byte,RSKP
LSH T1,-2 ;LOW-ORDER 2 BITS ALWAYS ZERO
MOVE P1,T1 ;SAVE MESSAGE TYPE
CAILE P1,NSPTLN ;LEGAL MSG TYPE?
JRST [ CALL .TOCTW## ;NO, OUTPUT MESSAGE TYPE
CALL .TSPAC## ;WRITE A SPACE
CALLRET FMTSTR] ;OUTPUT REST OF MSG AS A STRING
CALL .TTABC## ;YES, OUTPUT REST OF MSG ACCORDING TO TYPE
HLRZ T1,NSPTBL(P1) ;GET NAME OF MESSAGE TYPE
CALL .TSTRG## ;WRITE NAME STRING
WRTSTR <, > ;SET UP FOR TYPE-SPECIFIC ROUTINE'S OUTPUT
HRRZ T1,NSPTBL(P1) ;GET ROUTINE ADDR FROM RH OF TABLE ENTRY
SKIPE SCNNSP ;USER WANT NSP CONTROL MESSAGES?
IFSKP. ;NO,
CAIE T1,RCVDAT ;IS THIS AN NSP DATA MESSAGE?
CALLRET IGNMSG ;NO, IGNORE IT.
ENDIF.
CALL 0(T1) ;OUTPUT MESSAGE ACCORDING TO MSG TYPE
RET ;ERROR OF SOME SORT
RETSKP ;SUCCESS
;Table of Message Type names and Routine addresses
DEFINE MGTYPS,< ;{subtype,type}
MSGTYP (NoBEom,RCVDAT) ; 0: {0,0}
MSGTYP (DATACK,RCVACK) ; 1: {0,1}
MSGTYP (NOP, RCVNOP) ; 2: {0,2}
MSGTYP (<0,3>, FMTSTR) ; 3: {0,3}
MSGTYP (LNKSRV,RCVLKS) ; 4: {1,0}
MSGTYP (OTHACK,RCVACK) ; 5: {1,1}
MSGTYP (CI, RCVCI) ; 6: {1,2}
MSGTYP (<1,3>, FMTSTR) ; 7: {1,3}
MSGTYP (Bom, RCVDAT) ;10: {2,0}
MSGTYP (CA, RCVCA) ;11: {2,1}
MSGTYP (CC, RCVCC) ;12: {2,2}
MSGTYP (<2,3>, FMTSTR) ;13: {2,3}
MSGTYP (INTRPT,RCVDAT) ;14: {3,0}
MSGTYP (<3,1>, FMTSTR) ;15: {3,1}
MSGTYP (DI, RCVDI) ;16: {3,2}
MSGTYP (<3,3>, FMTSTR) ;17: {3,3}
MSGTYP (Eom, RCVDAT) ;20: {4,0}
MSGTYP (<4,1>, FMTSTR) ;21: {4,1}
MSGTYP (DC, RCVDC) ;22: {4,2}
MSGTYP (<4,3>, FMTSTR) ;23: {4,3}
MSGTYP (<5,0>, FMTSTR) ;24: {5,0}
MSGTYP (<5,1>, FMTSTR) ;25: {5,1}
MSGTYP (<5,2>, FMTSTR) ;26: {5,2}
MSGTYP (<5,3>, FMTSTR) ;27: {5,3}
MSGTYP (BomEom,RCVDAT) ;30: {6,0}
MSGTYP (<6,1>, FMTSTR) ;31: {6,1}
MSGTYP (ReCI, RCVCI) ;32: {6,2}
>;END OF MGTYPS MACRO
DEFINE MSGTYP(type,routine),<
XWD [ASCIZ /type/],routine
>
NSPTBL: MGTYPS
NSPTLN==.-NSPTBL-1
SUBTTL NSP Message Type Routines -- Data message
RCVDAT: CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
CALL ACKSEG ;PUT OUT ACK AND/OR SEGNUM
RET ;PROPOGATE ERROR
CALL .TCRLF##
WRTSTR < User Data Length: >
MOVE T1,SEQCNT ;GET REMAINING MSG LENGTH
CALL .TDECD ;TYPE OUT LENGTH
SKIPE SCNDAT ;USER SAY /NODATA?
SKIPG T1,SEQCNT ;YES, GET REMAINING MSG LENGTH AGAIN
RETSKP ;LEAVE NOW IF NO DATA TO TYPE
WRTSTR <, User Data: >
CALLRET FMTSTR ;PUT OUT REST OF MSG AS A STRING
SUBTTL NSP Message Type Routines -- ACK message
RCVACK: ;ACK message (Data or Other)
CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
CALL ACKFLD ;PUT OUT ACK FIELD ONLY
RET ;PROPOGATE ERROR
CALL .TCRLF##
RETSKP
SUBTTL NSP Message Type Routines -- LNKSRV message
RCVLKS: SAVEAC P1 ;LNKSRV message
CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
CALL ACKSEG ;PUT OUT ACK AND/OR SEGNUM
RET ;PROPOGATE ERROR
CALL .TCRLF##
CALL .TTABC## ;NEW LINE STARTS WITH A TAB
CALL GET1BY ;GET LSFLAGS FIELD
FMTERR No link service flags byte,RSKP
MOVE P1,T1 ;SAVE FLAGS BYTE IN P1
CALL GET1BY ;GET FCVAL FIELD
FMTERR No link service value byte,RSKP
TRNE T1,200 ;TEST THE SIGN BIT OF THE BYTE
ORCMI T1,377 ;ITS NEGATIVE, EXTEND THE SIGN
CALL .TDECD ;OUTPUT # OF DRQs (DECIMAL)
WRTSTR < credits on >
LOAD T2,LSINT,+P1 ;GET INTERPRETATION FIELD
MOVEI T1,[ASCIZ /Data/]
CAIE T2,LS.INR ;IS IT 'DATA' SUBLINK?
MOVEI T1,[ASCIZ /Other/]
CALL .TSTRG##
WRTSTR < sublink, >
LOAD T1,LSMOD,+P1 ;GET MODIFIER FIELD
MOVE T1,[[ASCIZ /no change to off flag/]
[ASCIZ /turn sublink OFF/]
[ASCIZ /turn sublink ON/]
[ASCIZ /?reserved modifier value?/]](T1)
CALL .TSTRG## ;YES, TYPE IT
CALL .TCRLF##
RETSKP
SUBTTL NSP Message Type Routines -- CI message
RCVCC: ;CC message
CALL RCVCIC ;COMMON CI/CC CODE
RET ;PROPOGATE ERROR
CALLRET FMTUDA ;FINISH OFF WITH USER DATA
RCVCI: ;CI message
CALL RCVCIC ;COMMON CI/CC CODE
RET ;PROPOGATE ERROR
CALLRET FMTCDA ;FINISH OFF WITH CONNECT DATA
RCVCIC: CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
WRTSTR <, Flow Control: >
CALL GET1BY ;GET SERVICES BYTE (EXTENSIBLE!)
FMTERR No services byte,RSKP
LOAD T1,SVOPT,+T1 ;GET FLOW CONTROL OPTION
MOVE T1,[[ASCIZ /None/]
[ASCIZ /Segment/]
[ASCIZ /Message/]
[ASCIZ /Illegal/]](T1)
CALL .TSTRG##
WRTSTR <, NSP Version: >
CALL GET1BY ;VERSION FIELD (EXTENSIBLE!)
FMTERR No INFO field,RSKP
CALL .TOCTW##
CALL .TCRLF##
WRTSTR < Segsize: >
CALL GET2BY ;GET SEGMENT SIZE BYTES
FMTERR No segsize field,RSKP
CALL .TDECD
RETSKP ;SUCCESS RETURN
SUBTTL NSP Message Type Routines -- CA message
RCVCA: ;CA message
WRTSTR <DLA: > ;CONNECT ACK ONLY HAS A DLA FIELD
CALL GET2BY ; WHICH IS 2 BYTES
FMTERR No dest link address bytes,RSKP
MOVEM T1,CURDLA ;STORE DLA FOR SECTION CHECK
CALL .TOCTW## ;LINK ADDRESSES IN OCTAL
CALL .TCRLF##
RETSKP
SUBTTL NSP Message Type Routines -- DI message
RCVDI: ;DI message
CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
WRTSTR <, Reason: >
CALL GET2BY ;GET REASON CODE
FMTERR No reason code,RSKP
CALL RSNTXT ;GET PTR TO REASON TEXT IN T1
CALLRET FMTUDA ;FORMAT THE USER DATA
SUBTTL RSNTXT - Type Out Text for DECnet Reject Reason
;RSNTXT - Type Out Text for DECnet Reject Reason
;
;Call: T1/ The Reason Code
; CALL RSNTXT
; Normal Return
DEFINE RSNMAC(code,text),<
CAIN T1,code
MOVEI T2,[ASCIZ |code: text|]
>
RSNTXT::MOVEI T2,0 ;SO WE KNOW IF NO REASON HAS MATCHED
RSNMAC RSNDBO,Disconnected/Rejected by Object
RSNMAC RSNRES,No Resources
RSNMAC RSNUNN,Unrecognized Node Name
RSNMAC RSNRNS,Remote Node Shut Down
RSNMAC RSNURO,Unrecognized Object
RSNMAC RSNIOF,Invalid Object Name Format
RSNMAC RSNOTB,Object Too Busy
RSNMAC RSNABM,Abort by Management
RSNMAC RSNABO,Abort by Object
RSNMAC RSNINF,Invalid Node Name Format
RSNMAC RSNLNS,Local Node Shut Down
RSNMAC RSNACR,Access Control Rejection
RSNMAC RSNNRO,No Response from Object
RSNMAC RSNNUR,Node Unreachable
RSNMAC RSNNLK,No Link
RSNMAC RSNDSC,Disconnect Complete
RSNMAC RSNIMG,Image Field Too Long
JUMPE T2,RSNT.1 ;JUMP IF NO MATCH FOUND
MOVE T1,T2 ;MOVE TO T1 FOR .TSTRG
CALL .TSTRG## ;GOT A MATCH, TYPE OUT TEXT
RET
RSNT.1: PUSH P,T1 ;NO MATCH, TYPE OUT CODE IN DECIMAL
MOVEI T1,[ASCIZ /Unknown reason code: /]
CALL .TSTRG##
POP P,T1
CALL .TDECD
RET
SUBTTL NSP Message Type Routines -- DC message
RCVDC: ;DC message
CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
WRTSTR <, Reason: >
CALL GET2BY ;GET REASON CODE
FMTERR No reason code,RSKP
CALL RSNTXT ;TYPE OUT REASON TEXT
CALL .TCRLF##
RETSKP
SUBTTL NSP Message Type Routines -- NOP message
RCVNOP: ;NOP message
CALL DLASLA ;PUT OUT DLA AND SLA
RET ;PROPOGATE ERROR
CALL ACKSEG ;PUT OUT ACK AND/OR SEGNUM
RET ;PROPOGATE ERROR
CALL .TCRLF##
WRTSTR < Test Data: >
CALLRET FMTSTR ;PUT OUT REST OF MSG AS A STRING
SUBTTL DLASLA - Output DLA and SLA for a Message
DLASLA: WRTSTR <DLA: >
CALL GET2BY ;DLA IS 2 BYTES LONG
FMTERR No dest link address bytes,RSKP
MOVEM T1,CURDLA ;STORE FOR SELECTION CHECK
CALL .TOCTW## ;LINK ADDRESSES ARE OCTAL
WRTSTR <, SLA: >
CALL GET2BY ;SLA IS 2 BYTES LONG
FMTERR No source link address bytes,RSKP
MOVEM T1,CURSLA ;STORE FOR SELECTION CHECK
CALL .TOCTW## ;LINK ADDRESSES ARE OCTAL
RETSKP ;SUCCESS RETURN
ACKFLD: SAVEAC P1
CALL GET2BY ;ACK & SEG BOTH 2 BYTES LONG
FMTERR No ACK field in ACK message,RSKP
MOVE P1,T1 ;SAVE ACK OR SEGNUM FIELD
CALL ACKPRT ;(P1)PRINT ACK FIELD
;SEE IF THERE IS A PHASE 4 CROSS-CHNL ACK
CALL GET2BY ;ACK & SEG BOTH 2 BYTES LONG
RETSKP ;ACK MESSAGE HAS NO FIELDS AFTER 'ACK'
MOVE P1,T1 ;SAVE ACK OR SEGNUM FIELD
CALL ACKPRT ;(P1)PRINT ACK FIELD
RETSKP ;SUCCESS RETURN
ACKSEG: SAVEAC P1
ACKSG1: CALL GET2BY ;ACK & SEG BOTH 2 BYTES LONG
FMTERR No segment number,RSKP
MOVE P1,T1 ;SAVE ACK OR SEGNUM FIELD
TXNN P1,AKPNT ;IS ACK PRESENT?
JRST ACKSG2 ;NO, THIS IS A SEG NUMBER
CALL ACKPRT ;(P1)PRINT ACK FIELD
JRST ACKSG1 ;TRY NEXT, MIGHT BE PHASE 4 CROSS-CHNL ACK
ACKSG2: TXNN P1,SGDLY ;ACK DELAY set?
JRST ACKSG3 ; -no
WRTSTR <, ACKDLY: ON >
ACKSG3: WRTSTR <, SEGNUM: >
MOVE T1,P1 ;RECOVER SEGMENT NUMBER
ANDI T1,SGNUM ;ONLY 12 BITS COUNT, IGNORE QUAL FIELD
CALL .TDECD ;(T1)WRITE SEGMENT NUMBER IN DECIMAL
RETSKP ;SUCCESS RETURN
ACKPRT: LOAD T2,AKQAL,+P1 ;GET QUALIFIER (ACK OR NAK)
MOVEI T1,[ASCIZ /, ACK: /] ;ASSUME ITS AN ACK
CAIN T2,AK$QNK ;IS IT A NAK?
MOVEI T1,[ASCIZ /, NAK: /] ;YES
CAIN T2,AK$CAK ;IS IT A CROSS-SUBCHNL ACK?
MOVEI T1,[ASCIZ /, CCACK: /] ;YES
CAIN T2,AK$CNK ;IS IT A CROSS-SUBCHNL NAK?
MOVEI T1,[ASCIZ /, CCNAK: /] ;YES
CALL .TSTRG##
LOAD T1,AKNUM,+P1 ;GET THE ACKNUM VALUE
CALLRET .TDECD ;TYPE IT OUT IN DECIMAL
SUBTTL Byte Manipulation Routines
;GETnBY - Get next n bytes from the current message block
;
;Set up by REDMSG
;
;Call: SEQPTR/ Byte pointer into SEQBFR
; SEQBFR/ The message all in one sequential lot
; SEQCNT/ Remaining length of message in SEQBFR
; CALL GETnBY
; 'No more' return
; Normal return with value in T1
GET1BY: SOSGE SEQCNT ;ANY MORE TO EAT?
RET ;NO, 'NO MORE' RETURN
ILDB T1,SEQPTR ;LOAD UP THE BYTE
RETSKP ;SUCCESS RETURN
GET2BY: MOVNI T1,2 ;WE'LL NEED TWO BYTES
ADDB T1,SEQCNT ;SUBTRACT 2 FROM COUNT
JUMPL T1,RTN ;'NO MORE' RETURN
ILDB T1,SEQPTR ;GET LOW-ORDER BYTE
ILDB T2,SEQPTR ; THEN HIGH-ORDER BYTE
LSH T2,10 ;SHIFT HIGH-ORDER LEFT 8 BITS
IOR T1,T2 ;MAKE UP 16-BIT VALUE
RETSKP ;SUCCESS RETURN
;GTOnBY - Get indicated n bytes from the current message block
;
;Set up by REDMSG
;
;Call: T1/ Offset to beginning of byte (first byte is offset ONE)
; SEQPTR/ Byte pointer into SEQBFR
; SEQBFR/ The message all in one sequential lot
; SEQCNT/ Remaining length of message in SEQBFR
; CALL GETnBY
; 'Out-of-range' return
; Normal return with value in T1
GTO1BY: CAMLE T1,SEQLEN ;.LEQ. LENGTH OF MESSAGE?
RET ;NO, 'OUT-OF-RANGE' RETURN
ADJBP T1,[POINT 8,SEQBFR] ;YES, MAKE A BYTE PTR TO INDICATED BYTE
LDB T1,T1 ;LOAD UP THE BYTE
RETSKP ;SUCCESS RETURN
GTO2BY: CAML T1,SEQLEN ;.LEQ. LENGTH-1 OF MESSAGE?
RET ;NO, 'OUT-OF-RANGE' RETURN
ADJBP T1,[POINT 8,SEQBFR] ;YES, MAKE A BYTE PTR TO FIRST BYTE
LDB T2,T1 ;LOAD UP LOW-ORDER BYTE
ILDB T1,T1 ;LOAD UP HIGH-ORDER BYTE
LSH T1,10 ;SHIFT LEFT 8 BITS TO MAKE IT HIGH-ORDER
IOR T1,T2 ;MAKE UP 16-BIT VALUE
RETSKP
;RED1BY - Get next byte from the current message block
;
;Called only by REDMSG
;
;Call: MS/ Ptr to current MSD
; MBO/ Offset from monitor address to MSGBLK
; CALL GETnBY
; 'No more' return
; Normal return with value in T1
RED1BY: DO.
LOAD T1,MDBYT,(MS) ;NUMBER OF BYTES LEFT IN THIS MSD
JUMPG T1,ENDLP. ;JUMP IF STILL SOME LEFT
LOAD MS,MDNXT,(MS) ;POINT TO NEXT MSD
JUMPE MS,RTN ;NON-SKIP RET IF EMPTY
SUB MS,MBO ;ADJUST MSD ADDRESS WITH OFFSET
JRST TOP. ;CHECK OUT THIS MSD NOW
ENDDO.
LOAD T2,MHIOL,+MSGHDR ;GET INPUT/OUTPUT/LOCAL INDICATOR
MOVEI T1,MD.PTR(MS) ;ASSUME INPUT OR LOCAL
CAIE T2,IOL.IN ;IS THIS MSG FOR INPUT?
MOVEI T1,MD.AUX(MS) ;NO, USE OUTPUT'S BYTE PTR
MOVE T2,(T1) ;GET BYTE POINTER CALLER WILL USE
TLZN T2,17 ;ERASE MONITOR'S INDEX
IFSKP. ;IF THERE WAS ONE...
LOAD T3,MDALA,(MS) ;GET ALLOCATED ADDRESS OF DATA
SUB T3,MBO ;ADJUST TO MSGBLK
CAIGE T3,MSGBLK+MB.LEN ;IS THE RESULT
CAIG T3,MSGBLK ; INSIDE THE MSG BLK?
MOVEI T3,USERDA ;NO, MUST BE IN USER DATA BLK
ADD T2,T3 ;ADD INDEX INTO Y FIELD OF BYTE PTR
MOVEM T2,(T1) ;RESTORE UPDATED BYTE PTR
ENDIF.
DECR MDBYT,(MS) ;ACCOUNT FOR BYTE WE READ
ILDB T1,(T1) ;GET NEXT BYTE TO RETURN IN T1
RETSKP ;SUCCESS RETURN
SUBTTL MSGLEN - Returns remaining message length
;MSGLEN - Returns remaining message length
;
;Call: MS & MBO set up by REDMSG
; CALL MSGLEN
; Error return
; Normal return with length in T1
MSGLEN: SETZ T1, ;COLLECT TOTAL COUNT HERE
SKIPN T4,MS ;DON'T DISTURB CALLER'S MS
RETSKP ;IF NO MSD, LENGTH IS ZERO
MSGLN1: OPSTR <ADD T1,>,MDBYT,(T4) ;NUMBER OF BYTES LEFT IN THIS MSD
LOAD T4,MDNXT,(T4) ;POINT TO NEXT MSD
JUMPE T4,RSKP ;SUCCESS RETURN WHEN WE GET TO END
SUB T4,MBO ;ADJUST NEW MSD ADDRESS WITH OFFSET
JRST MSGLN1 ;ADD IN THE NEXT MSD
SUBTTL Input/Output Routines
;REDBLK - Read the next data block from trace file into memory
;
;Call: T1/ AOBJN Pointer to block to fill
; CALL REDBLK
; Error Return (eg, EOF)
; Normal Return
REDBLK: SAVEAC P1
MOVE P1,T1 ;SAVE AOBJN PTR IN P1
REDBL1: CALL INBYT ;GET NEXT WORD FROM INPUT FILE
RET ;PROPOGATE ERROR RETURN
MOVEM T1,(P1) ;STORE WORD IN TARGET BLOCK
AOBJN P1,REDBL1 ;LOOP OVER WHOLE BLOCK
RETSKP ;SUCCESS RETURN
;TYPOUT - Called from SCAN
TYPOUT: SAVEAC T2
MOVE T2,TYPDEV ;GET TYPOUT DEVICE CODE
JRST @.+1(T2) ;DECIDE WHERE TO PUT OUT THIS CHAR
EXP TYPOTY ;(.TYTTY)TYPE DIRECTLY ON TTY
EXP TYPOFI ;(.TYFIL)TYPE DIRECTLY TO FILE (OUTPUT DEVICE)
EXP TYPOBF ;(.TYBUF)TYPE TO TEMP BUFFER FIRST
TYPOTY: OUTCHR T1 ;OUTPUT DIRECTLY TO TTY
RET ;ALWAYS TAKE NON-SKIP RET
TYPOFI: CALLRET .OTBYT ;OUTPUT DIRECTLY TO OUTPUT DEVICE
TYPOBF: AOS T2,TMPCNT
CAIGE T2,TMPWDS*5 ;ANY ROOM IN THE TEMP BUFFER?
IDPB T1,TMPPTR ;YES, WRITE TO TEMP OUTPUT BUFFER, BUFFER WILL
RET ; BE OUTPUT WHEN ALL TESTS ARE PASSED.
;TYPTBF, called to output temp buffer to real output device when record is
;completed and all tests are passed.
;Only returns +1
TYPTBF: MOVE T2,[POINT 7,TMPBUF] ;FRESH BYTE POINTER TO TEMP BUFFER
MOVEM T2,TMPPTR ;SET UP BYTE POINTER TO COLLECT OUTPUT
TYPTB1: SOSGE TMPCNT ;ANY BYTES TO PUT OUT?
CALLRET INITBF ;NO MORE, GO REINITIALIZE BUFFER HEADER
ILDB T1,TMPPTR ;GET NEXT OUTPUT BYTE
CALL .OTBYT ;PUT IT OUT
JRST TYPTB1 ;LOOP FOR MORE
;INITBF, called to initialize header for temp output buffer
;Only returns +1
INITBF: MOVE T2,[POINT 7,TMPBUF] ;FRESH BYTE POINTER TO TEMP BUFFER
MOVEM T2,TMPPTR ;SET UP FOR
SETZM TMPCNT ; NEXT RECORD OUTPUT
RET ;ONLY RETURN
;Call with byte to be output in T1
.OTBYT::
.OTBY1:!SOSGE H.FOUT+.BFCTR ;H.FOUT = HEADER FOR FILE OUTPUT
JRST OUTBYN ;NO ROOM, GET A NEW BUFFER
IDPB T1,H.FOUT+.BFPTR ;THE NORMAL OUTPUT DEPOSIT BYTE.
RET ;SUCCESS RETURN
OUTBYN: CALL .OTBUF ;OUTPUT THE BUFFER
RET ;"DON'T CONTINUE" RETURN
JRST .OTBY1 ;GOT A BUFFER, GO COUNT IT DOWN
;CALL CALL .OTBUF
; "DON'T CONTINUE" RETURN
; "OK" RETURN
.OTBUF: OUT F.FOUT,
RETSKP ;OK RETURN: SUCCESS
ERROR OUT,<Error from OUT UUO>
EXIT
;INBYT -- GET NEXT BYTE FROM DATA FILE
;CALL: CALL INBYT
; ERROR RETURN IF END-OF-FILE
; NORMAL RETURN WITH BYTE IN T1
INBYT: SOSGE H.FIN+.BFCTR ;SEE IF BYTE IN BUFFER
JRST INBYT1 ;NO--READ SOME MORE OF FILE
ILDB T1,H.FIN+.BFPTR ;FETCH BYTE
RETSKP ;SUCCESS RETURN
INBYT1: CALL INBUF ;INPUT A BUFFER
RET ;"DON'T CONTINUE" RETURN
JRST INBYT ;"OK" RETURN
;CALL CALL INBUF
; "DON'T CONTINUE" RETURN
; "OK" RETURN
INBUF: IN F.FIN, ;READ A BUFFER
RETSKP ;OK TO PROCEED: SUCCESS
;ERROR, CHECK IT OUT
GETSTS F.FIN, T1
TXNN T1, IO.ERR ;ANY ERRORS?
JRST INBUF1 ;NO, TEST FOR EOF
ERROR INP,<Error in file input>
EXIT
INBUF1: TXNN T1, IO.EOF ;HAVE WE SEEN EOF?
RSKP: AOS (P) ;NO--GET MORE DATA
RTN: RET ;YES--"DON'T CONTINUE" RETURN
SUBTTL Miscellaneous Routines
;Call: T1/ Circuit ID
; CALL .TCKT
; Normal Return
.TCKT: SAVEAC <P1>
MOVE P1,T1 ;PRESERVE CIRCUIT-ID
LOAD T1,LIDEV,+P1 ;GET THE DEVICE TYPE RIGHT JUSTIFIED
CAILE T1,0 ;IS THE DEVICE TYPE WITHIN RANGE?
CAILE T1,DEVTLN
JRST [MOVE T1,P1 ;NO - JUST OUTPUT IT IN OCTAL
JRST .TOCTW]
MOVE T1,DEVTAB(T1) ;GET THE NAME OF THE DEVICE
CALL .TSIXN## ;TYPE IT OUT
MOVEI T1,"-" ;TYPE THE "-"
CALL .TCHAR
LOAD T1,LIKON,+P1 ;NOW GET THE CONTROLLER (CPU) NUMBER
CALL .TOCTW ;TYPE IT OUT
MOVEI T1,"-" ;TYPE THE "-"
CALL .TCHAR
LOAD T1,LIUNI,+P1 ;AND LAST DO THE UNIT NUMBER
CALL .TOCTW ;TYPE IT AND RETURN
LOAD T1,LIDEV,+P1 ;GET DEVICE TYPE
CAXE T1,LD.CIP ;IS THIS A CI DEVICE?
RET ;NO
MOVEI T1,"." ;YES, TYPE
CALL .TCHAR ; A DOT
LOAD T1,LIDRP,+P1 ;LOAD THE DROP NUMBER (PORT ON THE CI)
CALLRET .TDECW## ;TYPE IT IN DECIMAL AND RETURN TO CALLER
DEVTAB: SIXBIT /TST/ ;TEST BED DRIVER
SIXBIT /DTE/ ;DTE
SIXBIT /KDP/ ;KDP
SIXBIT /DDP/ ;DDP
SIXBIT /CI/ ;CI
SIXBIT /NI/ ;NI
SIXBIT /DMR/ ;DMR
DEVTLN==.-DEVTAB
SUBTTL Miscellaneous Routines
;Call: T1/ value (node number)
; CALL .TNODE
; Normal Return
.TNODE: PUSH P,T1 ;SAVE WHOLE NODE NUMBER
ASH T1,-12 ;GET AREA NUMBER ONLY
CALL .TDECD ;PRINT IT WITH A DOT FOLLOWING
POP P,T1 ;RECOVER WHOLE NODE NUMBER
ANDI T1,1777 ;GET NODE-WITHIN-AREA NUMBER
CALLRET .TDECW ;PRINT WITHOUT DOT FOLLOWING
;Call: T1/ value
; CALL .TDECD
; Normal Return
.TDECD: CALL .TDECW ;TYPE T1 IN DECIMAL
MOVEI T1,"." ;LOAD UP A DECIMAL POINT
CALLRET .TCHAR ;FOLLOWED BY A DECIMAL POINT
IFN FTOPS10,<
.TTADS: ;TYPE OUT DATE/TIME, SHORT FORM
.TTADL: ;TYPE OUT DATE/TIME, LONG FORM
CALLRET .TDTTM## ;CALL SCAN'S TYPOUT ROUTINE
>;END IFN FTOPS10
IFN FTOPS20,< ;ALREADY MSECS ON TOPS20
.TTADL: SKIPA T3,[ -1 ] ;TYPE OUT DATE/TIME, LONG FORM
.TTADS: MOVSI T3,200001 ;TYPE OUT DATE/TIME, SHORT FORM
MOVE T2,T1 ;DATE/TIME IN AC 2
MOVEI T1,1(P) ;POINTER TO STRING SPACE
HRLI T1,440700 ;MAKE IT A 7-BIT POINTER FOR .TSTRG, BELOW
ADJSP P,20 ;MAKE SOME STRING SPACE
PUSH P,T1 ;SAVE PTR TO STRING SPACE
ODTIM ;OUTPUT DATE/TIME JSYS
ERJMP .+1 ;IGNORE ERRORS FOR NOW
SETZ T2, ;MAKE A NULL
IDPB T2,T1 ;STORE AT END OF DATE/TIME STRING FOR ASCIZ
POP P,T1 ;PTR TO START OF STRING SPACE AGAIN
CALL .TSTRG## ;OUTPUT ASCIZ STRING
ADJSP P,-20 ;CLEAR STACK
RET ;ONLY RETURN
>;END IFN FTOPS20
.TJIFY:
IFN FTOPS10,< ;ALREADY MSECS ON TOPS20
IMULI T1,^D1000 ;JIFFIES TO MSECS
IDIVI T1,^D60 ; WITHOUT LOSING PRECISION
>;END IFN FTOPS10
IDIV T1,[^D3600000] ;GET HOURS, WITH MINUTES IN REMAINDER
PUSH P,T2 ;SAVE REST
MOVEI T2," " ;FILL WITH SPACE
CALL .TDEC2## ;TYPE TWO DIGITS
CALL .TCOLN## ;TYPE COLON
POP P,T1 ;RESTORE REST
IDIVI T1,^D60000 ;GET MINS
PUSH P,T2 ;SAVE REST
CALL TDEC2Z ;TYPE TWO DIGITS WITH 0 FILLER
CALL .TCOLN## ;TYPE COLON
POP P,T1 ;RESTORE THE REST
IDIVI T1,^D1000 ;GET SECONDS
PUSH P,T2 ;SAVE REMAINDER
CALL TDEC2Z ;TYPE SECONDS
MOVEI T1,"." ;GET A DOT
CALL .TCHAR## ;TYPE IT
POP P,T1 ;RESTORE MILLISECOND REMAINDER
CAILE T1,^D99 ;SEE IF THREE DIGITS
CALLRET .TDECW## ;YES, JUST TYPE IT AND LEAVE NOW
PUSH P,T1 ;NO, PUT MSECS BACK ON THE STACK
MOVEI T1,"0" ;FILL WITH A ZERO
CALL .TCHAR## ;TYPE
POP P,T1 ;FINISH OFF WITH 2 MORE DIGITS
TDEC2Z: MOVEI T2,"0" ;FILL WITH 0
CALLRET .TDEC2## ;FINISH OFF WITH 2 DECIMAL DIGITS
SUBTTL Extra Routines
IFN FTOPS20,<
.HELPR::RET ;TOPS20 HAS NO HELPER
>;END IFN FTOPS20
IFN FTOPS10,<
G:: PUSH P,.JBOPC ;PICK UP OLD PC (FOR DDT RETURN)
POPJ P, ;RETURN, IGNORING LH, SAVING ALL ACS
>;END IFN FTOPS10
;This should be last
LITRAL::LIT
SUBTTL End of Program
END DNTATL