	.TITLE	ETHERMON_PARSE Parser and Accessories for Ethernet Monitor
	.IDENT	/V1.0/

;
;  define funny system symbols used by this program
;
	.LIBRARY	/SYS$LIBRARY:LIB/
	$NMADEF	GLOBAL
	.IF	NE NMA$C_STATE_ON
	.WARN	0	; inconsistency in FORTRAN code, fix it!!!!!
	.ENDC
	$TPADEF

	.SBTTL	FORTRAN COMMON's

	.PSECT	LCV_EXIT,NOEXE,RD,WRT,GBL,SHR,OVR,PIC,LONG
LCV_EXIT:
	.BLKB	1	; flag to indicate EXIT command entered

	.PSECT	PARSE_ARGS,NOEXE,RD,WRT,GBL,SHR,OVR,PIC,LONG
ICVPRS_NUMBER:
	.BLKL	1	; generic parsed number
BCVPRS_ADDRNUM:
	.BLKB	6	; parsed address number
BCVPRS_PROTNUM:
	.BLKB	2	; parsed protocol number
BCVPRS_DSTADR:
	.BLKB	6	; parsed address for destination
BCVPRS_SRCADR:
	.BLKB	6	; parsed address for source
		;*** next three bytes must remain in this order ***
BCVPRS_DSTMOD:
	.BLKB	1	; filter mode for destination addr (1=EXCLUDE, 2=ONLY)
BCVPRS_SRCMOD:
	.BLKB	1	; filter mode for source addr (1=EXCLUDE, 2=ONLY)
BCVPRS_PRTMOD:
	.BLKB	1	; filter mode for protocol (1=EXCLUDE, 2=ONLY)
		;*** previous three bytes must remain in this order ***
BCVPRS_FLTMOD:
	.BLKB	1	; overall filter mode (1=ENABLE, 2=DISABLE)
NCVPRS_FILESPECLEN:
	.BLKW	1	; length of used filespec buffer
CCVPRS_FILESPEC:
	.BLKB	128	; file specification buffer

	.PSECT	$LOCAL,NOEXE,RD,WRT,NOSHR,LCL,PIC,LONG
BLV_SAVE_FLT_ENA:
	.BLKB	1	; place to save filter EXCLUDE/ONLY flag

	.SBTTL	Command Line Parse State Table

