	.title	rnort
	.ident	/V02.00/
	.enable	gbl
	.enable	lc
;
;	This code is designed to replace the RSX/IAS/VMS system dependent
;	code required to decode the input command string for the program
;	RUNOFF.
;
;		Written by :	Gary McMillian
;				Physics Department
;				Rice University
;				P. O. Box 1892
;				Houston, Texas 77251
;
	.mcall	.close,.csigen,.exit,.print
	.mcall	.qset,.settop,.sreset,.wait
;
	.sbttl	Word Definitions
;
jsw	== 44				;Job Status Word
errbyt	== 52				;SYSCOM EMT error reporting byte
doc.ch	== 0				;LUN of 'DOC' file
rnt.ch	== 1				;LUN of 'RNT' file
rno.ch	== 3				;Starting 'RNO' file LUN
	.sbttl	Storage blocks
	.vars
limit:	.limit				;Two word block containing
					;lowest address of save image
					;first free word above image
devspc	= . - 2				;Address of memory area where
					;the device handlers are loaded
csiopt:	.blkw	1			;Number of options returned by CSI
	.even
	.sbttl	Text storage
	.const
;
;		CSI option table
;
csitab:	.word	'G,upcase		;Upper case switch
	.word	'F,formfd		;Form feed switch
	.word	'W,wait			;Wait for CR switch
	.word	'P,page			;Page range switch
	.word	'C,chaptr		;Chapter range switch
	.word	'A,appndx		;Appendix range switch
	.word	'S,pgsize		;Page size switch
	.ifdf	H$$PHN
	.word	'H,hyph			;Hyphenate control switch
	.endc
	.word	'M,warn			;Warning messages switch
	.word	'R,right		;Right shift output switch
	.word	'U,undrln		;Underline switch
	.word	'I,opttab		;RUNOFF Option Table display
	.word	'X,exit			;Exit program
	.word	'O,odd			;Odd page switch
	.word	'E,even			;Even page switch
	.ifdf	$PASS
	.word	'2,passe		;2 Pass switch
	.endc
	.word	0			;End of options flag
;
;		RUNOFF Option Table
;
	.text
	.nlist	bex
rnoopt:	.ascii	<15><12>"filspc.doc,filspc.rnt=filspc.rno[,,,,,filspc.rno]/options"<15><12>
	.ascii	<12><11>"Command String Options"<15><12><12>
	.ascii	<11>"/P:l:h"<11>"Print only pages l to h"<15><12>
	.ascii	<11>"/C:l:h"<11>"Print only chapters l to h"<15><12>
	.ascii	<11>"/A:l:h"<11>"Print only appendices l to h"<15><12>
	.ascii	<11>"/E[:N]"<11>"Print even numbered pages"<15><12>
	.ascii	<11>"/O[:N]"<11>"Print odd numbered pages"<15><12>
	.ascii	<11>"/F"<11>"Print standard ascii formfeed character"<15><12>
	.ascii	<11>"/F:n"<11>"Simulate FF with LF's (n=paper length)"<15><12>
	.ascii	<11>"/G[:N]"<11>"Force output to all uppercase"<15><12>
	.ifdf	H$$PHN
	.ascii	<11>"/H[:N]"<11>"Hyphenate output"<15><12>
	.endc
	.ascii	<11>"/M[:N]"<11>"Print warning messages"<15><12>
	.ascii	<11>"/R:n"<11>"Right shift output n spaces"<15><12>
	.ascii	<11>"/S:h:w"<11>"Set page size to height,width"<15><12>
	.ascii	<11>"/U:B"<11>"Underline with space-backspace"<15><12>
	.ascii	<11>"/U:L"<11>"Underline with line overprint"<15><12>
	.ascii	<11>"/U:S"<11>"Underline with hyphen on next line"<15><12>
	.ascii	<11>"/U:N"<11>"Underline suppressed"<15><12>
	.ascii	<11>"/W[:N]"<11>"Wait for CR between pages"<15><12>
	.ifdf	$PASS
	.ascii	<11>"/2[:N]"<11>"2 Pass mode"<15><12>
	.endc
	.asciz	<11>"/X"<11>"Exit program"
