













        Weird Tricks with the RSX Indirect Command Processor







                            - RX015 -





				    T. R. Wyant
				    E. I. DuPont de Nemours

				    A. E. Levan
				    System Research Laboratories

				    December 10, 1990

                          Housekeeping
                             Outline






		Housekeeping



		Command Procedure Libraries



		Structured Data Types



		Binary File I/O



		Screen Handling



		Error Control



		Parsing an MCR- or DCL-like syntax



		Multiple Precision Arithmetic



		Bibliography

                          Housekeeping





(1.1)                         Goal


The goal of this presentation is to exhibit some of the more
advanced, exotic, and otherwise weird things that can be done
with the RSX Indirect Command Processor (ICP), and to stimulate
more ideas in the same vein. This presentation is aimed at an
audience that is familiar with the RSX ICP, though attendance of
"Introduction to the RSX, P/OS, and RT Indirect Command File
Processor" (RX009) should give sufficient background. 


These slides and all command files cited as examples will be 
distributed on the FALL, 1990 RSX/IAS SIG tape.






(1.2)                        Caveats


The current releases of all the operating systems are assumed.


The examples cited all work under RSX-11M+ V3.0 C.


I am not the final authority on the ICP in all its multifarious 
versions. Errors in research and transcription do occur. I 
apologize in advance for these, but assume no responsibility for
their consequences.




(1.3)                    Acknowledgment



Allen A. Watson's paper, "Nifty Things to Do with RSX Indirect
Command Files", presented at the Spring, 1983 DECUS US
Symposium, was both an inspiration and a reference for this
paper. 

(2.0)              Command Procedure Libraries





A command procedure made up of many modules can be kept in a
	universal library.




To create the library:

		LBR library.CLB/CR::::UNI:CMD




To execute a module

		@library/LB:module




To execute module .MAIN.:

		@library/LB
	- or -	@library.CLB




To call another module on the same library as the caller:

		@/LB:module




You can store things other than command procedures in a command
	procedure library.




Readily available examples:

		LB:[1,2]INDSYS.CLB
		LB:[200,200]SYSGEN.CLB
		LB:[137,10]NETGEN.CLB

                       Structured Data Types
(3.1)           Using a String Symbol as an Array







Small arrays can be stored in a String Symbol and extracted 
	by forming a substring.






All elements in the array must be the same size.





The total size of all elements in the array must not exceed the
	maximum size of a String Symbol. 





The start and end of each element in the string must be manually
	calculated from the INDEX of the desired element and the
	SIZE of the elements, as follows:

		.SETN START (INDEX-1)*SIZE+1
		.SETN END START+SIZE-1





This works best with arrays where the element is one byte long,
	as the index can be used directly as both the start and
	the end of the substring. 

                     Structured Data Types
          Using a String Symbol as an Array (continued)
(3.1.1)             Example (from PRN.CMD)







PRN.CMD is a utility designed to print a file on an LA-series
	printer connected to the printer port of a VT100- or
	VT200-series terminal. 






The user selects the desired horizontal pitch, which is stored 
	in Numeric Symbol N$HPIT






The mapping of horizontal pitch to escape sequence argument is 
	stored in String Symbol S$PCHR:

		.SETS S$PCHR "5555568800224444"






The escape sequence is built by:

	.SETS S$HDR ESCAPE+"["+S$PCHR[N$HPIT:N$HPIT]+"w"

                     Structured Data Types
(3.2)      Using a String Symbol as an Attribute List







A String Symbol can be used to store a list of attributes to be
	associated with the name of the string symbol, or a
	portion thereof.





The attributes are listed in the string symbol's value,
	punctuated by a unique character. 





Attributes may be subdivided by using another unique character. 





Attributes can be checked using the 2-argument .TEST directive.
	It may help to start the list with a punctuating 
	character if you intend to do this.




