Google
 

Trailing-Edge - PDP-10 Archives - BB-FP64A-SB_1986 - 10,7/decnet/nsptst/nsptst.mac
There are 5 other files named nsptst.mac in the archive. Click here to see a list.
	TITLE	NSPTST		Test NSP uuo
	SUBTTL	T.Neustaedter/Tarl
	SEARCH	DCN

	Comment @

This program is intended as an aid to debugging DECnet-10 programs, and
as a working example of a program using the NSP. uuo.

It is intended that this program be used in conjuction with a listing of
NSPUSR.MEM, as many of the requested fields are inadequatley labeled when
this program requests them.

The NSP. uuo in this program will always set NS.WAI, so if you want to
exercise asynchronous I/O, you'll have to write your own hack.

	@


	$ONLY==I.PRM!I.GTT!I.LUO
	$INIT	NSP

;Macro to convert string block length in bytes to words

	DEFINE SLEN(BYTES),<1+<<BYTES+3>/4>>
	XP SMAX,400		;Maximum size for string block arg

;Define some blocks for use in NSP. uuo

$LVAR	FZER			;First zeroed location \
$BLOCK	UBLK,.NSAMX+1		;Block for the NSP uuo 	\
$BLOCK	CBLK,.NSCMX+1		;Connect block	       	 \
$BLOCK	SPDB,.NSDMX+1		;Source PDB (name follows)\
$BLOCK	SPNM,SLEN(^D16)		;Source process name	   |
$BLOCK	DPDB,.NSDMX+1		;Destination PDB       	   | Blocks zeroed
$BLOCK	DPNM,SLEN(^D16)		;Destination process name  |
$BLOCK	NODE,SLEN(^D6)		;Node name block	   | before every
$BLOCK	USER,SLEN(^D39)		;User ID		   | NSP. execution
$BLOCK	PASS,SLEN(^D39)		;Password		  /
$BLOCK	ACCT,SLEN(^D39)		;Account		 /
$BLOCK	DATA,SLEN(^D16)		;User data		/
$BLOCK	SBLK,SLEN(SMAX)		;String block	        |
$LVAR	LZER			;Last zeroed location  /


;Define some values for uuo description macros
;Flags indicating read, write, prived
        FL.R=40
        FL.W=20
        FL.P=10
        FL.=0
;Function code describing format of argument
        FN.CBL=1
        FN.SBL=2
        FN.ARG=3
        FN.BCT=4
        FN.BPT=5
;Macros to add up all the flags in an individual argument
        DEFINE CBL(A,B,C),<FL.'A+FL.'B+FL.'C+FN.CBL>
        DEFINE SBL(A,B,C),<FL.'A+FL.'B+FL.'C+FN.SBL>
        DEFINE ARG(A,B,C),<FL.'A+FL.'B+FL.'C+FN.ARG>
        DEFINE BCT(A,B,C),<FL.'A+FL.'B+FL.'C+FN.BCT>
        DEFINE BPT(A,B,C),<FL.'A+FL.'B+FL.'C+FN.BPT>
;Macro to build up a dispatch entry from all the above
	DEFINE NSPFNC(SIXNAM,ARG1,ARG2,ARG3,ASCNAM),<
	XWD SIXBIT \   SIXNAM \,[<ARG1>B5+<ARG2>B11+<ARG3>B17+.NSF'SIXNAM
				ASCIZ \ASCNAM\]
>

;These are the definitions of all the NSP. functions.  The format of the
;NSPFNC macro is function name followed by the three possible arguments
;of the NSP. UUO.
;
;	R = Read this arg from user's block
;	W = Write this arg into user's block
;	P = Privileged Argument

NSPTAB:
	NSPFNC EA,CBL(R),ARG(R),ARG(R,P),<Enter Active>
	NSPFNC EP,CBL(R),,,<Enter Passive>
	NSPFNC RI,CBL(W),ARG(W),ARG(W),<Read connect data>
	NSPFNC AC,SBL(R),ARG(R),ARG(R,P),<Accept connect>
	NSPFNC RJ,SBL(R),ARG(R,P),,<Reject connect>
	NSPFNC RC,SBL(W),ARG(W),ARG(W),<Read confirm info>
	NSPFNC SD,SBL(R),ARG(R,P),,<Synchronous disconnect>
	NSPFNC AB,SBL(R),ARG(R,P),,<Abort and release>
	NSPFNC RD,SBL(W),ARG(W),,<Read disconnect data>
	NSPFNC RL,,,,<Release channel>
	NSPFNC RS,ARG(W),ARG(W),,<Read status>
	NSPFNC IS,SBL(R),,,<Send interrupt data>
	NSPFNC IR,SBL(W),,,<Read interrupt data>
