File: RTESA.PG of Tape: Sources/Other/new-18
(Source file text) 

	NOLIST
	PAGE	57		UPDATE PAGE DEPTH TO 75 LINES
SWIT2	QUT	1,O'7644'	DECODER SWITCHES (M-X)
SWIT3	QUT	1,07645		SWITCHES (YZ, 0-9)
ZZDATE	QUT	1,O'7666'	OS-8 SYSTEM DATE WORD
	AIF	(&SWIT3.AN.2).EQ.0,.NO8LPI
	UNLINK	EJECT		KILL THE EJECT OPERATION CODE
	MACRO			AND REDEFINE IT AS AN ASSEMBLY NOOP
	EJECT
	ANOP
	MSKIP
	MEND
.NO8LPI	AIF	&ZZDATE,.ENTERED	CHECK TO SEE IF DATE WAS ENTERED
	ERROR:	TODAY'S DATE NOT ENTERED TO OS-8
	MONR	WE SHOULD ALWAYS HAVE DATE ON ASSEMBLY LISTINGS
.ENTERED AIF	(&SWIT2.AN.010).EQ.0,.NOLISTC
	LISTC			SWITCH 'U' SET - LIST ALL
	LIST			ALSO-LIST THE MACRO DEFINITIONS TOO
.NOLISTC ANOP
	LIST	<RTES>
	FILE	R T E S A  -- Documentation Program V-6a
	TITLE	Introduction
/
/
/
/
/	**************************************************
/	**						**
/	**	R T E S   D O C U M E N T A T I O N	**
/	**						**
/	**	         P R O G R A M			**
/	**						**
/	**		     V-6a			**
/	**						**
/	**************************************************
/
/
/
/	This program is a sophisticated documentation package for generating
/	all kinds of user and/or technical documentation. Among the important
/	features in RTES are:
/
/	1.	Automatic indexing facility for headings
/	2.	Resolution of forward, symbolic references to title headings
/	3.	Completely automatic hyphenation of the text.
/	4.	Justification algorithm that prevents RIVERS from occuring
/		in the text.
/	5.	Provision for avoiding bad page breaks in sections of text
/	6.	Simple provisions for generating upper/lower case printer
/		output when only an upper case console is available for input.
/	7.	Extraordinarily simple markup requirements including semantic
/		recognition of indents and runarounds etc.
/
/
/	RTES is intended to run on the following computers:
/
/	PDP8/a, PDP8/e, PDP8/m, PDP8/f, PDP8/i, PDP12
/	The computer system must have a minimum of 8-k of memory and
/	be able to support a minimum OS/8 configuration.
	TITLE	TEX Commands & Run-time options