Attributes can be extracted using the .PARSE directive.

                     Structured Data Types
     Using a String Symbol as an Attribute List (continued)
(3.2.1)             Example (from PRN.CMD)


PRN.CMD is a utility designed to print a file on an LA-series
	printer connected to the printer port of a VT100- or
	VT200-series terminal.

The arrow keys and the previous and next screen keys perform
	different functions, but all operate by incrementing or 
	decrementing a Numeric Symbol and clamping the result to
	a limit. The particulars are defined as follows:


    .; Define parameters used in processing the arrow keys:
    .; These are defined by:
    .;	.SETS ARROWx "axis,fac,sign,limit,test"
    .;   where:
    .;	x	= last character of escape sequence;
    .;	axis	= name of symbol to update;
    .;	fac	= factor to apply if PF1 in effect;
    .;	sign	= direction of travel along axis;
    .;	limit	= limiting value on the axis;
    .;	test	= type of test to make against limit.

    .SETS ARROWA "N$FLD,8,-,0.,<"	! <CSI>A = Up arrow.
    .SETS ARROWB "N$FLD,8,+,N$FMAX,>"	! <CSI>B = Down arrow.
    .SETS ARROWC "N$CVAL,10,+,N$CMAX,>"	! <CSI>C = Right arrow.
    .SETS ARROWD "N$CVAL,10,-,N$CMIN,<"	! <CSI>D = Left arrow.
    .SETS ARROW5 "N$SCR,8,-,0.,<"	! Fake for "Prev Screen"
    .SETS ARROW6 "N$SCR,8,+,N$SMAX,>"	! Fake for "Next Screen"


These are executed by:

    .PARSE ARROW'CHAR' "," AXIS FAC SIGN LIMIT TEST
    .IF ESCA0 = 0	.SETN ESCA0 1.	! Force param.
    .IFT GOLD .SETN ESCA0 ESCA0*'FAC'.	! Apply PF1.
    .SETN 'AXIS' 'AXIS''SIGN'ESCA0	! Set new loc.
    .IF 'AXIS' 'TEST' 'LIMIT'	.SETN 'AXIS' 'LIMIT'
    .SETF GOLD				! Clear shift key.
    .GOTO ESCPSR			! Get next character.

                     Structured Data Types
(3.3)         Using Groups of Symbols as an Array





An array of arbitrary size can be constructed by using a group
	of symbols with similar names. 



A symbol is defined for each accessible element in the array.
	These need not be the same type. 



Only those elements that are actually used need be defined.
	Arrays can be sparsely populated, or have ragged rows. 



The names of the individual symbols consist of a constant part
	(which can be thought of as the name of the array) and a
	variable part (which can be thought of as the index into
	the array). 



Array elements are referred to by using symbol substitution to
	construct the element's symbol name out of the array
	name and the element index(es). 



Substitution can not be done on an arbitrary array element. 



The method chosen for encoding the index(es) in the array
	element's symbol name must give rise to legal and unique
	symbol names for each element in the array. 



Use of %RnZ format control can be helpful when using Numeric
	Symbols as array indices.

                     Structured Data Types
         Using Groups of Symbols as an Array (continued)
(3.3.1)             Example (from UPS.CMD)








UPS.CMD is a command procedure to automate the transmission of a
	number of files over DECmail-11.





The names of the files are originally stored in String Symbol
	S$FILE, so the .TESTFILE directive can be used to check 
	for existence.





The number of files entered is counted in Numeric Symbol N$FILE.





The file name is stored in element N$FILE of array S$FL by:

	.SETS S$FL'N$FILE%DR2Z' S$FILE





When required, the file name is extracted from the array by:

	.SETS S$FILE S$FL'N$FILE%DR2Z'

                     Structured Data Types
(3.4)              Content-addressable Memory









In this scheme, the entire symbol name is chosen to reflect the 
	content of the symbol. For example, information about a 
	DECnet node can be stored in a symbol named after that 
	node.