COMMA	=	^X2C

	$INIT_STATE	CMDLIN_STATE,CMDLIN_KEY

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT
	$TRAN	'ADD',STATE_ADD
	$TRAN	'CLEAR',STATE_CLEAR
	$TRAN	'DISPLAY',STATE_DISPLAY
	$TRAN	'EXIT',TPA$_EXIT,EXIT_COMMAND
	$TRAN	'HELP',STATE_HELP
	$TRAN	'LOAD',STATE_LOAD
	$TRAN	'MONITOR',STATE_DISPLAY
	$TRAN	'SAVE',STATE_SAVE
	$TRAN	'SET',STATE_SET
	$TRAN	'SHOW',STATE_SHOW
	$TRAN	'SUMMARIZE',STATE_SUMMARIZE
	$TRAN	'TRACE',STATE_TRACE

	$STATE	ENDLIN
	$TRAN	TPA$_EOS,TPA$_EXIT
	$TRAN	'!',TPA$_EXIT

	$STATE	STATE_ADD
	$TRAN	'FILTER',STATE_ADD_FILTER

	$STATE	STATE_ADD_FILTER
	$TRAN	!FILTER_quals,STATE_ADD_FILTER
	$TRAN	!ENDLIN,TPA$_EXIT,ADD_FILTER

	$STATE	STATE_CLEAR
	$TRAN	'FILTER',STATE_CLEAR_FILTER
	$TRAN	'PROTOCOL_NAME',STATE_CLEAR_PROTNAM

	$STATE	STATE_CLEAR_FILTER
	$TRAN	!ALL_qual,STATE_CLEAR_FILTER_2,,,,-1
	$TRAN	TPA$_DECIMAL,STATE_CLEAR_FILTER_2,,,,1

	$STATE	STATE_CLEAR_FILTER_2
	$TRAN	!ENDLIN,TPA$_EXIT,CLEAR_FILTER

	$STATE	STATE_CLEAR_PROTNAM
	$TRAN	!ALL_qual,STATE_CLEAR_PROTNAM_2
	$TRAN	!protocol_num,STATE_CLEAR_PROTNAM_2

	$STATE	STATE_CLEAR_PROTNAM_2
	$TRAN	!ENDLIN,TPA$_EXIT

	$STATE	STATE_DISPLAY
	$TRAN	'DESTINATIONS',,,,,1
	$TRAN	'PROTOCOLS',,,,,2
	$TRAN	'SIZES',,,,,3
	$TRAN	'SOURCES',,,,,4
	$TRAN	'STATISTICS',,,,,5

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,DISPLAY
	$TRAN	'/'

	$STATE
	$TRAN	'ALL_STATISTICS',,,1,ICVPRS_NUMBER

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,DISPLAY

	$STATE	STATE_HELP
	$TRAN	!skip_to_end,TPA$_EXIT,HELP

	$STATE	STATE_LOAD
	$TRAN	!LOAD_SAVE_qual,,save_filter_mode
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	TPA$_FILESPEC,,save_filespec
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,LOAD

	$STATE	STATE_SAVE
	$TRAN	!LOAD_SAVE_qual,,save_filter_mode
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	TPA$_FILESPEC,,save_filespec
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,SAVE

	$STATE	STATE_SET
	$TRAN	'ADDRESS_NAME',STATE_SET_ADDRNAM
	$TRAN	'FILTER',STATE_SET_FILTER
	$TRAN	'INTERVAL',STATE_SET_INTERVAL
	$TRAN	'PROTOCOL_NAME',STATE_SET_PROTNAM

	$STATE	STATE_SET_ADDRNAM
	$TRAN	!AUTO_qual,STATE_SET_ADDRNAM_AUTO
	$TRAN	!address_num

	$STATE
	$TRAN	TPA$_SYMBOL,,save_filespec
	$TRAN	!quoted_string,,save_filespec

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,SET_ADDRNAM

	$STATE	STATE_SET_ADDRNAM_AUTO
	$TRAN	!ENDLIN,TPA$_EXIT,SET_ADDRNAM_AUTO

	$STATE	STATE_SET_FILTER
	$TRAN	!FILTER_SIZE_qual,STATE_SET_FILTER_3
	$TRAN	TPA$_DECIMAL,,save_number

	$STATE	STATE_SET_FILTER_2
	$TRAN	!FILTER_quals,STATE_SET_FILTER_2
	$TRAN	!ENDLIN,TPA$_EXIT,SET_FILTER

	$STATE	STATE_SET_FILTER_3
	$TRAN	!ENDLIN,TPA$_EXIT,SET_FILTER_SIZE

	$STATE	STATE_SET_INTERVAL
	$TRAN	TPA$_DECIMAL

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,SET_INTERVAL

	$STATE	STATE_SET_PROTNAM
	$TRAN	!protocol_num

	$STATE
	$TRAN	TPA$_SYMBOL,,save_filespec
	$TRAN	!quoted_string,,save_filespec

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,SET_PROTNAM

	$STATE	STATE_SHOW
	$TRAN	'ADDRESS_NAMES',STATE_SHOW_ADDRESS
	$TRAN	'FILTER',STATE_SHOW_FILTER
	$TRAN	'PORT_STATUS',STATE_SHOW_PORT
	$TRAN	'PROTOCOL_NAMES',STATE_SHOW_PROTOCOL

	$STATE	STATE_SHOW_ADDRESS
	$TRAN	!ENDLIN,TPA$_EXIT,SHOW_ADDRESS_NAMES

	$STATE	STATE_SHOW_FILTER
	$TRAN	!ENDLIN,TPA$_EXIT,SHOW_FILTER

	$STATE	STATE_SHOW_PORT
	$TRAN	!ZERO_qual,,,-1,ICVPRS_NUMBER
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	!ENDLIN,TPA$_EXIT,SHOW_PORT_STATUS

	$STATE	STATE_SHOW_PROTOCOL
	$TRAN	!ENDLIN,TPA$_EXIT,SHOW_PROTOCOL_NAMES

	$STATE	STATE_SUMMARIZE
	$TRAN	'DESTINATIONS',,,1,ICVPRS_NUMBER
	$TRAN	'INTERNET',,,7,ICVPRS_NUMBER
	$TRAN	'PROTOCOLS',,,2,ICVPRS_NUMBER
	$TRAN	'SIZES',,,3,ICVPRS_NUMBER
	$TRAN	'SOURCES',,,4,ICVPRS_NUMBER
	$TRAN	'STATISTICS',,,5,ICVPRS_NUMBER

	$STATE	STATE_SUMMARIZE_2
	$TRAN	!ENDLIN,TPA$_EXIT,SUMMARIZE
	$TRAN	'/'

	$STATE
	$TRAN	'INTERVAL',,,8,BCVPRS_PROTNUM

	$STATE
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	!delta_time,STATE_SUMMARIZE_2,get_delta_time

	$STATE	STATE_TRACE
	$TRAN	!ENDLIN,TPA$_EXIT,TRACE
	$TRAN	'/'

	$STATE
	$TRAN	'ASCII',STATE_TRACE,,1,BCVPRS_PROTNUM
	$TRAN	'BINARY',STATE_TRACE,,2,BCVPRS_PROTNUM
	$TRAN	'INTERVAL',STATE_TRACE_INTERVAL,,8,BCVPRS_PROTNUM
	$TRAN	'OUTPUT',STATE_TRACE_OUTPUT,,4,BCVPRS_PROTNUM

	$STATE	STATE_TRACE_INTERVAL
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	!delta_time,STATE_TRACE,get_delta_time

	$STATE	STATE_TRACE_OUTPUT
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	TPA$_FILESPEC,STATE_TRACE,save_filespec

	$STATE	ALL_qual
	$TRAN	'/'

	$STATE
	$TRAN	'ALL',TPA$_EXIT

	$STATE	address_num
	$TRAN	TPA$_HEX,,VALIDATE_ADDRNUM,,,0

	$STATE
	$TRAN	'-'

	$STATE
	$TRAN	TPA$_HEX,,VALIDATE_ADDRNUM,,,1

	$STATE
	$TRAN	'-'

	$STATE
	$TRAN	TPA$_HEX,,VALIDATE_ADDRNUM,,,2

	$STATE
	$TRAN	'-'

	$STATE
	$TRAN	TPA$_HEX,,VALIDATE_ADDRNUM,,,3

	$STATE
	$TRAN	'-'

	$STATE
	$TRAN	TPA$_HEX,,VALIDATE_ADDRNUM,,,4

	$STATE
	$TRAN	'-'

	$STATE
	$TRAN	TPA$_HEX,TPA$_EXIT,VALIDATE_ADDRNUM,,,5

	$STATE	AUTO_qual
	$TRAN	'/'

	$STATE
	$TRAN	'AUTOMATIC',TPA$_EXIT,,-1,ICVPRS_NUMBER
	$TRAN	'NOAUTOMATIC',TPA$_EXIT

	$STATE	DECnet_num
	$TRAN	TPA$_DECIMAL,,validate_DECnet_num,,,0

	$STATE
	$TRAN	'.'

	$STATE
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,validate_DECnet_num,,,1

	$STATE	delta_time
	$TRAN	TPA$_DECIMAL,,validate_time,,,23
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	':'
	$TRAN	TPA$_LAMBDA,TPA$_EXIT

	$STATE
	$TRAN	TPA$_DECIMAL,,validate_time,,,59
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	':'
	$TRAN	TPA$_LAMBDA,TPA$_EXIT

	$STATE
	$TRAN	TPA$_DECIMAL,,validate_time,,,59
	$TRAN	TPA$_LAMBDA

	$STATE
	$TRAN	'.'
	$TRAN	TPA$_LAMBDA,TPA$_EXIT

	$STATE
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,validate_time,,,99

	$STATE	FILTER_quals
	$TRAN	'/'

	$STATE
	$TRAN	'DISABLE',TPA$_EXIT,save_filter_mode,,,2
	$TRAN	'ENABLE',TPA$_EXIT,save_filter_mode,,,1
	$TRAN	'EXCLUDE',,save_filter_switch,,,1
	$TRAN	'NODESTINATION',TPA$_EXIT,mark_filter_switch,,,0
	$TRAN	'NOPROTOCOL',TPA$_EXIT,mark_filter_switch,,,2
	$TRAN	'NOSOURCE',TPA$_EXIT,mark_filter_switch,,,1
	$TRAN	'ONLY',,save_filter_switch,,,2

	$STATE
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	'('
	$TRAN	!FILTER_qual_subqual,TPA$_EXIT

	$STATE	FILTER_qual_2
	$TRAN	!FILTER_qual_subqual

	$STATE
	$TRAN	COMMA,FILTER_qual_2
	$TRAN	')',TPA$_EXIT

	$STATE	FILTER_qual_subqual
	$TRAN	'DESTINATION',FILTER_qual_subqual_DST
	$TRAN	'PROTOCOL',FILTER_qual_subqual_PRO
	$TRAN	'SOURCE',FILTER_qual_subqual_SRC

	$STATE	FILTER_qual_subqual_DST
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	!address_num,TPA$_EXIT,save_addr_as_dst
	$TRAN	!Internet_num
	$TRAN	!DECnet_num,FILTER_qual_subqual_DST_DEC
	$TRAN	TPA$_STRING,FILTER_qual_subqual_DST_2,check_node_name

	$STATE
	$TRAN	TPA$_LAMBDA,FILTER_qual_subqual_DST_2,check_Internet_num

	$STATE	FILTER_qual_subqual_DST_DEC
	$TRAN	TPA$_LAMBDA,,check_DECnet_num

	$STATE	FILTER_qual_subqual_DST_2
	$TRAN	TPA$_LAMBDA,TPA$_EXIT,save_addr_as_dst

	$STATE	FILTER_qual_subqual_PRO
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	!protocol_num,TPA$_EXIT,save_protocol_mode

	$STATE	FILTER_qual_subqual_SRC
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	!address_num,TPA$_EXIT,save_addr_as_src
	$TRAN	!Internet_num
	$TRAN	!DECnet_num,FILTER_qual_subqual_SRC_DEC
	$TRAN	TPA$_STRING,FILTER_qual_subqual_SRC_2,check_node_name

	$STATE
	$TRAN	TPA$_LAMBDA,FILTER_qual_subqual_SRC_2,check_Internet_num

	$STATE	FILTER_qual_subqual_SRC_DEC
	$TRAN	TPA$_LAMBDA,,check_DECnet_num

	$STATE	FILTER_qual_subqual_SRC_2
	$TRAN	TPA$_LAMBDA,TPA$_EXIT,save_addr_as_src

	$STATE	FILTER_SIZE_qual
	$TRAN	'/'

	$STATE
	$TRAN	'SIZE'

	$STATE
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	!FILTER_SIZE_subqual,TPA$_EXIT
	$TRAN	'('

	$STATE	FILTER_SIZE_qual_2
	$TRAN	!FILTER_SIZE_subqual

	$STATE
	$TRAN	COMMA,FILTER_SIZE_qual_2
	$TRAN	')',TPA$_EXIT

	$STATE	FILTER_SIZE_subqual
	$TRAN	'DISABLE',TPA$_EXIT,,2,BCVPRS_PROTNUM
	$TRAN	'ENABLE',TPA$_EXIT,,1,BCVPRS_PROTNUM
	$TRAN	'MAXIMUM',FILTER_SIZE_subqual_max
	$TRAN	'MINIMUM',FILTER_SIZE_subqual_min

	$STATE	FILTER_SIZE_subqual_max
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,VALIDATE_MSGLEN,,BCVPRS_SRCADR

	$STATE	FILTER_SIZE_subqual_min
	$TRAN	'='
	$TRAN	':'

	$STATE
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,VALIDATE_MSGLEN,,BCVPRS_DSTADR

	$STATE	Internet_num
	$TRAN	TPA$_DECIMAL,,validate_Inetnum,,,0

	$STATE
	$TRAN	'.'

	$STATE
	$TRAN	TPA$_DECIMAL,,validate_Inetnum,,,1

	$STATE
	$TRAN	'.'

	$STATE
	$TRAN	TPA$_DECIMAL,,validate_Inetnum,,,2

	$STATE
	$TRAN	'.'

	$STATE
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,validate_Inetnum,,,3

	$STATE	LOAD_SAVE_qual
	$TRAN	'/'

	$STATE
	$TRAN	'ADDRESSES',TPA$_EXIT,,,,1
	$TRAN	'FILTERS',TPA$_EXIT,,,,2
	$TRAN	'PROTOCOLS',TPA$_EXIT,,,,3

	$STATE	protocol_num
	$TRAN	TPA$_HEX,,VALIDATE_PROTNUM,,,0

	$STATE
	$TRAN	'-'

	$STATE
	$TRAN	TPA$_HEX,TPA$_EXIT,VALIDATE_PROTNUM,,,1

	$STATE	quoted_string
	$TRAN	'"'

	$STATE	quoted_string_2
	$TRAN	'"',TPA$_EXIT
	$TRAN	TPA$_ANY,quoted_string_2

	$STATE	skip_to_end
	$TRAN	!ENDLIN,TPA$_EXIT
	$TRAN	TPA$_ANY,skip_to_end

	$STATE	ZERO_qual
	$TRAN	'/'

	$STATE
	$TRAN	'ZERO',TPA$_EXIT

	$END_STATE

	.SBTTL	Command Parsing Subroutine

	.PSECT	$CODE,EXE,RD,NOWRT,LCL,SHR,PIC,LONG

	.ENTRY	EVALUATE_COMMAND,^M<R2,R3,R4,R5>
	CLRL	ICVPRS_NUMBER		; clear any variables related to filters,
	CLRW	BCVPRS_PROTNUM
	CLRL	BCVPRS_SRCADR
	CLRW	BCVPRS_SRCADR+4
	CLRL	BCVPRS_DSTADR
	CLRW	BCVPRS_DSTADR+4
	CLRB	BCVPRS_DSTMOD
	CLRB	BCVPRS_SRCMOD
	CLRB	BCVPRS_PRTMOD
	CLRB	BCVPRS_FLTMOD
	CLRW	NCVPRS_FILESPECLEN
	CLRB	BLV_SAVE_FLT_ENA
	SUBL2	#TPA$K_LENGTH0,SP	; build TPARSE argblk on stack,
	MOVC5	#0,(SP),#0,#TPA$K_LENGTH0,(SP) ; clear block,
	MOVL	#TPA$K_COUNT0,TPA$L_COUNT(SP) ; fill in the block,
	MOVL	#TPA$M_ABBREV,TPA$L_OPTIONS(SP)
	MOVAQ	@4(AP),R0
	MOVZWL	(R0),TPA$L_STRINGCNT(SP)
	MOVAB	@4(R0),TPA$L_STRINGPTR(SP)
	PUSHAB	CMDLIN_KEY		; call the parser,
	PUSHAB	CMDLIN_STATE
	PUSHAL	8(SP)
	CALLS	#3,G^LIB$TPARSE
	BLBS	R0,99$			; exit if successful,
	CMPL	R0,#LIB$_SYNTAXERR	; else test what type of error it was,
	BNEQ	90$			; not a syntax error, continue.
	BBC	#TPA$V_AMBIG,TPA$L_OPTIONS(SP),90$ ; skip if not ambiguous error,
	MOVL	#CLI$_ABVERB,R0		; else change error status,