;	NSPFNC DS,BCT(R,W),BPT(R,W),,<Send normal data>
;	NSPFNC DR,BCT(R,W),BPT(R,W),,<Read normal data>
	NSPFNC SQ,ARG(R),ARG(R),ARG(R),<Set quotas and goals>
	NSPFNC RQ,ARG(W),ARG(W),ARG(W),<Read quotas and goals>
	NSPFNC JS,ARG(R,P),ARG(R,P),,<Set job quotas & goals>
	NSPFNC JR,ARG(W),ARG(W),,<Read job quotas & goals>
	NSPFNC PI,ARG(R),,,<Set PSI reason mask>
NSPLEN=.-NSPTAB


START:	$SETUP			;Init LUUO package
	$INFORM INI,<NSP. test bed package>
	PUSH P,[.]		;save this as address to return to
START1:	$PROMPT T1,%SIXBIT,<Function to execute: .NSF>
	MOVE T2,[IOWD NSPLEN,NSPTAB] ;Pointer to function table
START2:	HLLZ T3,1(T2)		;Get a function name
	CAMN T3,T1		;is this the one?
	 JRST PRCFNC		;yes, process the function
	AOBJN T2,START2		;loop until we find it
	$WARN NSF,<No such function name, available names are:>
	MOVE T2,[IOWD NSPLEN,NSPTAB] ;Pointer to function table
START3:	TSTRG. [ASCIZ \.NSF\]	;Prefix function name
	HLLZ T1,1(T2)		;Get a name
	TSIXN. T1,		;Type it out
	TCHRI. .CHTAB		;Space over
	HRRZ T1,1(T2)		;Get pointer to extra info
	TLINE. 1(T1)		;and type long name
	AOBJN T2,START3		;And loop until we finish typing them out
	JRST START1		;try again.

PRCFNC:
	SETZM FZER		;clean first word of zeroable area
	MOVE T1,[FZER,,FZER+1]	;blt pointer
	BLT T1,LZER		;Clear entire zeroable area.
	HRRZ P1,1(T2)		;Get pointer to detail for this function
	TSTRG. [ASCIZ \** For function \]
	TLINE. 1(P1)		;Type out detailed name
	HRLZ T1,(P1)		;Get function code
	IOR T1,[NS.WAI!.NSAMX]	;Add flags and length
	MOVEM T1,UBLK+.NSAFN	;save in function and length word
	$PROMPT T1,%DECIMAL,<Channel to use: >
	MOVEM T1,UBLK+.NSACH	;save in channel field
	MOVE P1,(P1)		;Get detail on chunks to fill in
	LDB T1,[POINT 6,P1,5]	;get bits indicating type of block
	CALL GETARG		;Get argument to store here
	 JRST PRCEND		;error, abort function.
	MOVEM T1,UBLK+.NSAA1	;Save as argument 1
	LDB T1,[POINT 6,P1,11]	;Get bits for second argument
	CALL GETARG		;Get argument
	 JRST PRCEND
	MOVEM T1,UBLK+.NSAA2	;Save as argument 2
	LDB T1,[POINT 6,P1,17]	;Get bits for third argument
	CALL GETARG		;Get argument
	 JRST PRCEND
	MOVEM T1,UBLK+.NSAA3	;Save as argument 3
	MOVEI T1,UBLK		;pointer to argument block
	NSP. T1,		;do the function
	 $WARN NFF,<NSP uuo failed, Reason: >,TYPERR,T1
	HRRZ T2,UBLK+.NSACH
	$INFORM CHN,<Used channel number >,.TDECW##,T2
	MOVEI T1,SBLK		;Point to the generic string block
	MOVEI T2,[ASCIZ \String block contents: \]
	CALL TYPSBL		;Type it out if relevant
	 JRST PRCEND
	CALL TYPCBL		;Type out the connect block
	 JRST PRCEND