In effect, this is using the entire symbol table as an array.






The string symbol that contains the symbol name to be looked up
	had better be validated first to be sure it contains a
	legal symbol name. 






You must check for existence of the symbol before you use it, as
	a random symbol name is probably NOT defined in the
	symbol table. 

                     Structured Data Types
             Content-addressable Memory (continued)
(3.4.1)           Example (from CRASHDUMP.CMD)




CRASHDUMP.CMD is a crash dump analyzer preprocessor, that
	generates a CDA run appropriate to the system being
	analyzed, based on the system name.


.; The supported systems must be defined via:
.;	.SETS sysnam "cdanal;memsiz;crdev;blk;stbnam;hlptxt"
.;   Where:
.;	sysnam	is the name of the system to which the 
.;			information pertains;
.;	cdanal	is the name of the crash dump analyzer task
.;			file - the defaults are:
.;				device ---- LB:
.;				directory - <LIBUIC>
.;				name ------ CDA
.;				type ------ .TSK
.;	memsiz	is the memory size for the system;
.;	crdev	is a list of legal crash devices (separated by
.;			commas);
.;	blk	is the block on which the crash dump starts;
.;	stbnam	is the STB file name - the defaults are:
.;				device ---- LB:
.;				directory - <SYSUIC>
.;				name ------ RSX11M
.;				type ------ .STB
.;	hlptxt	is identifying text for the system.
.;

.SETS FENNY "CDAFSL;256;DR;2;;PDP 11/84"
.SETS MARVIN "CDA41;28;DX,DY;1;[1,64];PDP 11/03"
.SETS ZAPHOD "CDAFSL;512;DR;2;;PDP 11/74"

.;
.;	Get the system being dumped.
.;

.SYSASK:
	;
	.DISABLE LOWERCASE
	.ASKS [0:6:<NETNOD>] S$SYS What system is crashdump for
	.ENABLE LOWERCASE
	.IFT <ESCAPE>	.GOTO SYSHLP
	.IFF <ALPHAN>	.GOTO SYSERR
	.TEST S$NOGO ",'S$SYS',"
	.IF <STRLEN> > 0	.GOTO SYSERR
	.IFDF 'S$SYS'	.GOTO SYSOK

                      Structured Data Types
(3.5)            Searching a (Very) Sparse Array






It may be faster to iterate over the entire symbol table than
	over the elements of a very sparse array. 



Each time the Special String Symbol <NXTSYM> is referred to, it
	returns the name of the next symbol in the Symbol Table.



To initialize the iteration, you must:

			.SETS <NXTSYM> ""



You must refer to <NXTSYM> only once in each iteration, or you
	will skip symbols. A useful way to do this is: 

			.SETS SYMNAM <NXTSYM>



I recommend against defining any new symbols inside the
	iteration loop. 



The documentation of <NXTSYM> contains warnings about its
	availability for general use. My experience is that you
	might have to fiddle a bit to get it to work. 



For an example of <NXTSYM> in action, see:

			LB:[1,2]INDSYS/LB:SYMDMP

                     Structured Data Types
           Searching a (Very) Sparse Array (continued)
(3.5.1)           Example (from CRASHDUMP.CMD)






CRASHDUMP.CMD is a crash dump analyzer preprocessor, that
	generates a CDA run appropriate to the system being
	analyzed, based on the system name.



	; Valid system names are:
	.SETS <NXTSYM> ""

.; Now, loop through the Symbol Table:

.SYSHLL:

	.; Get the next Symbol name; if none, we are done:

	.SETS S$SYS <NXTSYM>
	.IF S$SYS = ""	.GOTO SYSASK

	.; If it is not alphanumeric, we do not want it:

	.TEST S$SYS
	.IFF <ALPHAN>	.GOTO SYSHLL

	.; If it is not a String Symbol, we do not want it:

	.TEST 'S$SYS'
	.IF <SYMTYP> <> 4	.GOTO SYSHLL

	.; If it is COMMAN or P0-P9, we do not want it:

	.TEST S$NOGO ",'S$SYS',"
	.IF <STRLEN> > 0	.GOTO SYSHLL

	.; It it a legal system name; pick it apart and display
	.; the identifying text;

	.PARSE 'S$SYS' ";" S$CDA S$MEM S$CDL S$CBK S$STB S$HELP
	;         'S$SYS%L6' - 'S$HELP'

	.; Go get the next Symbol:

	.GOTO SYSHLL

(4.0)                    Binary File I/O








I/O on files containing binary data can be done with the ICP, by
	converting the bytes to numeric values, and then
	assembling the byte values in ways appropriate to the
	field in which they occur. 





Any sequential file can be opened for read or append access. 





Files opened for output will have variable length records, with
	"list" carriage control. 





Use substitution with %V format control to convert bytes to
	their numeric values. 





If you wish to write a file with "unusual" attributes (fixed
	length records, no spanned blocks, etc.) you can invoke
	RMSDES to create an empty file, with the desired
	attributes, and then open it for append access. 

                         Binary File I/O
(4.1)               Example (from SYMDMP.CMD)







SYMDMP.CMD is a command file that reads a .OBJ or .STB file, and
	displays the symbols it finds there. 





Example of extracting a binary byte (from byte 5 of the record)
	and storing its value in Numeric Symbol O$FLG: 

	.SETS S$B0 S$REC[5:5]
	.SETN O$FLG 'S$B0%V'&377




Example of extracting a binary word (found in bytes 1 and 2 of
	the record) and storing its value in Numeric Symbol O$W:

	.SETS S$B0 S$REC[1:1]
	.SETS S$B1 S$REC[2:2]
	.SETN O$W ('S$B1%V'&377)*400+('S$B0%V'&377)




Example of extracting 6 characters (stored in RAD-50 in bytes 1
	through 4 of the record) and storing them in String
	Symbol S$SYM: 

	.SETS S$B0 S$REC[1:1]
	.SETS S$B1 S$REC[2:2]
	.SETN O$W ('S$B1%V'&377)*400+('S$B0%V'&377)
	.SETS S$SYM "'O$W%X'"
	.SETS S$B0 S$REC[3:3]
	.SETS S$B1 S$REC[4:4]
	.SETN O$W ('S$B1%V'&377)*400+('S$B0%V'&377)
	.SETS S$SYM "'S$SYM''O$W%X'"

                         Screen Handling
(5.1)               Screen Handling With FMS









The RSX-11M+ ICP comes with an interface to FMS-11.






Forms must be designed and inserted in a form library, just as
	for any FMS application. 






The .FORM directive is used to display forms and gather input. 







You can use .IFENABLED FMS to determine if FMS support is
	available. 






You can get a demonstration of the FMS capability of the ICP by:

	@LB:[1,2]INDSYS.CLB/LB:FMSDEM

                         Screen Handling
(5.2)              Screen Handling Without FMS






If you don't own RSX-11M+ and FMS-11, you can write your own
	screen handler for the ICP.



The ICP must do all input through the .ASKS directive.



The terminal must be conditioned so that escape sequences
	generated by the function keys are passed at the end of
	an input string:

		MCR>SET /ESCSEQ=TI:



The ICP must be conditioned so that escape sequences generated
	by the function keys are accepted at the end of an input
	string: 

		.ENABLE ESCAPE-SEQUENCE



The prompt sequence of the .ASKS is used to position the cursor
	for input. Unwanted characters are supressed by:

		.DISABLE DISPLAY



The ICP must parse the function key escape sequence off the end
	of the .ASKS input string, and interpret it. 

                         Screen Handling
(5.2)        Screen Handling Without FMS (continued)







You should enable use of the type-ahead buffer:

		.DISABLE DETACH