90$:	PUSHL	R0			; build message vector on stack,
	PUSHL	#1
	$PUTMSG_S	MSGVEC=12(SP)	; report error,
99$:	RET				; return.

	.SBTTL	Command Execution Support Subroutines

	.ENTRY	EXIT_COMMAND,^M<>
	MNEGB	#1,LCV_EXIT		; flag EXIT command as entered,
	RET				; return.

	.ENTRY	VALIDATE_MSGLEN,^M<>
	CMPL	TPA$L_NUMBER(AP),#46	; test if number is too small,
	BLSSU	98$			; skip if error,
	CMPL	TPA$L_NUMBER(AP),#1500	; test if number is too large,
	BLEQU	99$			; skip if OK,
98$:	MOVL	#ETH__MSGLEN,R0		; else report error.
99$:	RET

	.ENTRY	validate_time,^M<>
	CMPL	TPA$L_NUMBER(AP),-	; check if number in range,
		TPA$L_PARAM(AP)
	BLEQU	99$			; skip out if OK,
	MOVZWL	#SS$_IVTIME,R0		; else report error.
99$:	RET

day_prolog:
	.ASCID	"0 "

	.ENTRY	get_delta_time,^M<>
	CLRQ	-(SP)			; make an empty dynamic string descriptor,
	MOVW	#^X020E,2(SP)
	PUSHAQ	day_prolog		; build properly formatted time string,
	PUSHAQ	4(SP)
	CALLS	#2,G^STR$APPEND
	PUSHAQ	TPA$L_TOKENCNT(AP)
	PUSHAQ	4(SP)
	CALLS	#2,G^STR$APPEND
	$BINTIM_S	TIMBUF=4(SP),-	; attempt to translate time,
			TIMADR=BCVPRS_DSTADR
	PUSHR	#^M<R0>			; preserve $BINTIM status,
	PUSHAQ	4(SP)			; release the dynamic string,
	CALLS	#1,G^STR$FREE1_DX
	POPR	#^M<R0>			; restore $BINTIM status,
	RET				; return w/results (whatever they are).

	.ENTRY	save_number,^M<>
	MOVL	TPA$L_NUMBER(AP),ICVPRS_NUMBER ; copy number from argblk to COMMON,
	RET				; exit.

	.ENTRY	save_filter_mode,^M<>
	MOVB	TPA$L_PARAM(AP),BCVPRS_FLTMOD ; save filter mode,
	RET				; exit.

	.ENTRY	mark_filter_switch,^M<>
	MOVL	TPA$L_PARAM(AP),R1	; get number of desired target,
	MNEGB	#1,BCVPRS_DSTMOD[R1]	; mark filter mode as "clear it",
	RET				; exit.

	.ENTRY	save_filter_switch,^M<>
	MOVB	TPA$L_PARAM(AP),BLV_SAVE_FLT_ENA ; save filter EXCLUDE/ONLY switch,
	RET				; exit.

	.ENTRY	VALIDATE_ADDRNUM,^M<>
	MOVL	TPA$L_PARAM(AP),R1	; get index into buffer array,
	MOVB	TPA$L_NUMBER(AP),BCVPRS_ADDRNUM[R1] ; copy value into buffer,
	CMPL	TPA$L_TOKENCNT(AP),#2	; test if number too long,
	BGTRU	98$			; bomb if too long,
	CMPL	TPA$L_NUMBER(AP),#^XFF	; is number in range?
	BLEQU	99$			; skip out if so,