;
;		RUNOFF introduction
;
rnomsg:	.asciz	"RT-11 RUNOFF  Type /I for option information."
;
;		Table of Contents header
;
tochd:	.ascii	/.TOC/
	.EVEN
	.list	bex
	.sbttl	RUNOFF start
	.code
$start::mov	sp,spsav		;Save initial stack pointer
	.settop	#-2.			;Request all available memory
	mov	r0,xtop			;Highest available memory address
	.print	#rnomsg			;Send user a little message
	return				;Return to RUNOFF
	.sbttl	RUNOFF restart
;
;		Initialize file I/O and traceback pointers
;
restrt::clr	depth			;Set .REQUIRE nesting depth
	mov	lev,r0			;Get address of 'RNO' descriptor
	mov	#rno.ch,l.lun(r0)	;Initialize LUN of 'RNO' files
	clr	l.blk(r0)		;Initialize current block number
	mov	#rnoend+1,l.chr(r0)	;Initialize current character address
	clr	docblk+l.blk		;Initialize .DOC block number
	mov	docblk+l.beg,docblk+l.chr	;and current character address
	clr	rntblk+l.blk		;Initialize .RNT block number
	mov	rntblk+l.beg,rntblk+l.chr	;and current character address
	mov	#trcbuf+2,trcbuf	;Point trcbuf to current buffer
	clr	@trcbuf			;Initialize current line number
;
;		Command String Interpreter
;
;	First pass: PASSW bit set in $SWTCH and SW.DIS bit set in $OUTSW
;	and CSI interprets terminal input.
;	Second pass: PASSW bit set in $SWTCH and SW.DIS bit clear in $OUTSW
;	and CSI interprets command string in memory.
;
;
	.ifdf	$pass
	biteqb	#sw.dis,$outsw,1$	;If not second pass, then 1$
	.csigen	devspc,#defext,#linbuf	;Interpret command string
	mov	(sp)+,csiopt		;Pop .csigen option count off stack
	jmp	2$			;Copy Command String into line buffer
	.endc
;
1$:	clrb	$outsw			;Enable output
	.sreset				;Software reset
	.ifdf	dblbuf
	.qset	#xque,#2		;Request extra I/O queue elements
	.endc
	bic	#40000,@#jsw		;Set JSW for all uppercase
	.csigen	devspc,#defext,#0,#linbuf	;Interpret command string
	mov	(sp)+,csiopt		;Pop .csigen option count off stack
	mov	r0,xbot			;Lowest available memory address
	bis	#40000,@#jsw		;Set JSW for lower case input
;
;		Initialize Dynamic Memory Buffers
;
	clr	lnkhd			;New linked list of buffers
	call	LNKSET			;Set up new linked list of buffers
;
;		Copy Command String to Line Buffer
;
2$:	mov	#ibuf1,r3		;Point r3 to input buffer header
	call	clrbf			;clear input buffer
	mov	bf.cad(r3),r2		;Point r2 to data buffer
	add	#bflnk+1,r2		;Skip over forward/backward links
	clr	r4			;Initialize character counter
	mov	#linbuf,r0		;Point r0 to command line buffer
3$:	tsteqb	(r0),4$			;Command line terminated with NULL
	movb	(r0)+,(r2)+		;Transfer character
	inc	r4			;Increment character counter
	br	3$			;Loop until NULL encountered
4$:	movb	#CR,(r2)+		;Carriage return
	movb	#LF,(r2)		;Line feed
	add	#2,r4			;Adjust character count
	mov	r2,bf.add(r3)		;Enter current character address
	mov	r4,bf.ful(r3)		;Enter number of bytes processed
	mov	r4,bf.max(r3)		;Enter maximum number of bytes
	clr	bf.cnt(r3)		;Enter count of characters remaining