Literal escape sequences should not be embedded in the command
	file. 



Constant escape sequences (eg: home cursor, clear screen, setup
	sequences) should be assigned to appropriately named
	string symbols on initialization. 



Variable escape sequences (eg: cursor postioning) should be
	generated in .GOSUB modules.



Input should also be done in a .GOSUB module, so that the escape
	sequence can be easily parsed off the rest of the input.



Avoid leaving the cursor on the last line of the screen. If you
	must, repaint the screen after the inevitable scroll-up.



You can SET /NOECHO=TI:, and have the ICP take care of
	displaying the characters on the screen. 

                         Screen Handling
             Screen Handling Without FMS (continued)
(5.2.1)              Example (from PRN.CMD)



PRN.CMD is a utility designed to print a file on an LA-series
	printer connected to the printer port of a VT100- or
	VT200-series terminal.


.; Required ICP initialization:

	.ENABLE SUBSTITUTION
	.DISABLE DISPLAY
	.DISABLE DETACH
	.ENABLE CONTROL-Z
	.ENABLE ESCAPE-SEQUENCE
	.ENABLE OVERFLOW


.; Required TT: driver initialization

	.ENABLE QUIET
	'MCR'SET /FORMFEED=TI:
	'MCR'SET /LOWER=TI:
	'MCR'SET /ESCSEQ=TI:
	'MCR'SET /BUF=TI:132.
	.DISABLE QUIET


.; Useful symbol definitions (for ASCII terminals):

	.SETN NJUNK 33			! Define ESCAPE to be
	.SETS ESCAPE "'NJUNK%V'"	!    an <ESC> character
	.SETN NJUNK 217			! Define SS3 to be an
	.SETS SS3 "'NJUNK%V'"		!    <SS3> (="<ESC>O")
	.SETN NJUNK 233			! Define CSI to be a
	.SETS CSI "'NJUNK%V'"		!    <CSI> (="<ESC>[")


.; Useful symbol definitions (for ANSI terminals):

	.SETS HOME ESCAPE+"[H"		! HOME homes cursor
	.SETS CLEAR ESCAPE+"[J"		! CLEAR clears screen
	.SETS CLRLIN ESCAPE+"[K"	! Clear line.
	.SETS BOLD ESCAPE+"[1m"		! Bold video.
	.SETS REV ESCAPE+"[7m"		! Reverse video
	.SETS NML ESCAPE+"[m"		! Normal screen attrib.
	.SETS BOTTOM ESCAPE+"[24;1H"

.; The following initializes a DEC VT100 or VT200 series
.;	terminal by homing and clearing the screen, loading the
.;	normal ASCII character set into G0 and the graphics
.;	character set into G1, and selecting G0. 

	.SETS INIT HOME+CLEAR+ESCAPE+"(B"+ESCAPE+")0"+SI+NML

                         Screen Handling
             Screen Handling Without FMS (continued)
(5.2.1)       Example (from SCRED.CMD) (continued)



And, some useful subroutines:

	.;
	.;	.GOSUB ASKE size;line;column\fldtxt
	.;
	.; Positions the cursor at the given line and column,
	.; displays "fldtxt" in a reverse video field,
	.; and issues a .ASKS. On return,
	.;	TEXT contains the text part of the answer;
	.;	ESCSEQ contains the escape sequence;
	.;	<STRLEN> contains the location of the escape
	.;	    character.
	.;