/
/	Run-time Options:
/
/	/U	Handle input from an upper/case only console. In this case,
/		all characters are assumed to be in lower case. To generate
/		upper case characters, the following conventions are used:
/
/		a. The / character forces the next character to be in upper
/		   case.
/		b. Two / characters in a row force all following characters
/		   to be in upper case until a single / character is found.
/
/		For example, to generate: ''Now is the TIME for all Good Men''
/		the input would be: ''/NOW IS THE //TIME/ FOR ALL /GOOD /MEN''
/
/	/I	Inhibits the generation of the cross-reference directory of
/		all sections and also disallows [=] type references.
/
/	/D	Double column mode. The text is divided into two equal
/		columns. Requires minimum of 16k memory.
/
/	/F	Forces all output from RTES to be in upper case. This option
/		is only useful when an upper case line-printer is being
/		used and the input contains lower case characters which
/		would not otherwise print on the line-printer.
/
/	/H	Disable hyphenation. RTES will not request hyphenation
/		for underset lines.
/
/	/L	List all words that were hyphenated, showing hyphenation
/		points.
/
/	/M	Disable automatic hyphenation, retain manual hyphenation
/
/	/P	Proof mode. In this mode, the file, page and line number
/		of the original source file are printed in the right-hand
/		margin to facilitate making corrections (almost exactly
/		like a PAGE8 assembled source listing). This makes it
/		extremely convenient to update the original document with
/		DISC's ICE text editor program.
/
/	/T	Tighten up lines in output document by reduing thresshold
/		for an underset line.
/
/	/N	No symbolic references: If this switch is set, RTES assumes
/		that there are no symbolic references to process and will
/		therefore skip pass 1.
/
/	/V	Print hyphenation audit trail on normal LPT on device
/		address 66.
/
/	/Z	Inhibit output of ASCII Control/z code at end of output
/		file.
/
/	NOTE:	RTES is a three-pass program. Two passes are necessary
/		in order to resolve all forward references. The third pass
/		is necessary in order to ensure that all page references
/		are precisely accurate. Avoiding pass 3 would mean that
/		some page references could be off. WHY? because forward
/		symbolic references mean that the length of the section #
/		may not be known until pass 2. However, the length of these
/		section numbers can affect the line justification which
/		in turn can affect the paging.
/
/	Pass 1	Only function is to build the symbol table of all section
/		header references.
/
/	Pass 2	In this pass, the section references are known, so the
/		hyphenation can be performed. At the same time, the symbol
/		table is rebuilt again on top of the old one, since in pass 2
/		we can now insert the precise page numbers for all references.
/
/	Pass 3	Final output is generated during this pass.
/
/	Note that we could avoid pass 3, by putting the table of contents at
/	the end of the listing and doing the hyphenation concurrently with
/	the output. However, it is much more convenient to go to an extra
/	pass so the operator does not have to wait around to do the hyphenation
/
/	=nnnn	This command sets a floating margin for the final output.
/		The default value is zero, which means that the output will
/		start in column one on the output device. If a non-zero value
/		is present, RTES will automatically indent all lines on the
/		final output by the specified amount in 'nnn'.
/
/
/	RTES commands:
/
/	All RTES commands are enclosed in square brackets. Command letters
/	can be entered in either upper or lower case.
/
/	[/]	Prints the / character (needed only when a / has to be printed
/		and the /U option is being used)
/
/	[[	Replaced by the number of spaces set in PARADENT. Normally
/		used for generating fixed paragraph indents.
/
/	[[]	Prints the [ character alone
/
/	[]]	Prints the ] character alone
/
/	[  ]	Generates fixed spaces (i.e. non-justifying spaces)
/		for each space which is contained within the brackets
/		without inhibiting justification on previous justification
/		spaces.
/
/	[\]	Prints the \ character alone. The \ character is used as a
/		discretionary (conditional) hyphen.
/
/	[D]	This is replaced by today's date from OS/8 in the form:
/		23. Sep. 1976. An error is generated if there is no date in
/		the OS/8 date word.
/
/	[j]	Resume justification of input. Only needed when a [n]
/		command has been given.
/
/	[n]	No justification. Line justification is inhibited. In
/		typesetting terminology, this generates a RAGGED RIGHT
/		condition (i.e. ragged right-hand margin).
/
/	[h]	Disable hyphenation on the next word. Used when automatic
/		hyphenation generates a bad break on a word that can not
/		be hyphenated.
/
/	[1]	Where 1 represents a digit from 1 to 9. This command is
/		replaced by a string in the form:
/			1.23.4
/		which is used for a section number on the documentation.
/		The digit represents the current level in the section number.
/		RTES automatically keeps track of all the section numbers and
/		increments the number associated with that level whenever this
/		type of command is given. All text following the section number
/		command is treated as a SYMBOLIC LABEL for that section for
/		use in resolving symbolic references (see - command below)
/		and for generation of the index of contents. In generating
/		a section number, trailing section numbers greater than the
/		current level are trimmed. Each section has an initial value
/		of 0. Study the example below:
/
/		INPUT:
/
/		[1]Introduction
/		  [2]Opening remarks
/		  [2]Use of program
/		  [2]General error conditions
/		    [3]Initialization errors
/		    [3]Compile-time errors
/		    [3]Run-time errors
/		    [3]Operator errors
/		  [2]System requirements
/		[1]System commands
/
/	On output, this will generate the following:
/
/		1. Introduction
/		  1.1  Opening Remarks
/		  1.2  Use of Program
/		  1.3  General error conditions
/		    1.3.1  Initialization errors
/		    1.3.2  Compile-time errors
/		    1.3.3  Run-time errors
/		    1.3.4  Operator errors
/		  1.4  System Requirements
/		2. System Commands
/
/	[p]	Unconditional page eject. This command should be issued on a
/		line by itself, since all remaining characters on the line
/		up to the LF on that line are stripped.
/
/	[Pnn]	Conditional page eject. A page eject occurs if there are less
/		than nn lines left on the current page.
/
/	[Mnn]	Set right-hand margin at column position 'nn'. All remaining
/		characters on the line will be stripped and ignored.
/
/	[Vnn]	Vertical Tab to line 'nn' on the page. Sufficient blank lines
/		are generated to reach line 'nn' on the output page. If already
/		past line 'nn', this command has no effect.
/
/	[Wx]	Space out line to full line width by inserting the appropriate
/		number of blanks at this point in the line. Generally
/		used before a quad right or quad centre command. If 'x' is
/		present, then the character 'x' is used to space out the line.
/		instead of a blank.
/
/	[c]	Centre line. The line to the left of this command will be
/		centred on the current column. The line may begin with an
/		an indent in which case the text is centred over the
/		the indented text to follow.
/
/	[r]	Set line to the left of this command flush against the
/		right-hand margin of the current line. In typesetting
/		terminology, this is a quad right command. As with the [c]
/		command, all remaining characters on the line are stripped.
/
/	[S#text] Switched text. '#' represents a digit from 0-9. If the
/		associated run-time switch, is set, the text will appear
/		on the final output. I.e. if the command is [S4....], the
/		text will only appear if /4 is issued to the COMMAND DECODER.
/		Otherwise, all text after the 'S' up to and including the
/		closing square bracket are stripped and do not appear on
/		the final output. This command can be used to insert notes
/		into the RTES source which will not appear on the final
/		copy as well as for providing conditional blocks of text.
/
/	[-]	Prints the '-' (hyphen) character without having RTES
/		treat it as a hyphenation character (i.e. RTES will not
/		attempt to hyphenate a line at that point).
/
/	[=text]	This is symbolic reference to a section number. 'text' is
/		the text string associated with that section. The entire
/		command is replaced with the numeric section number associated
/		with 'text', followed by the page number.
/		Following the example above of the [1] type command, the
/		following line:
/			See section [=initialization errors]
/		will be replaced by:
/			See section 1.3.1 (Pg. 72)
/		In searching for the associated text (a symbol table is
/		built during pass 1 in the RTES program), upper/lower case
/		differences are ignored. The 'text' need contain only enough
/		of the text to identify the referenced section. Leading blanks
/		are ignored during the search.
/
/	[Faa,bb,cc]	Set page format. aa is the drop from the title line
/		(which appears on the top line).
/		bb is the number of lines per
/		page (exluding margins and title).
/		and cc is the number of lines for
/		the bottom margin. A value of 0 for cc causes a form feed
/		to be sent instead of a number of blank lines.
/
/	[nnn]	Generate ASCII code 'nnn' where the 'nnn' represents
/		the three octal digits of the ASCII code. The ASCII
/		code generated is treated as having NO WIDTH. This
/		allows backspacing or special control characters to
/		be passed by the program.
/
/	The very first line in the source input file is treated as a title
/	for the documentation. This line is limited to 132 characters in
/	length. As a special feature, the [d] command is permitted in this
/	title, so that the user can place the current date in the title.
/	Also, a [p] command is also allowed, which is replaced by the
/	page number. A [t] command generates the total number of pages
/	in the output file.
/	If the first line in the file is null (i.e. just a
/	CR/LF), then no title appears on the output.
/	A typical title line is shown below:
/
/	NUCLEUS Operating System Description	[d]	Page  [p] of [t]
/
/	which would generate:
/
/	NUCLEUS Operating System Description    Sep.14, 1976   Page  4 of 10
	TITLE	Macro defintiions and equivalences
/
CTLZ	EQU	0232		ASCII end-of-file code for OS/8
CR	EQU	0215		ASCII carriage return
LF	EQU	0212		ASCII Line feed code
FF	EQU	0214		ASCII form feed
DELETE	EQU	0377		ASCII delete/rubout code
TAB	EQU	0211		ASCII Tabulation code
DHYPHEN	EQU	'\		Definition for discretionary hypen
SLASH	EQU	'/		Defintion of character for u/l case processing
/
LSIZE	EQU	9		Number of different levels allowed on sections
LPT	EQU	066		Device address for audit trail printer
LEN	EQU	140		Length of line buffer
/
/	following UNLINKs ensure compatibility with PDP8/i and PDP8/l systems
/
	UNLINK	BSW
	UNLINK	MQL
	UNLINK	MQA
/
/
USR	QUT	1,07700		Load point for non-resident USR routines
OSDATE	QUT	1,07666		Location of OS/8 Date word
OSBIP	QUT	0,07777		OS/8 Batch in progress word
SWITCH1	QUT	1,07643		Location of 1st. DECODER switch (A-L)
SWITCH2	QUT	1,07644		Location of 2nd. DECODER switch (M-X)
SWITCH3	QUT	1,07645		Location of 3rd DECODER switch (Y,Z,0-9)
/
	MACRO			COMMON LOOPING MACRO
	LOOP	<ADDRESS><COUNT=CNTR>
<>	ISZ	<COUNT>
	JMP	<ADDRESS>
	MEND
	TITLE	Page Zero cells
/
/	Page Zero cells
/
/
	ORG	0
MWIDTH	DC	80		Default maximum width for line
TOPM	DC	2		Default value for top margin on page
MLINES	DC	55		Default value for maximum lines on page
BOTTOMM	DC	0		Default bottom margin (0=do form feed)
/
	AS	3		Reserve 4,5,6 for ODT breakpoints
/
FINDENT	DC	0		Default value for floating left margin
/
	ORG	010
XR	EQU	*
	DC	0		Temporary indexing cells
XR1	EQU	*
	DC	0		"		"	"
XR2	EQU	*
	DC	0		"		"	"
/
LXR	DC	0		Line buffer pointer
KXR	DC	0		Non-temporary indexing cell
DXR	DC	0		"	"	"	"
EXR	DC	0		"	"	"	"
/
	ORG	020
/
TEMP	EQU	*
	DC	0		Standard temporary cells
TEMP1	EQU	*
	DC	0		"		"	"
TEMP2	EQU	*
	DC	0		"		"	"
TEMP3	EQU	*
	DC	0		"		"	"
CNTR	EQU	*
	DC	0		Temporary loop counter
/
PARADENT DC	5		Default value for paragraph indent.
GAP	DC	4		Gap between columns in double column mode
PTR	DC	0		General pointer cell
CURW	DC	0		Current width of line being processed
THISW	DC	0		Width of new word being processed
MAXW	DC	0		Maximum width allowed on current line
DROP	DC	0		Current value for top marging
LINES	DC	0		Current value for number of lines on page
BOTTOM	DC	0		Current value for bottom margin
/
INDENT	DC	0		Number of spaces for indent on current line
NXINDENT DC	0		Number of spaces for indent on next line
/
CHAR	DC	0		Most recent character read by GETC routine
NEXTC	DC	0		Provides 1-character look-ahead for GETC
NEXTSV	DC	0		Save cell for NEXTC while recapitulating
NEXTSV2	DC	0		Save cell for NEXTC in SWITCH & GETEXR Subrs.
JFLAG	DC	0		Justification Flag: 0=justify, 1=no justify
COMC	DC	0		Command character (in [x] type commands)
DPTR	DC	0		Pointer used by DATE section of GETC routine
/
SAVEP	DC	0		Saves address into line during hyphenation
SAVEC	DC	0		Saves character at SAVEP address
/
SPACES	DC	0		Count for number of spaces to add on line
SPACNT	DC	0		Count of number of spaces which can be added
/
LEFT	DC	0		Counts number of lines left on the output page
/
GCNTR	DC	0		Loop counter for the GENSP and GENCR routines
HIGH	DC	0		High order part returned by BINDEC
MID	DC	0		Middle part returned by BINASC/BINDEC
LOW	DC	0		Low order part of result from BINASC/BINDEC
FATAL	DC	0		Set non-zero on FATAL error condition
/
/	Cells needed by the OS/8 packing and unpacking routines
/
PKPTR	DC	OUTBUF		Pointer for the PAKUP routine
PKPTR2	DC	0		Pointer for the PIKUP routine
KCELL	DC	0		Temporary save cell
/
/	Cells for OS/8 device drivers
/
IDEV	DC	0		Entry point address for input driver
ODEV	DC	0		Entry point address for output driver
FPTR	DC	0		Pointer to current input file
OMLENGTH DC	0		Minus length available for output file
COLUMN	DC	0		Current column on input line (TAB restoration)
/
ERROR	DC	0		Number of error on call
ERCALL	DC	0		Address of last call to error routine (DEBUG)
OVBLK	DC	0		Current output virtual block
MLENGTH	DC	0		Minus length left for input file
IVBLK	DC	0		Current input virtual block
/
IFLAG	DC	0		Non-zero if index generation inhibited
DCNTR	DC	0		Loop counter
HYPHO	DC	0		Non-zero if hyphenation successful
MAXF	DC	0		CDF to highest memory field (set by CORE)
NUMBER	DC	0		Contains number in GETNUM routine
PASS	DC	0		Identifies pass (0=pass 1; 1 = pass 2)
SYMPTR	DC	SYMB		Insertion pointer into symbol table
SYMPTR2	DC	0		Extraction pointer into symbol table
HFLAG	DC	0		LH/RH flag for IHALF routine
CASE	DC	040		Set to 0 if upper case forced (see LDC)
GETCHAR	DC	GETKAR		Also LDC (/U option) or also GETEXR
GETCSV	DC	0		Save cell for GETCHAR (see SWITCH & GETEXR)
OUTCHAR	DC	NULL		Set to PAKUP during pass 2
LPTR	DC	0		Pointer cell
RPTR	DC	0		Pointer cell
/
HYPHP	DC	0		Pointer into hyphenation record table
HYPHF	DC	0		LH/RH flag for hyphenation record table
SAVE	DC	0		Non-temporary save cell
EXTRAL	DC	0		Count of extra lines to produce after DUMPLN
SYMTOP	DC	SYMB		Marks highest address in symbol table
CDFTOP	DC	06211		Marks highest CDF into the symbol table
DISPLAY	DC	0		Display counter for lines set (for MQ)
LEVELSR	DC	0		Pointer to output Subr. for DOLEVEL Subr.
SFLAG	DC	0		Flag to check for duplicate references
PFLAG	DC	0		As above but checks for perfect references
ERFLAG	DC	0		Set to 1 after error while calling DUMPLN
TABFLAG	DC	0		Set to -1 after indent on line (for tab)
EJFLAG	DC	-1		Set to -1 to force page eject
TOTALPG	DC	0		Count of total pages in file (for [t] in title)
NFLAG	DC	0		Set to 02000 if /N switch set, else 0
WPTR	DC	0		If non-zero has address of [w] command
WCHAR	DC	0		Character to leader with on [w] command
TWIDTH	DC	0		Total line width of title line (for [w])
OLDW	DC	0		Save value for MAXW in case [w] in title
SYSTART	DC	SYMB		Start of symbol table
PAKUPR	DC	PAKUP		Set to 'PAKF' if /D set
PAKIT	DC	0		0 = send to PAKUP, 4000 = send to PAKF
	TITLE	Initial entry to RTES program
/
	ORG	0200
	LDI	1		AC non-zero to show direct call
	JMPI	*+1		Off to do pre-pass initialization
	DC	RTES		...
	TITLE	Field 0 buffers and tables
/
	DSEC			Ensure auto-paging disabled here
/
	DC	0		Pre-sentinel on LINEB buffer
LINEB	QUT	%*,*		Main line buffer
	ORG	LINEB+LEN	Allocate room for line buffer
	DC	-1,-1		Trapping sentinels on LINEB
SPTABLE	AS	40		Space address table for justification
DAYBUF	AS	15		Room for today's date
REFER	AS	40+1		Room for reference table (during search)
/
/	Table of all punctuation characters which allow extra spaces to be
/	added during justification.
/
PUNCTAB	DC	-'.,-',,-':,-';,-'?,-'!,-'),0
/
/	Correction/page number buffer for /P proofs and for errors
/
NHYPH	DC	' 		Set to # if hyphenation unsuccessful on line
PSECT	DC	' ,' 
SECTION	DC	'1,'.,' ,'1,'.,' ,' ,'1,' ,' ,' ,' ,0
/
WORD	AS	41		Room for word to be hyphenated
SAVEB	AS	41		Room for section/page number on reference
	EJECT
/
/	Here for messages
/
ERMESS	TEXT	' FEHLER - %'
/
/	Table of addresses of all error messages
/
MBASE	DC	E0MS,E1MS,E2MS,E3MS,E4MS,E5MS,E6MS,E7MS,E8MS,E9MS,E10MS,E11MS
/
INMSG	DC	'I,'N,'H,'A,'L,'T,'S,'V,'E,'R,'Z,'E,'I,'C,'H,'N,'I,'S,0
	EJECT
/
/	Here for the command table. 
/
/	First word contains ASCII character of command
/	Second word contains the dispatch address for the command
/
COMTAB	DC	'N,NCOM		No justification
	DC	'J,JCOM		Resume justification
	DC	'P,PAGEJ	Generate page eject
	DC	'W,WCOM		Space out line to full width
	DC	' ,FSPACE	Fixed space
	DC	'[,PCHECK	Generate [ or paragraph indent
	DC	'],SPECIAL	Generate ]
	DC	'/,SPECIAL	Generate /
	DC	'\,SPECIAL	Generate \
	DC	'-,SPECIAL	Generate - (not as a hyphen)
	DC	'D,DCOM		Generate text string with today's date
	DC	'H,HCOM		Disable hyphenation of next word
	DC	'C,CCOM		Centred line
	DC	'R,RCOM		Line at right margin
	DC	'=,SREF		Symbolic reference
	DC	'F,FCOM		Page format command
	DC	'S,SCOM		Switched text command
	DC	'M,MCOM		Set right-hand margin
	DC	'V,VCOM		Do vertical tab
/
	DC	0		Sentinel on command table
/
PAGENUM	DC	1		Current page number
/
LEVEL	AS	LSIZE+1		Allocation for main LEVEL buffer
/
NLEVEL	AS	LSIZE+1		Temporary LEVEL table
	EJECT
	TITLE	Pre-pass initialization circuit
/
/	Here to begin processing of the program. First step is to
/	reset default parameters, since we may be starting the second
/	or third pass in the program.
/
	ISEC	0		Enable auto paging
/
PASS2	TAD	=GETC2		Reset co-routine linkage
	DCA	GETCX+0		...
	DCA	INDENT		Reset indent back to zero
	DCA	NXINDENT	Reset indent for next line back to zero
	DCA	DISPLAY		Reset line display counter back to zero
	LDI	1		Initialize page number back to 1
	DCA	PAGENUM		...
	DCA	EXTRAL		Clear extra line count cell
	DCA	LEFT		Mark no lines left on the page
	LDI	-1		Force page eject before index
	DCA	EJFLAG		...
	JMS	INDEX		Process the index now
/
/	Initialize pointers/parameters in the input routines to force
/	start again at the beginning of the input file.
/
	TAD	=07617-1	Initialize pointer to DECODER file table
	DCA	FPTR		...
	TAD	=RNEXT		Initialize co-routine linkage to force new read
	DCA	PIKX+0		...
	LDI	1		Mark virtual block of 1
	DCA	IVBLK		...
	LDI	-1		and input file length of 1, this will force
	DCA	MLENGTH		an immediate move to a new input file
/
/	Now clear out the file/page/line number area
/	Also reset the page number for TITLE back to 1
/
	TAD	='0		Initialize to '0. 1.  1'
	DCA	SECTION		...
	TAD	=' 		...
	DCA	SECTION+2	...
	TAD	='1		...
	DCA	SECTION+3	...
	TAD	=' 		...
	DCA	SECTION+5	...
	TAD	=' 		...
	DCA	SECTION+6	...
	TAD	='1		...
	DCA	SECTION+7	...
/
/	Zero out the buffer that contains the current level for each
/	section number.
/
	TAD	=-LSIZE		Set loop counter for number of levels
	DCA	CNTR		...
	TAD	=LEVEL-1	Set pointer to level table
	DCA	XR		...
/
0H	DCAI	XR		Zero out a word
	LOOP	0B		Loop till all cleared
/
	TAD	=040		In case /U, set now to lower case
	DCA	CASE		...
	TAD	=HPOINTS-1	Reset pointer to hyphenation record table
	DCA	HYPHP		...
	DCA	HYPHF		Set to start with left byte
/
/	Before doing anything else, we must process the title line in the
/	file and store it in the buffer TITLE.
/
	TAD	=TITLE-1	Set pointer to the title buffer
	DCA	LXR		...
	DCA	TWIDTH		Set title width to zero
	TAD	=-(135-3)	Set maximum size of title permitted
	DCA	DCNTR		as a loop counter
	JMS	GETC		Prime the GETC routine to set CHAR
	CLA			Ignore garbage currently in NEXTC
/
/	Loop here to process the title line in the file
/
1H	JMS	GETC		Get character out of the file
	TAD	=-LF		LF marks the end of the title line
	SNA			Test for LF now
	JMP	2F		LF all done here on end of line
/
	TAD	=LF-'[		Test for [ (possible [d] or [p] commands)
	SNA
	JMP	3F		OK - we have a possible command here
	TAD	='[		Else restore original character
	JMS	5F		Move character into TITLE buffer
	INC	TWIDTH		Count width of this character
	JMP	1B		Loop back for next character
/
/	Subroutine to store character into TITLE buffer and check for overflow
/	When line overflows, 5h does not return
/
5H	SUB
	CDF	%TITLE		To field of title buffer
	DCAI	LXR		Store into the TITLE buffer
	CDF	%*		Reset back to main field now
	ISZ	DCNTR		More room in the buffer?
	RET	5B		Yes - so return to call
/
/	Here when LF found, or the 132 character limit has been exceeded
/
2H	TAD	=CR		Install CR/LF at the end of the line
	JMS	5B		Insert carriage return
	TAD	=LF		...
	JMS	5B		Insert line feed
	JMS	5B		Install zero sentinel on the line
	LDI	-1		Mark line buffer empty now
	DCA	LINEB		...
	LDI	-1		and no back up word to read
	DCA	LINEB+1		...
	JMS	EOLCK		Check for extra lines/indent following LF
	TAD	EXTRAL		Get count of extra lines
	JMS	GENCR		Generate them now (if any)
	DCA	EXTRAL		Must clear this cell out now
	JMP	NEWLN		Off for new line now
/
/	Here when [ found in title line--may be a P, W, T or D command.
/
3H	JMS	GETC		Get the command character
	JMS	FOLD		Fold over to upper case for testing
	TAD	=-'T		Test for [t] command in title
	SNA			Skip if not
	JMP	8F		Off to do total pages in file
	TAD	='T-'P		Look for [P] command (do page #)
	SNA
	JMP	4F		P found -- off to insert page # flag
	TAD	='P-'W		Test for [w] command (fill up line to width)
	SNA
	JMP	9F		Off to handle [w] command
	TAD	='W-'D		Check for [d] command (do date
	SNA			Skip if not [d] command
	JMP	0F		Handle [d] command
	TAD	='D-'M		Test for margin command
	SZA CLA			Skip if [m] command
	JMS	E1		ERROR - UNDEFINED COMMAND FOUND
/
/	Handle margin setting for text
/
	JMS	GETNUM		Get numeric value for margin
	CMA IAC			And save value
	DCA	OLDW		Save for later use in title
	TAD	OLDW		Reget value again
	TAD	GAP		subtract intercolumn gap in case /d option
SLASHD4	STL RAR			#NOP# if /D not set. If set, divide by 2
	DCA	MAXW		...
	JMP	1B		All done (] already removed)
/
/	Here to insert today's date into the title buffer
/
0H	TAD	=DAYBUF-1	Set pointer to OS/8 date buffer
	DCA	DXR		...
	TAD	=13		Account for full width of date
	TAD	TWIDTH		...
	DCA	TWIDTH		...
	TAD	DAYBUF		Do we have an OS/8 date set?
	SMA CLA			Skip if not
	JMP	6F		Yes we have -- continue
	INC	FATAL		Mark this as a fatal error now
	JMS	E4		Print error and quit
/
6H	TADI	DXR		Get next character in the date
	SNA			Test for sentinel
	JMP	*+3		All done when sentinel is found
/
	JMS	5B		Else insert character into buffer
	JMP	6B		Loop back for next character
/
/	Here when done with command, also merge from [p], [w] & [t] commands
/
7H	JMS	FLUSHB		Flush the remaining square bracket
	JMP	1B		Loop back for next character in title
/
/	Here to handle the [p] command. Just set 02000 word into the buffer
/	to show that the page number goes there.
/
4H	TAD	=01000		Special flag to show page goes here
/
/	Here to handle the [t] command. Just set 01000 word into the buffer
/	to show that the total number of pages goes there.
/
8H	TAD	=01000		Special flag value
	JMS	5B		Insert into the buffer
	LDI	3		Account for width of page number
	TAD	TWIDTH		...
	DCA	TWIDTH		...
	JMP	7B		Loop back now to flush ] after command
/
/	Here for the [w] command, place 0400 flag word into buffer
/	to show that this is where all additional space should be
/	placed to fill out the line.
/
9H	TAD	=0400		Insert flag
	JMS	5B		...
	JMP	7B		Loop back now to flush ] after command
/
/	Routine to convert a binary number in the AC in the range 0-99 to
/	two ASCII digits. High order ASCII digit is returned in the AC
/	and the low order digit is returned in the cell LOW
/	If there is a leading zero, the AC will be clear on exit
/
BINASC	SUB
	DCA	TEMP		Save the number for a moment
	DCA	CNTR		Zero the counter
	TAD	TEMP		Reget the number again
/
	TAD	=-10		Divide the number by 10 to get the high digit
	INC	CNTR		Count the subtractions that we made
	SMA			Skip if gone too far
	JMP	*-3		Else loop
/
	TAD	=10+'0		Restore the digit and set in ASCII
	DCA	LOW		Save the low order digit
/
	LDI	-1		(Compensate for CNTR too large by one)
	TAD	CNTR		Get the high order part of the count
	SZA			Skip if the high order digit is zero
	TAD	='0		Non-zero -- change to ASCII digit then
	RET	BINASC		Return with result in AC and LOW
	TITLE	Entry point to process a new line for output
/
/	Loop here to build a new line for output. First, we must
/	copy over a possible word that did not fit on the previous
/	line.
/
NEWLN	DCA	CURW		Set current line width back to zero
	DCA	THISW		Set width of current word to zero
	TAD	=LINEB-1	Reset pointer to the line buffer
	DCA	LXR		...
	TADX	SWITCH1		Get DECODER switches with /H option
	AND	=020		Isolate the /H bit
	DCA	HYPHO		Clear hyphenation flag (disable if /H set)
	TAD	NXINDENT	Set indent for current line
	DCA	INDENT		...
	TAD	=' 		Reset no hyphenation flag (for debug in /P)
	DCA	NHYPH		...
/
/	Scan to sentinel in line buffer to find the word that did not fit
/
	TAD	LXR		Copy pointer to the line buffer
	DCA	KXR		...
/
	TADI	KXR		Load the next character
	SMA CLA			Scan until sentinel found
	JMP	*-2		Keep looking for it
/
	TAD	=RECAP		Set co-routine linkage to re-read this word
	DCA	GETCX+0		...
	JMS	GETC		Prime the GETC routine now (AC #0 but OK)
/
/	Loop here to get the next character out of the output buffer
/	and store into the line buffer.
/
MLOOP	JMS	ABORTCK		Check for abort on ^C
	JMS	GETC		Get the next character from buffer
	TAD	=-'[		Test for a command
	SNA
	JMP	COMMAND		Off to handle a command
	TAD	='[-' 		Test for space
	SNA
	JMP	BLANK		Off to process a blank
	TAD	=(' )-('-)	Test for hyphen
	SNA
	JMP	REALH		Off to process a hyphen
	TAD	=('-)-LF	Test for LF code
	SNA
	JMP	EOL		Off to process end of line code
	TAD	=LF-DHYPHEN	Test for discretionary hyphen
	SNA
	JMP	DISCRET		Off to handle discretionary hyphen
	TAD	=DHYPHEN-CTLZ	Test for end of all input files
	SNA			Skip if not
	JMP	EOF		OK - off to handle end of files now
	TAD	=CTLZ-']	Test for possible ']' after switched text
	SNA CLA			Skip if not
	JMP	MLOOP		Ok, skip the ']' then
/
/	Come back here to handle normal characters. They just get
/	stored into the line buffer
/
NORMAL	TAD	CHAR		Get the character read by GETC routine
	JMS	STAC		Store into buffer (and check overflow)
	JMP	MLOOP		Off for the next character now
/
/	Little subroutine to store characters into the line buffer
/	and check for overflow. NOTE: do not use CNTR cell since it is
/	used as a loop counter when storing blanks of a paragraph indent.
/
STAC	SUB
	DCAI	LXR		Store character into line buffer
	ISZ	THISW		Increment width of this word
	NOP			(Could skip during INDEX routine (?))
	TAD	LXR		Check now for line overflow
	TAD	=-(LINEB+LEN)	(In case there were no blanks in the line)
	SPA CLA			Skip if line has overflowed.
	RET	STAC		No overflow -- return to call
	JMS	E0		ERROR - LINE OVERFLOW WITH NO SPACES!
	EJECT
/
/	Here to handle the open bracket which marks the start of a command
/	First check for a number which indicates a level command
/	or [nnn] type command
/
COMMAND	JMS	OVERSET		Close off current line if already overset
	JMS	GETC		Read the letter of the command
	TAD	=-(LSIZE+'0)-1	Test for decimal digit in level range
	CLL			...
	TAD	=(LSIZE+'0)-'1+1 ...
	SZL			Skip if not in range
	JMP	LEVELC		Else off to handle level/[nnn] type command
	TAD	='1		Restore the original character
/
	JMS	FOLD		Fold to upper case for table search
	CMA IAC			Negate character value and store
	DCA	COMC		...
	TAD	=COMTAB-2	Set pointer to command dispatch table
	DCA	XR		...
/
/	Loop here to find the command in the command table
/
1H	INC	XR		Step over the dispatch address
	TADI	XR		Get the letter of the command
	SNA			Test for sentinel on table
	JMS	E1		ERROR -- UNDEFINED COMMAND FOUND
/
	TAD	COMC		Compare with command we are looking for
	SZA CLA			Skip if we have a match
	JMP	1B		Else keep looking for a match
/
	TADI	XR		Match found -- load dispatch address
	DCA	TEMP		...
	JMPI	TEMP		Dispatch to command processor routine
/
/	Subroutine to test for lower case character in the AC. If the
/	ASCII code is >0340, we subtract 040 from the code to force
/	the ASCII character to be in upper case.
/
FOLD	SUB
	TAD	=-0340		Test for ASCII code > 0340
	SMA			Skip if not (was < 0340)
	TAD	=-040		Change lower case to upper case
	TAD	=0340		Restore the original character
	RET	FOLD
	EJECT
	TITLE	Processing of the level command
/
/	Here to handle a new level. Come here with the binary level
/	number as a positive number in the AC.
/
LEVELC	DCA	COMC		Save the binary level number (less 1)
	JMS	GETC		Get the next character
	TAD	=-']		Test for end of command
	SZA			skip if end of command (was level command)
	JMP	ANYCODE		Else must be the [nnn] type command
/
/	Since we are starting a new section, ensure that there are at
/	least four lines left on the current page
/	(note: EJFLAG may already be set by prior [p] command)
/
	LDI	-3		Test for at least four lines left on page
	TAD	LEFT		...
	SMA SZA CLA		Skip if less than 4 four lines left
	JMP	*+3		Ok, we have at least 4 lines left here
/
	LDI	-1		Else set for eject before this line
	DCA	EJFLAG		...
/
/
	TAD	COMC		Reget the level number
	TAD	=LEVEL		Index table of levels
	DCA	TEMP		Save pointer
	ISZI	TEMP		Step that level (could skip if garbage file)
/
/	Now that we have incremented this level, we must now zero out
/	all the following levels.
/
0H	INC	TEMP		Step pointer to the next level
	TADI	TEMP		Load value at that level
	SNA CLA			If zero, we have gone far enough
	JMP	*+3		Ok, all done here
/
	DCAI	TEMP		Else set this level to zero
	JMP	0B		And loop for the next one
/
/	Now dump out the current level into the LINEB buffer in the
/	form: 1.2.4. etc.
/
	TAD	LXR		Save position of line buffer before section
	DCA	KXR		in case this line is to be stripped.
	TAD	=LEVEL		Point to start of level table
	JMS	DOLEVEL,STAC	Dump that level now (via STAC call)
	EJECT
/
/	Here we copy over the level information for this entry.
/	Note that we do this in all three passes although it is really only
/	necessary for the first two passes. In pass 1 the section numbers
/	are correct but the page numbers may be off. In pass 2 we can insert
/	the correct page numbers. In pass 3, we just redundantly copy what
/	was stored in pass 2.
/
/	A symbol table entry looks as follows:
/
/	word 1		binary value of current page #
/	word 2		binary value for level 1
/	word 3		binary value for level 2
/	......		......
/	word n		binary value for level n-1
/	0		Sentinel on levels
/	ab		Text for section in folded, 6-bit ASCII
/	cd		...
/	....		...
/	0		Full word of zero for sentinel on entry
/
/
/	First get the current page number to insert as word 1 for this
/	entry. Note that PAGENUM is always one larger than the current
/	page. However, we have to check if this line will be at the
/	top of the following page.
/
	TAD	EJFLAG		Test for forced page eject
	SNA CLA			Skip if forcing eject
	LDI	-1		Else account for page number 1+ current #
	TAD	PAGENUM		Get the number for the next page
	JMS	ISYM		And insert into the symbol table
	TAD	=LEVEL-1	Set pointer to LEVEL
	DCA	XR		...
/
/	Loop here copying until the end of the table is found.
/
4H	TADI	XR		Load next entry in table
	SNA			Test for last significant entry
	JMP	*+3		SENTINEL -- all done here
	JMS	ISYM		Insert full word into symbol table
	JMP	4B		Loop back for next
/
	JMS	SYMCDF		Set CDF back to symbol table
	DCAI	SYMPTR		Install full-word sentinel on LEVEL section
	CDF	%*		Reset current field
/
	DCA	HFLAG		Set to start packing from left half
	DCA	IHALF+0		Mark -- no calls yet to IHALF routine
/
/	Now read the entire tag line on this level all the way up to the
/	LF character at the end of the line. At the same time, we copy this
/	entry into the symbol table
/
5H	JMS	GETC		Get next character from section label
	TAD	=-LF		Test for end of line code
	SNA CLA			Skip if not at end
	JMP	6F		All done on end of line code
/
	TAD	CHAR		Reget the character we just read
	JMS	STAC		First install as text into the line buffer
/
	TAD	CHAR		Get the character again
	TAD	=-' 		Test for a blank here
	SPA			Test for code < 240
	JMP	5B		Ignore control codes (AC non-zero, but OK)
	SZA CLA			Skip if we have a blank
	JMP	*+4		Something else
/
	TAD	IHALF		Have we stored anything yet?
	SNA CLA			Skip if so
	JMP	5B		NO -- so trim off this leading blank then
/
	TAD	CHAR		Reget again
	JMS	FOLD		Fold over to upper case
	JMS	IHALF		Insert halfword into table
	JMP	5B		Loop back for next character
/
/	Here at end of entry -- install sentinel
/
6H	JMS	INCSYM		Skip to next position in the table
	JMS	ISYM		Install sentinel character of zero
	JMS	EOLCK		Check for indent/extra lines after LF code
/
/	Test now to see if we overflowed the column width for this line
/
	TAD	CURW		Get width accumulated so far this line
	TAD	THISW		Add width accumulated on section header
	TAD	INDENT		Add in any indent on this line
	TAD	MAXW		Subtract maximum line width
	SMA SZA CLA		Skip if still room on this line
	JMS	E10		Log error - section header overflowed line
	TAD	IHALF+0		Did anything follow the section number?
	SNA CLA			Skip if so,
	TAD	KXR		Was this a completely null section header?
	TAD	=-(LINEB-1)	on a line by itself?
	SZA CLA			Skip if so
	JMP	LNDUMP		NO: so print out the line now
	TAD	KXR		Reset pointer now to make a blank line
	DCA	LXR		...
	JMP	LNDUMP		Install sentinels and avoid printing this line
	EJECT
/
/	Here to handle the [nnn] type command. All we do is read the next
/	three characters and treat them as octal digits for the ASCII code
/
ANYCODE	TAD	=']-'0		Isolate binary value
	DCA	SAVE		And save for a moment
	LDI	-2		Decrement column count to account for the 'nnn'
	TAD	COLUMN		...
	DCA	COLUMN		...
	LDI	-1		Decrement THISW since we have no width here
	TAD	THISW		...
	DCA	THISW		...
/
	JMS	GETC		Get the third character
	AND	=7		Isolate the binary code
	DCA	TEMP		And save it
/
/	Now assemble the full octal ASCII code
/
	TAD	COMC		Get the digit (less 1)
	CLL IAC RAL		Shift one digit position (and add back 1)
	RTL			...
	TAD	SAVE		Add in the second digit
	RAL			Shift another digit position
	RTL			...
	TAD	TEMP		Add in the final digit
	JMP	SPECIAL+1	Off to store the character now
	EJECT
/
/	subroutine DOLEVEL inserts a section number into the line buffer
/	LINEB via calls to STAC. On entry to this routine, AC will contain
/	the address either of LEVEL or NLEVEL. Routine converts all binary
/	level numbers to leading-zero-suppressed ASCII numbers and supplies
/	a period after each level.
/
/	call:
/		TAD	<ADDRESS>	Address of level buffer
/		JMS	DOLEVEL,SUBR	Address of Subr. to call for output
/
	ROOM	10
DOLEVEL	SUB
	DCA	PTR		Save pointer to this table of levels
	TADI	DOLEVEL		Get address of subroutine to call for output
	DCA	LEVELSR		...
	INC	DOLEVEL		Step return address over argument
/
/	Loop here to dump out the next level
/
1H	TADI	PTR		Load binary value of next level
	INC	PTR		Step to next level for next time
	JMS	BINDEC		Else convert to decimal and store
	TAD	HIGH		Get high order part
	SZA			Skip to suppress
	JMSI	LEVELSR		Else store into buffer
	TAD	MID		Get middle part of number
	SZA			Skip to suppress it
	JMSI	LEVELSR		Else insert into the buffer
	TAD	LOW		Always insert the low order part
	JMSI	LEVELSR		...
/
/	Note: to trim off the trailing period on section numbers, simply
/	move the next two lines of code so the period is stored after
/	the test for the last level of the section number.
/
	TAD	='.-0200	Insert period (don't treat as punctuation)
	JMSI	LEVELSR		...
	TADI	PTR		Was this the last level we just did?
	SNA CLA			If zero, we are done here
	RET	DOLEVEL		So return
	JMP	1B		and loop back for next level
/
/	subroutine STAPG stores HIGH, MID, and LOW into the buffer via STAC
/	calls. Leading zeroes are changed to blanks
/	On entry, AC contains address of subroutine to call for output
/
STAPG	SUB
	DCA	LEVELSR		Save address of subroutine to call for output
	TAD	HIGH		Get high order part
	SNA			Skip if not leading zero
	TAD	=' 		Else change leading zero to a blank
	JMSI	LEVELSR		Else store into buffer
	TAD	MID		Get middle part of number
	SNA			Skip if not leading zero
	TAD	=' 		Else change leading zero to a blank
	JMSI	LEVELSR		Else insert into the buffer
	TAD	LOW		Always insert the low order part
	JMSI	LEVELSR		...
	RET	STAPG
/
/	subroutine IHALF takes the left half of the AC and installs
/	the half-word into the next available slot in the symbol table
/	HFLAG controls which half of the word to store in.
/
IHALF	SUB
	AND	=077		Truncate now to 6-bit byte
	SNA			don't allow '@' since it appears as 00
	RET	IHALF		Just strip @ characters
	DCA	SAVE		Save the new character
/
	TAD	HFLAG		Are we about to store in left half?
	SNA CLA			Skip if not 
	JMS	INCSYM		Yes - so step pointer to next word now
/
	LDI	04000		Flip the LH/RH flag bit
	TAD	HFLAG		(and leave the result in the link)
	DCA	HFLAG		(and in HFLAG)
/
	TAD	SAVE		Reget the character to store
	JMS	SYMCDF		Set to field of symbol table now
	SZL			Test the flag now
	JMP	*+5		We will store in the right byte here
/
	CLL RTL			Storing left, so shift it over
	RTL			...
	RTL			...
	JMP	*+2		Skip to zero out right hand byte
/
	TADI	SYMPTR		Storing right, so merge in the old left byte
	DCAI	SYMPTR		And store it back
	CDF	%*		Reset current field
	RET	IHALF		And return
	EJECT
/
/	ISYM routine stores one full word (in the AC on entry) into the
/	current symbol table slot. INCSYM is then called to step the pointer
/	to the next position.
/
ISYM	SUB
	JMS	SYMCDF		To current field in symbol table
	DCAI	SYMPTR		Store AC into this slot in table
	CDF	%*		Ensure current field reset
	JMS	INCSYM		Step the pointer now
	RET	ISYM		...
/
/	SYMCDF routine simply sets the data field to the current data field
/	in which the SYMPTR pointer is pointing.
/
SYMCDF	SUB
	CDF	1		CDF to symbol table field
	RET	SYMCDF		...
/
/	INCSYM routine simply increments SYMPTR by one word position. We use
/	a subroutine to increment the pointer so we can check for entering
/	a new memory field and also to ensure that the last 256 locations
/	of field 1 are skipped, and the last 128 locations of all subsequent
/	memory fields are skipped. We also check for overflow of available
/	memory.
/
INCSYM	SUB
	TAD	NFLAG		If the /N flag is set, never increment
	SZA CLA			Skip if not set
	RET	INCSYM		/N set--we are not building a symbol table
/
	INC	SYMPTR		Step to next physical word in memory
	TAD	SYMCDF+1	Get CDF instruction to current field
	TAD	=-06211		TEST - are we in field 1?
	SNA CLA			Skip if not
	TAD	=0200		Yes - table stops at 7400 in field 1
	TAD	=-07600		Else test now for stopping at 7600
	TAD	SYMPTR		Compare now with current value of pointer
	SZA CLA			Skip if past the logical end of a memory field
	RET	INCSYM		Not past - return now
/
	DCA	SYMPTR		Set to start at location 0 in next field
	TAD	SYMCDF+1	Reget the CDF instruction
	JMS	NEXTF		Move to next field
	DCA	SYMCDF+1	And store it back
	RET	INCSYM		Return to call now
/
/	SYMCDF2 routine simply sets the data field to the current data field
/	in which the SYMPTR2 pointer is pointing.
/
SYMCDF2	SUB
	CDF	1		CDF to symbol table field
	RET	SYMCDF2		...
/
/	INCSYM2 routine simply increments SYMPTR2 by one word position. We use
/	a subroutine to increment the pointer so we can check for entering
/	a new memory field and also to ensure that the last 256 locations
/	of field 1 are skipped, and the last 128 locations of all subsequent
/	memory fields are skipped. We also check for overflow of available
/	memory.
/
INCSYM2	SUB
	INC	SYMPTR2		Step to next physical word in memory
	TAD	SYMCDF2+1	Get CDF instruction to current field
	TAD	=-06211		TEST - are we in field 1?
	SNA CLA			Skip if not
	TAD	=0200		Yes - table stops at 7400 in field 1
	TAD	=-07600		Else test now for stopping at 7600
	TAD	SYMPTR2		Compare now with current value of pointer
	SZA CLA			Skip if past the logical end of a memory field
	RET	INCSYM2		Not past - return now
/
	DCA	SYMPTR2		Set to start at location 0 in next field
/
	TAD	SYMCDF2+1	Reget the CDF instruction
	JMS	NEXTF		Step to next memory field
	DCA	SYMCDF2+1	And store it back
	RET	INCSYM2		Return to call now
/
/	Here to update CDF instruction in AC to next memory field. Must
/	check for fields 2,3 and /D option. If so, we step directly
/	to field 4
/
NEXTF	SUB
	TAD	=-06211		CDF to field 1?
	SNA			Skip if not
SLASHD	TAD	=2.LS.3		<#NOP# if /D not set> step to field 4
	TAD	=06211+(1.LS.3)	Step to next field, restore CDF instruction
	DCA	TEMP		Save it
	TAD	TEMP		...
	CMA IAC			Test for entering non-existent field
	TAD	MAXF		...
	SZA CLA			Skip if so
	JMP	*+3		All ok here
/
	INC	FATAL		Fatal error: don't return here
	JMS	E7		Print error message
/
	TAD	TEMP		Get new CDF
	RET	NEXTF		Return it in the AC
/
/	Here to handle a special character which appears in brackets
/	Just output the character as if it was a normal character.
/
SPECIAL	TAD	CHAR		Get the special character
/
/	Merge here with character in AC from the [nnn] type command
/
	TAD	=0400		Set 0400 flag bit so we always ignore it
	DCA	COMC		Save for a moment
	LDI	-2		Fix up column width
	TAD	COLUMN		(We only had one real character here)
	DCA	COLUMN		...
/
/	Merge here to finish up from the [w] command
/
WCOM2	JMS	FLUSHB		Flush out the ] that must follow
	TAD	COMC		Reget the special character
	JMP	NORMAL+1	Off to store into line buffer now
/
/	Here for the page eject command ([p]). Just set EJFLAG to force
/	an eject in the DUMPLN routine
/	Must also test for [Pnn] form of command for conditional eject
/
PAGEJ	JMS	IFLINE		Print out prior line if not printed yet
	JMS	GETNUM		Get a possible digit that may follow
	DCA	EJFLAG		Save for a moment (EJFLAG is available)
	JMS	FLUSHLF		Flush all characters now till end of line
	JMS	EOLCK		Check for indent/more lines after LF code
	TAD	EJFLAG		Reget the value of number in [p] command
	SNA			Test for zero (unconditional)
	JMP	1F		Zero - jump to force an eject
	CMA IAC			Else negate and compare with
	TAD	LEFT		the number of lines left on this page
	SMA CLA			Skip if no room left on this page
	JMP	*+3		OK, there is still room left
/
1H	DCA	EXTRAL		Clear out any blank lines after [p] command
	LDI	-1		Set for page eject before next line
/
	DCA	EJFLAG		...
/
/	Merge here from the [m] and [f] and [v] commands to print extra lines
/
PAGEJ2	TAD	EXTRAL		Generate any extra blank lines now
	JMS	GENCR		(in case [Pnn] type command and no eject)
	DCA	EXTRAL		Ensure this cell cleared out now
	JMP	NEWLN		Off to start a new line now
/
/	Subroutine to flush out all remaining characters on the line until a
/	LF code is found.
/
FLUSHLF	SUB
	JMS	GETC		Get next character out of the buffer
	TAD	=-LF		Look for end of line code
	SZA CLA			Skip if at end
	JMP	FLUSHLF+1	Else loop
	RET	FLUSHLF		All done -- return
/
/	Little subroutine to flush out the ] bracket that follows a command
/
FLUSHB	SUB
	JMS	GETC		Get the next character
	TAD	=-']		Must be a closing bracket here
	SNA CLA			Skip if not
	RET	FLUSHB		All ok -- return now
	JMS	E2		ERROR - COMMAND DOES NOT END WITH ]
/
/	Here for [[. This may be either a [[] command or just a [[ command
/
PCHECK	TAD	NEXTC		Look ahead at next character
	TAD	=-']		Closing bracket (for [[] command)
	SNA CLA			skip if not
	JMP	SPECIAL		Was a [[] command, execute it
/
/	Here for the [[ command which generates a paragraph indent of
/	five spaces.
/
	TAD	PARADENT	Get value for paragraph indent
	CMA IAC			Negate and set as
	DCA	CNTR		Loop counter
/
/	Loop here to store fixed blanks of the paragraph indent
/
0H	TAD	=' 		store a fixed blank
	JMS	STAC		...
	LOOP	0B		Loop till all stored
	JMP	MLOOP		All done here
	TITLE	Fixed Space and Hyphen handling
/
/	Here to handle special case of a fixed space in brackets. Main point
/	here is that we must store a special space code that:
/
/		a. will not be treated as a justification space, and
/		b. will not inhibit justification of the prior part of the line
/
FSPACE	LDI	-2		Adjust column setting to account for the
	TAD	COLUMN		brackets around the spaces
	DCA	COLUMN		...
FSPACE2	TAD	=' -0200	Use a normal space but WITHOUT the mark bit!
	JMS	STAC		Store that blank
	JMS	GETC		Get the next character
	TAD	=-']		Test for end of series of blanks
	SNA			Skip if not
	JMP	MLOOP		All done here
	TAD	=']-' 		Must be a space if not end
	SNA CLA			Skip if invalid character here
	JMP	FSPACE2		Ok -- off to store another fixed space
	JMS	E1		Invalid command
/
/	Here to handle a discretionary hyphen. First job is to check to see
/	whether the line is overset or not, since the J & H routines assume
/	that they can scan back to a discretionary hyphen for a break-point
/
DISCRET	TAD	=DHYPHEN	Mark character now in case were are overset
	DCA	CHAR		...
	LDI	1		Must be room for a real hyphen if we need it
	JMS	OVERSET		Test for overset line now
/
/	Line not overset - so store discretionary hyphen code into buffer
/
	TAD	=DHYPHEN-0200	Store hyphen code less flag bit (DUMPLN strips)
	JMS	STAC		Insert into the buffer
	TAD	=DELETE		Delete goes after (allows room for sentinel)
	JMS	STAC		...
/
	LDI	-2		Account now for fact that this hyphen has no
/
/	Merge here from real hyphen routine
/
5H	TAD	THISW		real width (i.e. until it is used)
	TAD	CURW		Add to width on this line
	DCA	CURW		Set new line width
	DCA	THISW		Reset word width back to zero
	JMP	MLOOP		Off for next character now
	EJECT
/
/	Here to handle a real hyphen. Main thing here is that we can break
/	a line on a real hyphen--so we must treat it specially.
/
REALH	LDI	1		Must be room for hyphen too on this line
	JMS	OVERSET		Test for oversetting this line
	TAD	CHAR		Then store the hyphen code into the buffer
	JMS	STAC		...
	TAD	=DELETE		allow room for sentinel here
	JMS	STAC		...
	LDI	-1		Account for fact that delete has no width
	JMP	5B		Merge now with discretionary hyphen processing
	TITLE	Process RTES commands
/
/	Here for the [w] command which specifies where we should fill
/	out the line with spaces to the full line width.
/
WCOM	TAD	=02000		Flag value to show where space goes
	DCA	COMC		Save (prepare for merge at WCOM2)
	LDI	1		Save address of where width goes
	TAD	LXR		...
	DCA	WPTR		For later use when [c] or [r] command found
	LDI	-1		Account for no width yet of this ''character''
	TAD	THISW		...
	DCA	THISW		...
	TAD	=' 		Default leadering character to a blank
	DCA	WCHAR		...
	JMS	GETC		Get the following character
	TAD	=-']		Test for end of command
	SNA			Skip if not
	JMP	WCOM2+1		All done here (off to store COMC)
	TAD	=']		Else restore character for leadering
	DCA	WCHAR		And save it
	JMP	WCOM2		Off to insist on ] being found now
/
/	Here for the [h] command which disables hyphenation of the next
/	word.
/
HCOM	INC	HYPHO		Prevent hyphenation of following word
	JMP	1F		All done
/
/	Here for the [n] command which disables line justification
/
NCOM	LDI	1		Set to turn JFLAG on below
/
/	Here for the [j] command which re-enables line justification
/
JCOM	DCA	JFLAG		Turn justification flag back on again
1H	JMS	FLUSHB		Flush out following ]
	JMP	MLOOP		Off for next character
/
/	Here for the [d] command which generates a string of the
/	current date. Must check that we really have a date here
/
DCOM	JMS	FLUSHB		Flush out ] from the [d] command
	TAD	DAYBUF		If first character is negative -- no date
	SPA CLA			Skip if we have a date here
	JMS	E4		ERROR - [D] AND NO OS/8 DATE ENTERED
/
	TAD	=DAYBUF-1	Set pointer to where date string is stored
/
/	Merge here from the end of the [-text] reference command to
/	generate the section and page number reference with the pointer
/	to where the string is stored in the AC
/
SWITCH	DCA	EXR		Set pointer to the string
	TAD	GETCHAR		Get current pointer (to PIKUP or LDC)
	DCA	GETCSV		and save it
	TAD	NEXTC		Get the next character from stream
	DCA	NEXTSV2		and save while we switch
	TAD	=GETEXR		Set pointer to read this string
	DCA	GETCHAR		...
	JMP	MLOOP-1		Off to prime NEXTC and return to MLOOP
/
/	Here to handle a centred line. Just compute the new indent for
/	the current line to get the prior text centred properly
/
CCOM	TAD	THISW		Get width of previous word
	TAD	CURW		Add accumulated width on the line
	TAD	INDENT		Add indent already present on this line
	TAD	MAXW		Subtract total line width
	CLL CMA IAC RAR		Make positive and divide by two
/
/	Merge here from right-hand margin command to set new indent value
/	Unless we have a [w] command in effect.
/
1H	DCA	PTR		Save value for a moment
	TAD	WPTR		Do we have a [w] command in effect?
	SZA			Skip if not
	JMP	3F		Yes - so handle it now
/
/	Also merge back here if [w] not on same line as [c] or [r]
/
4H	TAD	INDENT		No, so add value to current indent
	TAD	PTR		...
	DCA	INDENT		Set the new indent
/
/	Merge back here after processing prior [w] type command
/
2H	JMS	FLUSHB		Flush out the ] that must follow
	JMS	FLUSHLF		Flush all remaining characters on that line
	JMS	EOLCK		Check for multiple lines/indents after LF code
	JMP	LNDUMP		Off to print this line out now
/
/	Here for the [r] command which sets the previous text flush against
/	the right-hand margin.
/
RCOM	TAD	THISW		Get width of previous word
	TAD	CURW		Add accumulated width on the line
	TAD	INDENT		Add indent on this line
	TAD	MAXW		Subtract total line width
	CMA IAC			Make it a positive value
	JMP	1B		Back to set new indent value
/
/	Here to handle a [r] or [c] command when there was a prior [w]
/	command on the line.
/
3H	DCA	TEMP		Copy over the address now
	DCA	WPTR		Clear address to show no [w] in effect now
/
	LDI	-02000		First check that we are on the same line
	TADI	TEMP		Should find 2000 flag if so
	SZA CLA			Skip if still on same line
	JMP	4B		[w] not on same line, so skip it then
/
	LDI	02000		Set the flag to show leadering task
	TAD	PTR		Add spacing needed on this line
	DCAI	TEMP		Insert into the line where [w] command was
	JMP	2B		Loop back now to conclude processing
	EJECT
/
/	Here for the [s] command which allows text to be conditionally
/	stripped from the source file.
/
SCOM	JMS	GETC		Get the next character
	TAD	=-']		If just [s] command alone, this marks end
	SNA			of the text block to be stripped
	JMP	MLOOP		OK, all done here now
/
	TAD	=']-'9-1	Test for valid decimal digit
	CLL			...
	TAD	='9-'0+1	...
	SNL			Skip if decimal digit
	JMS	E6		Syntax error -- not a digit
	CMA			Negate and
	DCA	CNTR		Set as loop counter
	LDI	02000		set to ripple a bit through the AC
/
	RAR			Shift bit to find correct /n bit
	ISZ	CNTR		...
	JMP	*-2		...
/
	ANDX	SWITCH3		Isolate appropriate run-time switch
	SZA CLA			Skip if the switch is NOT set
	JMP	MLOOP		Switch is set -- so allow this text to appear
/
/	Loop here to strip all the text now until we find an [s] command
/	which marks the end of this conditional text block
/
2H	JMS	GETC		Get the next character
	TAD	=-'[		Look for start of another command
	SNA			Skip if not
	JMP	3F		Off to check out command now,
	TAD	='[-CTLZ	Ensure we don't pass the end-of-file if
	SNA CLA			The ] was forgotten
	JMS	E2		Error - closing ] was omitted
	JMP	2B		Else keep looking
/
3H	JMS	GETC		Get character after the '['
	JMS	FOLD		Fold to upper case alphabetic
	TAD	=-'S		Test for possible end to this command
	SNA CLA			Skip if not an [s] command
	JMP	SCOM		[S] command -- off to process it
	JMP	2B		Else loop back for next character
	EJECT
/
/	Here for the [f] command which sets the top margin, number of lines
/	and bottom margin formats.
/
FCOM	JMS	GETNUM		Get value for top margin
	DCA	DROP		And save it
	JMS	GETNUM		Get the number of lines per page
SLASHD2	CLL RAL			#NOP# if /D not set. If /D, multiply by two
	DCA	LINES		And save it
	JMS	GETNUM		Get the bottom margin
	DCA	BOTTOM		Set bottom margin
/
/	Merge here from the [p], [m] and [v] commands
/
FCOM2	TAD	CHAR		Ensure command ended with ]
	TAD	=-']		...
	SZA CLA			Skip if so
	JMS	E6		Syntax error in numeric command field
	JMS	IFLINE		Dump out prior line now if necessary
	JMS	FLUSHLF		Flush out all characters now to LF code
	JMS	EOLCK		Check for extra lines/indent after LF code
	JMP	PAGEJ2		Off now to generate extra lines needed
/
/	Here for the [m] command. Read the new position for the right
/	hand margin.
/
MCOM	JMS	GETNUM		Get new value for right-hand margin
	CMA IAC			Negate
	TAD	GAP		and subtract intercolumn gap in case /d
SLASHD3	STL RAR			#NOP# if /D not set. Else divide by two
	DCA	MAXW		For maximum line width
	JMP	FCOM2		Finish up now
/
/	Here for the [v] command. Read the position on the page that we
/	have to drop to and then set EXTRAL so that we will generate
/	the appropriate number of blank lines to get to that line.
/	If already past that line, ignore the [v] command.
/
VCOM	JMS	GETNUM		Read the line we have to tabulate to
	DCA	TEMP		Save line to get to
	LDI	2		LEFT is 2 larger than line about to go out
	TAD	LINES		Add number of lines on the page
	CMA IAC			Subtract from
	TAD	LEFT		Number of lines left on page
	TAD	TEMP		Now subtract from position to get to
	SPA			Skip if not past that line yet
	CLA			Past the line, set for no extra lines then
	DCA	PTR		Save number of blank lines to generate
	JMS	IFLINE		Dump out prior line now (if necessary)
	JMS	FLUSHLF		Flush out to LF code now
	JMS	EOLCK		Check for any blank lines/indent
	TAD	PTR		Get count of lines to generate
	DCA	EXTRAL		Set count (remove prior un-needed value)
	JMP	PAGEJ2		Merge back now to finish up
	EJECT
/
/	subroutine GETNUM reads a binary number from the character stream
/	and returns that value in the AC. Only valid terminators to a number
/	are a comma or a closing bracket.
/
GETNUM	SUB
	DCA	NUMBER		Initialize the result to zero
	JMS	GETC		Get the next character
	TAD	=-']		Test for ending bracket
	SZA			Skip if so
	TAD	=']-',		Else test for legal comma
	SNA			Skip if not terminator
	JMP	4F		TERMINATOR - all done here
/
	TAD	=',-'9-1	Must be a valid decimal digit now
	CLL			...
	TAD	='9-'0+1	...
	SNL			Skip if valid decimal digit
	JMS	E6		NOT A DIGIT  --  Syntax error in number
/
	DCA	TEMP		Save new binary digit
	TAD	NUMBER		Get current number
	CLL RTL			Multiply it by 10
	TAD	NUMBER		...
	CLL RAL			...
	TAD	TEMP		Add in the new digit
	JMP	GETNUM+1	Loop to store the digit and get next one
/
/	Here when done - just return the result in the AC
/
4H	TAD	NUMBER		Get the result
	RET	GETNUM		...
	TITLE	Process the symbolic reference command
/
/	Here to handle symbolic reference command
/
SREF	TAD	NFLAG		Are we inhibiting symbol table?
	SZA CLA			Skip if not
	JMS	E8		YES - symbolic references not allowed then
/
	DCA	SFLAG		Mark: no references seen yet at all
	DCA	PFLAG		Mark: no perfect matches found yet
	TAD	=06211		Setup CDF instruction for search
	DCA	SYMCDF2+1	...
	TAD	SYSTART		And initialize pointer to symbol table
	DCA	SYMPTR2		...
/
	DCA	HFLAG		Set to start with RH
	TAD	=-80		Label field limited to 80 characters
	DCA	GCNTR		...
	TAD	=REFER-1	Set pointer to buffer that will hold
	DCA	RPTR		the referenced label
/
/	Ensure all leading blanks after hyphen are trimmed.
/
8H	TAD	NEXTC		Peek ahead at next character
	TAD	=-' 		Look for blank
	SZA CLA			Skip if blank
	JMP	0F		All ok here -- continue
	JMS	GETC		Flush out leading blank
	CLA			Ignore the blank now in CHAR
	JMP	8B		Loop back now
/
/	Loop here to read the entire label on this reference and copy over
/	into the 30 word table REFER in 6-bit, folded ASCII code.
/	Note that for this reference, we will change a LF code to a blank
/
0H	JMS	GETC		Get the next character
	JMS	FOLD		Fold to upper case
	TAD	=-LF		Test for LF code
	SNA			Skip if not
	TAD	=' -LF		Else change LF to blank now
	TAD	=LF-']		Test for end of label
	SNA			...
	JMP	1F		All done with label here
/
	TAD	=']		Not at end, copy character over
	AND	=077		Truncate to 6-bit code
	SNA			Must not be an @ character (because it's 0)
	JMP	0B		Ignore @ character
	DCA	TEMP		Save this character
/
	LDI	04000		Flip the RH/LH switch
	TAD	HFLAG		...
	DCA	HFLAG		...
/
	TAD	TEMP		Reget the character
	SNL			If storing left, must advance pointer now
	INC	RPTR		OK - step the pointer
/
	SZL			If storing left, must move byte to LH of AC
	JMP	*+5		Ok - storing right
/
	CLL RTL			Shift the byte over
	RTL			...
	RTL			...
	JMP	*+2		Jump to zero right byte below
/
	TADI	RPTR		RH so merge in the old LH
	DCAI	RPTR		And store it back
/
	LOOP	0B,GCNTR	Loop back now
/
/	Here at end, install sentinel on REFER table
/
1H	INC	RPTR		Step pointer to next location
	DCAI	RPTR		Install the sentinel
	DCA	HFLAG		Reset the LH/RH switch again
	JMP	7F		Off to check for end of table now
/
/	Loop here to look for a match here on the next item
/
2H	TAD	=REFER-1	Set pointer to text to match
	DCA	RPTR		...
	TAD	=NLEVEL-1	Set pointer to where we will save LEVEL
	DCA	LPTR		...
	JMP	*+2		Don't step the pointer the first time through
/
/	Loop here to skip over the LEVEL field in the symbol table and
/	also save this level number in the NLEVEL table in case we match
/	on the text
/
3H	JMS	INCSYM2		Step the pointer to first word
	JMS	SYMCDF2		Set to field of table
	TADI	SYMPTR2		Get word from the table
	CDF	%*		Reset current field
	INC	LPTR		Step pointer into NLEVEL table
	DCAI	LPTR		Store LEVEL information into table
	TADI	LPTR		Reget the LEVEL
	SZA CLA			Skip if sentinel on LEVEL field
	JMP	3B		Else keep looking for it.
/
/	Loop here now to look for a match on the label on this section
/
4H	JMS	INCSYM2		Step pointer into text field in symbol table
	JMS	SYMCDF2		Set to field of table
	TADI	SYMPTR2		Load next pair of characters
	CDF	%*		Reset current field
	DCA	TEMP		Save for a moment
	TAD	TEMP		Reget and
	AND	=07700		Save the left byte
	CMA IAC			...
	DCA	TEMP1		negated
	TAD	TEMP		Reget again
	AND	=077		Save the right-hand byte
	CMA IAC			negated
	DCA	TEMP2		...
/
/	Now compare each byte individually, since we don't know
/	whether we have an odd or even # of characters in the string
/
	INC	RPTR		Step the pointer to the next word
	TADI	RPTR		Get the left byte
	AND	=07700		Isolate it
	SNA
	JMP	6F		Sentinel--we have a match here
	TAD	TEMP1		Compare with left byte we saved
	SZA CLA			Skip if we match here
	JMP	5F		Definitely no match here
/
	TADI	RPTR		Get the right byte
	AND	=077		Isolate it
	SNA			Test for sentinel on string
	JMP	6F+1		All done on sentinel (we have a match)
	TAD	TEMP2		Compare with right byte from table
	SNA CLA			Skip if no match
	JMP	4B		Else keep going if still matching
/
/	Here when there is no match, check for end of table
/
5H	JMS	SYMCDF2
	TADI	SYMPTR2		Are we already at the sentinel?
	CDF	%*		Reset field
	SNA CLA			Skip if not
	JMP	*+3		Ok -- we have found sentinel on text field
	JMS	INCSYM2		Else step pointer
	JMP	5B		and loop back till sentinel found
/
/	Here at start of a new entry. Test now to see if we are at the
/	end of the table.
/
	JMS	INCSYM2		Step past sentinel on last entry
/
/	Come here at the beginning to check for the end of the table
/
7H	TAD	SYMCDF2+1	Get CDF instruction
	CMA IAC			Negate and see if
	TAD	CDFTOP		we are now in the same field
	SZA CLA			Skip if so
	JMP	2B		Different fields -- definitely not at end yet
/
	TAD	SYMPTR2		Fields match - compare word pointers
	CMA IAC			...
	TAD	SYMTOP		...
	SZA CLA			Skip if at the end of the table
	JMP	2B		Not at end - so continue
/
/	Here at end of the table. Check now to see if we had a good match.
/	This is an error if we are in pass 2 or 3
/	(but not if we are in pass 1 since this may be a forward
/	reference) unless SFLAG is set which indicates that we did find
/	a match here
/
	TAD	PFLAG		Did we find a perfect match here?
	SNA CLA			Skip if so
	TAD	SFLAG		If not, did we find more than 1 match?
	TAD	=-1		...
	SMA SZA CLA		Skip if one perfect, or 1 normal match
	JMS	E11		OK--we definitely had a duplicate entry then
/
/	Ok, test now to see if we found a match at all here
/
	TAD	PFLAG		A perfect match?
	TAD	SFLAG		or any match at all in the table?
	SZA CLA			Skip if not
	JMP	SREFX		We did -- all done here
/
	TAD	PASS		Which pass are we in?
	SNA CLA			Skip if in pass 2/3
	JMP	MLOOP		Pass 1 -- not an error
	JMS	E8		Pass 2 -- definitely an error now
/
/	Here when we had a match. Just dump out the LEVEL number now
/	into the LINEB buffer, and follow it with the page number
/	First, however, we must check for a perfect match on the level
/	reference.
/
6H	TAD	=07700		Set mask for full word
	TAD	=077		Set mask for right byte only
	DCA	TEMP3		...
	TAD	TEMP		Get the word from the table
	AND	TEMP3		Mask, if necessary
	SZA CLA			Skip if perfect match here
	JMP	1F		Ok, we did not have a perfect match then
/
	TAD	PFLAG		Get count of perfect matches
	INC	PFLAG		increment count of perfect matches
	SZA CLA			Skip if first perfect match
	JMS	E11		Error - duplicate references here
	JMP	2F		Off to store the perfect match
/
1H	TAD	PFLAG		Have we had a prior, perfect match?
	SZA CLA			Skip if not
	JMP	5B		Yes we have (so ignore this imperfect match)
	INC	SFLAG		Update count of imperfect matches found
/
/	Come here to store the value of this section number
/
2H	TAD	=SAVEB-1	Initialize pointer
	DCA	KXR		for storing the generated text
	TAD	=NLEVEL+1	Set pointer to saved LEVEL information
	JMS	DOLEVEL,PUTKXR	Insert the level information via KXR
	EJECT
/
/	Now do the page number. This is complicated by the fact that to
/	retain hyphenation/justification/paging we must output the same
/	number of units in pass 2 and pass 3. If we don't do this, there
/	is a small chance that the hyphenation/paging may get out of
/	synchronization. The chance seems admittedly small, but it did
/	happen to us once, so we should ensure this can not happen.
/
/	we do this by outputting a slightly different message depending
/	on the page number to be processed:
/
/	(S.  1)			for 1 digit page
/	(S. 23)			for 2 digit page
/	(S 123)		for 3 digit page
/
/	Note that the '.' has no mark bit (this avoids it being treated
/	as a punctuation period, which can affect the line justification
/	algorithm from pass to pass, if the # of pages change!). For the
/	same reason, the separating blank must not be recognized as a
/	place where the line could be broken up.
/
	TAD	NLEVEL		Get the saved page number
	JMS	BINDEC		Convert to decimal ASCII number
	TAD	=' 		Justifiable blank here
	JMS	PUTKXR		...
	TAD	='(		Open parenthesis
	JMS	PUTKXR		...
	TAD	='S		Capital S
	JMS	PUTKXR		...
/
	TAD	HIGH		Get the high order digit
	SZA CLA			Skip if 2-digit page number
	JMP	9F		3-digit page number -- all done here
	TAD	='.-0200	Period after 'S' for 2-digit number
	JMS	PUTKXR		...
	TAD	MID		Do we have a single-digit page number?
	SZA CLA			Skip if 1 digit
	JMP	9F		Off to insert separating blank now
	TAD	=' -0200	Extra blank for one digit
	JMS	PUTKXR		...
/
/	Merge here to output blank before page number
/
9H	TAD	=' -0200	Non-justifying blank here
	JMS	PUTKXR		...
/
	TAD	HIGH		Get high order part
	SZA			Ignore if zero
	JMS	PUTKXR		Else store into buffer
	TAD	MID		Get middle part
	SZA			Skip if leading zero
	JMS	PUTKXR		Else store into buffer
	TAD	LOW		Always store the low order part
	JMS	PUTKXR		...
	TAD	=')		Closing parenthesis
	JMS	PUTKXR		...
/
	JMS	PUTKXR		Install sentinel of 0 on the buffer
	JMP	5B		Loop back now to check for duplicate entry
/
/	Come back here at the end when everything is all right
/
SREFX	TAD	=SAVEB-1	Get pointer to the buffer
	JMP	SWITCH		Off to read this string now
/
/	Little subroutine to place contents of AC via KXR
/
PUTKXR	SUB
	DCAI	KXR		Store into buffer
	RET	PUTKXR		All ok
	EJECT