;
;		Process CSI switches
;
begin:	tst	csiopt			;Do we have any options?
	bgt	1$			;More options
	jmp	setflg			;No more options
1$:	mov	#csitab,r0		;Address of CSI option table
	mov	(sp)+,r1		;Get CSI option from stack
	dec	csiopt			;Decrement option count
loop:	mov	(r0)+,r2		;Get option from option table
	beq	error			;End of option table, no match
	cmpneb	r1,r2,2$		;Valid option?
	jmp	@(r0)			;Process option
2$:	tst	(r0)+			;Point r0 to address of next option
	br	loop			;Repeat until match or error
error:	mov	#15.,r0			;Command String Syntax error
	jmp	ILINP			;Output error message
;
;		Case Conversion
;
upcase:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bis	#upcsw,$swtch		;Set uppercase flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bic	#upcsw,$swtch		;Clear upper case flag in switch word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character
;
;		Form Feed
;
formfd:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bis	#ffdsw,$swtch		;Enable form feeds
	br	2$			;Process next option
1$:	bic	#ffdsw,$swtch		;Disable form feeds
	mov	(sp)+,lppg		;Get paper length
2$:	jmp	begin			;Process next option
;
;		Page Wait
;
wait:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bis	#pausw,$swtch		;Set page wait flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bic	#pausw,$swtch		;Clear page wait flag in swich word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character
;
;		Page Range
;
page:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
2$:	jmp	error			;Should be an option value
1$:	mov	(sp)+,hghpag		;Save highest page to print
	mov	(sp)+,r1		;Look for page character again
	dec	csiopt			;Decrement option count
	cmpneb	#'P,r1,2$		;Test for page character
	mov	(sp)+,lowpag		;Save lowest page to print
	jmp	begin			;Process next option
;
;		Chapter Range
;
chaptr:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
2$:	jmp	error			;Should be an option value
1$:	mov	(sp)+,hghchp		;Save highest chapter to print
	mov	(sp)+,r1		;Look for chapter character again
	dec	csiopt			;Decrement option count
	cmpneb	#'C,r1,2$		;Test for chapter character
	mov	(sp)+,lowchp		;Save lowest chapter to print
	jmp	begin			;Process next option
;
;		Appendix Range
;
appndx:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
2$:	jmp	error			;Should be an option value
1$:	mov	(sp)+,hghapn		;Save highest appendix to print
	mov	(sp)+,r1		;Look for appendix character again
	dec	csiopt			;Decrement option count
	cmpneb	#'A,r1,2$		;Test for appendix character
	mov	(sp)+,lowapn		;Save lowest appendix to print
	jmp	begin			;Process next option
;
;		Page Size
;
pgsize:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
2$:	jmp	error			;Should be an option value
1$:	mov	(sp)+,prmrg		;Save page width
	mov	(sp)+,r1		;Look for size character again
	dec	csiopt			;Decrement option count
	cmpneb	#'S,r1,2$		;Test for size character
	mov	(sp)+,pnlpg		;Save page height
	jmp	begin			;Process next option
;
;		Hyphenate
;
	.ifdf	H$$PHN
hyph:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bis	#hypsw,$swtch		;Set hyphenation flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bic	#hypsw,$swtch		;Clear hyphenation flag in switch word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character
	.endc
;
;		Even pages
;
even:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bic	#evesw,$swtch		;Clear even flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bis	#evesw,$swtch		;Set even flag in switch word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character
;
;		Odd pages
;
odd:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bic	#oddsw,$swtch		;Clear odd flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bis	#oddsw,$swtch		;Set odd flag in switch word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character

;
;		Right Shift
;
right:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	jmp	error			;Should be an option value
1$:	mov	(sp)+,rigshi		;Get right shift option value
	jmp	begin			;Process next option