.ASKE:
	.PARSE COMMAN ";" FLDSIZ COMMAN
	.PARSE COMMAN "\" COMMAN FLDTXT
	.GOSUB POSITN 'COMMAN%C'
	.TEST FLDTXT
	.SETS FLDTMP FLDTXT+BLANKS[<STRLEN>+1:'FLDSIZ'.]
	.SETS ESCSEQ ""
	.INC N$FLD

	.DISABLE LOWERCASE
	.ASKS [::FLDTXT] TEXT 'COMMAN''REV''FLDTMP''COMMAN'
	.ENABLE LOWERCASE

	.SETS S$ERR ""
	.SETS S$GOTO "DISPAT"
	.IFT <EOF>	.RETURN
	.TEST TEXT ESCAPE
	.IF <STRLEN> = 0	.TEST TEXT CSI
	.IF <STRLEN> = 0	.TEST TEXT SS3
	.IF <STRLEN> <> 0	.SETS ESCSEQ TEXT[<STRLEN>:*]
	.IF <STRLEN> <> 0	.SETS TEXT TEXT[1:<STRLEN>-1]
	.IF TEXT = ""	.SETS TEXT FLDTXT

	.TEST TEXT
	.SETS FLDTMP TEXT+BLANKS[<STRLEN>+1:'FLDSIZ'.]
	;'COMMAN''REV''FLDTMP''BOTTOM''NML''CLRLIN''HOME'
	.RETURN

	.;
	.;	.GOSUB POSITN line;column
	.;
	.; returns the escape sequence in COMMAN.
	.;
	.; The following is suitable for an ANSI terminal.
	.;
.POSITN:
	.SETS COMMAN ESCAPE+"["+"'COMMAN%C'"+"H"
	.RETURN

                         Screen Handling
             Screen Handling Without FMS (continued)
(5.2.1)       Example (from SCRED.CMD) (continued)



.; Initialize the escape sequence parser:

.ESCPSI:
	.SETS ESCTYP "INI"	! Set parser "state".
	.SETN ESCAMX 0.		! Set number of arguments.
	.SETN ESCA0 0.		! Clear the first argument.

.; Main parser loop:

	.; Strip off the next character (if any), convert it to 
	.; a number, and do a "computed" GO TO based on current 
	.; parser state and character code:

.ESCPSR:
	.IF ESCSEQ = ""	.GOTO 'S$GOTO'	! If done, get more.
	.SETS CHAR ESCSEQ[1:1]		! Get first character,
	.SETS ESCSEQ ESCSEQ[2:*]	!  remove from buffer.
	.SETN CVALUE 'CHAR%V'		! Get its value.
	.ONERR ESCPSE			! Trap unexpected chars.
	.GOTO 'ESCTYP''CVALUE'		! Handle this character.

			.
			.
			.

	.; First character = <ESC>; set state:

.INI33:	.SETS ESCTYP "ESC"		! Go to escape "state".
	.GOTO ESCPSR			! Get next character.

	.; First character is <SS3>, or

.INI217:.;

	.; First was <ESC> and second is "O"; set state:

.ESC117:.SETS ESCTYP "SS3"		! Go to SS3 "state".
	.GOTO ESCPSR			! Get next character.


	.; Got <SS3>P = PF1 - use it as shift key:

.SS3120:.SETN N$FLD N$OFLD
	.SETT GOLD			! Set shift flag.
	.GOTO ESCPSI			! Get next escape seq.

(6.0)                     Error Control






It can be useful to perform an operation even though it may
	produce an error in the ICP. 



The ICP can be set to dispatch errors to the label of your
	choice for handling, using:

		.ONERR label



The .ONERR directive must be reasserted after each error
	trapped. 



Errors are divided into numbered classes, as described in the
	ICP documentation. You can set bits in Special Numeric
	Symbol <ERRCTL> to determine which classes are trapped. 



On entry to your error handler, Special Numeric Symbol <ERRNUM>
	contains the Error Class Number of the error
	encountered. 



The Error Classes are pretty broad (there are only two). If you
	are expecting more than one source of error, you will
	need to build your own logic to distinguish between
	them.



The manual says you should not resume processing after trapping
	a Class 2 Error. I have found that it works in some
	cases, but recommend trying each case out before you
	build an application around it. 

                          Error Control
(6.1)                Example (from PRN.CMD)