98$:	MOVL	#ETH__BADADDRNUM,R0 ; else report syntax error.
99$:	RET

DECnet_num_limits:
	.LONG	63
	.LONG	1023

	.ENTRY	validate_DECnet_num,^M<>
	MOVL	TPA$L_PARAM(AP),R1	; get index into buffer array,
	MOVW	TPA$L_NUMBER(AP),BCVPRS_ADDRNUM[R1] ; copy value into buffer,
	TSTL	TPA$L_NUMBER(AP)	; test if number is non-zero,
	BEQL	98$			; abort if not,
	CMPL	TPA$L_NUMBER(AP),-	; is number in range?
		DECnet_num_limits[R1]
	BLEQU	99$			; skip out if so,
98$:	MOVL	#ETH__INVNODSPC,R0	; else report syntax error.
99$:	RET

	.ENTRY	validate_Inetnum,^M<>
	MOVL	TPA$L_PARAM(AP),R1	; get index into buffer array,
	MOVB	TPA$L_NUMBER(AP),BCVPRS_ADDRNUM[R1] ; copy value into buffer,
	CMPL	TPA$L_NUMBER(AP),#^XFF	; is number in range?
	BLSSU	99$			; skip out if so,
	MOVL	#ETH__BADADDRNUM,R0 ; else report syntax error.