;
;		Underline Mode
;
undrln:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	jmp	error			;Should be an option value
1$:	mov	(sp)+,ulswt		;Get underline option value
	jmp	begin			;Process next option
;
;		2 Pass Mode
;
	.ifdf	$PASS
passe:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bis	#passw,$swtch		;Set two pass flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bic	#passw,$swtch		;Clear two pass flag in switch word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character
	.endc
;
;		Warning Messages
;
warn:	tst	r1			;Is there an option value?
	bmi	1$			;Yes.
	bic	#warsw,$swtch		;Clear warning flag in switch word
	br	2$			;Process next option
1$:	cmpneb	#^RN,(sp)+,3$		;Test for N character
	bis	#warsw,$swtch		;Set warning flag in switch word
2$:	jmp	begin			;Process next option
3$:	jmp	error			;Incorrect switch character
;
;		Option Table Display
;
opttab:	tst	r1			;Is there an option value?
	bpl	1$			;No.
	jmp	error			;Should be no option value
1$:	.print	#rnoopt			;Print RUNOFF option table
	jmp	RUNOFF			;Restart program
;
;		Exit program
;
exit:	.exit				;Exit RUNOFF
;
;		Finish Processing Options
;
setflg:	clr	r1			;Set to clear case shift
	biteq	#upcsw,$swtch,1$	;Shift to uppercase?
	mov	#401,r1			;Yes.
1$:	mov	r1,case			;Set case control flags
	mov	prmrg,rmarg		;Set right margin
	CLC				;Clear carry
	ASL	LPPG			;Convert to half lines
	ASL	PNLPG			;Convert to half lines
	mov	pnlpg,nlpg		;Set page length
	movb	#'_,$ulch		;Set underline char as underscore
	cmpne	#^RB,ulswt,2$		;Not backspace mode?
	clrb	$ulmsw			;Set backspace switch
	br	5$			;Go to next switch
2$:	cmpne	#^RS,ulswt,3$		;Not simulate mode?
	incb	$ulmsw			;Set simulate switch
	movb	#'-,$ulch		;Set underline char as hyphen
	br	5$			;Go to next switch
3$:	cmpne	#^RL,ulswt,4$		;Overprint mode?
	comb	$ulmsw			;Set overprint switch
	br	5$			;Go to next switch
4$:	cmpne	#^RN,ulswt,5$		;Disable underlining?
	comb	$unlsw			;Set no underline switch
5$:	.ifdf	H$$PHN
	bitne	#hypsw,$swtch,6$	;Hyphenation flag set?
	.endc
	movb	#-1,$hypsw		;No. Set it permanently off
	.ifdf	$pass
6$:	biteq	#passw,$swtch,files	;If not 2 pass mode, then files
	movb	$outsw,r2		;Get current output control switch
	com	r2			;Reverse output control switch
	bic	#^C<sw.dis>,r2		;Clear all except disable bit
	movb	r2,$outsw		;Save new output control switch
	.iff
6$:
	.endc
;
;		Determine if .DOC, .RNT, and .RNO files opened
;
files:	.wait	#rno.ch			;Determine if RNO channel open
	bcc	1$			;File opened
	mov	#18.,r0			;Input file specification error
	jmp	ILINP			;Send error message to user
1$:	.wait	#doc.ch			;Determine if DOC channel open
	bcc	2$			;File opened
	mov	#16.,r0			;Output file specification error
	jmp	ILINP			;Send error message to user
2$:	.wait	#rnt.ch			;Determine if RNT channel open
	bcs	3$			;No Table of Contents
	clrb	$tocsw			;Set TOC enable
	mov	#tochd,r1		;Output TOC header
	mov	#4.,r2			;Number of characters output
	call	OUTTOC			;Write characters to .RNT
3$:	jmp	LGO			;Enter main RUNOFF loop
	.end