PRN.CMD is a utility designed to print a file on an LA-series
	printer connected to the printer port of a VT100- or
	VT200-series terminal.






.; Main parser loop:

	.; Strip off the next character (if any), convert it to 
	.; a number, and do a "computed" GO TO based on current 
	.; parser state and character code:

.ESCPSR:
	.IF ESCSEQ = ""	.GOTO 'S$GOTO'	! If done, get more.
	.SETS CHAR ESCSEQ[1:1]		! Get first character,
	.SETS ESCSEQ ESCSEQ[2:*]	!  remove from buffer.
	.SETN CVALUE 'CHAR%V'		! Get its value.
	.ONERR ESCPSE			! Trap unexpected chars.
	.GOTO 'ESCTYP''CVALUE'		! Handle this character.

	.; Any unrecognised characters end up here.

.ESCPSE:.SETN N$FLD N$OFLD		! Error. Recover field,
	.SETF GOLD			! Turn off gold key,
	.GOTO 'S$GOTO'			! Go do whatever.

(7.0)          Parsing an MCR- or DCL-like Syntax




Command Files can be invoked in much the same way as a CLI
	command.



The parameters passed are available to the Command File in
	string symbols  P0-P9. 



Parsing these parameters normally takes place in two phases: 

	Parsing the file specification(s);

	Parsing the switches and options.



You need to design a command syntax that is both clear and
	easily parsed. Either MCR or DCL can serve as a model. 



You get a "nicer" parser if you can process all the file
	specifications in one loop, with an inner loop for the
	switches. 



You should specifically check for a null command line, and get
	the information you need through .ASKx directives. 



If the syntax for switches is properly defined, your switch
	parser code will be completely generic. This is done by:

	Defining a consistent symbol name convention for storing
		switch settings;

	Defining a consistent and restricted argument syntax.

               Parsing an MCR- or DCL-like Syntax
(7.1)               Example (from SYMDMP.CMD)






.; PHASE 1 - Parsing the file specification(s):



.; Define and initialize the command switches:

	.SETF V$SP	! Define /SP (spool) and assume false.
	.SETT V$BR	! Define /BR (page break), assume true.



.; Determine processing mode (interactive or command line):

	.IF P1 = ""	.GOTO PROMPT



.; Get the file specs, from either MCR or DCL syntax:

	.IF P2 <> ""	.GOTO SWIEXT
	.PARSE P1 "=" S$OUT S$FIL
	.IF S$FIL <> ""	.GOTO SWIEXT
	.SETS S$FIL S$OUT
	.SETS S$OUT ""



.; Peel the switches off the file specifications:

.SWIEXT:.PARSE S$FIL "/" S$FIL S$SWIT
	.PARSE S$OUT "/" S$OUT S$JUNK
	.SETS S$SWIT "/"+S$SWIT+"/"+S$JUNK

               Parsing an MCR- or DCL-like Syntax
(7.1)         Example (from SYMDMP.CMD) (continued)


.; PHASE 2 - Parsing the switches and options:

.SWITLP:
	.IF S$SWIT = ""	.GOTO PROCES

.; Peel the next switch off, and get its arguments:

	.PARSE S$SWIT "/" S$SWX S$SWIT
	.PARSE S$SWX ":" S$SWX S$SWP

.; Figure out whether it is asserted or negated:

	.SETT L$ASRT
	.IF S$SWX = ""	.GOTO SWITLP
	.IF S$DASH = S$SWX[1:1]	.GOTO SWITNM
	.IF S$NO <> S$SWX[1:2]	.GOTO SWITAS
	.SETS S$SWX S$SWX[2:*]
.SWITNM:.SETS S$SWX S$SWX[2:*]
	.SETF L$ASRT
.SWITAS:.SETS S$SWX S$SWX[1:2]

.; See if this switch has a corresponding V$sw symbol:

	.TEST S$SWX
	.IFF <ALPHAN>		.GOTO SWIBAD
	.IFNDF V$'S$SWX'	.GOTO SWIBAD