PRCEND:
	JRST START1		;and do again.

TYPERR:	SKIPL T1		;Make sure not negative
	CAXLE T1,ERRMAX		;Range check
	 SETZ T1,		;zero error code is catch all
	TSTRG. @ERRTAB(T1)	;Type out error string
	RET			;and return

ERRTAB:
	[ASCIZ \%NE???(?) Unknown error code\]
	[ASCIZ \%NEABE(1) Argument block format error\]
	[ASCIZ \%NEALF(2) Allocation failure\]
	[ASCIZ \%NEBCN(3) Bad channel number\]
	[ASCIZ \%NEBFT(4) Bad format type in process block\]
	[ASCIZ \%NECFE(5) Connect block format error\]
	[ASCIZ \%NEIDL(6) Interrupt data too long\]
	[ASCIZ \%NEIFM(7) Illegal flow control mode\]
	[ASCIZ \%NEILF(10) Illegal function\]
	[ASCIZ \%NEJQX(11) Job quota exhausted\]
	[ASCIZ \%NELQX(12) Link quota exhausted\]
	[ASCIZ \%NENCD(13) No connect data to read\]
	[ASCIZ \%NEPIO(14) Percentage input out of bounds\]
	[ASCIZ \%NEPRV(15) No privileges to perform function\]
	[ASCIZ \%NESTB(16) Segment size too big\]
	[ASCIZ \%NEUKN(17) Unknown node name\]
	[ASCIZ \%NEUXS(20) Unexpected state: unspecified\]
	[ASCIZ \%NEWNA(21) Wrong number of arguments\]
	[ASCIZ \%NEWRS(22) Function called in wrong state\]
	[ASCIZ \%NECBL(23) Connect block length error\]
	[ASCIZ \%NEPBL(24) Process block length error\]
	[ASCIZ \%NESBL(25) String block length error\]
	[ASCIZ \%NEUDS(26) Unexpected state: disconnect sent\]
	[ASCIZ \%NEUDC(27) Unexpected state: disconnect confirmed\]
	[ASCIZ \%NEUCF(30) Unexpected state: no confidence\]
	[ASCIZ \%NEULK(31) Unexpected state: no link\]
	[ASCIZ \%NEUCM(32) Unexpected state: no communication\]
	[ASCIZ \%NEUNR(33) Unexpected state: no resources\]
	[ASCIZ \%NERBO(34) Rejected by object\]
	[ASCIZ \%NEDBO(35) Disconnected by object (when running) \]
	[ASCIZ \%NERES(36) No resources\]
	[ASCIZ \%NEUNN(37) Unrecognized node name\]
	[ASCIZ \%NERNS(40) Remote node shut down\]
	[ASCIZ \%NEURO(41) Unrecognized object\]
	[ASCIZ \%NEIOF(42) Invalid object name format\]
	[ASCIZ \%NEOTB(43) Object too busy\]
	[ASCIZ \%NEABM(44) Abort by management\]
	[ASCIZ \%NEABO(45) Abort by object\]
	[ASCIZ \%NEINF(46) Invalid node name format\]
	[ASCIZ \%NELNS(47) Local node shut down\]
	[ASCIZ \%NEACR(50) Access control rejection\]
	[ASCIZ \%NENRO(51) No response from object\]
	[ASCIZ \%NENUR(52) Node unreachable\]
	[ASCIZ \%NENLK(53) No link\]
	[ASCIZ \%NEDSC(54) Disconnect complete\]
	[ASCIZ \%NEIMG(55) Image field too long\]
	[ASCIZ \%NEREJ(56) Unspecified reject reason\]
	[ASCIZ \%NEBCF(57) Bad combo of ns.eom & ns.wai flags\]
	[ASCIZ \%NEADE(60) Address error\]
ERRMAX=.-ERRTAB


GETARG:	LDB T2,[POINT 3,T1,35]	;Get the actual function code
	JRST @.+1(T2)		;dispatch
	IFIW RETZER		;(0) No arg, return zero
	IFIW RETCBL		;(1) Get a connect block
	IFIW RETSBL		;(2) Get a string block
	IFIW RETARG		;(3) Get a word
	IFIW RETBCT		;(4) Byte count (save string)
	IFIW RETBPT		;(5) Byte pointer (get from saved)
	IFIW RETERR		;(6) Error, no such code
	IFIW RETERR		;(7) Error, no such code

