	.TITLE	GCIN
	.IDENT	/V01/
	.PSECT	$TEMP,RW,D,OVR,GBL
	.BLKB	1
TBUFF:	.BLKB	SUBMAX+2
	.PSECT	GCTABL,RW,D
;
;	INPUT CHARACTER PARSING TABLES
;		TO ADD MORE FLAGS THESE TABLES MUST BE CHANGED
;		THE FLAG DEFINITIONS COORESPOND TO THE FLAG SWITCHES
;
GC.UC==0			; Upper case letters
GC.LC==2			; Lower case letters
GC.AFL==4			; Accept flag
GC.CFL==6			; Capitalize flag
GC.UFL==10			; Underline flag
GC.LFL==12			; Lowercase flag
GC.SFL==14			; Uppercase flag
GC.QFL==16			; Quoted space flag
GC.OFL==20			; Overstrike flag
GC.IFL==22			; Index flag
GC.HFL==24			; Hyphenation flag
GC.EFL==26			; Escape flag
GC.SUB==30			; substitute flag
GC.BRK==32			; break flag
GC.NFL==34			; COMMAND FLAG
GC.CR==36			; CARRIAGE RETURN
GC.TAB==40			; tab input char
GC.LF==42			; lin feed input
GC.DIG==44			; digit (0-9)
GC.SPC==46			; space
GC.MSC==50			; MISCELLANEOUS CHARS
GC.SPF==52			; Special flag
GC.EQ1==54			; Equation flags
GC.EQ2==56			; Equation flags
GC.SIX==60			; Subindex flag
GO.UNL==-2			; underline 1 char
GO.ESC==-12			; begin escape sequence
GO.QTS==-14			; quoted space output
GO.BS==-16			; backspace output
GO.TAB=-20			; Tab count byte follows
GO.ELP=-22			; Ellipses count follows this
GC.ILL=-24			; illegal character
GO.REP=-26			; Repeat characters
GO.INX=-30			; Index entry
GO.TOC=-32
;
;	THE FOLLOWING CORRESPOND TO THE ASCII CHARACTERS
;
GCTABL:: .BYTE	GC.ILL,GC.ILL,GC.ILL,GC.ILL,GC.ILL,GC.ILL	; NUL-ENQ
	.BYTE	GC.ILL,GC.ILL,GO.BS				; ACK-BS
	.BYTE	GC.TAB,GC.LF,GC.ILL,GC.ILL			; TAB,LF,VT,FF
	.BYTE	GC.CR,GC.ILL,GC.ILL,GC.ILL			; CR,SO,SI,DLE
	.BYTE	GC.ILL,GC.ILL,GC.ILL,GO.TOC,GC.ILL		; DC1-nak
	.BYTE	GO.INX,GO.REP,GO.TAB,GO.ELP,GC.ILL		; SYN-SUB
	.BYTE	GO.ESC,GO.UNL,GC.ILL,GC.ILL,GC.ILL		; ESC-US
	.BYTE	GC.SPC						; SPACE
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC	;  - &
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC	; ' - ,
	.BYTE	GC.MSC,GC.MSC,GC.MSC				; - . /
	.BYTE	GC.DIG,GC.DIG,GC.DIG,GC.DIG,GC.DIG		; 0 - 4
	.BYTE	GC.DIG,GC.DIG,GC.DIG,GC.DIG,GC.DIG		; 5 - 9
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC ; : - @
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC		; UPPER CASE
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC		; UPPER CASE
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC		; UPPER CASE
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC	; UPPER CASE
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC	; [ - `
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC		; LOWER CASE
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC		; LOWER CASE
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC		; LOWER CASE
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC	; LOWER CASE
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC			; { - ~
	.BYTE	GO.QTS						; DEL
;
;	CHARACTER DEFINITION TABLE
;
CH.BRK==1			; Char is followed by break
CH.ES2==2			; Char is second char in escape seq.
CH.FLC==4			; CHAR MAY BE FLAG CHAR
CH.FLG==10			; CHAR IS CURRENTLY FLAG CHAR
CH.PER==20			; CHAR IS PUNCTUATION
CH.VOW==40			; character is a vowel
CH.PNC==100			; char is punctuation (for routine HYPHEN)
CH.UNL==200			; char is not underlinable
CHTABL:: .BLKB	9.			; Nul-BS
	.BYTE	CH.FLC			; Tab
	.BLKB	22.			; LF-US
	.BYTE	CH.PNC!CH.UNL		; "space"
	.BYTE	CH.FLC!CH.PNC!CH.PER	; !
	.BYTE	CH.FLC!CH.PNC		; "
	.BYTE	CH.FLC			; #
	.BYTE	CH.FLC			; $
	.BYTE	CH.FLC			; %
	.BYTE	CH.FLC			; &
	.BYTE	CH.FLC			; '
	.BYTE	CH.FLC!CH.PNC		; (
	.BYTE	CH.FLC!CH.PNC		; )
	.BYTE	CH.FLC			; *
	.BYTE	CH.FLC			; +
	.BYTE	CH.FLC!CH.PNC		; ,
	.BYTE	CH.FLC			; -
	.BYTE	CH.FLC!CH.PER!CH.PNC	; .
	.BYTE	CH.FLC!CH.PNC		; /
	.BLKB	10.						; 0 - 9
	.BYTE	CH.FLC!CH.PER,CH.FLC!CH.PER			; : ;
	.BYTE	CH.FLC,CH.FLC,CH.FLC				; < = >
	.BYTE	CH.FLC!CH.PER,CH.FLC!CH.PNC			; ? @
	.BYTE	CH.VOW,0,0,0,CH.VOW,0,0,0			; A-H
	.BYTE	CH.VOW,0,0,0,0,0,CH.VOW,0			; I-P
	.BYTE	0,0,0,0,CH.VOW,0,0,0				; Q-X
	.BYTE	CH.VOW,0					; Y-Z
	.BYTE	CH.FLC			; [
	.BYTE	CH.FLC!CH.PNC		; \
	.BYTE	CH.FLC			; ]
	.BYTE	CH.FLC			; ^
	.BYTE	CH.FLC			; _ underscore
	.BYTE	CH.FLC			; `
	.BYTE	CH.VOW,0,0,0,CH.VOW,0,0,0			; A-H
	.BYTE	CH.VOW,0,0,0,0,0,CH.VOW,0			; I-P
	.BYTE	0,0,0,0,CH.VOW,0,0,0				; Q-X
	.BYTE	CH.VOW,0					; Y-Z
	.BYTE	CH.FLC,CH.FLC,CH.FLC,CH.FLC			; { - ~
	.BYTE	CH.PNC						; DEL
	.even

	.psect	$TABL,RO,D,LCL,CON
BITABL:: .WORD	1,2,4,10,20,40,100,200,400
	.WORD	1000,2000,4000,10000,20000,40000,100000
	.PSECT	TEXT,RO,D,LCL,CON
ILSBCM:	.ASCIZ	/RNO -- Unrecognized command/
ILSBST:	.ASCIZ	/RNO -- Too many nested substitutions/
ILSBND:	.ASCIZ	/RNO -- Undefined substitution/
ILUNES:	.ASCIZ	/RNO -- Undefined escape seq./
	.PSECT	$CODE,I,RO,LCL,CON
;
;	THE JUMP TABLE TO PARSE CHARS
;
;		NOTE: HOOK FOR AUTOINDEXING EXISTS BUT NO AUTO INDEX ROUTINE YET
	.WORD	HLTER,GOTOC,GOINX,GOREP,HLTER,GOELP,GOTAB
	.WORD	GOBS,GOQTS,GOESC,HLTER,HLTER,HLTER,GOUNL
GCJMP:	.WORD	GCDN,GCUP,GCACC,GCCAP
	.WORD	GCUNL,SHFDN,SHFUP,GCQTS
	.WORD	GCOVR,GCIFL,GCHYP,GCESC
	.WORD	GCSUB,GCBRK,GCINR,GCCR
	.WORD	GCTAB,GCLF,GCINR,GCSPC
	.WORD	GCINR,GCSPF,GCEQN1,GCEQN2
	.WORD	GCSIX
;
;	GET INPUT CHARACTER FROM SOURCE FILE AND INTERPRET IT
;
GCIN::	CALL	CCIN		; GET CHARACTER FROM FILE.
GCIN1:	MOVB	GCTABL(R1),R0	; GET CHARACTER TYPE
DSPTCH:	JMP	@GCJMP(R0)	; DISPATCH ACCORDING TO TABLE
;
;	HERE ARE SPECIAL CHARACTER CASES
;
;	UPPER CASE
GCDN:	TSTB	CASE		; CONVERSION NECESSARY
	BGE	GCINR		; NO
GCDN1:	ADD	#40,R1		; CONVERT CASE IF NECESSARY
	BR	GCINR		; 		
;	LOWER CASE LETTERS
GCUP:	TSTB	CASE		; CONVERSION NECESSARY
	BLE	GCINR		; NO
GCUP1:	SUB	#40,R1		; CONVERT TO UPPER CASE
	BR	GCINR		; 		
;	CAPITALIZE FLAG
GCCAP:	TSTNEB	$CFLSW+1,GCINR	; Flag temporarily disabled ?
	MOVB	#1,CASE		; SET WORD CAPITALIZE CONVERSION VALUE
	BR	GCIN		; 
;	ACCEPT FLAG
GCACC:	TSTNEB	$AFLSW+1,GCINR	; Flag temporarily disabled ?
	CALL	CCIN		; READ CHARACTER NO TRANSLATION
	CMPB	R1,#SPC		; Compare with space
	BGT	GCINR		; Not space or less ?
	BEQ	GCQTS1		; Space ? Make it quoted space
	BR	GCIN1		; Less than space ?
;	UNDERLINE FLAG
GCUNL:	TSTNEB	$UFLSW+1,GCINR	; Flag temporarily disabled ?
	BITB	#^C<SW.TDS>,$UNLSW	; CHECK UNDERLINING SWITCH
	BNE	GCIN		; Permanently disabled ?
	MOV	#ULCHS,R1	; SET TO UNDERLINE CHARACTER
	MOV	R1,$UNLLN	; Set to mark this line as underlined
	JMP	GCINO		; 
;	OVERSTRIKE FLAG
GCOVR:	TSTNEB	$OFLSW+1,GCINR	; Flag temporarily disabled ?
	BISB	#SW.TDS,$AUHYP	; Temporary disable hyphenation
	TSTEQB	$OVRSW,10$	; OVERSTRIKE ENABLED?
	INC	OVRCT		; YES, COUNT ABORTED CHARS.
	BR	GCIN		; MORE INPUT	
10$:	MOV	#BS,R1		; MAKE IT BACK SPACE
	ADD	PHSP,LINBK	; Add to remaining chars
	SUB	PHSP,SPCH	; Subtract from spacing characters
	BR	GCINO		; 
;	HYPHENATE FLAG
GCHYP:	TSTNEB	RETSW,GCLF	; Return ?
	TSTNEB	$HFLSW+1,GCINR	; Flag temporarily disabled ?
	BISB	#SW.TDS,$AUHYP	; Set temporary no auto hyphenation
	TST	LINBK		; Check room on page
	BLE	GCIN		; No room for hyphenation ?
	CMPEQB	LCH,#SPC,GCIN	; Last char space ?
	CMPEQB	LCH,#TAB,GCIN	; or tab ?
	CMPEQB	LCH,#NXS,GCIN	; or non expandable space ?
	MOV	SPCH,HYPSP	; Hyphenation spacing chars.
	BR	GCIN
;	QUOTED SPACE FLAG
GCQTS:	TSTNEB	$QFLSW+1,GCINR	; Flag temporarily disabled ?
	TSTNEB	RETSW,GCLF	; Return ?
	MOVB	ULOCK,CASE	; RESET CASE
GCQTS1:	MOV	#NXS,R1		; SET NON EXPANDABLE SPACE
	BISB	#SW.TDS,$AUHYP	; Set temporary no auto hyphenation
	BR	GCINR1		; AND SAVE IT
GCINR::	BIC	#1002,CASE	; Reset temporary upper case conversion
GCINR1:	TSTEQ	OVRCT,10$	; NO BACKSPACE ABORTS
	DEC	OVRCT		; DECREMENT ABORTS
	BR	GCIN		; NEXT CHAR
10$:	ADD	PHSP,SPCH	; Add to spacing char count
	MOVB	R1,LCH		; SAVE LAST CHARACTER
	CALL	PUBYT		; OUTPUT CHAR
	MOV	TESMSK,R4	; Cancel escapes ?
	BEQ	12$		; No ?
	CALL	ESCEND		; Cancel them
12$:	MOVB	LCH,R1
	BITEQB	#CH.BRK,CHTABL(R1),16$	; No AutoBreak ?
	TSTNEB	$AUBRK,16$	; No break ?
	TST	LINBK		; Past end of line ?
	BLE	16$		; Yes ?
	BISB	#SW.TDS,$AUHYP	; set temporary no hyphenation
	TSTEQB	$TABPD,14$	; No right tabs ?
	CALL	BRKTS		; Set them up
	BR	16$		; done
14$:	CALL	BRKSV		; Set up break here
16$:	SUB	PHSP,LINBK	; Subtract from char count remaining
	BEQ	20$
	BCC	70$		; NO
	CMPEQ	PHSP,#1,70$	; Single decrement ?
20$:	MOV	SPCH,LNINS	; Char count at last character
	TSTNE	BRCNT,30$	; NO breaks this line?
	CALL	BRKSV		; Save break here
30$:	TSTNEB	$GCEND,GCLF	; Immediate end requested?
70$:	JMP	GCIN		; Continue
GCLF:	RETURN
GCINO:	CALL	PBYT		; OUTPUT CHAR
	JMP	GCIN		; CONTINUE PARSING INPUT

;
;ROUTINE TO READ INPUT FROM FILE AND REMOVE BAD INPUT
;		R1=	CHARACTER READ
;
CCIN::	MOV	BUFAD,R1	; input buffer header
10$:	CALL	GBYT1		; get input
	BIC	#^C<177>,R1	; CLEAR EXCESS BITS
;	BCS	20$		; Not ok?
;	BEQ	20$		; At end of buffer ?
	BLOS	20$		; At end of buffer ?
	TSTB	GCTABL(R1)	; LEGAL CHARACTER?
	BLT	CCIN		; NO GET ANOTHER
	RETURN
20$:	MOVB	SUBSTK,R1	; Get current substitute stack
	BEQ	30$		; End of input line ?
	DEC	R1		; pop stack
	DEC	R1		; pop stack
	MOVB	R1,SUBSTK	; New value
25$:	MOV	BUFADD(R1),R1	; New buffer address
	MOV	R1,BUFAD	; Save it
	BR	10$		; try again
30$:	MOV	BUFADD,BUFAD	; Restore
	CALL	FIN		; NO. READ FROM FILE
	BCC	CCIN		; Successful input ?
	RETURN			; None to get
;
;	routine to parse substitution - SUBSTITUTE FLAG
;
GCSUB:	TSTEQB	$SBFSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	MOV	R3,-(SP)	; save
	MOV	BUFAD,R3	; get buffer header for input
	MOV	#TBUFF-1,R2	; temporary buffer
	MOVB	R1,(R2)+	; Save flag
	CLRB	(R2)		; Clear in case no more
	MOV	BF.FUL(R3),-(SP) ; save current location
	MOV	#SUBMAX,R4	; max number of char/label
50$:	CALL	GBYT		; get input
	CMP	R1,#SPC		; non printable?
	BLE	60$		; yes, done
	CMPNEB	GCTABL(R1),#GC.LC,55$	; Not lower case ?
	CMPEQ	R2,#TBUFF,55$		; Not first char ?
	SUB	#40,R1		; Make it lower case
55$:	MOVB	R1,(R2)+	; Save char
	SOB	R4,50$		; no, continue
60$:	CLRB	(R2)+		; Chock end of string
	MOV	#TBUFF,R2	; Start of buffer
	CMPNEB	(R2),$SBFSW,65$	; First char not substitute flag ?
	MOVB	#'$,(R2)	; Make first char $
65$:	MOV	(SP)+,R1	; current location
	CALL	FNDBF		; go back to it
	CALL	FNDSB		; Find substitution
	MOV	(SP)+,R3	; restore
	JMP	GCIN
;
;	Find substitutions All registers destroyed
;
FNDSB::	MOVB	SUBSTK,R3	; substitution stack pointer
	CMPB	R3,SUBSTK+1	; max stack reached?
	BLO	40$		; no
	MOV	#ILSBST,R0	; Too many nestings error
	BR	20$
10$:	MOV	#ILSBND,R0	; Undefined substitution error
	TSTB	TBUFF
	BGE	20$		; Not command ?
	MOV	#ILSBCM,R0	; Undefined command
20$:	CALL	EROUT
	MOV	#TBUFF-1,R0	; Print substitution
	BICB	#200,1(R0)	; Clear extra bits
	CALL	EROUT
	CALL	ONLIN		; Print line number
30$:	SEC
	return
40$:	MOV	BUFADD+2(R3),R3	; next stack header
	MOV	#SUBF0,R2	; Prototype header
	CALL	SAVTBF		; Get prototype header
	CALL	GWRD		; First index
	BCS	10$		; None?
70$:	TSTEQ	R1,10$		; None ?
	CALL	FNDBF		; Find next entry
	CALL	GWRD		; get next index
	BCS	10$		; end, no escape found
	MOV	R1,R4		; save
	MOV	#TBUFF,R2	; temporary buffer
	MOV	BF.FUL(R3),BF.SPC(R3)	; Save index for traceback
80$:	CALL	GBYT		; Get next char in key word table
	BCS	10$		; None?
	TSTEQ	R1,90$		; end of search?
81$:	CMPEQB	R1,(R2)+,80$	; match?
	TSTB	TBUFF		; Check first byte
	BGT	87$		; Not command ?
	DEC	R2		; Go back to last char checked
	CMPEQB	R1,#SPC,80$	; Space in table ?
	CMPNEB	-1(R2),#SPC,87$	; Char before last not space ?
	CMPEQB	(R2)+,#SPC,81$	; Current space ?
87$:	MOV	R4,R1		; Next entry index
	BR	70$		; search again
90$:	TSTB	TBUFF		; Check for command
	BGT	92$		; Not commad
	MOVB	(R2),R0		; Get terminal char
	CMPEQB	GCTABL(R0),#GC.UC,87$	; Upper case char ?
92$:	MOV	R2,R1		; end of string
	SUB	#TBUFF,R1	; find string length
	MOVB	SUBSTK,R3	; current input
	ADD	#2,R3		; next entry
	TSTB	TBUFF
	BLT	95$		; Command ?
	TSTNEB	$SUBSW,100$	; substitution suppressed?
95$:	MOVB	R3,SUBSTK	; into stack
	MOV	BUFADD(R3),BUFAD; New buffer address
100$:	MOV	BUFADD-2(R3),R3	; input buffer header
	ADD	BF.FUL(R3),R1	; add word size to current index
	CALL	FNDBF		; skip over $ and key word
	CLC
	RETURN			; done, continue with normal sequence

;
;	TAB character handled here.  It is expanded.
;
GCTAB:	TSTNEB	$TABSW,GCSPC	; NO TABS ALLOWED?
	BISB	#SW.TDS,$AUHYP	; No autohyphenation now
	MOVB	ULOCK,CASE	; RESTORE CASE
	CALL	BRKTS		; Test + execute right tabs
	CLR	R2
	CALL	TABB		; FIND WHERE NEXT TAB STOP IS
	CMP	R2,LINBK	; Does this exceed line size?
	BLE	20$		; It is OK ?
	TST	LINBK		; Currently too long ?
	BLT	10$		; Yes
	CALL	BRKSV		; No, put break here
10$:;	MOV	#-1,LINBK	; Set line too long
	MOVB	#TAB,R1		; Current char
	RETURN
20$:	TSTEQB	$TABLF,30$	; Left justify  tabs ?
	MOV	#1,R2		; Only 1 space for right justify
	MOVB	R2,$TABPD	; Now set 1 tab pending
30$:	CMPNEB	LCH,#TAB,25$	; Was last char not tab ?
	TSTEQ	LTAB,25$	; No tab pending
	SUB	R2,LINBK	; AND DECREMENT LINBK COUNT BY THAT AMOUNT
	ADD	R2,SPCH		; Add to spacing characters
	CALL	ADDTAB		; Add r2 to previous tab
	BR	TABXIT		;
25$:	CALL	BRKSV		; Set break here
	SUB	R2,LINBK	; AND DECREMENT LINBK COUNT BY THAT AMOUNT
	ADD	R2,SPCH		; Add to spacing characters
	MOVB	#TAB,LCH	; LAST CHAR
	MOVB	#TABO,R1	; Set to output tab
	TSTEQB	$ELIPS,40$	; No ellipses?
	MOVB	#ELIP,R1	; Yes, set to output ellipses
40$:	CALL	PBYT		; Into buffer
	MOV	R2,R1		; Number of spaces
	CALL	PBYT		; Into buffer
	MOV	BF.ADD(R3),LTAB	; Address of last tab char
TABXIT:	JMP	GCIN		; Next char
;
;	End of line action, space if fill disabled
;
GCCR:	TSTNEB	$CENSW,10$	; Centering enabled ?
	TSTNEB	$RIGSW,10$	; Right justify enabled
	BITNE	#FILLF,F.1,GCSPC ; Fill enabled ?
10$:	CALL	BRKTS		; Test tab + break
	TST	LINBK		; Past end of line ?
	BGE	TABXIT		; No ?
	RETURN			; Yes !
;
;	Handle spaces in input stream
;
GCSPC::	TSTNEB	RETSW,SPCRET	; Return ?
	MOVB	ULOCK,CASE	; RESTORE CASE
	TST	LINBK		; Line full ?
	BGE	10$		; NO ?
	TSTNE	@EQSTK,10$	; Equation being formatted ?
	RETURN			; Yes, break for full line
10$:	CALL	BRKTS		; Test and set up right tabs
	BITEQ	#FILLF,F.1,30$	; FILL disabled ?
	MOVB	LCH,R1		; GET PREVIOUS CHARACTER WHAT WAS IT?
	BEQ	TABXIT		; Start of new line ?
	CMPEQ	R1,#SPC,TABXIT	; Space before space ?
	CMPEQ	R1,#TAB,TABXIT	; Tab before space ?
	CMPEQ	R1,#NXS,TABXIT	; Non expandable space before space ?
	TSTEQB	$PERSW,30$	; Automatic punctuation spacing disabled ?
	BITEQB	#CH.PER,CHTABL(R1),30$ ; Not Punctuation before space ?
	CMP	LINBK,#1	; Space left ?
	BLE	30$		; No
20$:	CALL	50$		; Set up for space
	CALL	PUBYT		; Save space
	ADD	PHSP,SPCH	; Add to spacing chars
	SUB	PHSP,LINBK	; And subtract from char left
	MOV	#NXS,R1		; Next output non expandable space
	BR	40$		; 
30$:	CALL	50$		; 
40$:	BICB	#SW.TDS,$HYPSW	; Allow hyphenation
	BICB	#SW.TDS,$AUHYP	; Allow auto hyphenation
	CLR	HYPSP
	JMP	GCINR1		; RETURN CHAR.
50$:	TSTNE	@EQSTK,70$		; Equation in progress
	CALL	BRKSV		; Set up for break here
	TSTNEB	$NOSPC,70$	; No expandable spaces allowed ?
	INC	SPCNT		; COUNT THIS SPACE
	MOV	#SPC,R1		; SPACE CHARACTER (EXPANDABLE)
60$:	RETURN			; 
70$:	MOV	#NXS,R1		; Make it non expandable
SPCRET:	RETURN
;
;	break flag here
;
GCBRK:	TSTNEB	RETSW,SPCRET	; Return ?
	TSTEQB	$BRFSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	BISB	#SW.TDS,$AUHYP	; set temporary no hyphenation
	TST	LINBK		; Past end of line
	BGE	10$		; Not yet
	RETURN
10$:	TSTEQB	$TABPD,20$	; No right tabs ?
	CALL	BRKTS		; Set them up
	JMP	GCIN		; done
20$:	CALL	BRKSV		; Set up break here
	JMP	GCIN		; next char
;
;	Test and set up right tab
;
	.ENABL	LSB
BRKTS:	TSTEQB	$TABPD,10$	; No tab pending?
	TSTEQ	LTAB,10$	; No tab address ?
	CLRB	$TABPD		; No more tabs pending
	MOV	#-1,R2		; Initial tab
	CALL	TABB		; Find next tab stop
	DEC	R2		;
	CMP	R2,LINBK	; Too many for line ?
	BGT	10$		; YES. TREAT AS SPACE, NOT TAB
	ADD	R2,SPCH		; Spacing chars
	SUB	R2,LINBK	; Current length this line
ADDTAB:	MOVB	@LTAB,R1	; Get last tab
	ADD	R2,R1		; Add on more
	MOVB	R1,@LTAB	; Increment old tab
10$:	RETURN
	.DSABL	LSB
;
;	Set up break (save current character status)
;
BRKSV::	CALL	LSINSV		; save input addresses
	CLRB	HYPSP
	INC	BRCNT		; count breaks this line
	MOV	PHSP,LPHSP	; Spacing at break
	MOV	CASE,CASSAV	; SAVE CURRENT CASE
	MOV	BF.FUL(R3),LSTSP ; POSITION IN BUFFER
	MOV	ESMSK,LESMSK	; Save current escape mask
	MOVB	$UNLSW,LUNLSW	; And underline status
	MOVB	LCH,LSCH	; SAVE CHAR BEFORE SPACE
	MOV	SPCNT,SPCNSV	; Save old space count
	MOV	SPCH,LSPCH	; Save current spacing char count
	RETURN

;
;	Here we handle Index flag
;
GCIFL:	TSTEQB	$IFLSW+1,10$	; Autoindex flag on ?
	JMP	GCINR		; No, ouput char
10$:	CALL	AINDEX		; Do autoindex
	JMP	GCIN		; Continue
;
;	SUBINDEX FLAG
;
GCSIX:	CMPNEB	LCH,#SPC,20$	; Not last space
	MOV	LSTSP,R1	; Abort last space
	CALL	RSTBF		; Terminate buffer here
20$:	CLR	LCH		; Set last to null
	MOVB	#SXCHR,R1	; Get subindex character
	JMP	GCINO		; Save subindex flag
;
;	HERE WE HANDLE SEPARATE ESCAPE SEQUENCES
;
GCESC:	TSTEQB	$EFLSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	MOV	R1,R5		; First character
	CALL	CCIN		; GET NEXT CHAR
GCES1:	CALL	ESCSEQ		; ESCAPE SEQUENCE?
	BCC	10$		; No ?
	MOV	#ILUNES,R0	; Message undefined escape
	CALL	EROUT		; Print message
	CALL	ONLIN		; Print line number
10$:	JMP	GCIN		; NEXT CHAR
;
;	Special Flag character detected
;
GCSPF:	TSTEQB	$SPFSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	MOV	#'^+100000,R5	; Move in shift up operator+ temp flag
	CALL	ESCSEQ		; Execute sequence
	BCC	10$		; Not executed ?
	MOV	#ILUNES,R0	; Message undefined escape
	CALL	EROUT		; Print message
	CALL	ONLIN		; Print line number
10$:	JMP	GCIN		; Continue
;
;	SUBROUTINE TO FIND ESCAPE SEQUENCE FROM TABLE
;
;		R4=Escape sequence mask
;		R3	is preserved/ all other registers changed
	.enabl	LSB
ESCBEG:: CLR	R5		; Look for begin sequence
	BR	1$
ESCEND:: MOV	#177,R5		; Look for end sequence
1$:	TSTEQ	R4,7$		; No escapes ?
	TSTNEB	$ESCSW,7$	; Escapes disabled ?
	MOV	R3,-(SP)	; Save current buffer
	MOV	#ESCBF,R3	; Escape buffer
	CALL	BEGBF		; Start at beginning
	MOV	(SP)+,R3	; Restore
2$:	TSTEQ	R4,7$		; Done ?
	CALL	11$		; Do next sequence
	BCC	2$		; Ok ?
7$:	RETURN
11$:	MOV	R3,-(SP)	; Save current buffer
	MOV	#ESCBF,R3	; Escape buffer
12$:	CALL	GBYT		; Get count
	BCS	17$		; Done ?
	MOV	BF.FUL(R3),-(SP)	; And current index
	MOV	R1,R2		; Character count
	CALL	GBYT		; Skip 1 byte
	CALL	GBYT		; Skip 1 byte
	CALL	GBYT		; Skip 1 byte
	MOV	R1,-(SP)	; Save status
	BITNEB	#ES.LCK,R1,4$	; Is this lock status ?
3$:	TST	(SP)+		; Pop status
	MOV	R2,R1		; number of bytes to skip
	ADD	(SP)+,R1	; New index
	CALL	FNDBF		; skip them
	BR	12$		; Try again
4$:	CALL	GBYT		; Get lock byte
	BLT	5$		; Unlock ?
	TSTNEB	R5,3$		; Lock desired ?
	ADD	#BITABL,R1	; Now points to table
	BITEQ	(R1),R4,3$	; Not requested escape ?
	BIC	(R1),R4		; Clear 1 bit
	BR	31$		; Ok!
5$:	TSTEQB	R5,3$		; Unlock desired ?
	ADD	#BITABL-177600,R1	; Compensate for hi bits
	BITEQ	(R1),R4,3$	; Not requested escape ?
	BIC	(R1),R4		; Clear 1 bit
	BITNE	(R1),TESMSK,32$	; Clearing temporary bit?
	BR	31$
;
;	R5	= first char
;	R1	= second char
;	R3,R5	are preserved
;	C	= set if sequence not found
;
ESCSQ0:	CMPB	GCTABL(R1),#GC.LC; Check if letter
	BGT	ESCSEQ		; Not letter ?
	BITNEB	#CH.ES2,CHTABL(R1),ESCSEQ; Escape character ?
	SEC
	RETURN
ESCSEQ:	MOV	R3,-(SP)	; save current buffer
	MOV	#ESCBF,R3	; escape buffer
	MOV	R1,R4		; SAVE CHAR
	CALL	BEGBF		; Start at beginning
10$:	CALL	GBYT		; get beginning of sequence
	BCC	20$		; not end of table?
	MOVB	R4,R1		; GET CHAR BACK
17$:	MOV	(SP)+,R3	; restore
15$:	SEC			; NO SEQ FOUND	
	RETURN
20$:	MOV	BF.FUL(R3),-(SP)	; And save current index
	MOV	R1,R2		; number of bytes in sequence
	CALL	GBYT		; get next bytes
	CMPNEB	R5,R1,25$	; MATCH WITH CHAR?
	CALL	GBYT		; get next bytes
	CMPEQB	R4,R1,30$	; MATCH WITH CHAR?
25$:	MOV	R2,R1		; number of bytes to skip
	ADD	(SP)+,R1	; add on current index
	CALL	FNDBF		; skip them
	BR	10$				
30$:	TSTEQB	$ESCSW,27$	; ESCAPE SEQUENCES not DISABLED?
	JMP	55$		; Disabled
27$:	BISB	#SW.TDS,$AUHYP	; set temporary no hyphenation
	CALL	GBYT		; Get flag byte
	BEQ	40$		; No flag byte ?
	MOVB	R1,-(SP)	; Save bit mask
	BITEQB	#ES.LCK,(SP),31$	; Not lock/Unlock ?
	CALL	GBYT			; Get lock word
	BLT	21$			; Unlock ?
	ADD	#BITABL,R1		; Points to bit table
	BITNE	(R1),ESMSK,54$		; Is it currently locked on ?
	BIS	(R1),ESMSK		; Lock it on
	TST	R5			; Do we do temporary lock
	BGT	31$			; No
	BITEQB	#ES.CHR,(SP),31$	; Not temporary sequence
	BIS	(R1),TESMSK		; Set temporary mask
	BR	31$
21$:	ADD	#BITABL-177600,R1	; Compensate for hi bits
	BITEQ	(R1),ESMSK,54$		; Currently locked off ?
32$:	BIC	(R1),ESMSK		; Lock it off
	BIC	(R1),TESMSK		; Clear temporary mask also
31$:	BITEQB	#ES.VSP,(SP),33$	; No vertical spacing
	CALL	GBYT			; Get vertical spacing
	TSTNEB	$PAGNG,299$		; No paging ?
	SUB	R1,LINEC3		; Decrement lines left
	ADD	R1,BF.VSP(R3)		; Add to saved spacing
299$:	ADD	CURVS,R1		; Add on current VS
	MOV	R1,CURVS		; Save current
	CMP	R1,MINVS		; Compare with min
	BGT	311$			; Bigger ?
	MOV	R1,MINVS		; New min
311$:	CMP	R1,MAXVS		; Compare with max
	BLT	312$			; Smaller ?
	MOV	R1,MAXVS		; New max
312$:	ADD	R1,BF.VSP(R3)		; Count deferred text line
33$:	BITEQB	#ES.HSP,(SP),37$	; No Horizontal spacing
	CALL	GBYT			; Get horizontal spacing
	BITNEB	#ES.PSP,(SP),35$	; Permanent spacing ?
	MOVB	R4,LCH		; Set last char
	ADD	R1,SPCH		; Count spacing chars
	SUB	R1,LINBK	; And remove from available spaces
	BR	37$
35$:	BICB	#40,$NOSPC	; Set for expandable spaces ok
	BICB	#40,$TABSW	; Enable tabs
	MOV	R1,PHSP		; Set permanent horiz spacing
	BICB	#SW.TD2,$AUHYP	; Temporary hyphenation off
	CMPEQ	R1,#1,37$	; Spacing 1 ?
	BISB	#SW.TD2,$AUHYP	; set temporary no hyphenation
	BISB	#40,$NOSPC	; Set no expandable spaces
	BISB	#40,$TABSW	; Set no tabs
37$:	TST	(SP)+		; Pop saved flags
40$:	MOV	(SP)+,R1	; Index for transfer
	ADD	#2,R1		; Points to status now
	SUB	#2,R2		; Number of bytest to transfer
	CALL	FNDBF		; Go back to start of sequence
	MOV	(SP)+,R3	; Output buffer
	MOV	#ESC,R1		; Mark escape sequence in output buffer
45$:	CALL	PUBYT		; OUTPUT IT	
50$:	MOV	#ESCBF,R1	; escape buffer
	CALL	GBYT1		; get next bytes
	CALL	PBYT		; OUTPUT CHAR	
	SOB	R2,50$
	CLR	R1		; Mark end of sequence
	CALL	PBYT		; Into buffer
	BR	60$
54$:	TST	(SP)+		; Pop stack
55$:	TST	(SP)+		; Pop stack
	MOV	(SP)+,R3	; Restore buffer address
60$:	CLC			; SUCCESS	
	RETURN			; 		
	.DSABL	LSB
;
;	ROUTINE TO FIND NEXT TABSTOP FOR OUTLIN ROUTINE.
;	OUTPUT	R2=	DISTANCE TO NEXT STOP
;		R0,R1 are destroyed
;
TABB:	CLR	R0		; START AT FIRST TABSTOP
	ADD	SPCH,R2		; NUMBER OF SPACING CHARS
	ADD	LMARG,R2	; ADD ON LEFT MARGIN
	ADD	INDCT,R2	; PLUS INDENTATION
	BR	20$		; PRE-ENDCHECK, IN CASE NONE.
10$:	MOVB	TABTAB-1(R0),R1	; GET CURRENT TAB STOP
	BIC	#177400,R1	; Clear extra bits
	CMP	R2,R1		; THIS STOP BEYOND CURRENT POS?
	BLO	40$		; YES. GET DIFFERENCE
20$:	CMP	R0,NTABS	; LOOKED AT ALL TAB STOPS?
	BHIS	30$		; Yes
	INC	R0		; ADVANCE TO NEXT ENTRY
	BR	10$
30$:	MOV	RMARG,R1	; YES. ASSUME A TABSTOP AT RIGHT END
40$:	SUB	R2,R1		; GET DISTANCE TO TABSTOP
	MOV	R1,R2		; ANSWER IN A
	BGT	50$		; At least 1 space?
	MOV	#1,R2		; No make it 1
50$:	CLR	OVRCT		; NO ABORTS
	RETURN			; 

;
;	UPPER CASE FLAG
;
	.ENABL	LSB
SHFUP:	TSTEQB	$SFLSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	CALL	CCIN		; READ A CHARACTER
	BITEQB	CHTABL(R1),#CH.FLG,40$	; Not flag character ?
	CMPNE	R1,$UFLSW,10$	; LOCK ON UNDERLINE?
	BICB	#SW.TDS,$UNLSW	; UNDERLINING POSSIBLY ON
	BR	30$
10$:	CMPNE	R1,$CFLSW,20$	; NOT LOCK UPPER CASE?
	MOV	#401,CASE	; SET UPPER CASE + LOCK
	BR	30$		; READ ONOTHER CHAR
20$:	CMPNE	R1,$SFLSW,40$	; NOT UNLOCK ALL?
	CALL	UPCAS		; SET TO UPPER CASE
30$:	JMP	GCIN		; AND GO READ ANOTHER CHARACTER
40$:	MOVB	$SFLSW,R5	; MATCH CHAR
	CALL	ESCSQ0		; SEARCH FOR ESCAPE SEQUENCE
	BCC	30$		; FOUND ONE!	
	MOVB	GCTABL(R1),R0	; CHAR TYPE?
	CMPNE	R0,#GC.LC,50$	; NOT LOWER CASE?
	JMP	GCUP1		; LOWER CASE, SHIFT IT.
50$:	CMP	R0,#GC.LC	; ALPHABETIC CHAR?
	BLE	60$		; YES, DO NOT EXECUTE IT
	JMP	@GCJMP(R0)	; DISPATCH IT
60$:	JMP	GCINR
;
;	LOWER CASE FLAG DETECTED
;
SHFDN:	TSTEQB	$LFLSW+1,2$	; Flag not disabled ?
	JMP	GCINR
2$:	CALL	CCIN		; GET ANOTHER CHARACTER
	BITEQB	CHTABL(R1),#CH.FLG,80$	; Not flag character ?
	CMPNE	R1,$UFLSW,70$	; UNLOCK UNDERLINE?
	BISB	#SW.TDS,$UNLSW	; UNDERLINING OFF
	BR	30$		; 
70$:	CMPNE	R1,$LFLSW,80$	; NOT LOWERCASE LOCK?
	CALL	LWCAS		; SET LOWER CASE SHIFT
	BR	30$		; 		
80$:	MOVB	$LFLSW,R5	; MATCH CHAR
	CALL	ESCSQ0		; HANDLE ESCAPE SEQUENCES
	BCC	30$		; FOUND ESC SEQ	
	MOVB	GCTABL(R1),R0	; CHAR TYPE?
	CMPNE	R0,#GC.UC,50$	; NOT UPPER CASE?
	BITNE	#UPCSW,$SWTCH,60$ ; IS UP SHIFT MANDATED?
	JMP	GCDN1		; SHIFT TO LOWER CASE
	.DSABL	LSB

;
; CASE SELECTION COMMANDS
;

	.ENABL	LSB
LWCAS::	MOV	#-1,R1		; SET FOR CONVERSION TO LOWER CASE
	BR	10$		; 		
UPCAS::	CLR	R1		; SET FOR NO CASE CONVERSION
10$:	BITEQ	#UPCSW,$SWTCH,20$	; Not Upper case only?
	MOV	#401,R1		; FORCE TO UPPER CASE
20$:	MOV	R1,CASE		; SET CASE CONVERSION
	RETURN			; 
	.DSABL	LSB
;
; COROUTINE TO SHIFT TO UPPER CASE TEMPORARILY
;

SHFUC::	MOV	(SP),-(SP)	; COPY RETURN ADDRESS
	MOV	CASE,2(SP)	; SAVE CURRENT CASE
	MOV	#401,CASE	; UPPER CASE ONLY	
	CALL	@(SP)+		; CALL THE CALLER BACK
	MOV	(SP)+,CASE	; RESTORE PREVIOUS CASE	
SHXIT:	RETURN			; 
;
;	PUT STRING ENDED BY ZERO BYTE TO BUFFER
;		R0=	STRING ADDRESS
;
PSTRZB:: MOVB	(R0)+,R1	; GET FIRST CHAR
	BEQ	SHXIT		; DONE
	MOV	R0,-(SP)
	CALL	PBYT		; PUT IT
	INC	BF.SPC(R3)	; Count chars
	MOV	(SP)+,R0
	INC	R2		; COUNTS CHARS.
	BR	PSTRZB		; CONTINUE
	.DSABL	LSB

;
; ROUTINES TO OUTPUT A STRING TO THE OUTPUT FILE
;	R3=BUFFER ADDRESS FOR STRING
;		Output terminates at either null or end of input buffer
;		Z or C tell user what form of termination occurred.
;
;		This one starts at top of buffer
PSTRPA::CALL	BEGBF		; SET TO TOP OF BUFFER
	CLRB	EXSP1		; No multiple spaces
	CLRB	EXSP2		; No multiple spaces
	CLRB	EXSP3		; No multiple spaces
	CLRB	EXSTAT		; No status
	MOVB	#-1,EXMSP	; No multiple micro spaces
;
;	This one starts anywhere in buffer
;
CCOUT::	CLRB	$ULOSW		; No underlining at first
CCOUT1:	CLRB	$ULOSW		; Reset underlining
CCOUT2:	CALL	GBYT		; Get 1 byte
	BCS	GOEND
	BGT	10$		; No extra bits
	BEQ	GOEND		; End of input buffer ?
	INCB	$ULOSW		; Set underline
	BIC	#^C<177>,R1	; Clear extra bits
10$:
	.ifdf	$DEBUG
	CALL	CHROUT
	.endc
	CMPEQB	R1,#SPC,GOSPC	; Is it space ?
	MOVB	GCTABL(R1),R0	; GET CHAR TYPE
	BGE	GOPRN		; PRINTABLE
	JMP	@GCJMP(R0)	; EXECUTE FUNCTION
;	Handle single underline
GOUNL:	INCB	$ULOSW
	BR	CCOUT2
;	Printable char
GOPRN:	CALL	CCPRN		; Print 1 char
	BR	CCOUT1
GOSPC:	MOVB	EXSP1,-(SP)	; YES. HOW MANY MULTIPLE SPACES?
	MOVB	EXMSP,1(SP)	; Micro spaces
	DECB	EXSP2		; TO EXTRA BLANKS YET?
	BGE	70$		; NO.
	TSTEQB	EXSP3,80$	; EXTRA SPACES TO RIGHT?
	BR	90$		; LEFT. NO MORE EXTRAS, JUST LOOP
70$:	TSTEQB	EXSP3,90$	; NO EXTRA SPACES LEFT OR RIGHT?
80$:	BITEQB	#HD.VAR,EXSTAT,85$	; No micro spacing ?
	INCB	1(SP)		; Micro spacing count
	BR	90$
85$:	INCB	(SP)		; Extra space to output
90$:	BITEQB	#HD.VAR,EXSTAT,110$	; No micro spacing ?
	MOVB	1(SP),R1	; count
	BLE	110$		; micro count too small ?
	TSTEQB	$ULMSW,94$	; Underline by BS ?
	MOV	CPOS,R0		; Current position
	CMP	R0,#ULNSZ	; check with max
	BHI	95$		; Too big ?
	BIS	#200,R1		; Now is count for underline buffer
	MOVB	R1,UBUFF-1(R0)	; Into buffer
	MOVB	#-1,$UNLRS
	INC	CPOS		; Next position
	BR	95$
94$:	TSTEQB	$ULOSW,95$	; No underlining ?
	MOV	#1,R2		; Number of chars to underline
	CALL	CCUNL
95$:	DECB	1(SP)		; Count micro spaces
	BLT	110$		; None ?
	MOV	#VARESC+1,R2	; Address of escape sequence buffer
100$:	MOVB	(R2)+,R1	; Data to output
	BEQ	95$		; Another to output
	CALL	FOUT		; Output it
	BR	100$		; And try again
110$:	CALL	CCSPC		; OUTPUT SPACES	
	DECB	(SP)		; Decrement counter
	BGT	110$		; Not done ?
	TST	(SP)+		; Pop counter
	JMP	CCOUT1
GOQTS:	CALL	CCSPC		; Turn quoted space to single space
	JMP	CCOUT1
GOEND:	RETURN
GOESC:	CALL	GBYT		; Get flag byte
	BEQ	90$		; No flag byte ?
	MOVB	R1,-(SP)	; Save bit mask
	BITEQB	#ES.LCK,(SP),10$	; Not lock/Unlock ?
	CALL	GBYT			; Get lock word
10$:	BITEQB	#ES.VSP,(SP),20$	; No vertical spacing
	CALL	GBYT			; Get vertical spacing
	TSTNEB	$PAGNG,20$		; No paging
	SUB	R1,LINEC1		; Decrement lines left
	SUB	R1,LINEC2		; Decrement lines left
20$:	BITEQB	#ES.HSP,(SP),80$	; No Horizontal spacing
	CALL	GBYT			; Get horizontal spacing
	BLE	80$			; Too small ?
	BITNEB	#ES.PSP,(SP),40$	; Permanent spacing ?
	TSTNEB	$ULOSW,30$		; Underline ?
	ADD	R1,CPOS			; No
	BR	80$
30$:	MOV	R1,R2			; Number of undelines
	CALL	CCUNL			; Perform underlining
	BR	80$
40$:	MOV	R1,PHSPOU		; Set permanent horiz spacing
;
;	Now output escape sequence
;
80$:	TST	(SP)+
90$:	CALL	GBYT		; Get escape sequence chars
	BEQ	100$		; Done ?
	CALL	FOUT		; Output char with no interpretation
	BR	90$		; More ?
100$:	JMP	CCOUT1		; End of escape seq buffer ?
;	Handle backspaces
GOBS:	SUB	PHSPOU,CPOS		; New position
	BGT	10$		; OK ?
	MOV	#1,CPOS		; No, make it 1
10$:	CALL	FOUT		; Output backspace
	JMP	CCOUT1
;	Handle tabs
GOTAB:	CALL	GBYT		; Get next input byte
	MOVB	R1,-(SP)	; Save it
10$:	BGT	20$		; Not done yet
15$:	TST	(SP)+		; Pop stack
	JMP	CCOUT1
20$:	CALL	CCSPC		; Output a space
	DECB	(SP)		; Done?
	BR	10$		; Check it
;	Handle tabs with ellipses
GOELP:	CALL	GBYT		; Get 1 byte
	CLR	-(SP)		; Clear counter on stack
	MOVB	R1,(SP)		; Save count
10$:	BGT	20$		; Spaces to output ?
15$:	TST	(SP)+		; Done so pop stack
	JMP	CCOUT1
20$:	CALL	CCSPC		; Output 1 space
30$:	DEC	(SP)		; Done yet?
	BLE	15$		; Not yet
	BITNEB	#1,CPOS,20$	; Output space?
	CMPB	(SP),#1		; Output space?
	BLE	20$		; Yes
	MOVB	#'.,R1		; No, do period
	CALL	CCPRN		; Output printable char
	BR	30$
;	Handle repeated output
GOREP:	CALL	GBYT		; Get repeat count
	BEQ	50$		; Repeat zero ?
	.ifdf	$DEBUG
	CALL	CHROUT
	.endc
	CLR	-(SP)		; Clear count on stack
	MOVB	R1,(SP)		; Save count
	MOV	BF.FUL(R3),-(SP)	; Save input index
10$:	CALL	CCOUT1		; Now output string
	DEC	2(SP)		; Done ?
	BLE	20$		; Yes ?
	MOV	(SP),R1		; Rewind input buffer
	CALL	FNDBF		; Back over string
	BR	10$		; Repeat
20$:	ADD	#4,SP		; Pop stack
	JMP	CCOUT1		; And continue
50$:	CALL	55$		; Stack up reequest to kill repeat
	JMP	CCOUT1		; And continue
55$:	CALL	GBYT		; Get char
	BNE	60$		; Not done ?
	RETURN
60$:	CMPEQB	R1,#ESC,70$	; Escape sequence ?
	CMPNEB	R1,#REPO,55$	; No repeat ?
	CALL	GBYT		; Skip count
	CALL	55$		; Stack another skip
	BR	55$		; Done with imbedded repeat
70$:	CALL	GBYT		; Skip status
80$:	CALL	GBYT		; Get sequence
	BNE	80$		; Not terminator ?
	BR	55$
;
;	section to fill in index entries
;
GOINX:	CALL	GWRD		; Get address inside index buffer
	MOV	R1,R4		; backward link
	MOV	R3,-(SP)	; Save
	MOV	#INXBF,R3	; Get index buffer address
	CALL	FNDBF		; get next entry
	CALL	GWRD		; get link to next
	MOV	R1,R5
10$:	MOV	R5,R1		; next entry
	BEQ	15$		; End of line ?
	CALL	FNDBF		; find it
	BCS	90$		; OK ?
	CALL	GWRD		; get next foreward link
	BCS	90$		; end of input
	MOV	R1,R2
	CALL	GBYT		; get status byte
	BCS	90$		; end of input
	BITne	#X.ENT,R1,15$	; No entry ?
	MOV	R5,R4		; R4 has backward link
	MOV	R2,R5		; next foreward link
	BR	10$
15$:	MOV	R4,R1		; Go back to last one
	CALL	FNDBF		; Get the index entry address
	MOV	BF.MAX(R3),R1	; New entry address
	CALL	PWRD		; Link to end
	CALL	ENDBF		; Now go to end
	MOV	R5,R1		; Save foreward link
	CALL	PWRD
	MOV	#X.PAG,R1	; Set for page number
	TSTNEB	$CHPSW,30$	; no chapter print?
	TSTEQB	APNDN,20$	; No appendix?
	BIS	#X.AP,R1	; Set appendix status
	BR	30$		; no chapter if appendix
20$:	TSTEQB	CHPTN,30$	; No chapter?
	BIS	#X.CH,R1
30$:	TSTEQB	SUBPGE,40$	; No subpage?
	BIS	#X.SPG,R1
40$:	CALL	PBYT		; Save status bits
	TSTNEB	$CHPSW,60$	; no chapter print?
	MOVB	APNDN,R1
	BEQ	50$
	CALL	PBYT		; put appendix
	BR	60$
50$:	MOVB	CHPTN,R1
	BEQ	60$
	CALL	PBYT		; put chapter
60$:	MOV	PAGENO,R1
	BNE	65$		; Not zero ?
	INC	R1		; Make it 1
65$:	BIS	PAGDSP,R1	; Add on display bits
	CALL	PWRD		; put chapter
70$:	MOVB	SUBPGE,R1
	BEQ	80$
	CALL	PBYT		; put subpage
80$:	MOV	(SP)+,R3	; Restore
	JMP	CCOUT1
90$:	CALL	HLTER
;
;	Routine to output TOC entries
;
GOTOC:: MOV	#TTBUF,R2	; Get temporary buffer
10$:	CALL	GBYT		; Get 1 byte
	MOVB	R1,(R2)+	; Into buffer
	BNE	10$
	MOV	#TTBUF+1,R1	; Address of array
	SUB	R1,R2		; Size of array
	DEC	R2		; Final
	BLE	40$		; None ??
	CALL	OUTTOC		; Output the toc line
	TSTB	TTBUF		; Check type of output
	BLE	40$		; No number requested ??
	MOV	R3,-(SP)	; Save R3
	MOV	#TTBF,R3	; Get temporary buffer
	CALL	CLRBF		; Clear it
	MOV	#TAB,R1		; Tab char.
	CALL	PBYT		; into buffer
	CALL	PUTPAG		; Get page number
	MOV	BF.FUL(R3),R2	; Get size
	MOV	(SP)+,R3	; Restore
	MOV	#TTBUF,R1	; Start of buffer
	CALL	OUTTOC		; And output it
40$:	JMP	CCOUT1
;
;	Subroutine to output printable chars
;
CCSPC::	MOV	#SPC,R1		; GET SPACE
CCPRN::	TSTEQB	$ULOSW,NOUNL	; No underlining ?
	MOV	PHSPOU,R2	; Number of underlines
	CALL	CCUNL		; YES, DO IT
	JMP	FOUT		; output character
NOUNL:	ADD	PHSPOU,CPOS	; INCREMENT POSITION COUNTER
	JMP	FOUT		; OUTPUT CHAR
;
;	Do underlining
;
CCUNL:	MOV	R1,-(SP)	; SAVE CHAR
80$:	TSTB	$ULMSW
	BNE	90$		; Underline by line or sim. ?
	MOV	R2,-(SP)	; Save count
	ADD	R2,CPOS		; New position
82$:	MOV	#LPUS,R1	; GET UNDERLINE
	CALL	FOUT		; OUTPUT IT
	SUB	PHSPOU,R2	; Remaining count
	BGT	82$		; More to do ?
	MOV	(SP)+,R2	; Get count again
84$:	MOV	#BS,R1		; GET BACKSPACE
	CALL	FOUT		; OUTPUT IT
	SUB	PHSPOU,R2	; Remaining count
	BGT	84$		; More to do ?
	BR	100$
90$:	MOV	CPOS,R0		; POSITION
	CMP	R0,#ULNSZ	; TOO BIG?
	BHI	95$		; YES
	MOVB	$ULCH,UBUFF-1(R0) ; PUT IT INTO BUFFER
	CMP	R0,ULNMAX	; SMALLER DUE TO BS
	BLOS	100$		; YES, KEEP MAX
	MOV	R0,ULNMAX	; AND SAVE LAST ADDRESS
95$:	INC	CPOS
	SOB	R2,90$		; Do it for each char
100$:	MOV	(SP)+,R1	; GET SAVED CHAR
	RETURN
;
;	Service equation flags
;
GCEQN1:	TSTNE	$EQFSW,NOEQN	; No equations ?
	JMP	GCEQ1		; Process left brace
GCEQN2:	TSTNE	$EQFSW,NOEQN	; No equations ?
	JMP	GCEQ2		; Process right brace
NOEQN:	JMP	GCINR		; Output the char
;
;	Output byte underlined
;
PUBYT::	TSTNEB	$UNLSW,11$	; No underline this char ?
	BIC	#^C<177>,R1	; Set to proper range
	BITNEB	#CH.UNL,CHTABL(R1),11$	; Underlining not allowed ?
	BIS	#200,R1		; Mark it as underlined
11$:	JMP	PBYT		; OUTPUT CHAR
	.END