99$:	RET

	.ENTRY	VALIDATE_PROTNUM,^M<>
	MOVL	TPA$L_PARAM(AP),R1	; get index into buffer array,
	MOVB	TPA$L_NUMBER(AP),BCVPRS_PROTNUM[R1] ; copy value into buffer,
	CMPL	TPA$L_TOKENCNT(AP),#2	; test if number too long,
	BGTRU	98$			; bomb if too long,
	CMPL	TPA$L_NUMBER(AP),#^XFF	; is number in range?
	BLEQU	99$			; skip out if so,
98$:	MOVL	#ETH__BADPROTNUM,R0 ; else report syntax error.
99$:	RET

	.ENTRY	check_DECnet_num,^M<>
	MOVZWL	BCVPRS_ADDRNUM,R1	; get network area number,
	ASHL	#10,R1,R1		; shift into position,
	BISW2	BCVPRS_ADDRNUM+2,R1	; OR in the node number,
	MOVW	R1,BCVPRS_ADDRNUM+4	; use as top 2 bytes of Ethernet addr,
	MOVL	#^X000400AA,BCVPRS_ADDRNUM ; fill in DECnet low longword,
	RET				; return successfully.

	.ENTRY	save_addr_as_dst,^M<>
	MOVL	BCVPRS_ADDRNUM,BCVPRS_DSTADR ; copy 1st part of address,
	MOVW	BCVPRS_ADDRNUM+4,BCVPRS_DSTADR+4 ; copy rest of address,
	MOVB	BLV_SAVE_FLT_ENA,BCVPRS_DSTMOD ; save mode of address,
	RET				; exit.

	.ENTRY	save_addr_as_src,^M<>
	MOVL	BCVPRS_ADDRNUM,BCVPRS_SRCADR ; copy 1st part of address,
	MOVW	BCVPRS_ADDRNUM+4,BCVPRS_SRCADR+4 ; copy rest of address,
	MOVB	BLV_SAVE_FLT_ENA,BCVPRS_SRCMOD ; save mode of address,
	RET				; exit.

	.ENTRY	save_protocol_mode,^M<>
	MOVB	BLV_SAVE_FLT_ENA,BCVPRS_PRTMOD ; save mode of protocol,
	RET				; exit.

	.ENTRY	save_filespec,^M<R2,R3,R4,R5>
	PUSHR	#^M<R0>			; preserve success status,
	MOVC5	TPA$L_TOKENCNT(AP),-	; copy string to COMMON buffer,
		@TPA$L_TOKENPTR(AP),#^A/ /,#128,CCVPRS_FILESPEC
	MOVW	TPA$L_TOKENCNT(AP),NCVPRS_FILESPECLEN ; save string length,
	CMPW	TPA$L_TOKENCNT(AP),#128
	BLEQU	90$
	MOVW	#128,NCVPRS_FILESPECLEN ; adjust if string truncated,
90$:	POPR	#^M<R0>			; restore success status,
	RET				; exit.

	.END