.; Dispatch the rest based on the symbol type:

	.TEST V$'S$SWX'
	.GOTO SWIT'<SYMTYP>'

.; Logical symbol. Set its value to switch polarity:

.SWIT0:	.IF S$SWP <> ""	.GOTO SWINPR
	.SETL V$'S$SWX' L$ASRT
	.GOTO SWITLP

.; Numeric symbol. Set its value to switch parameter:

.SWIT2:	.IFF L$ASRT	.GOTO SWINNG
	.TEST S$SWP
	.IFF <NUMBER>	.GOTO SWIIVP
	.SETN V$'S$SWX' 'S$SWP'
	.GOTO SWITLP

.; String symbol. Set its value to switch parameter:

.SWIT4:	.IFF L$ASRT	.GOTO SWINNG
	.SETS V$'S$SWX' S$SWP
	.GOTO SWITLP

(8.0)            Multiple Precision Arithmetic










Access to the carry bit is necessary (and sufficient) for most
	multiple-precision algorithms.






If multiple-precision numbers are stored eight  bits at a time
	in a Numeric Symbol array, the ninth bit can be used as
	the carry bit.






If only eight bits of a numeric symbol are used, the standard 
	precision of the ICP is sufficient for multiplication.






Isolation of 8-bit results and the carry bit from each other (or
	of the low byte from the high byte in multiplication) is
	done using the bitwise AND function. 

                 Multiple Precision Arithmetic
(8.1)                Example (from BRU.CMD)



BRU.CMD is a BRU preprocessor that generates mounts, dismounts, 
	and BRU command lines based on user input and the
	current state of the system. 


It was desired to reproduce the same algorithm INI uses for
	calculating the initial and maximum index file size for
	a volume. This is a multiple precision algorithm.


A portion of the addition routine is presented here to
	demonstrate the handling of eight bit results. The
	addends are stored in arrays OT$A and OT$B (elements 0
	through 3), and the sum is formed in array OT$C
	(elements 0 through 3):


	.; Add the corresponding bytes of the two addends,
	.; with carry.

	.SETN OT$C0 OT$A0+OT$B0
	.SETN OT$C1 OT$A1+OT$B1+(OT$C0/400&377)
	.SETN OT$C2 OT$A2+OT$B2+(OT$C1/400&377)
	.SETN OT$C3 OT$A3+OT$B3+(OT$C2/400&377)

	.; Strip out the carry bits.

	.SETN OT$C0 OT$C0&377
	.SETN OT$C1 OT$C1&377
	.SETN OT$C2 OT$C2&377
	.SETN OT$C3 OT$C3&377


Subtraction is implemented similarly, but a "borrow" is assumed 
	for all partial results (to avoid blowing up with
	OVERFLOW disabled), and stripped at the end.


Multiplication is done by forming all useful cross-products, one
	at a time, and adding each to a running sum, shifted by
	the proper number of array elements.


Division is done by the shift-and-subtract method, and is the
	only algorithm that requires iteration.

                          Bibliography



"Nifty Things to Do with RSX Indirect Command Files"
	Allen A. Watson
	RSX/IAS SIG Symposium Handout
	Spring 1983 DECUS US Symposium


LA50 Printer Programmer Reference Manual
	Documents printer escape sequences.


RSX LB:[1,2]ICP.HLP
	On-line help file for ICP. Contains some information 
	that is not in the manual.


RSX LB:[1,2]INDSYS.CLB
	Sample command routines.


RSX-11M/M-Plus Task Builder Manual
	Documents object file layout.


RSX-11M/M-Plus Indirect Command Processor Manual
	The primary reference for the ICP under RSX.


RSX-11 Utilities Manual
	Reference for the librarian task (LBR).


VT220 Programmer Pocket Guide
	Documents escape sequences for VT2xx terminals.