RETZER:	SETZ T1,		;Return clean AC
	RETSKP			;and success since we didn't fail

RETERR:	$ERROR INV,<Invalid argument code for function>
	EXIT

;Service routine. Read a string into a string block
;Call
;	T1/ Flags
;	T2/ length allowed (in bytes)
;	T3/ Pointer to block to fill in
;Return
;	T1/ Pointer to string block filled in

INPSBL:	CALL .SAV2		;Preserve P1
	MOVE P1,T3		;preserve pointers
	MOVE P2,T2		;preserve length
	TRNN T1,FL.R		;is the monitor going to read this?
	 JRST INPSB3		;No, just set up the block header
INPSB1:	$PROMPT T3,%ASCII,<String: >
	MOVE T3,[POINT 7,.NMUL##] ;BPT to scan string storage area
	MOVE T4,[POINT 8,1(P1)]	;Pointer to string area
INPSB2:	ILDB T1,T3		;get a byte from scan string area
	JUMPE T1,INPSB3		;done, do accounting
	IDPB T1,T4		;Save in string area
	SOJGE T2,INPSB2		;loop
	$WARN STL,<String too long for field>
	MOVE T2,P2		;restore length we will accept
	JRST INPSB1		;and try again.

INPSB3:	MOVE T1,P2		;Copy number of bytes allowed
	SUB P2,T2		;Find out how many bytes we got
	ADDI T1,3		;round up to nearest word
	IDIVI T1,4		;convert into words
	ADDI T1,1		;Add overhead word of header
	HRL T1,P2		;bytes,,words
	MOVEM T1,(P1)		;store as string block header
	MOVE T1,P1		;get back pointer to string block
	RETSKP			;and return success
;Service routine. Type a string block
;Call
;	T1/ Pointer to string block
;	T2/ Descriptor string to type out
;Return
;	RETSKP

TYPSBL:	HLRZ T4,(T1)		;Get number of bytes in string block
	JUMPE T4,.POPJ1##	;Nothing there, return
	TSTRG. (T2)		;Type out descriptor of this string block
	MOVE T3,[POINT 8,1(T1)]	;Byte pointer to data in string block
TYPSB2:	ILDB T2,T3		;Get a byte from string
	TCHRI. (T2)		;Type it out
	SOJG T4,TYPSB2		;Loop until end
	TCRLF.			;end line
	RETSKP
;Service routine. Input a process descriptor block
;Call
;	T1/ Flags from GETARG
;	T2/ Pointer to block to use as PDB block
;	    Block must be immediatley followed by 5 words for process name
;Return
;	T1/ Pointer to PDB block

INPPDB:	CALL .SAV1		;Storage
	MOVE P1,T2		;Save pointer to pdb block
	MOVEI T2,.NSDMX		;Length of PDB
	MOVEM T2,.NSDFL(P1)	;Save in PDB
	MOVEI T2,.NSDMX+1(P1)	;Pointer to process name block
	MOVEM T2,.NSDPN(P1)	;Store in process block
	TRNN T1,FL.R		;Is the monitor going to read this?
	 JRST INPPD6		;No, just keep on going
INPPD2:	$PROMPT T2,%DECIMAL,<Format type 0,1 or 2: >
	SKIPL T2		;Range check
	CAILE T2,2		;to within reason
	 $WARN FTO,<Format type may only be 0,1 or 2>,,,INPPD2
	MOVEM T2,.NSDFM(P1)	;save as format type
	JUMPN T2,INPPD5		;If non-zero format type, skip object type
	$PROMPT T2,%DECIMAL,<Object type: >
	CAXL T2,-2		;Range check
	CAXLE T2,^D255		;to within reason (neg 1 is anything)
	 $WARN OBO,<Object type must be less than 255.>,,,INPPD2
	MOVEM T2,.NSDOB(P1)	;save as object type
	JRST INPPD7		;and skip ppn and process name
INPPD5:
	CAXE T2,2		;Format type 2?
	 JRST INPPD6		;No, don't ask for PPN
	$PROMPT T2,%OCTAL,<PPN (full word format): >
	MOVEM T2,.NSDPP(P1)	;Save in block
INPPD6:
	MOVEI T2,^D16		;Max 16 characters for process name
	MOVE T3,.NSDPN(P1)	;Get pointer to string block area
	TRNE T1,FL.R		;Is this going to be read?
	TSTRG. [ASCIZ \Process name \] ;start up string
	CALL INPSBL		;Get string block
	 RET			;propagate error
INPPD7:	MOVE T1,P1		;get back pointer to process block
	RETSKP			;return success
;Service routine. Type out a PDB
;Call
;	T1/ Pointer to PDB
;	T2/ Pointer to header string

TYPPDB:
	CALL .SAV1		;Storage
	MOVE P1,T1		;Store pointer to PDB
	SKIPN .NSDFM(P1)	;Format type 0?
	SKIPE .NSDOB(P1)	;object type 0?
	TRNA			;Something non zero, lets type this out
	RETSKP			;yes to both being zero, forget about him
	TSTRG. (T2)		;Type out header
	MOVE T1,.NSDFM(P1)	;Get format type
	TSTRG. [ASCIZ \Format type \]
	TDECW. T1,		;TYpe it out in decimal
	TCHRI. ","
	JUMPN T1,TYPPD2		;non zero, skip object type code
	TSTRG. [ASCIZ \ Object type \]
	MOVE T1,.NSDOB(P1)	;Get object type
	TDECW. T1,		;and type it out
	RETSKP			;and return

TYPPD2:	CAIE T1,2		;Format type 2
	 JRST TYPPD3		;No, skip PPN
	TSTRG. [ASCIZ \ PPN=\]	;Indicate PPN coming next
	MOVE T1,.NSDPP(P1)	;Get ppn
	TXWDW. T1,		;Type it out as a PPN
TYPPD3:	SKIPN T1,.NSDPN(P1)	;Get pointer to process name block
	 RETSKP			;None there, done
	MOVEI T2,[ASCIZ \, Name=\] ;header if needed
	JRST TYPSBL		;And type it out, returning

RETCBL:	CALL .SAV2		;save a couple of acs
	MOVE P1,T1		;save flags
	MOVEI T2,.NSCMX		;Get length of connect block
	MOVEM T2,CBLK+.NSCNL	;save as length
	TRNE P1,FL.R		;Is this going to be read?
	TSTRG. [ASCIZ \Node name \] ;head up question
	MOVEI T3,NODE		;pointer to node block
	MOVEI T2,6		;maximum length to node name block
	CALL INPSBL		;Read string block
	 RET			;propagate error
	MOVEM T1,CBLK+.NSCND	;save pointer in connect block
	TRNE P1,FL.R		;Is this going to be read?
	TLINE. [ASCIZ \Source process descriptor:\]
	MOVE T1,P1		;Get back flags again
	MOVEI T2,SPDB		;Pointer to source PDB block
	CALL INPPDB		;Read process descriptor block
	 RET			;failure, return
	MOVEM T1,CBLK+.NSCSD	;Save in connect block
	TRNE P1,FL.R		;Is this going to be read?
	TLINE. [ASCIZ \Destination process descriptor:\]
	MOVE T1,P1		;Get back flags yet again
	MOVEI T2,DPDB		;pointer to destination PDB block
	CALL INPPDB		;Read pdb
	 RET			;propagate return
	MOVEM T1,CBLK+.NSCDD	;save as destination pdb
	TRNE P1,FL.R
	TSTRG. [ASCIZ \User id \]
	MOVE T1,P1		;flags yet again
	MOVEI T2,^D39		;Length
	MOVEI T3,USER		;User id string area
	CALL INPSBL		;Read a string block
	 RET			;propagate return
	MOVEM T1,CBLK+.NSCUS	;store in block
	TRNE P1,FL.R
	TSTRG. [ASCIZ \Password \]
	MOVE T1,P1		;flags yet again
	MOVEI T2,^D39		;Length
	MOVEI T3,PASS		;Password
	CALL INPSBL		;Read a string block
	 RET			;propagate return
	MOVEM T1,CBLK+.NSCPW	;store in block
	TRNE P1,FL.R
	TSTRG. [ASCIZ \Account \]
	MOVE T1,P1		;flags yet again
	MOVEI T2,^D39		;Length
	MOVEI T3,ACCT		;Account string area
	CALL INPSBL		;Read a string block
	 RET			;propagate return
	MOVEM T1,CBLK+.NSCAC	;store in block
	TRNE P1,FL.R
	TSTRG. [ASCIZ \User data \]
	MOVE T1,P1		;flags yet again
	MOVEI T2,^D39		;Length
	MOVEI T3,DATA		;User data string area
	CALL INPSBL		;Read a string block
	 RET			;propagate return
	MOVEM T1,CBLK+.NSCUD	;store in block
	MOVEI T1,CBLK		;Pointer to connect block
	RETSKP
;Type out connect block if anything interesting

TYPCBL:
	SKIPN CBLK+.NSCNL	;Did we use the connect block?
	 RETSKP			;Nope, just return
	TLINE. [ASCIZ \Connect block contains: \]
	SKIPN T1,CBLK+.NSCND	;Is there a node name block?
	 JRST TYPCB1		;No, skip over this
	MOVEI T2,[ASCIZ \Node name: \]
	CALL TYPSBL		;Type the string block out (if anything there)
	 RET
TYPCB1:	SKIPN T1,CBLK+.NSCSD	;Is there a source process descriptor?
	 JRST TYPCB2		;No.
	MOVEI T2,[ASCIZ \Source PDB: \]
	CALL TYPPDB		;Type the PDB
	 RET
	TCRLF.
TYPCB2:	SKIPN T1,CBLK+.NSCDD	;Destination pdb?
	 JRST TYPCB3		;no
	MOVEI T2,[ASCIZ \Destination PDB: \]
	CALL TYPPDB		;Type it out
	 RET
	TCRLF.
TYPCB3:	SKIPN T1,CBLK+.NSCUS	;User id?
	 JRST TYPCB4		;no
	MOVEI T2,[ASCIZ \User ID: \]
	CALL TYPSBL
	 RET
TYPCB4:	SKIPN T1,CBLK+.NSCPW	;Password?
	 JRST TYPCB5		;no
	MOVEI T2,[ASCIZ \Password: \]
	CALL TYPSBL
	 RET
TYPCB5:	SKIPN T1,CBLK+.NSCAC	;Account?
	 JRST TYPCB6		;no
	MOVEI T2,[ASCIZ \Account: \]
	CALL TYPSBL
	 RET
TYPCB6:	SKIPN T1,CBLK+.NSCUD	;User data?
	 JRST TYPCB7
	MOVEI T2,[ASCIZ \User data: \]
	CALL TYPSBL
	 RET
TYPCB7:	RETSKP			;Finit.

RETARG:	TRNN T1,FL.R		;Is this going to be read?
	 TDZA T1,T1		;No, just return a 0
	$PROMPT T1,%OCTAL,<Argument: >
	RETSKP			;Return success

RETSBL:
	MOVEI T2,SMAX		;Get size of string block we will take
	MOVEI T3,SBLK		;Pointer to string block
	JRST INPSBL		;And input it

RETBCT:
RETBPT:
	$DIE UNF,<Unfinished code>
SAVJMP:	EXCH	F,-1(P)		;Swap things around a bit
	EXCH	F,(P)		;muddy the water a bit
	EXCH	F,-1(P)		;make things confusing
	POPJ	P,		;return to caller with stack set up

.SAV1:
	EXCH	P1,(P)		;save current value of P1, get calling PC
	PUSH	P,P1		;push calling PC
	MOVE	P1,-1(P)	;restore original value of PC
	PUSHJ	P,SAVJMP	;return to caller, with stack fixed up
	 SKP			;non skip return
	 AOS	-1(P)		;skip return, bump higher level return pc
	JRST	.RES1		;pop acs off
.SAV2:
	EXCH	P1,(P)		;save current value of P1, get calling PC
	PUSH	P,P2
	PUSH	P,P1		;push calling PC
	MOVE	P1,-2(P)	;restore original value of PC
	PUSHJ	P,SAVJMP	;return to caller, with stack fixed up
	 SKP			;non skip return
	 AOS	-2(P)		;skip return, bump higher level return pc
;	JRST	.RES2		;pop acs off

.RES2:	POP	P,P2		;  few
.RES1:	POP	P,P1		;   acs
	RET			;return to higher level routine

	END START