[net.sources] TECO for 6502 source

keith@reed.UUCP (Keith Packard) (12/23/85)

*** REPLACE THIS LINE WITH YOUR MESSAGE ***

	.ASECT
	.TITLE TECO V1.2  29-MAR-82
;******************************************
;******             TECO             ******
;******        Copyright 1985        ******
;******                              ******
;******         Bob Ankeney          ******
;******         5740 SE 18th Ave     ******
;******         Portland, OR 97202   ******
;******                              ******
;******      All Rights Reserved     ******
;******                              ******
;****** Permission is granted to     ******
;****** reproduce, without profit,   ******
;****** any portion of this program. ******
;******************************************
;
;---------------------------------------------------------------------
;		Modification history
;
;	01/01/84	Added EU, KB buffer.
;	12/28/83	Fixed O command (@O/tag/).
;	12/26/83	Added EI.
;	12/23/83	Added ES and EV.
;	12/18/83	Added ^Z command.
;	12/18/83	Added case comparison (^X) to search.
;	12/14/83	Added search string modifiers.
;	12/11/83	Completed search string building.
;	12/10/83	Added ^Q command.
;	12/10/83	Added G* and G_ search string and filespec.
;	12/09/83	Added := and :==, simplified E flags.
;	12/09/83	Added m,nUxUy capability.
;	12/09/83	Added parenthetical expressions.
;	11/27/83	Added ^EQn to search strings and ^ conversion.
;	11/26/83	Added Q-register push-down list.
;	11/25/83	Added bounded search (m,nStext$, ::Stext$).
;	06/06/83	Rewrote input handler for video terminals.
;
;---------------------------------------------------------------------
;	CONSTANT DEFINITIONS
;
	VERNUM=29	; TECO VERSION NUMBER
;
	USR=$214
	DATE=$3C2	; CURRENT DATE WORD
	CNISTA=$40C	; CONSOLE INPUT STATUS
	CONINP=CNISTA+5	; GET CHAR FROM CONSOLE
	CONPOS=$420	; CONSOLE POSITION
	CNSTAI=CONPOS+3	; CONSOLE INP STAT BITS
	CNSTAO=CNSTAI+1	; CONSOLE OUT STAT BITS
	CNCTLO=CNSTAO+1	; =1 IF CTL/O IN EFFECT
	LEADIN=$426
	CURSUP=$428
	BACKSP=$42B
	CTCRTN=$3CB	; ^C RETURN ADDRESS
	CONIN=$400
	BINPUT=CONIN+3
	CONOUT=BINPUT+3
	BINOUT=CONOUT+3
	MONITR=$A00
	SRHBUF=$2100	; SYS DIRECTORY BUFFER USED FOR
			; TEMP SEARCH STRING BUILDING
	LOOKUP=0
	ENTER=1
	CLOSE=2
	DELET=3
	RENAME=4
	INQUIR=8
	FETCH=INQUIR
	RD2ASC=12
	SCAN=15
;
	COMPTR=$30	; COMMAND INPUT POINTER
	CMDPTR=COMPTR+2	; COMMAND BUFFER POINTER
	LASTLF=CMDPTR+2
	BUFPTR=LASTLF+2	; BUFFER POINTER
	TEMPTR=BUFPTR+2
	TMPTR1=TEMPTR+2
	TXTPTR=TMPTR1+2
	QSTART=TXTPTR+2	; START OF Q REGISTER N
	CHRPTR=QSTART+2
	INPTR=CHRPTR+2	; INPUT BUFFER POINTER
	OUTPTR=INPTR+2	; OUTPUT BUFFER POINTER
	EIPTR=OUTPTR+2	; INDIRECT FILE BUFFER POINTER
;
	*=$2500
;
TMPSTO	.BYTE 0
TMPSTI	.BYTE 0
LSTCHR	.BYTE 0
INCHAR	.BYTE 0
BUFST	.WORD 0		; START OF BUFFER
BUFSIZ	.WORD 0		; # CHARS IN BUFFER
ENDBUF	.WORD 0		; =BUFST+BUFSIZ
BUFTHQ	.WORD 0		; 3/4 THROUGH BUFFER
BUFEND	.WORD 0		; LAST CHAR IN BUFFERS
	CMDST=BUFEND
CMDCNT	.WORD 0		; # CHARS LEFT IN COMMAND
CMDREG	.BYTE 0		; Q REG OF COMMAND (36 IF COMMAND STRING)
MAXEND	.WORD $BFFF	; MAXIMUM BUFFER END
CHRCNT	.WORD 0
LOARG	.WORD 0
HIARG	.WORD 0
LSTARG	.WORD 0
GOTLO	.BYTE 0
GOTHI	.BYTE 0
NUMASM	.BYTE 0
LASTOP	.BYTE 0
OPER	.BYTE 0
RADIX	.BYTE 10
MULNUM	.WORD 0
DIVNUM	.WORD 0
DIGCNT	.BYTE 0
ESCHAR	.BYTE 0		; ESC FOR NORMAL, ELSE / FOR @S/.../
TEMP	.WORD 0
TEMP1	.WORD 0
TEMPX	.BYTE 0
TEMPX1	.BYTE 0
TMPBUF	.WORD TEMBUF
TEMBUF	.BYTE 0
ENDLIM	.WORD 0
STRSIZ	.WORD 0		; LENGTH OF LAST STRING
SRHCNT	.WORD 0
SRHLEN	.BYTE 0
SRHSIZ	.BYTE 0
NEGATE	.BYTE 0
QRGTMP	.BYTE 0
VERFLG	.WORD 0		; FOR ES AND EV
;
QDEPTH	.WORD 0		; DEPTH OF Q REGISTER PUSHDOWN LIST
PRDPTH	.BYTE 0		; # LEVELS OF PARENS *3
	MAXPAR=24	; MAX 8 LEVELS OF PARENS
PARSTK	*=*+MAXPAR
PSHCNT	.BYTE 0		; # LEVELS ON PUSHDOWN LIST
PSHLST	*=*+32		; # CHARS LEFT IN COMMAND
PSHREG	*=*+32		; FIRST BYTE = Q REG * OF COMMAND
			; SECOND BYTE= 0 -> ITERATION, 1 -> MACRO
ITRCNT	*=*+32		; ITERATION COUNT
GOTAT	.BYTE 0		; =1 IF LAST CHAR='@'
GOTCLN	.BYTE 0		; =1 IF LAST CHAR=';'
TRCMOD	.BYTE 0		; TRACE MODE FLAG
TRCTMP	.BYTE 0
TSTCHR	.BYTE 0		; CHAR TESTED IN CHRTST
PAGSRH	.BYTE 0		; SEARCH ACROSS PAGES
BOUNDS	.WORD 0		; SEARCH BOUNDS FOR M,NS
NOFAIL	.BYTE 0		; FLAG =1 FOR 0,NS
OLDPTR	.WORD 0		; TEMP BUFPTR FOR 0,NS
; **** NEXT 4 LINES MUST STAY IN THIS ORDER!!
QRGCNT	*=*+72		; SIZE OF Q REGS
CMDSIZ	.WORD 0		; SIZE OF COMMAND STRING
FSPCSZ	.WORD 0		; SIZE OF FILE SPEC
LSTCNT	.WORD 0		; SIZE OF LAST SEARCH STR
;
QVAL	*=*+72		; Q REG NUMERICS
SRHMES	.BYTE '?SEARCH FAILURE ',0
SRHMS1	.BYTE 'FOR "',0
SRHMS2	.BYTE 'IN ITERATION',0
LSTSRH	*=*+256
FILSPC	*=*+18		; FILESPEC BUFFER
FLSPTR	.WORD FILSPC
	.WORD LSTSRH
;
TINBUF	*=*+$80		; KEYBOARD BUFFER
TINSIZ	.BYTE 0
;
BUFTMP	.WORD 0
RADWRD	.WORD 0		; RAD40 WORD
CHAR	.BYTE 0,0,0	; 3 ASCII CHARS
FRSTCH	.BYTE 0		; =1 IF >1 CHARS TYPED
LSTERR	.BYTE 0		; =1 IF LAST CMD GAVE ERR
NUMSGN	.BYTE 0
NUMSTR	.WORD 0,0,0
TAGPTR	.WORD 0		; POINTER TO O TAG
TAGCNT	.WORD 0		; # CHARS IN TAG
;
EDFLAG	.WORD 0		; ED FLAG (FOR YANK CMD)
EHFLAG	.WORD 0		; EH FLAG
EOFLAG	.WORD 0		; TECO VERSION #
ESFLAG	.WORD 0		; ES FLAG
ETFLAG	.WORD 0		; ET FLAG (FOR ^C COMMAND)
EUFLAG	.WORD 0		; EU FLAG
EVFLAG	.WORD 0		; EV FLAG
XFLAG	.WORD 0		; ^X FLAG
EFLAGS	.BYTE 'DHOSTUV'
	EFGCNT=*-EFLAGS
;	I/O PARAMS
DIRBUF	*=*+$12		; DIRECTORY ENTRY
OUTFIL	*=*+21
	OUTHLR=OUTFIL+14
	OUTDEV=OUTFIL+11
	OUTUNT=OUTFIL+12
OUTUUP	.BYTE 0		; =OUTUNT OR $40
OUTSIZ	.BYTE 4		; SIZE OF OUTPUT BUFFER
OUTOPN	.BYTE 0		; >0 IF FILE OPEN
CLSBUF	*=*+18		; FOR CLOSE & RENAME
;
INFILE	*=*+18
	INHLR=INFILE+14
	INDEV=INFILE+11
	INUNIT=INFILE+12
INSIZE	.BYTE 4		; SIZE OF INPUT BUFFER
INOPEN	.BYTE 0		; >0 IF INP FILE OPEN
INLEN	.WORD 0
FFFLAG	.BYTE 0		; FORM FEED FLAG
GOTEOF	.BYTE 0		; >0 IF GOT EOF
COLONA	.BYTE 0		; :A COMMAND
;
EIFILE	*=*+18
	EIHLR=EIFILE+14
	EIDEV=EIFILE+11
	EIUNIT=EIFILE+12
	EISZ=1
EISIZE	.BYTE EISZ	; SIZE OF INDIRECT BUFFER
EIOPEN	.BYTE 0		; <>0 IF INDIRECT FILE OPEN
EILEN	.BYTE 0		; # BLOCKS LEFT IN FILE
EIST	.WORD EIBUF
EIEND	.WORD 0
EIFPTR	.WORD EIFILE
EIBUF	*=256*EISZ+*	; INDIRECT FILE BUFFER
;
EBFLAG	.BYTE 0		; >0 IF EB COMMAND
SUPSED	.BYTE 0		; >0 TO SUPERSEDE
SUPMES	.BYTE 'Supersede? ',0
DELMES	.BYTE 13,10,'Delete TECO.TMP? ',0
ANSMES	.BYTE 'NO',0,'YES',0
TMPNAM	.RAD40 'TECO     ','TMP'
CLSLEN	.WORD 0		; CLOSING OUTPUT LENGTH
FETIN	.WORD 0
RADBAK	.RAD40 'BAK'
FNMPTR	.WORD 0,0
ENDPTR	.WORD TECEND
XABPTR	.WORD XABERR
STRPTR	.WORD NUMSTR
CLSPTR	.WORD CLSBUF
IFLPTR	.WORD INFILE
OFLPTR	.WORD OUTFIL
;
;	*** INFO FOR " COMMAND ***
QUOLST	.BYTE 'G>L<TSEFUCNAVWDR'	; " CHARS
QUODSP	.WORD QUOTEG	; "G
	.WORD QUOTEG	; ">
	.WORD QUOTEL	; "L
	.WORD QUOTEL	; "<
	.WORD QUOTEL	; "T
	.WORD QUOTEL	; "S
	.WORD QUOTEE	; "E
	.WORD QUOTEE	; "F
	.WORD QUOTEE	; "U
	.WORD QUOTEC	; "C
	.WORD QUOTEN	; "N
	.WORD QUOTEA	; "A
	.WORD QUOTEV	; "V
	.WORD QUOTEW	; "W
	.WORD QUOTED	; "D
	.WORD QUOTER	; "R
;
;	*** INFO FOR COMMAND SKIPPING ***
SKPCHR	.BYTE 0
SKITCT	.BYTE 0			; SKIP ITERATION COUNT
SKCNCT	.BYTE 0			; SKIP CONDITIONAL COUNT
SKPQLS	.BYTE 30,'%GMQUX[]'	; Q REGISTER COMMANDS
SKPSPC	.BYTE 1,'!"$''<>@EF^'	; SPECIAL COMMANDS
SKPTBL	.WORD SKPCTA		; SPECIAL COMMAND
	.WORD SKPTAG		; DISPATCH TABLE
	.WORD SKPQUO
	.WORD SKPHEX
	.WORD SKPCND
	.WORD SKPITR
	.WORD SKPGTR
	.WORD SKPAT
	.WORD SKPE
	.WORD SKPF
	.WORD SKPUP
SKPESC	.BYTE 9,21,'INOS_'	; COMMANDS REQUIRING $
SKECMD	.BYTE 'BEGINRW'		; E COMMANDS REQUIRING $
	SKPEND=*
;
TECO	LDA CNSTAO	; SAVE OUTPUT STATUS BITS
	STA TMPSTO
	ORA #$24	; ENABLE UPARROW ON CTRL
	STA CNSTAO	; CHARS AND $ ON ESCAPE
	LDA CNSTAI
	STA TMPSTI
;
	LDA ENDPTR	; INIT POINTERS
	STA INST
	STA OUTST
	STA BUFST
	STA BUFEND
	STA BUFPTR
	LDA ENDPTR+1
	STA INST+1
	CLC
	ADC INSIZE
	STA OUTST+1
	ADC OUTSIZ
	STA BUFST+1
	STA BUFEND+1
	STA BUFPTR+1
;
	LDA EIST
	STA EIEND
	LDA EIST+1
	ADC EISIZE
	STA EIEND+1
;
	LDX #71		; ZERO Q REGISTERS
	LDA #0
QCLEAR	STA QRGCNT,X
	STA QVAL,X
	DEX
	BPL QCLEAR
;
	LDX #EFLAGS-EDFLAG
EFGZRO	STA EDFLAG-1,X	; ZERO E FLAGS
	DEX
	BNE EFGZRO
;
	STA CMDSIZ
	STA CMDSIZ+1
	STA BUFSIZ
	STA BUFSIZ+1
;
	STA INOPEN
	STA OUTOPN
	STA EIOPEN
;
	STA LSTERR
	STA FRSTCH
	STA QDEPTH
	STA QDEPTH+1
	STA LSTCNT
	STA FSPCSZ
	STA TINSIZ	; KB BUFFER EMPTY
	TAY
;
	LDA #VERNUM	; INIT VERSION #
	STA EOFLAG
	LDA #$FF
	STA EUFLAG
	STA EUFLAG+1
	LDA #6
	STA ETFLAG
	LDA #2
	STA ETFLAG+1
;
	JSR INITCM
;
GETCMD	JSR CRLF
GTCMD1	LDA EVFLAG	; CHECK FOR EV
	STA VERFLG
	LDA EVFLAG+1
	STA VERFLG+1
	JSR EDTVER
;
GTCMD2	LDA #$FF	; DISABLE ^C TRAPPING
	STA CTCRTN
	STA CTCRTN+1
	STY LSTCHR	; LAST CHAR TYPED
	LDY #0
;
	STY CNCTLO	; DISABLE ^O FLAG
	LDA EIOPEN	; INDIRECT FILE OPEN?
	BEQ GTCMD3
	JSR TINTST	; YES- ANYTHING LEFT?
	BCS GETINP	; YES
GTCMD3	LDA #'*		; PRINT PROMPT
	JSR CONOUT
GETINP	JSR TTYIN	; GET CHAR FROM CONSOLE
	CMP #0
	BEQ GETINP	; IGNORE NULLS
	STA INCHAR
;
	CPY FRSTCH	; FIRST CHAR TYPED YET?
	BEQ CHKSTR
	JMP NOFRST
;
CHKSTR	CPY EIOPEN
	BEQ CKSTR1
	JMP BDFRST
;
CKSTR1	CMP #'*		; YES- CHECK FOR *N OR ?
	BNE CKQUES
	JSR TTYIN	; PUT LAST CMD IN Q REG
	JSR GTQRG1	; GET Q REG NUMBER
	JSR GETQST
	JSR QBFPTR
	JSR QZERO
	LDA CMDSIZ
	STA CHRCNT
	STA QRGCNT,X
	LDA CMDSIZ+1
	STA CHRCNT+1
	STA QRGCNT+1,X
	SEC		; GET COMMAND BUFFER START
	LDA CMDST
	SBC CMDSIZ
	STA TXTPTR
	LDA CMDST+1
	SBC CMDSIZ+1
	STA TXTPTR+1
	JSR INTEXT
	JSR RESPTR
	JMP GETCMD
;
CKQUES	CMP #'?
	BNE CHKLF
	LDX LSTERR
	BEQ BDFRST
	LDA CMDREG
	ASL A
	TAX
	JSR GETQST
;
CKERND	LDA QSTART
	CMP CMDPTR
	BNE ERRPRT
	LDA QSTART+1
	CMP CMDPTR+1
	BEQ PTERND
;
ERRPRT	LDA (QSTART),Y
	JSR TTYOUT
	INC QSTART
	BNE CKERND
	INC QSTART+1
	BNE CKERND
;
PTERND	LDA #'?
	JSR CONOUT
GETJMP	JMP GETCMD
;
IQNERR	LDA #17		; ?IQN ERROR
	JMP ERROR
;
CHKLF	CMP #10		; LF?
	BNE CHKBS
	LDA CURSUP	; YES- EAT LF
	JSR SPCOUT
;
	STY SRHCNT+1	; DO LT$$
	LDA #1
SPCMOV	STA SRHCNT
	JSR LMOVE1
;
	JSR KILINE	; ERASE INPUT LINE
	LDA EVFLAG	; NO PRINT IF EV ACTIVE
	ORA EVFLAG+1
	BNE G1JMP
	STY SRHCNT+1	; 1T
	LDA #1
	STA SRHCNT
	JSR LFFIND
	JSR FNDRG1
	JSR TYPCHK
G1JMP	JMP GTCMD1
;
CHKBS	CMP #8		; BS?
	BNE BDFRST
	LDA #$FF	; YES- DO -LT$$
	STA SRHCNT+1
	BNE SPCMOV
;
BDFRST	INC FRSTCH
	PHA
	JSR INITCM	; INIT COMMAND POINTER
	PLA
;
NOFRST	CPY EIOPEN
	BNE NOCTLU
	CMP #$7F	; DELETE?
	BNE CKCTLC
	STA LSTCHR
	LDA COMPTR	; YES- AT START OF BUF?
	CMP CMDST
	BNE NOBFST
	LDA COMPTR+1
	CMP CMDST+1
	BEQ GETJMP
;
NOBFST	JSR DELCHR	; NO- REMOVE CHAR
	JMP GETINP
;
CKCTLC	LDA INCHAR
	CMP #$03	; ^C?
	BNE NOCTLC
	CMP LSTCHR	; YES- WAS LAST CHAR
	BNE NOEXIT	; ALSO ^C?
	JMP TECOEX	; YES- EXIT TECO
;
NOEXIT	JSR EATBUF	; NO- ERASE INPUT BUF
	JSR CRLF
	LDY #3
	JMP GTCMD2
;
NOCTLC	CMP #$15	; ^U?
	BNE NOCTLU
	JSR KILINE
	JSR FINDLF	; YES- DELETE UP TO
	PHP		; SAVE STATUS
	SEC		; UPDATE CMDSIZ (=CMDSIZ
	LDA CMDSIZ	; -COMPTR+LASTLF)
	SBC COMPTR
	PHA
	LDA CMDSIZ+1
	SBC COMPTR+1
	STA TEMP
	CLC
	PLA
	ADC LASTLF
	STA CMDSIZ
	LDA TEMP
	ADC LASTLF+1
	STA CMDSIZ+1
;
	LDA LASTLF	; LAST LINE FEED
	STA COMPTR
	LDA LASTLF+1
	STA COMPTR+1
	PLP
	BCS INPJMP
	JMP GTCMD1	; BUFFER EMPTY- PRINT *
;
NOCTLU	CMP #$1B	; ESCAPE?
	BNE NOTESC
	CMP LSTCHR	; WAS LAST CHAR ESCAPE?
	BNE ADDCHR
	JSR PUTCHR	; YES- ADD TO BUF AND
	JMP GOTCMD	; PROCESS INPUT BUFFER
;
NOTESC	CPY EIOPEN
	BNE ADDCHR
	LDA LSTCHR	; LAST CHAR ^G?
	CMP #7
	BNE ADDCHR
	LDA INCHAR	; YES- THIS CHAR ^G?
	CMP #7
	BNE CHKSPC
	JSR REMCHR	; YES- ALLOW *N
	STY FRSTCH
	LDA COMPTR
	STA BUFEND
	LDA COMPTR+1
	STA BUFEND+1
	JMP GETCMD	; YES- EAT BUFFER
;
CHKSPC	CMP #$20	; NO- SPACE?
	BNE NOSPAC
	JSR REMCHR	; YES- REMOVE ^G FROM BUFFER
	JSR CRLF
	JSR REDRAW	; REDRAW CURRENT LINE
INPJMP	JMP GETINP
;
NOSPAC	CMP #'*		; ASTERISK?
	BNE ADDCHR
	JSR REMCHR	; YES- REMOVE ^G FROM BUFFER
	LDA CMDST	; PRINT OUT BUFFER
	STA LASTLF
	LDA CMDST+1
	STA LASTLF+1
	JSR CRLF
	JSR CTLGPR
	JMP GETINP
;
ADDCHR	LDA INCHAR
	STA LSTCHR
	JSR PUTCHR	; ADD CHAR TO BUFFER
	BCC JMPINP
	CPY EIOPEN
	BNE JMPINP
	CMP #13		; CARRIAGE RETURN?
	BNE JMPINP
;
ADDLF	LDA #10		; YES- ADD LF
	JSR CONOUT
	JSR PUTCHR
JMPINP	JMP GETINP
;
DELCHR	JSR REMCHR	; REMOVE CHAR FROM BUFFER
	LDA (COMPTR),Y	; GET CHAR FROM BUFFER
	CMP #$20	; CONTROL CHAR?
	BCS ONECHR
	CMP #$1B	; ESCAPE?
	BEQ ONECHR	; YES- ERASE '$'
	CMP #7		; ^G?
	BEQ DELRTN	; YES- NON-PRINTING
	CMP #12		; FORM FEED?
	BEQ DELRTN	; YES- NON-PRINTING
	CMP #9		; TAB?
	BNE NOTTAB
	JSR KILINE	; YES- REDRAW LINE
GOTCR	JSR REDRAW
DELRTN	RTS
;
NOTTAB	CMP #10		; LF?
	BNE NOTLFD
	LDA CURSUP	; YES- CURSOR UP
	JMP SPCOUT
;
NOTLFD	CMP #13		; CR?
	BEQ GOTCR	; YES- REDRAW LINE
;
	JSR ERASE	; NO- DELETE ^ + CHAR
ONECHR	JMP ERASE
;
REDRAW	JSR FINDLF	; PRINT CURRENT LINE
	BCS PRTCMD
;
CTLGPR	LDA #'*
	JSR CONOUT
PRTCMD	LDA COMPTR	; DONE WITH LINE?
	CMP LASTLF
	BNE CHROUT
	LDA COMPTR+1
	CMP LASTLF+1
	BNE CHROUT
;
	STY LSTCHR
	RTS
;
CHROUT	LDA (LASTLF),Y	; PRINT CHAR
	JSR CONOUT
	INC LASTLF
	BNE PRTCMD
	INC LASTLF+1
	BNE PRTCMD
;
KILINE	LDA CNSTAI	; CRLF OR ERASE LINE?
	AND #$10
	BNE ERALIN
	JMP CRLF
;
ERALIN	LDA CONPOS
	BEQ KILRTN
	JSR ERASE	; ERASE LAST CHAR
	JMP ERALIN
KILRTN	RTS
;
ERASE	JSR BACK	; BACKSPACE, SPACE, BACKSPACE
	LDA #$20
	JSR CONOUT
;
BACK	DEC CONPOS	; PRINT BACKSPACE
	LDA BACKSP
SPCOUT	BEQ NOSPCL
	BPL NOLEAD
	PHA		; NEEDS LEADIN
	LDA LEADIN
	JSR BINOUT
	PLA
	AND #$7F
NOLEAD	JSR BINOUT
NOSPCL	RTS
;
PUTCHR	PHA
	SEC		; CHECK FOR FULL BUFFER
	LDA MAXEND
	SBC COMPTR
	STA TEMP
	LDA MAXEND+1
	SBC COMPTR+1
	BNE PUTCH1
	LDA TEMP	; >10 CHARS LEFT IN BUFFER?
	CMP #10
	BCS PUTCH1
	LDA #7		; NO- PRINT BELL
	JSR CONOUT
	LDA TEMP
	BNE PUTCH1
	PLA		; NO ROOM- IGNORE CHAR
	CLC
	RTS
;
PUTCH1	PLA
	STA (COMPTR),Y	; ADD CHAR TO BUFFER
	INC COMPTR
	BNE INCPSZ
	INC COMPTR+1
INCPSZ	INC CMDSIZ
	BNE ADDRTN
	INC CMDSIZ+1
ADDRTN	SEC		; ECHO IT
	RTS
;
REMCHR	SEC		; REMOVE CHAR FROM BUF
	LDA COMPTR
	SBC #1
	STA COMPTR
	LDA COMPTR+1
	SBC #0
	STA COMPTR+1
	SEC
	LDA CMDSIZ
	SBC #1
	STA CMDSIZ
	LDA CMDSIZ+1
	SBC #0
	STA CMDSIZ+1
	RTS
;
FINDLF	LDA COMPTR	; FIND LAST LF IN BUFFER
	STA LASTLF
	LDA COMPTR+1
	STA LASTLF+1
;
FNDLF1	LDA LASTLF+1	; AT BEGINNING OF BUF?
	CMP CMDST+1
	BNE NOTBGN
	LDA LASTLF
	CMP CMDST
	BNE NOTBGN
	CLC		; YES- RETURN CARRY CLR
	RTS
;
NOTBGN	SEC		; DEC POINTER
	LDA LASTLF
	SBC #1
	STA LASTLF
	LDA LASTLF+1
	SBC #0
	STA LASTLF+1
;
	LDA (LASTLF),Y	; IS CHAR A LF?
	CMP #10
	BNE FNDLF1
	INC LASTLF	; YES- INC PTR & RETURN
	BNE FNDRTN
	INC LASTLF+1
	SEC
FNDRTN	RTS
;
CRLF	LDA #13		; PRINT CR/LF COMBO
	JSR CONOUT
	LDA #10
	JSR CONOUT
	RTS
;
DIGCHK	SEC		; CHECK FOR LEGAL DIGIT
	SBC #'0
	BPL LONMOK
DIGERR	CLC
	RTS		; RETURN WITH CARRY CLR
;
LONMOK	CMP #10
	BPL DIGERR
	SEC
	RTS		; RETURN CARRY SET
;
INITCM	SEC		; INIT COMMAND PTR
	LDA BUFEND
	SBC CMDSIZ
	STA BUFEND
	STA COMPTR
	LDA BUFEND+1
	SBC CMDSIZ+1
	STA BUFEND+1
CMDZRO	STA COMPTR+1
	STY CMDSIZ
	STY CMDSIZ+1
	RTS
;
EATBUF	SEC		; EAT CURRENT INP BUFFER
	LDA COMPTR
	SBC CMDSIZ
	STA COMPTR
	LDA COMPTR+1
	SBC CMDSIZ+1
	JMP CMDZRO
;
;
GOTCMD	LDX EIOPEN
	BNE GOTCM1
	JSR CRLF	; GOT COMMAND, PROCESS
GOTCM1	LDA XABPTR	; ON ^C, JMP XABERR
	STA CTCRTN
	LDA XABPTR+1
	STA CTCRTN+1
	LDA CMDST
	STA CMDPTR
	LDA CMDST+1
	STA CMDPTR+1
	LDA COMPTR
	STA BUFEND
	LDA COMPTR+1
	STA BUFEND+1
	LDA CMDSIZ
	STA CMDCNT
	LDA CMDSIZ+1
	STA CMDCNT+1
	LDA #36		; COMMAND STRING = Q REG #36
	STA CMDREG
	STY PSHCNT	; PUSH DOWN LEVEL
	STY FRSTCH
	STY LSTERR
	STY TRCMOD
	STY PRDPTH
;
PROCMD	LDY #0
	STY LOARG
	STY LOARG+1
	STY GOTLO
;
PRCMD1	LDA #1
	STA NUMASM
	STY GOTHI
	TYA
;
PRCMD2	STA HIARG
	STA HIARG+1
PRCMD3	STY LSTARG
	STY LSTARG+1
	STY LASTOP
	LDA #'+		; OPERATOR=ADD
	STA OPER
;
NXTCMD	JSR CNISTA	; CHAR TYPED?
	BCC NXTCM1
	JSR CONIN	; YES- ^C?
	CMP #3
	BEQ XABERR
	LDX TINSIZ	; NO- ADD TO KB BUFFER
	BMI NXTCM1	; FULL- IGNORE
	STA TINBUF,X
	INC TINSIZ
	BNE NXTCM1
;
XABERR	STY TINSIZ
	LDA CMDREG	; DURING MACRO?
	CMP #36
	BNE XABER1
	LDA ETFLAG+1	; YES- BIT 0 OF ET FLAG SET?
	BPL XABER1
	AND #$7F
	STA ETFLAG+1	; YES- RESET & GET NEW COMMAND
	JMP NXTCM1
;
XABER1	LDA #33		; ?XAB ERROR
	JMP ERROR
;
NXTCM1	STY GOTAT	; =1 IF LAST CHAR='@'
	STY GOTCLN	; =1 IF LAST CHAR=':'
	STY COLONA
	JSR GTCMCH	; GET CHAR FROM BUFFER
	BCC CMDONE	; DONE WITH COMMAND
;
EXECMD	ASL A
	TAX
	LDA JMPTBL,X
	STA CMDJMP+1
	LDA JMPTBL+1,X
	STA CMDJMP+2
CMDJMP	JMP $0000	; EXECUTE COMMAND
;
CMDONE	LDA PRDPTH	; ANY )'S LEFT?
	BEQ CMDON1
MRPERR	LDA #42		; YES- ?MRP ERROR
	JMP ERROR
;
CMDON1	LDA PSHCNT	; DONE WITH ITERATIONS/MACROS?
	BEQ DONEOK
	JSR CHKITR
	BCS UTCERR	; ITERATION LEFT ON STACK
	JSR POP		; MACRO- POP FROM STACK
	DEC PSHCNT
	JMP NXTCMD
;
UTCERR	LDA #11		; ?UTC ERROR
	JMP ERROR
DONEOK	JMP GTCMD1	; YES- GET NEXT COMMAND
;
UPAROW	JSR GTCMCH	; UPARROW COMMAND
	BCC ILLERR
	CMP #$40
	BMI ILLERR
	AND #$1F	; CONVERT TO CTRL CHAR
	JMP EXECMD
;
ILLERR	TYA		; ?ILL ERROR
	JMP ERROR
;
GTCMCH	JSR GETCHR	; GET COMMAND CHAR
	BCC GTCMER
	AND #$7F
	CMP #$60	; LOWER CASE?
	BMI GTCMDN
	SBC #$20	; YES- MAKE UPPER CASE
GTCMDN	SEC
GTCMER	RTS
;
GETCHR	LDA (CMDPTR),Y	; GET CHAR FROM INP BUF
	STA INCHAR
	SEC		; AT END OF BUF?
	LDA CMDCNT
	SBC #1
	STA CMDCNT
	LDA CMDCNT+1
	SBC #0
	STA CMDCNT+1
	BCC GETRTN	; END OF COMMAND STRING
	INC CMDPTR
	BNE CKTRAC
	INC CMDPTR+1
CKTRAC	LDA TRCMOD	; TRACE MODE?
	BEQ GETRTN
	LDA INCHAR	; YES- ECHO CHAR
	JSR CONOUT
	SEC
GETRTN	LDA INCHAR
	RTS
;
DIGIT	LDA RADIX	; RADIX=8?
	CMP #8
	BNE DIGOK
	LDA INCHAR	; YES- DIGIT 8 OR 9?
	CMP #'8
	BMI DIGOK
	LDA #1		; YES- ?ILN ERROR
	JMP ERROR
;
DIGOK	LDA NUMASM
	ORA LASTOP
	BNE EXPOK
BADEXP	LDA #2		; ?IEX ERROR
	JMP ERROR
;
EXPOK	INC NUMASM
	INC GOTHI
	LDA RADIX
	STA MULNUM
	STY MULNUM+1
	STY LASTOP
	LDA LSTARG	; SAVE LSTARG
	PHA
	LDA LSTARG+1
	PHA
	JSR MULT	; MULTIPLY HIVAL*RADIX
	SEC
	LDA INCHAR
	SBC #'0
	CLC
	ADC LSTARG
	STA HIARG
	LDA LSTARG+1
	ADC #0
	STA HIARG+1
	PLA		; RESTORE LSTARG
	STA LSTARG+1
	PLA
	STA LSTARG
	JMP NXTCMD
;
LPAR	LDX PRDPTH	; ( COMMAND
	CPX #MAXPAR	; ROOM LEFT ON STACK?
	BNE LPAR1
	LDA #8		; NO- ?PDO ERROR
	JMP ERROR
;
LPAR1	LDA LASTOP	; MUST HAVE JUST HAD OPERATION
	BNE LPAR2
	LDA GOTHI
	BNE BADEXP
;
LPAR2	LDA OPER
	STA PARSTK,X
	INX
	LDA LSTARG
	STA PARSTK,X
	INX
	LDA LSTARG+1
	STA PARSTK,X
	INX
	STX PRDPTH
	JMP PRCMD1
;
RPAR	LDA LASTOP	; ) COMMAND
	BEQ RPAR1	; LAST CHAR OP?
	LDA #44		; YES- ?NAP ERROR
	JMP ERROR
;
RPAR1	JSR DOOPER
	LDX PRDPTH
	BNE RPAR2
	LDA #43		; ?ERP ERROR
	JMP ERROR
;
RPAR2	LDA LSTARG
	STA HIARG
	LDA LSTARG+1
	STA HIARG+1
	DEX
	LDA PARSTK,X
	STA LSTARG+1
	DEX
	LDA PARSTK,X
	STA LSTARG
	DEX
	LDA PARSTK,X
	STA OPER
	STX PRDPTH
	STY LASTOP
	INC NUMASM
	JMP NXTCMD
;
;
;	PERFORM OPERATION
DOOPER	LDA LASTOP	; LAST CHAR AN OPERATOR?
	BEQ DOOPR1
	JMP BADEXP	; YES- ?IEX ERROR
;
DOOPR1	LDA OPER
	CMP #'+		; DO OPERATION
	BNE NOTADD
	CLC		; ADD
	LDA LSTARG
	ADC HIARG
	STA LSTARG
	LDA LSTARG+1
	ADC HIARG+1
	STA LSTARG+1
;
DONEOP	STY HIARG
	STY HIARG+1
	STY NUMASM
	LDA INCHAR
	STA OPER
	INC LASTOP
	RTS
;
NOTADD	CMP #'-
	BNE NOTSUB
	SEC		; SUBTRACT
	LDA LSTARG
	SBC HIARG
	STA LSTARG
	LDA LSTARG+1
	SBC HIARG+1
	STA LSTARG+1
	JMP DONEOP
;
NOTSUB	CMP #'*
	BNE NOTMUL
	LDA LSTARG
	STA MULNUM
	LDA LSTARG+1
	STA MULNUM+1
	JSR MULT
	JMP DONEOP
;
NOTMUL	CMP #'/
	BNE NOTDIV
	LDA HIARG	; DIVIDE
	STA DIVNUM
	LDA HIARG+1
	STA DIVNUM+1
	LDA LSTARG
	STA HIARG
	LDA LSTARG+1
	STA HIARG+1
	JSR DIVIDE
	JMP DONEOP
;
NOTDIV	CMP #'&
	BNE NOTAND
	LDA LSTARG	; AND
	AND HIARG
	STA LSTARG
	LDA LSTARG+1
	AND HIARG+1
	STA LSTARG+1
	JMP DONEOP
;
NOTAND	CMP #'#
	BNE NOTOR
	LDA LSTARG	; OR
	ORA HIARG
	STA LSTARG
	LDA LSTARG+1
	ORA HIARG+1
	STA LSTARG+1
	JMP DONEOP
;
NOTOR	JMP BADEXP	; ???
;
NEWOP	JSR DOOPER
	JMP NXTCMD
;
CMPCMD	LDA HIARG	; UPARROW/BACKSPACE CMD
	EOR #$FF	; COMPLEMENT LSTARG
	STA HIARG
	LDA HIARG+1
	EOR #$FF
	STA HIARG+1
	JMP NXTCMD
;
ASCCMD	JSR GETCHR	; UPARROW/UPARROW CMD
ASCRTN	STA HIARG
	STY HIARG+1
VALRTN	STY LASTOP
	INC GOTHI
	JMP NXTCMD
;
CARETT	LDA GOTHI	; UPARROW/T COMMAND
	BEQ GETTCH	; ARGUMENT GIVEN?
	LDA LASTOP	; COULD BE n+^T
	BNE GETTCH
	JSR DOOPER	; YES- PRINT CHR(LSTARG)
	LDA LSTARG
	JSR TTYOUT
	JMP PROCMD
;
GETTCH	LDA ETFLAG	; READ WITH NO WAIT?
	AND #$20
	BEQ GTTCH1
	LDA TINSIZ
	BNE GTTCH1
	JSR CNISTA	; YES- CHAR READY?
	BCS GTTCH1
	JMP NOTZRO	; NO- RETURN -1
;
GTTCH1	JSR TTYIN	; READ CHAR FROM KEYBRD
ASCJMP	JMP ASCRTN
;
CARETQ	JSR CHKARG	; ^Q COMMAND
	LDA LSTARG
	STA SRHCNT
	LDA LSTARG+1
	STA SRHCNT+1
	JSR LFFIND
	SEC
	LDA TEMPTR
	SBC BUFPTR
	STA HIARG
	LDA TEMPTR+1
	SBC BUFPTR+1
	STA HIARG+1
	JMP NEWVAL
;
CARETA	LDA #1		; UPARROW/A COMMAND
	JSR FDESC2	; FIND CLOSING ^A
	LDA CHRCNT
	ORA CHRCNT+1
	BEQ CTLADN
;
GETACH	LDA (TXTPTR),Y
	JSR TTYOUT
	INC TXTPTR
	BNE NXTCTA
	INC TXTPTR+1
NXTCTA	JSR DECCNT
	BNE GETACH
CTLADN	JMP PROCMD
;
BVALUE	TYA		; B=0
	BEQ ASCJMP
;
ZVALUE	LDA BUFSIZ	; Z=BUFSIZ
	STA HIARG
	LDA BUFSIZ+1
	STA HIARG+1
	JMP VALRTN
;
HVALUE	STY LOARG	; H=B,Z
	STY LOARG+1
	INC GOTLO
	BNE ZVALUE
;
DOTVAL	JSR GETDOT	; . COMMAND
	JMP VALRTN
;
CARETB	LDA DATE	; ^B COMMAND
	STA HIARG
	LDA DATE+1
	STA HIARG+1
	INC GOTHI
	JMP NXTCMD
;
CARETC	LDA CMDREG	; ^C COMMAND
	CMP #36		; DURING MACRO?
	BEQ CTCEXT
	JMP GETCMD	; YES- GET NEW COMMAND LINE
CTCEXT	JMP TECOEX	; NO- EXIT TECO
;
COMMA	LDA GOTHI	; , COMMAND
	BNE COMOK
	LDA #18		; ?NAC ERROR
	JMP ERROR
;
COMOK	JSR DOOPER
	LDA LSTARG
	STA LOARG
	LDA LSTARG+1
	STA LOARG+1
	INC GOTLO
	JMP PRCMD1
;
LMOVE	JSR CHKARG	; L COMMAND
	LDA LSTARG	; SEARCH FOR LF
	STA SRHCNT
	LDA LSTARG+1
	STA SRHCNT+1
	JSR LMOVE1
	JMP PROCMD
;
LMOVE1	JSR LFFIND
	LDA TEMPTR	; POSITION POINTER THERE
	STA BUFPTR
	LDA TEMPTR+1
	STA BUFPTR+1
	RTS
;
CMOVE	JSR CHKARG	; C COMMAND
CMOVE1	JSR CKPTR1
	BEQ GOTC
POPERR	LDA #7		; ?POP ERROR
	JMP ERROR
;
GOTC	LDA ENDLIM
	STA BUFPTR
	LDA ENDLIM+1
	STA BUFPTR+1
	JMP PROCMD
;
JMOVE	JSR DOOPER	; J COMMAND
	JSR BPTR	; RESET POINTER
	JMP CMOVE1
;
RMOVE	JSR CHKARG	; R COMMAND
	SEC		; = -NC
	TYA		; NEGATE LSTARG
	SBC LSTARG
	STA LSTARG
	TYA
	SBC LSTARG+1
	STA LSTARG+1
	JMP CMOVE1
;
TYPE	JSR CHKARG	; T COMMAND
	JSR TYPOUT
	JMP PROCMD
;
VERIFY	JSR CHKARG	; V COMMAND
	LDA LSTARG
	PHA
	LDA LSTARG+1
	PHA
	SEC		; DO 1-NT
	LDA #1
	SBC LSTARG
	STA LSTARG
	TYA
	SBC LSTARG+1
	STA LSTARG+1
	JSR TYPOUT
;
	PLA		; NOW DO NT
	STA LSTARG+1
	PLA
	STA LSTARG
	JSR TYPOUT
	JMP PROCMD
;
TYPOUT	JSR FNDARG	; = T COMMAND
;
TYPCHK	SEC		; DONE?
	LDA TEMPTR
	SBC LSTARG
	LDA TEMPTR+1
	SBC LSTARG+1
	BCS TYPDON
;
	LDA (TEMPTR),Y
	JSR TTYOUT
	JSR INCTEM
	JMP TYPCHK
TYPDON	RTS
;
GETDOT	SEC		; GET VALUE OF .
	LDA BUFPTR	; .=BUFPTR-BUFST
	SBC BUFST
	STA HIARG
	LDA BUFPTR+1
	SBC BUFST+1
	STA HIARG+1
	RTS
;
DRADIX	LDA #10		; UPARROW/D COMMAND
RDXRTN	STA RADIX	; CHANGE RADIX
	JMP PROCMD
;
ORADIX	LDA #8		; UPARROW/O COMMAND
	BNE RDXRTN
;
HRADIX	LDA #16
	BNE RDXRTN
;
HEXCMD	LDX #4		; $ COMMAND
NXTHEX	JSR GTCMCH	; GET 4 HEX DIGITS
	BCC BADHEX
	JSR CHKHEX
	BCC BADHEX
	STA TEMP
;
	LDY #4		; MULTIPLY BY 16
	LDA HIARG
SFTHEX	ASL A
	ROL HIARG+1
	DEY
	BNE SFTHEX
;
	ORA TEMP	; ADD DIGIT
	STA HIARG
	DEX
	BNE NXTHEX
	INC GOTHI
	JMP NXTCMD
;
BADHEX	LDA #40		; ?IHC ERROR
	JMP ERROR
;
CHKHEX	JSR DIGCHK	; 0..9?
	BCS HXGOOD
	BMI HEXBAD
	SBC #6		; NO- A..F?
	CMP #10
	BCC HEXBAD
	CMP #16
	BCS HEXBAD
HXGOOD	SEC		; YES- RETURN CARRY SET
	RTS
;
HEXBAD	CLC		; NO- RETURN CARRY CLEAR
	RTS
;
CARETS	SEC		; UPARROW/S COMMAND
	TYA		; RETURN -STRSIZ
	SBC STRSIZ
	STA HIARG
	TYA
	SBC STRSIZ+1
	STA HIARG+1
	JMP VALRTN
;
CARETY	JSR GETDOT	; UPARROW/Y COMMAND
	SEC		; =.+^S,.
	LDA HIARG
	SBC STRSIZ
	STA LOARG
	LDA HIARG+1
	SBC STRSIZ+1
	STA LOARG+1
	INC GOTLO
	JMP VALRTN
;
CARETZ	LDX #74		; ^Z COMMAND
	STY QSTART
	STY QSTART+1
	JSR ADDQST	; # CHARS FOR Q REG/COMMAND
	LDA QSTART	; STRING STORAGE
	STA HIARG
	LDA QSTART+1
	STA HIARG+1
	JMP VALRTN
;
EQUAL	LDA GOTHI	; LAST CHAR OPERATOR?
	BNE EXPROK
	LDA #3		; YES- ?NAE ERROR
	JMP ERROR
;
EXPROK	LDA RADIX
	STA TEMP1
	LDA (CMDPTR),Y	; :==?
	CMP #'=
	BNE EQUAL1
	JSR GETCHR
	LDA #8		; YES- PRINT IN OCTAL
	STA RADIX
;
EQUAL1	JSR CVTNUM
RESOUT	LDA NUMSTR,X
	JSR CONOUT
	INX
	CPX #6
	BNE RESOUT
;
	LDA GOTCLN	; :=?
	BNE EQUAL2	; YES- NO CRLF
	JSR CRLF
EQUAL2	LDA TEMP1	; RESTORE RADIX
	STA RADIX
	JMP PROCMD
;
;	CONVERT NUMBER TO STRING OF CURRENT RADIX
CVTNUM	JSR DOOPER
	STY NUMSGN
	LDA RADIX	; NEGATIVE BASE 10 #?
	CMP #10
	BNE NODCNG
	LDA LSTARG+1
	BPL NODCNG
	SEC		; YES- NEGATE & FLAG
	TYA
	SBC LSTARG
	STA LSTARG
	TYA
	SBC LSTARG+1
	STA LSTARG+1
	LDA #'-
	STA NUMSGN
;
NODCNG	LDX #5		; CONVERT UP TO 5 DIGITS
CVTDIV	LDA LSTARG+1
	STA TEMP+1
	LDA LSTARG
	STY LSTARG
	STY LSTARG+1
	SEC
CVTDV1	SBC RADIX
	BCC CVTDV3
CVTDV2	INC LSTARG
	BNE CVTDV1
	INC LSTARG+1
	BNE CVTDV1
;
CVTDV3	PHA
	LDA TEMP+1
	BEQ CVTDON
	DEC TEMP+1
	PLA
	SEC
	BCS CVTDV2
;
CVTDON	PLA		; CONVERT REMAINDER TO ASCII DIGIT
	ADC RADIX
	SED
	CLC
	ADC #'0
	CLD
	STA NUMSTR,X
	DEX
	BPL CVTDIV
;
	INX		; SKIP LEADING ZEROES
SKPLD0	LDA NUMSTR,X
	CMP #'0
	BNE GOTCVT
	INX
	CPX #5
	BNE SKPLD0
;
GOTCVT	LDA NUMSGN	; INSERT SIGN?
	BEQ CVTRTN
	DEX
	STA NUMSTR,X
CVTRTN	RTS
;
;	SEARCH FOR SRHCNT LF'S & RETURN IN TEMPTR
LFFIND	LDA BUFPTR
	STA TEMPTR
	LDA BUFPTR+1
	STA TEMPTR+1
	LDA SRHCNT+1	; NEGATIVE SEARCH?
	BMI NEGSRH
	ORA SRHCNT
	BNE POSRCH
;
NEGSRH	SEC		; YES- COUNT=-SRHCNT+1
	LDA #1
	SBC SRHCNT
	STA SRHCNT
	TYA
	SBC SRHCNT+1
	STA SRHCNT+1
;
LFIND1	JSR DECTEM
	SEC		; DONE?
	LDA TEMPTR
	SBC BUFST
	LDA TEMPTR+1
	SBC BUFST+1
	BCC FNDONM	; YES- RETURN
	LDA (TEMPTR),Y	; NO- LF?
	CMP #10
	BNE LFIND1
	JSR DECSRH
	BNE LFIND1
;
FNDONM	JSR INCTEM
FNDONE	RTS
;
POSRCH	JSR GETEND	; POSITIVE SEARCH
POSRH1	SEC		; DONE?
	LDA TEMPTR
	SBC ENDBUF
	LDA TEMPTR+1
	SBC ENDBUF+1
	BCS FNDONE
	LDA (TEMPTR),Y	; NO- LF?
	CMP #10
	BEQ LFOUND
POSRH2	JSR INCTEM	; NO- INC POINTER
	JMP POSRH1
;
LFOUND	JSR DECSRH	; YES- DEC COUNT
	BNE POSRH2
	BEQ FNDONM
;
;	MULTIPLY HIARG*MULNUM WITH RESULT IN LSTARG
MULT	STY LSTARG
	STY LSTARG+1
;
	LDX #16
MULT1	LSR MULNUM+1
	ROR MULNUM
	BCC NXTMUL
;
	CLC
	LDA LSTARG
	ADC HIARG
	STA LSTARG
	LDA LSTARG+1
	ADC HIARG+1
	STA LSTARG+1
;
NXTMUL	ASL HIARG
	ROL HIARG+1
	DEX
	BNE MULT1
MULDON	RTS
;
;	DIVIDE HIARG/DIVNUM WITH RESULT IN LSTARG
DIVIDE	LDA DIVNUM	; DIVIDE BY 0?
	ORA DIVNUM+1
	BNE DIVOK
	PLA		; EAT JSR
	PLA
	LDA #4		; YES- ?DIV ERROR
	JMP ERROR
;
DIVOK	STY LSTARG
	STY LSTARG+1
;
DIV1	SEC
	LDA HIARG
	SBC DIVNUM
	STA HIARG
	LDA HIARG+1
	SBC DIVNUM+1
	STA HIARG+1
	BCC DIVDON
	INC LSTARG
	BNE DIV1
	INC LSTARG+1
	JMP DIV1
DIVDON	RTS
;
CHKARG	LDA PRDPTH	; MAKE SURE ()'S MATCHED
	BEQ CKARG1
	JMP MRPERR
;
CKARG1	LDA GOTHI	; HIARG SPECIFIED?
	BNE ARGOK
	LDA #1		; NO- DEFAULT TO 1
	STA GOTHI
	STA HIARG
	STY HIARG+1
	STY LASTOP
ARGOK	JSR DOOPER
	RTS
;
;	GET LOW LIMIT IN TEMPTR & HI LIMIT IN LSTARG
;	FOR LINE ORIENTED OR M,N TYPE COMMANDS
FNDARG	LDA GOTLO	; ARGS OF FORM M,N?
	BNE LOHIOK
	LDA LSTARG	; SEARCH FOR LF
	STA SRHCNT
	LDA LSTARG+1
	STA SRHCNT+1
	JSR LFFIND
	LDA LSTARG+1	; NEGATIVE?
	BMI NEGARG
	ORA LSTARG
	BEQ NEGARG
;
FNDRG1	LDA TEMPTR	; NO- DO .,TEMPTR
	STA LSTARG
	LDA TEMPTR+1
	STA LSTARG+1
	LDA BUFPTR
	STA TEMPTR
	LDA BUFPTR+1
	STA TEMPTR+1
	RTS
;
NEGARG	LDA BUFPTR	; YES- DO TEMPTR,.
	STA LSTARG
	LDA BUFPTR+1
	STA LSTARG+1
	RTS
;
LOHIOK	JSR ADDST	; ADD BUFST TO ARGS
	LDA TEMPTR	; CHECK FOR LEGAL LIMITS
	STA CHRPTR
	LDA TEMPTR+1
	STA CHRPTR+1
	JSR CHKPTR
	LDA ENDLIM
	STA TEMPTR
	LDA ENDLIM+1
	STA TEMPTR+1
;
	LDA LSTARG
	STA CHRPTR
	LDA LSTARG+1
	STA CHRPTR+1
	JSR CHKPTR
	LDA ENDLIM
	STA LSTARG
	LDA ENDLIM+1
	STA LSTARG+1
	RTS
;
BPTR	LDA BUFST	; RESET POINTER TO
	STA BUFPTR	; START OF PAGE
	LDA BUFST+1
	STA BUFPTR+1
	RTS
;
ADDST	CLC		; ADD BUFST TO ARGS
	LDA LOARG
	ADC BUFST
	STA TEMPTR
	LDA LOARG+1
	ADC BUFST+1
	STA TEMPTR+1
	CLC
	LDA LSTARG
	ADC BUFST
	STA LSTARG
	LDA LSTARG+1
	ADC BUFST+1
	STA LSTARG+1
	RTS
;
GETEND	CLC		; COMPUTE BUFFER END
	LDA BUFST
	ADC BUFSIZ
	STA ENDBUF
	LDA BUFST+1
	ADC BUFSIZ+1
	STA ENDBUF+1
	RTS
;
INCTEM	INC TEMPTR
	BNE INCRTN
	INC TEMPTR+1
INCRTN	RTS
;
INCTM1	INC TMPTR1
	BNE INCRTN
	INC TMPTR1+1
	RTS
;
INCPTR	INC BUFPTR
	BNE INCRTN
	INC BUFPTR+1
	RTS
;
DECTEM	LDA TEMPTR
	BNE DCTEMA
	DEC TEMPTR+1
DCTEMA	DEC TEMPTR
	RTS
;
DECTM1	LDA TMPTR1
	BNE DCTM1A
	DEC TMPTR1+1
DCTM1A	DEC TMPTR1
	RTS
;
DECSRH	SEC
	LDA SRHCNT
	SBC #1
	STA SRHCNT
	LDA SRHCNT+1
	SBC #0
	STA SRHCNT+1
	ORA SRHCNT
	RTS
;
DECPTR	LDA BUFPTR
	BNE DCPTR1
	DEC BUFPTR+1
DCPTR1	DEC BUFPTR
	RTS
;
DECCNT	SEC
	LDA CHRCNT
	SBC #1
	STA CHRCNT
	LDA CHRCNT+1
	SBC #0
	STA CHRCNT+1
	ORA CHRCNT
	RTS
;
FNDESC	LDA #$1B	; FIND ESCAPE IN COMMAND
FDESC2	STA ESCHAR
	STY CHRCNT
	STY CHRCNT+1
	LDA GOTAT	; COMMAND OF FORM @I//?
	BEQ SAVPTR
	JSR GETCHR	; YES- GET DELIMITER
	BCC FNDERR
	STA ESCHAR
;
SAVPTR	LDA CMDPTR	; SAVE POINTER
	STA TXTPTR
	LDA CMDPTR+1
	STA TXTPTR+1
;
FDESC1	JSR GETCHR
	BCC FNDERR
	CMP ESCHAR
	BEQ ESCFND
	INC CHRCNT
	BNE FDESC1
	INC CHRCNT+1
	BNE FDESC1
ESCFND	RTS
;
FNDERR	JMP UTCERR
;
BADCMD	TYA		; ?ILL ERROR
	JMP ERROR
;
;	SEE IF BUFPTR+LSTARG WITHIN RANGE
CKPTR1	CLC
	LDA LSTARG
	STA CHRCNT
	ADC BUFPTR
	STA CHRPTR
	LDA LSTARG+1
	STA CHRCNT+1
	ADC BUFPTR+1
	STA CHRPTR+1
;
;	SEE IF CHRPTR BETWEEN 0,Z
CHKPTR	SEC
	LDA CHRPTR
	SBC BUFST
	LDA CHRPTR+1
	SBC BUFST+1
	BCS LOWOK
	LDA BUFST	; <0; POINT TO START
	STA ENDLIM
	LDA BUFST+1
	STA ENDLIM+1
	LDA #$FF	; RETURN <0
	RTS
;
LOWOK	JSR GETEND	; BEYOND END?
	SEC
	LDA ENDBUF
	STA ENDLIM
	SBC CHRPTR
	LDA ENDBUF+1
	STA ENDLIM+1
	SBC CHRPTR+1
	BCS HIGHOK
	LDA #1		; RETURN >0
	RTS
;
HIGHOK	LDA CHRPTR
	STA ENDLIM
	LDA CHRPTR+1
	STA ENDLIM+1
	TYA		; RETURN =0
	RTS
;
TRACE	LDA TRCMOD	; ? COMMAND
	EOR #$FF
	STA TRCMOD
	JMP PROCMD
;
DELCMD	LDA GOTLO	; M,ND?
	BNE KILL	; YES- DO M,NK
	JSR CHKARG	; D COMMAND
	JSR CKPTR1
	BEQ GOTD
DTBERR	LDA #10		; ?DTB ERROR
	JMP ERROR
;
GOTD	LDA LSTARG+1	; -ND?
	BPL DELTXT
	LDA ENDLIM	; YES; DO -NC
	STA BUFPTR
	LDA ENDLIM+1
	STA BUFPTR+1
;
	SEC		; NEGATE CHRCNT
	TYA
	SBC CHRCNT
	STA CHRCNT
	TYA
	SBC CHRCNT+1
	STA CHRCNT+1
;
DELTXT	JSR DELETE	; DELETE N CHARS
	JMP PROCMD
;
KILL	JSR CHKARG	; K COMMAND
	JSR FNDARG
	SEC		; COMPUTE N-M+1
	LDA LSTARG
	SBC TEMPTR
	STA CHRCNT
	LDA LSTARG+1
	SBC TEMPTR+1
	STA CHRCNT+1
	BCC DTBERR
;
	LDA TEMPTR	; MOVE PTR BACK M CHARS
	STA BUFPTR
	LDA TEMPTR+1
	STA BUFPTR+1
	JSR DELETE	; DELETE CHARS M THRU N
	JMP PROCMD
;
INSCMD	JSR FNDESC	; I COMMAND
	LDA GOTHI	; PRECEDED BY ARGUMENT?
	BEQ INSTXT
	LDA CHRCNT	; YES- MAKE SURE NO TEXT
	ORA CHRCNT+1	; AFTER 'I'
	BEQ INSVAL
IIAERR	LDA #6		; NO- ?IIA ERROR
	JMP ERROR
;
INSVAL	JSR DOOPER	; INSERT CHR$(LSTARG)
	LDA LSTARG
	STA TEMBUF
	JSR VALINS
	JMP PROCMD
;
INSTXT	JSR INSERT	; INSERT CHARS UP TO ESC
	JMP PROCMD
;
TABCMD	SEC		; TAB COMMAND
	LDA CMDPTR	; INSERT TEXT INCLUDES TAB
	SBC #1
	STA TXTPTR
	LDA CMDPTR+1
	SBC #0
	STA TXTPTR+1
	STY CHRCNT+1	; ALREADY GOT 1 CHAR
	LDA #1
	STA CHRCNT
	LDA #$1B	; SEARCH FOR ESC
	STA TEMP
	JSR FDESC1
	JMP INSTXT	; INSERT REST OF TEXT
;
VALINS	JSR SETEMP	; INSERT CHR$(TEMBUF)
	JMP INSERT
;
SETEMP	LDA TMPBUF	; INSERT CHR$(TEMBUF)
	STA TXTPTR
	LDA TMPBUF+1
	STA TXTPTR+1
	LDA #1
	STA CHRCNT
	STY CHRCNT+1
	RTS
;
BKSLSH	LDA GOTHI	; \ COMMAND
	BEQ BKSLS1
	JSR CVTNUM	; N\ COMMAND
	TXA
	EOR #$FF	; GET 6-X
	CLC
	ADC #7
	STA CHRCNT
	STY CHRCNT+1
	CLC		; GET POINTER
	TXA
	ADC STRPTR
	STA TXTPTR
	TYA
	ADC STRPTR+1
	STA TXTPTR+1
	JSR INSERT	; INSERT NUMBER STRING
	JMP PROCMD
;
BKSLS1	LDA #1		; ASSEMBLE # AFTER BUFPTR
	STA CHRCNT
	STY CHRCNT+1
	STY HIARG
	STY HIARG+1
	STY NUMSGN
	LDA LSTARG
	PHA
	LDA LSTARG+1
	PHA
;
	JSR GETEND
	JSR ENDCHK
	BCC BKSLDN
	LDA RADIX	; SIGNED DECIMAL?
	CMP #10
	BNE NODCNM
	LDA (BUFPTR),Y
	CMP #'+
	BEQ GOTSGN
	CMP #'-
	BNE NODCNM
	INC NUMSGN
GOTSGN	JSR INCPTR
;
NODCNM	JSR ENDCHK	; GET DIGIT FROM BUFFER
	BCC BKSLDN
	LDA (BUFPTR),Y
	JSR CHKHEX
	BCC BKSLDN
	CMP RADIX
	BPL BKSLDN
	PHA		; YES- GET HIARG*RADIX+DIGIT
	LDA RADIX
	STA MULNUM
	STY MULNUM+1
	JSR MULT
	CLC
	PLA
	ADC LSTARG
	STA HIARG
	TYA
	ADC LSTARG+1
	STA HIARG+1
	JSR INCPTR
	JMP NODCNM
;
BKSLDN	PLA		; RESTORE LSTARG
	STA LSTARG+1
	PLA
	STA LSTARG
	LDA NUMSGN
	BEQ BKSLPS
	SEC		; NEGATE ARG
	TYA
	SBC HIARG
	STA HIARG
	TYA
	SBC HIARG+1
	STA HIARG+1
BKSLPS	JMP VALRTN
;
ITERST	JSR ITRADD	; < COMMAND
	JMP PROCMD
;
ITRADD	TYA		; ADD ITERATION TO PUSHDOWN LIST
	JSR PUSH
	LDA GOTHI	; ARG GIVEN?
	BNE ITRARG
	LDA #$FF	; NO- MAKE INFINITE
	STA ITRCNT,X
	STA ITRCNT+1,X
	RTS
;
ITRARG	STX TEMPX
	JSR DOOPER
	LDX TEMPX
	LDA LSTARG+1	; ARG <=0?
	BMI ITRNEG	; YES- IGNORE ITERATION
	STA ITRCNT+1,X
	ORA LSTARG
	BEQ ITRNEG
	LDA LSTARG	; SAVE COUNT
	STA ITRCNT,X
ITREXT	RTS
;
ITRNEG	DEC PSHCNT	; SKIP TO END OF ITERATION
	LDA #'>
	JMP SKPCMD
;
ITREND	JSR CHKITR	; > COMMAND
	BCC BNIERR
	LDA ITRCNT+1,X	; INFINITE ITERATION?
	BMI NXTITR
	SEC
	LDA ITRCNT,X
	SBC #1
	STA ITRCNT,X
	LDA ITRCNT+1,X
	SBC #0
	STA ITRCNT+1,X
	ORA ITRCNT,X
	BEQ ITRDON
;
NXTITR	JSR POP		; POINT TO AFTER <
	JMP PROCMD
;
BNIERR	LDA #9		; ?BNI ERROR
	JMP ERROR
;
ITRDON	DEC PSHCNT	; DONE WITH ITERATION
JMPPRO	JMP PROCMD
;
SEMCMD	JSR CHKITR	; ; COMMAND
	BCS SEMIOK
	LDA #15		; ?SNI ERROR
	JMP ERROR
;
SEMIOK	LDA GOTHI	; ARGUMENT GIVEN?
	BNE SEMOK1
	LDA #16		; NO- ?NAS ERROR
	JMP ERROR
;
SEMOK1	JSR DOOPER
	LDA LSTARG+1	; ARG>0?
	BMI JMPPRO	; NO- IGNORE
	JSR ITRNEG	; YES- EXIT ITERATION
	JMP PROCMD
;
;	*** PUSH ITERATION/MACRO ON PUSHDOWN LIST ***
;	*** A=0 FOR ITERATION, 1 FOR MACRO        ***
PUSH	PHA
	LDA PSHCNT
	CMP #16
	BNE PUSHOK
	LDA #8		; ?PDO ERROR
	JMP ERROR
;
PUSHOK	ASL A
	TAX
	LDA CMDCNT	; SAVE # CHARS LEFT IN COMMAND
	STA PSHLST,X
	LDA CMDCNT+1
	STA PSHLST+1,X
	LDA CMDREG
	STA PSHREG,X
	PLA
	STA PSHREG+1,X
	INC PSHCNT
	RTS
;
;	*** POP ITERATION/MACRO FROM PUSHDOWN LIST   ***
POP	STX TEMPX
	LDA PSHLST,X	; GET # CHARS LEFT IN COMMAND
	STA CMDCNT
	LDA PSHLST+1,X
	STA CMDCNT+1
	LDA PSHREG,X	; GET COMMAND REG #
	STA CMDREG
	ASL A
	TAX		; COMPUTE COMMAND START
	INX
	INX
	JSR GETQST
	SEC
	LDA QSTART
	SBC CMDCNT
	STA CMDPTR
	LDA QSTART+1
	SBC CMDCNT+1
	STA CMDPTR+1
	LDX TEMPX
	RTS
;
CHKITR	LDA PSHCNT	; ITERATION LAST ON STACK?
	BEQ BADITR
	ASL A
	TAX
	DEX
	DEX
	LDA PSHREG+1,X
	BNE BADITR
	SEC		; YES- RETURN CARRY SET
	RTS
;
BADITR	CLC		; NO- RETURN CARRY CLEAR
	RTS
;
QUOCMD	LDA GOTHI	; " COMMAND
	BNE QUOCM1
	LDA #37		; ?NAQ ERROR
	JMP ERROR
;
QUOCM1	JSR DOOPER
	JSR GTCMCH
	LDX #15
FNDQUO	CMP QUOLST,X
	BEQ GOTQUO
	DEX
	BPL FNDQUO
	LDA #38		; ?IQC ERROR
	JMP ERROR
;
GOTQUO	TXA
	ASL A
	TAX
	LDA QUODSP,X	; GET JUMP ADDRESS
	STA QUOJMP+1
	LDA QUODSP+1,X
	STA QUOJMP+2
QUOJMP	JMP $0000
;
QUOTEG	LDA LSTARG+1	; "G,">
	BMI QUOSKP
	ORA LSTARG
	BNE QUOEXE
;
QUOSKP	LDA #''		; SKIP TO '
	JSR SKPCMD
QUOEXE	JMP PROCMD
;
QUOTEL	LDA LSTARG+1	; "L,"<,"T,"S
	BPL QUOSKP
	JMP PROCMD
;
QUOTEE	LDA LSTARG	; "E,"F,"U
	ORA LSTARG+1
	BNE QUOSKP
	JMP PROCMD
;
QUOTEC	LDA LSTARG	; "C
	AND #$7F
	CMP #'.
	BEQ QUOEXE
	CMP #'$
	BEQ QUOEXE
QUOTER	JSR QUODIG	; 0..9?
	BCS QUOEXE
QUOTEA	JSR QUOUPC	; A..Z?
	BCS QUOEXE
QUOTEV	JSR QUOLRC	; a..z?
	BCS QUOEXE
	JMP QUOSKP
;
QUOTEN	LDA LSTARG	; "N
	ORA LSTARG+1
	BEQ QUOSKP
	JMP PROCMD
;
QUOTEW	JSR QUOUPC	; "W
	BCC QUOSKP
	JMP PROCMD
;
QUOTED	JSR QUODIG	; "D
	BCC QUOSKP
	JMP PROCMD
;
QUODIG	LDA LSTARG	; RETURN CARRY SET IF LSTARG IN '0..'9
	AND #$7F
	CMP #'0
	BMI QUOCLC
	CMP #'9+1
	BPL QUOCLC
QUOSEC	SEC
	RTS
;
QUOUPC	LDA LSTARG	; RETURN CARRY SET IF LSTARG IN 'A..'Z
	AND #$7F
	CMP #'A
	BMI QUOCLC
	CMP #'Z+1
	BMI QUOSEC
QUOCLC	CLC
	RTS
;
QUOLRC	LDA LSTARG	; RETURN CARRY SET IF LSTARG IN 'a..'z
	AND #$7F
	CMP #97
	BMI QUOCLC
	CMP #123
	BPL QUOCLC
	BMI QUOSEC
;
OCMD	JSR FNDESC	; O COMMAND
	LDA TXTPTR
	STA TAGPTR
	LDA TXTPTR+1
	STA TAGPTR+1
	LDA CHRCNT
	STA TAGCNT
	LDA CHRCNT+1
	STA TAGCNT+1
;
	LDA PSHCNT	; GET STARTING POINT FOR TAG SEARCH
	ASL A
	TAX
	BNE GETOST
	LDA CMDREG
;
OCMD1	ASL A
	TAX
	JSR GETQST
	LDA QSTART
	STA CMDPTR
	LDA QSTART+1
	STA CMDPTR+1
	LDA QRGCNT,X
	STA CMDCNT
	LDA QRGCNT+1,X
	STA CMDCNT+1
	JMP TAGFND
;
GETOST	DEX		; LAST ITERATION/MACRO IN THIS Q REG?
	DEX
	LDA CMDREG
	CMP PSHREG,X
	BNE OCMD1
	JSR POP		; YES- POP START
;
TAGFND	LDA #'!		; FIND TAG
	JSR SKPCMD
	LDA TAGCNT
	STA SRHCNT
	LDA TAGCNT+1
	STA SRHCNT+1
	LDA TAGPTR
	STA TEMPTR
	LDA TAGPTR+1
	STA TEMPTR+1
;
TAGCMP	LDA SRHCNT	; ENTIRE LABEL FOUND?
	ORA SRHCNT+1
	BNE TGCMP1
	JSR GETCHR	; YES- THIS MUST BE TAG END
	CMP #'!
	BNE NOMTCH
	JMP PROCMD	; YES- DONE!
;
TGCMP1	JSR GETCHR
	BCC BADTAG
	CMP #'!
	BEQ TAGFND	; SHORTER TAG
	CMP (TEMPTR),Y
	BNE NOMTCH
	JSR INCTEM
	LDA SRHCNT	; DEC SRHCNT
	BNE TGCMP2
	DEC SRHCNT+1
TGCMP2	DEC SRHCNT
	JMP TAGCMP
;
NOMTCH	JSR TAGSKP	; SKIP TO END OF TAG
	JMP TAGFND	; CHECK NEXT
;
TAGSKP	JSR GETCHR	; SKIP TO END OF TAG
	BCC BADTAG
	CMP #'!
	BNE TAGSKP
	RTS
;
BADTAG	LDA #39		; ?TAG ERROR
	JMP ERROR
;
TAGCMD	JSR TAGSKP	; ! COMMAND
	JMP PROCMD
;
;
;	*** SKIP COMMANDS UNTIL CHAR IN A IS FOUND.
SKPCMD	STA SKPCHR
	LDA PSHCNT
	STA SKITCT	; SKIP ITERAION COUNT
	STY SKCNCT	; SKIP CONDITIONAL COUNT
	LDA TRCMOD	; DISABLE COMMAND ECHO
	STA TRCTMP
	STY TRCMOD
SKPCM1	STY GOTAT
SKPCM2	JSR GTCMCH
	BCC SKPERR
SKPCM3	CMP SKPCHR
	BEQ SKPDON
;
	LDX #SKPSPC-SKPQLS-1
SKPQCK	CMP SKPQLS,X	; Q REG COMMAND?
	BEQ GOTQSK
	DEX
	BPL SKPQCK
;
SKSPCK	INX		; SPECIAL CHAR?
	CMP SKPSPC,X
	BEQ GOTSPC
	CPX #SKPTBL-SKPSPC-1
	BNE SKSPCK
;
	LDX #0
SKESCK	CMP SKPESC,X	; SKIP TO ESCAPE?
	BEQ SKPCH	; NO- SKIP NEXT COMMAND
	INX
	CPX #SKECMD-SKPESC
	BNE SKESCK
	BEQ SKPCM1
;
SKPCH	JSR FNDESC	; YES- SKIP TO IT
	JMP SKPCM1
;
GOTQSK	JSR GTCMCH	; GET Q REG #
	BCS SKPCM1
SKPERR	JMP UTCERR
;
GOTSPC	TXA		; GOT SPECIAL CHAR
	ASL A		; GET JMP ADDRESS
	TAX
	LDA SKPTBL,X
	STA SKPJMP+1
	LDA SKPTBL+1,X
	STA SKPJMP+2
SKPJMP	JMP $0000
;
SKPDON	CMP #'>		; ITERATIONS MATCH?
	BNE CKCNSK
	LDX SKITCT
	CPX PSHCNT
	BNE SKPGTR	; NO- FIND NEXT >
	LDX SKCNCT	; CONDITIONALS MATCH?
	BEQ SKPRTN
	LDA #35		; NO- ?ICN ERROR
	JMP ERROR
;
SKPRTN	LDX TRCTMP	; RESTORE TRACE FLAG
	STX TRCMOD
	BEQ SKPRT1	; ENABLED?
	JSR CONOUT	; YES- ECHO CHAR FOUND
SKPRT1	RTS
;
CKCNSK	CMP #''		; CONDITIONALS MATCH?
	BNE SKPRTN
	LDX SKCNCT
	BNE SKPCND
	LDX SKITCT	; ITERATIONS SHOULD MATCH
	CPX PSHCNT
	BEQ SKPRTN
IINERR	LDA #36		; ?IIN ERROR
	JMP ERROR
;
SKPCTA	LDA #1		; FIND CLOSING ^A
	JSR FDESC2
SKCNJP	JMP SKPCM1
;
SKPQUO	INC SKCNCT	; SKIP "CONDITION
	JMP GOTQSK
;
SKPTAG	JSR TAGSKP	; SKIP TO END OF TAG
	JMP SKPCM1
;
SKPCND	DEC SKCNCT	; SKIP ' (END CONDITIONAL)
	JMP SKPCM1
;
SKPHEX	LDX #4		; SKIP $HEX CONSTANT
SKPHX1	JSR GTCMCH	; SKIP 4 CHARS
	BCC SKPERR
	DEX
	BNE SKPHX1
	JMP SKPCM1
;
SKPITR	STY GOTHI	; SKIP < ITERATION
	JSR ITRADD
	JMP SKPCM1
;
SKPGTR	JSR CHKITR	; SKIP >
	BCC IINERR
	DEC PSHCNT
	JMP SKPCM1
;
SKPAT	INC GOTAT	; SKIP @ COMMAND
	JMP SKPCM2
;
SKPE	JSR GTCMCH	; SKIP E COMMAND
	LDX #SKPEND-SKECMD-1	; ER$ TYPE COMMAND?
SKPE1	CMP SKECMD,X
	BEQ SKCHJP	; YES- SKIP TO ESCAPE
	DEX
	BPL SKPE1
	JMP SKPCM1	; NO- SKIP NEXT COMMAND
;
SKPF	JSR GTCMCH	; SKIP F COMMAND
	CMP #'R
	BEQ SKCHJP
	CMP #'N
	BEQ SKPF1
	CMP #'S
	BEQ SKPF1
SKJMP1	JMP SKPCM1
;
SKPF1	JSR FNDESC	; SKIP FSTEXT$TEXT$
	STY GOTAT
SKCHJP	JMP SKPCH
;
SKPUP	JSR GTCMCH	; SKIP ^
	CMP #$40
	BMI SKJMP1	; SHOULD BE ERROR
	AND #$1F
	JMP SKPCM3
;
INSERT	JSR INTEXT	; INSERT TEXT
	CLC		; INC BUFFER SIZE
	LDA STRSIZ
	ADC BUFSIZ
	STA BUFSIZ
	LDA STRSIZ+1
	ADC BUFSIZ+1
	STA BUFSIZ+1
INSDON	RTS
;
;	INSERT CHRCNT CHARS (POINTED TO BY TXTPTR)
;	FOLLOWING BUFPTR.
INTEXT	LDA CHRCNT	; SAVE LENGTH OF INSERT
	STA STRSIZ
	LDA CHRCNT+1
	STA STRSIZ+1
	ORA CHRCNT	; =0?
	BEQ INSDON
;
	CLC		; COMPUTE NEW SIZE
	LDA BUFEND
	STA TEMPTR
	ADC CHRCNT
	STA TMPTR1
	LDA BUFEND+1
	STA TEMPTR+1
	ADC CHRCNT+1
	STA TMPTR1+1
;
	SEC		; ENOUGH ROOM?
	LDA MAXEND
	SBC TMPTR1
	LDA MAXEND+1
	SBC TMPTR1+1
	BCS SIZEOK
	PLA		; NO- ?MEM ERROR
	PLA
	LDA #5
	JMP ERROR
;
SIZEOK	LDA TMPTR1	; SAVE NEW BUFFER END
	STA BUFEND
	LDA TMPTR1+1
	STA BUFEND+1
;
	SEC		; INSERT BEFORE CMDPTR?
	LDA CMDPTR
	SBC BUFPTR
	LDA CMDPTR+1
	SBC BUFPTR+1
	BCC CKBFPT
	CLC		; YES- UPDATE CMDPTR
	LDA CMDPTR
	ADC CHRCNT
	STA CMDPTR
	LDA CMDPTR+1
	ADC CHRCNT+1
	STA CMDPTR+1
;
CKBFPT	SEC		; TEXT AFTER BUFPTR?
	LDA BUFPTR
	SBC TXTPTR
	LDA BUFPTR+1
	SBC TXTPTR+1
	BCS MOVFWD
	JSR FIXCMD	; YES- MOVE TXTPTR (BECAUSE TEXT MOVES)
;
MOVFWD	LDA TEMPTR	; DONE?
	CMP BUFPTR
	BNE MVFWD1
	LDA TEMPTR+1
	CMP BUFPTR+1
	BEQ TXTINS
;
MVFWD1	JSR DECTEM	; NO- MOVE TEXT FORWARD
	JSR DECTM1
	LDA (TEMPTR),Y
	STA (TMPTR1),Y
	JMP MOVFWD
;
TXTINS	LDA (TXTPTR),Y	; NOW INSERT TEXT
	STA (BUFPTR),Y
	JSR INCPTR
	INC TXTPTR
	BNE DECNTR
	INC TXTPTR+1
DECNTR	JSR DECCNT
	BNE TXTINS
	RTS
;
FIXCMD	CLC
	LDA TXTPTR
	ADC CHRCNT
	STA TXTPTR
	LDA TXTPTR+1
	ADC CHRCNT+1
	STA TXTPTR+1
	RTS
;
DELETE	JSR DLTEXT
	SEC		; UPDATE BUFFER SIZE
	LDA BUFSIZ
	SBC CHRCNT
	STA BUFSIZ
	LDA BUFSIZ+1
	SBC CHRCNT+1
	STA BUFSIZ+1
	RTS
;
;	DELETE CHRCNT CHARS FOLLOWING BUFPTR.
DLTEXT	CLC
	LDA BUFPTR
	STA TMPTR1
	ADC CHRCNT
	STA TEMPTR
	LDA BUFPTR+1
	STA TMPTR1+1
	ADC CHRCNT+1
	STA TEMPTR+1
	SEC		; DELETE BEFORE CMDPTR?
	LDA CMDPTR
	SBC TEMPTR
	LDA CMDPTR+1
	SBC TEMPTR+1
	BCC MVBCK1
	SEC		; YES- UPDATE CMDPTR
	LDA CMDPTR
	SBC CHRCNT
	STA CMDPTR
	LDA CMDPTR+1
	SBC CHRCNT+1
	STA CMDPTR+1
;
MVBCK1	LDA TEMPTR	; DONE?
	CMP BUFEND
	BNE NOTDON
	LDA TEMPTR+1
	CMP BUFEND+1
	BNE NOTDON
;
	LDA TMPTR1	; YES- SET NEW BUFFER END
	STA BUFEND
	LDA TMPTR1+1
	STA BUFEND+1
	RTS
;
NOTDON	LDA (TEMPTR),Y
	STA (TMPTR1),Y
	JSR INCTEM
	JSR INCTM1
	JMP MVBCK1
;
ECMD	JSR GTCMCH	; E COMMAND- GET NEXT CHR
	CMP #'W
	BNE NOTEW
	STY EBFLAG	; EW COMMAND
	JSR EDITWR
	JMP PROCMD
;
NOTEW	CMP #'F
	BNE NOTEF
	JSR CLSOUT	; EF COMMAND
	JMP PROCMD
;
NOTEF	CMP #'C
	BNE NOTEC
	JSR CLSALL	; EC COMMAND
PROJMP	JMP PROCMD
;
NOTEC	CMP #'X
	BNE NOTEX
	JSR CLSALL	; EX COMMAND
	JMP TECOEX
;
NOTEX	CMP #'R
	BNE NOTER
	JSR EDITRD	; ER COMMAND
EDTRTN	LDA GOTCLN
	BEQ PROJMP
	LDA GOTEOF
	BNE PROJMP
VALJMP	JMP VALRTN	; :ER COMMAND
;
NOTER	CMP #'B
	BNE NOTEB
	LDA CMDCNT
	STA TEMP1
	LDA CMDCNT+1
	STA TEMP1+1
	JSR EDITRD
	CMP #0		; LOOKUP FAIL?
	BEQ VALJMP	; YES- MUST BE :EB - RETURN 0
;
	INC EBFLAG
	LDA TXTPTR	; POINT BACK TO NAME FOR
	STA CMDPTR	; EDIT WRITE
	LDA TXTPTR+1
	STA CMDPTR+1
	LDA TEMP1
	STA CMDCNT
	LDA TEMP1+1
	STA CMDCNT+1
	LDA TRCMOD
	STA TRCTMP
	STY TRCMOD
	JSR EDITWR
	LDA TRCTMP
	STA TRCMOD
	JMP EDTRTN
;
NOTEB	CMP #'K
	BNE NOTEK
	LDA OUTOPN	; EK COMMAND
	BEQ EKRTN
	JSR DELTMP	; UNDO EW OR EB
	STY OUTOPN
EKRTN	JMP PROCMD
;
NOTEK	CMP #'E
	BNE NOTEE
	LDA CLSPTR	; EE COMMAND
	STA SCNOUT
	LDA CLSPTR+1
	STA SCNOUT+1
	JSR GETFIL	; GET FILE NAME
	LDA CLSBUF+12	; DELETE FILE
	ORA #$40
	TAX
	LDA CLSBUF+11
	JSR USR
	.BYTE DELET
	.WORD CLSBUF
	JMP DIRERR
	JMP PROCMD
;
NOTEE	CMP #'I
	BNE NOTEI
	LDA EIFPTR	; EI COMMAND
	STA SCNOUT
	LDA EIFPTR+1
	STA SCNOUT+1
	JSR GETFIL	; LOOKUP INDIRECT FILE
	BCS EICMD0
	STY EIOPEN	; EI$
	JMP PROCMD
;
EICMD0	LDA EIUNIT
	ORA #$40
	TAX
	LDA EIDEV
	JSR USR
	.BYTE LOOKUP
	.WORD EIFILE
	.WORD DIRBUF
	JMP FNFERR
;
	LDA DIRBUF+$C	; INIT STARTING BLOCK
	STA EIPAGE
	LDA DIRBUF+$D
	STA EIPAGE+1
	LDA DIRBUF+$E	; AND LENGTH
	STA EILEN
	LDA DIRBUF+$F
	BEQ EICMD1
	JMP STLERR	; FILE TOO BIG
;
EICMD1	LDA EIEND	; EMPTY BUFFER
	STA EIPTR
	LDA EIEND+1
	STA EIPTR+1
	INC EIOPEN
	JMP PROCMD
;
NOTEI	CMP #'Q
	BNE NOTEQ
	JMP NOTOPN	; EQ COMMAND
;
NOTEQ	LDX #EFGCNT-1	; SEARCH FOR E FLAG
FNDFLG	CMP EFLAGS,X
	BEQ GOTFLG
	DEX
	BPL FNDFLG
IECERR	LDA #23		; NOT FOUND- ?IEC ERROR
	JMP ERROR
;
GOTFLG	STA TEMP
	TXA
	ASL A
	TAX
	LDA TEMP
	CMP #'O
	BEQ FLGVAL	; EO IS READ-ONLY
;
FLGTYP	LDA GOTHI	; SET FLAG?
	BEQ FLGVAL
	LDA LASTOP	; COULD BE n+Ex
	BNE FLGVAL
	JSR DOOPER	; YES
	LDA LSTARG
	STA EDFLAG,X
	LDA TEMP	; ET?
	CMP #'T
	BEQ GOTET
	LDA LSTARG+1
	STA EDFLAG+1,X
	JMP PROCMD
;
GOTET	LDA LSTARG+1
	AND #$F9	; BITS 9 AND 10 READ ONLY
	STA LSTARG+1
	LDA ETFLAG+1
	AND #6
	ORA LSTARG+1
	STA ETFLAG+1
	LDA LSTARG	; LOWER CASE ALLOWED?
	AND #4		; PUT CONVERSION BIT IN CNSTAI
	ASL A
	EOR #8
	STA TEMP
	LDA CNSTAI
	AND #$F7
	ORA TEMP
	STA CNSTAI
	JMP PROCMD
;
FLGVAL	LDA EDFLAG,X	; NO- GET VALUE
	STA HIARG
	LDA EDFLAG+1,X
	STA HIARG+1
	JMP VALRTN
;
CTXCMD	LDX #EFGCNT*2	; ^X COMMAND
	BNE FLGTYP
;
PCMD	LDA (CMDPTR),Y	; P COMMAND
	CMP #'W		; PW COMMAND?
	BNE NOTPW
	JSR GTCMCH
	LDA GOTLO	; YES- M,NPW?
	BNE NOTPW
	INC FFFLAG	; NO- APPEND FF TO PAGE
;
NOTPW	LDA GOTLO	; M,N COMMAND?
	BNE NOTCOM
	JSR CHKARG	; NO- GET REPETITION CNT
	LDA LSTARG
	STA TEMP1
	LDA LSTARG+1
	BEQ NEWPAG
	LDA #26		; ?IPC ERROR
	JMP ERROR
;
NEWPAG	JSR PAGOUT	; OUTPUT PAGE
	JSR YNKPAG	; GET NEXT PAGE
	DEC TEMP1
	BNE NEWPAG
;
INRTN	JSR INUP
	JMP PROCMD
;
NOTCOM	JSR FNDARG	; M,NP COMMAND
	JSR OUTPUT
	JMP PROCMD
;
;
YCMD	JSR YANK	; Y COMMAND
	JMP INRTN
;
ACMD	LDA GOTHI	; A COMMAND
	BEQ NOAARG	; NA?
	JSR DOOPER
	JSR CKPTR1	; YES- GET CHAR AT .+ARG
	BEQ AARGOK
	LDA #$FF	; RETURN -1
	STA HIARG
	STA HIARG+1
	JMP NEWVAL
;
AARGOK	LDA (CHRPTR),Y
	STA HIARG
	STY HIARG+1
	JMP NEWVAL
;
NOAARG	LDA GOTCLN	; FLAG IF :A
	STA COLONA
	JSR APPEND	; NO- APPEND PAGE
	JMP INRTN
;
INUP	LDA INOPEN	; RAISE HEAD FOR FLOPPY
	BEQ IGNORE
	LDA INUNIT
	ORA #$20
	TAX
	JSR INHLR
	.BYTE 0
	NOP		; IGNORE ERRORS
	NOP
	NOP
IGNORE	RTS
;
OUTUP	LDA OUTOPN	; RAISE HEAD FOR FLOPPY
	BEQ IGNORE
	LDA OUTUNT
	ORA #$20
	TAX
	JSR OUTHLR
	.BYTE 0
	NOP		; IGNORE ERRORS
	NOP
	NOP
	RTS
;
;	EDIT WRITE ROUTINE
EDITWR	STY FFFLAG
	LDA OUTOPN	; FILE ALREADY OPEN?
	BEQ WRITOK
	LDA #25		; YES- ?OFO ERROR
	JMP ERROR
;
WRITOK	LDA OFLPTR	; RETURN DATA IN OUTFIL
	STA SCNOUT
	LDA OFLPTR+1
	STA SCNOUT+1
	STY SUPSED
	JSR GETFIL	; GET FILE NAME
;
	LDA EBFLAG
	BNE NOFILE
;
	LDA OUTDEV	; LOOKUP FILE
	LDX OUTUNT
	JSR USR
	.BYTE LOOKUP
	.WORD OUTFIL
	.WORD DIRBUF
	JMP NOFILE	; NOT FOUND
;
	JSR INUP
	LDX #0		; IT EXISTS- SUPERSEDE?
SUPOUT	LDA SUPMES,X	; PRINT 'SUPERSEDE? '
	BEQ SUPDON
	JSR TTYOUT
	INX
	BNE SUPOUT
;
SUPDON	JSR GETANS	; GET ANSWER
	BNE SETSUP
	JMP PROCMD	; NO- IGNORE EW
SETSUP	INC SUPSED
;
NOFILE	LDA OUTUNT	; DELETE ANY EXISTING 'TECO.TMP'
	ORA #$40
	TAX
	STA OUTUUP
	LDA OUTDEV
	JSR USR
	.BYTE DELET
	.WORD TMPNAM
	NOP		; IGNORE ERRORS
	NOP
	NOP
;
	LDA #$FF	; USE LARGEST EMPTY ENTRY
	STA CLSLEN
	STA CLSLEN+1
;
	LDX OUTUUP	; NOW ENTER IT
	LDA OUTDEV
	JSR USR
	.BYTE ENTER
	.WORD TMPNAM
	.WORD OUTFIL+17
	JMP DIRERR
;
	INC OUTOPN
	LDA OUTFIL+17	; INIT STARTING BLOCK
	STA OUTPAG
	LDA OUTFIL+18
	STA OUTPAG+1
	LDA OUTST	; INIT STARTING POINTER
	STA OUTPTR
	LDA OUTST+1
	STA OUTPTR+1
	RTS
;
DIRERR	LDA #22		; ?DIR ERROR
	JMP ERROR
;
;	EDIT READ ROUTINE
EDITRD	LDA IFLPTR	; RETURN DATA IN INFILE
	STA SCNOUT
	LDA IFLPTR+1
	STA SCNOUT+1
	JSR GETFIL	; GET FILENAME & LOOKUP
	LDA INUNIT	; FILE
	ORA #$40
	TAX
	LDA INDEV
	JSR USR
	.BYTE LOOKUP
	.WORD INFILE
	.WORD DIRBUF
	JMP NOINFL	; NOT FOUND
;
RDFND	LDA DIRBUF+$C	; INIT STARTING BLOCK
	STA INPAGE
	LDA DIRBUF+$D
	STA INPAGE+1
	LDA DIRBUF+$E	; LENGTH
	STA INLEN
	LDA DIRBUF+$F
	STA INLEN+1
	LDA OUTST	; EMPTY INPUT BUFFER
	STA INPTR
	LDA OUTST+1
	STA INPTR+1
	INC INOPEN
	STY GOTEOF
	LDA #$FF
	CPY GOTCLN	; :ER?
	BEQ ERRTS1
ERRTS	STA HIARG	; YES- RETURN VALUE
	STA HIARG+1
ERRTS1	RTS
;
NOINFL	LDA GOTCLN
	BEQ FNFERR
	TYA		; :ER COMMAND
	BEQ ERRTS
;
FNFERR	LDA #27		; ?FNF ERROR
	JMP ERROR
;
;	YANK PAGE IN
YANK	LDA BUFSIZ
	ORA BUFSIZ+1	; BUFFER EMPTY?
	BEQ YNKPG1
	LDA OUTOPN	; NO- OUTPUT FILE OPEN?
	BEQ YNKPAG
	LDA EDFLAG	; YES- -1ED?
	CMP #$FF
	BEQ YNKPAG
	LDA #31		; NO- ?YCA ERROR
	JMP ERROR
;
YNKPAG	JSR ZERPAG
YNKPG1	JMP APPEND
;
;	EXIT TECO
TECOEX	LDA OUTOPN	; OUTPUT FILE OPEN?
	BEQ NOTOPN
	LDX #0
DELCHK	LDA DELMES,X	; DELETE TECO.TMP?
	BEQ DELDON
	JSR TTYOUT
	INX
	BNE DELCHK
;
DELDON	JSR GETANS	; GET ANSWER
	BEQ CLOSEX	; NO- CLOSE TECO.TMP
	JSR DELTMP
;
NOTOPN	LDA TMPSTO	; RESTORE CONSOLE STATUS
	STA CNSTAO	; BITS
	LDA TMPSTI
	STA CNSTAI
	JMP MONITR	; GO TO MONITOR
;
CLOSEX	JSR CLSTMP	; CLOSE TECO.TMP & EXIT
	JMP NOTOPN
;
DELTMP	LDA OUTDEV	; YES- DELETE TECO.TMP
	LDX OUTUUP
	JSR USR
	.BYTE DELET
	.WORD TMPNAM
	JMP OUTERR
	RTS
;
;	OUTPUT CURRENT PAGE
PAGOUT	LDA BUFST	; DO 0,ZP
	STA TEMPTR
	LDA BUFST+1
	STA TEMPTR+1
	JSR GETEND
	LDA ENDBUF
	STA LSTARG
	LDA ENDBUF+1
	STA LSTARG+1
	JSR OUTPUT
	LDA FFFLAG	; APPEND FF?
	BEQ PAGRTN
	LDA #12		; YES
	JSR ADDOUT
PAGRTN	RTS
;
;	ADD CHARS FROM TEMPTR TO LSTARG TO OUTPUT BUF
OUTPUT	LDA OUTOPN	; OUTPUT OPEN?
	BNE OUTPT1
NFOERR	LDA #24		; NO- ?NFO ERROR
	JMP ERROR
;
OUTPT1	LDA TEMPTR	; DONE?
	CMP LSTARG
	BNE ADOUT
	LDA TEMPTR+1
	CMP LSTARG+1
	BEQ PAGRTN
;
ADOUT	LDA (TEMPTR),Y	; NO- GET CHAR
	JSR ADDOUT	; ADD TO OUTPUT BUFFER
	INC TEMPTR
	BNE OUTPT1
	INC TEMPTR+1
	BNE OUTPT1
;
;
;	ADD CHAR TO OUTPUT BUFFER
ADDOUT	STA (OUTPTR),Y
	INC OUTPTR
	BNE ADOUT1
	INC OUTPTR+1
;
ADOUT1	LDA OUTPTR	; OUTPUT BUFFER FULL?
	CMP BUFST
	BNE OUTRTN
	LDA OUTPTR+1
	CMP BUFST+1
	BNE OUTRTN
;
	LDA OUTSIZ
	STA OUBLCT
;
OUTBLK	SEC		; DEC BLOCK COUNT
	LDA OUTFIL+19
	SBC OUBLCT
	STA OUTFIL+19
	LDA OUTFIL+20
	SBC #0
	STA OUTFIL+20
	BCS OUTBL1
	JSR OUTUP	; ?FUL ERROR
	LDA #34
	JMP ERROR
;
OUTBL1	LDA OUTUNT	; WRITE BLOCK
	ORA #$80
	TAX
	JSR OUTHLR
OUBLCT	.BYTE 0
OUTST	.WORD 0
OUTPAG	.WORD 0
	JMP OUTERR	; OUTPUT ERROR
;
	LDA OUTST	; RESET POINTER
	STA OUTPTR
	LDA OUTST+1
	STA OUTPTR+1
	CLC		; INC BLOCK POINTER
	LDA OUTPAG
	ADC OUBLCT
	STA OUTPAG
	BCC OUTRTN
	INC OUTPAG+1
OUTRTN	RTS
;
OUTERR	JSR OUTUP	; OUTPUT ERROR
	LDA #19
	JMP ERROR
;
;	WRITE REMAINDER OF INPUT FILE TO OUTPUT FILE
;	AND CLOSE BOTH
CLSALL	JSR PAGOUT	; OUTPUT CURRENT PAGE
	JSR ZERPAG
	LDA INOPEN
	BEQ NOAPND
	LDA GOTEOF	; GOT ALL INPUT?
	BEQ DMPAGE
NOAPND	JSR CLSOUT	; YES- CLOSE OUTPUT FILE
	STY INOPEN
	RTS
;
DMPAGE	JSR APPEND	; NO- GET NEXT PAGE
	JMP CLSALL
;
;	CLOSE TECO.TMP
CLSTMP	LDA OUTOPN
	BNE ADDCTZ
	JMP NFOERR
;
ADDCTZ	LDA #26		; ADD ^Z
	JSR ADDOUT
NULFIL	LDA OUTPTR	; NULL FILL REST
	CMP BUFST
	BEQ ZERODN
	TYA
	JSR ADDOUT
	JMP NULFIL
;
ZERODN	SEC		; # BLOCKS LEFT IN OUTPUT FILE
	LDA OUTSIZ
	SBC BUFST+1
	CLC
	ADC OUTPTR+1
	STA OUBLCT
	BEQ GETCLS	; NOTHING LEFT
	JSR OUTBLK	; ADD TO OUTPUT FILE
;
GETCLS	SEC		; COMPUTE CLOSING LENGTH
	LDA OUTPAG
	SBC OUTFIL+17
	STA CLSLEN
	LDA OUTPAG+1
	SBC OUTFIL+18
	STA CLSLEN+1
;
	LDA OUTDEV	; CLOSE TECO.TMP
	LDX OUTUNT
	JSR USR
	.BYTE CLOSE
	.WORD TMPNAM
	JMP OUTERR
	RTS
;
CLSOUT	JSR CLSTMP	; CLOSE OUTPUT FILE
	LDA EBFLAG	; WAS THIS AN EB?
	BEQ NOTEB1
	LDX #0		; YES- KILL FILE.BAK
BACKUP	LDA OUTFIL,X
	STA CLSBUF,X
	STA CLSBUF+8,X
	INX
	CPX #8
	BNE BACKUP
;
	LDA RADBAK
	STA CLSBUF+14
	LDA RADBAK+1
	STA CLSBUF+15
;
	LDA OUTDEV
	LDX OUTUNT
	JSR USR
	.BYTE DELET
	.WORD CLSBUF+8
	NOP		; DIDN'T EXIST ANYWAY
	NOP
	NOP
;
	LDX OUTUNT	; RENAME FILE->FILE.BAK
	JSR RENOUT
;
NOTEB1	LDA SUPSED	; SUPERSEDE?
	BEQ NOSUP
	LDA OUTDEV	; YES
	LDX OUTUNT
	JSR USR
	.BYTE DELET
	.WORD OUTFIL
	JMP OUTERR
;
NOSUP	LDX #0		; RENAME FILE<TECO.TMP
NEWNAM	LDA TMPNAM,X
	STA CLSBUF,X
	LDA OUTFIL,X
	STA CLSBUF+8,X
	INX
	CPX #8
	BNE NEWNAM
;
	STY OUTOPN
	LDX OUTUUP
;
RENOUT	LDA #0		; DON'T LOCK
	STA CLSBUF+16
	LDA OUTDEV
	JSR USR
	.BYTE RENAME
	.WORD CLSBUF
	JMP OUTERR
	RTS
;
;	APPEND NEXT PAGE
APPEND	STY FFFLAG
	LDA INOPEN	; INPUT FILE OPEN?
	BNE APPAGE
	LDA #28		; ?NFI ERROR
	JMP ERROR
;
APPAGE	LDA GOTEOF	; GOT EOF YET?
	BEQ NOEOF
EOFERR	JSR INUP	; YES- ?EOF ERROR
	JSR OUTUP	; RAISE HEADS
	LDA #29
	JMP ERROR
;
NOEOF	STY CHRCNT
	STY CHRCNT+1
	SEC		; COMPUTE 3/4 THROUGH BUFFER
	LDA MAXEND	; T1=MAXEND-BUFST
	SBC BUFST
	STA BUFTHQ
	LDA MAXEND+1
	SBC BUFST+1
	LSR A		; T1=T1/2
	PHA
	ROR BUFTHQ
	LDX BUFTHQ
	LSR A		; T1=(T1/2)+T1
	STA BUFTHQ+1
	ROR BUFTHQ
	TXA
	CLC
	ADC BUFTHQ
	TAX
	PLA
	ADC BUFTHQ+1
	PHA
	CLC		; =(MAXEND-BUFST)*3/4+BUFST
	TXA
	ADC BUFST
	STA BUFTHQ
	PLA
	ADC BUFST+1
	STA BUFTHQ+1
;
GETPAG	JSR CKINFL	; INPUT BUFFER EMPTY?
	BCC GOTPAG
	LDA INLEN+1	; ANYTHING LEFT?
	BNE STINSZ
	LDA INLEN
	BEQ EOFERR	; NO- ?EOF ERROR
	CMP INSIZE	; <INSIZE BLOCKS LEFT?
	BCC STINCT
STINSZ	LDA INSIZE
STINCT	STA INBLCT
	LDX INUNIT
	JSR INHLR
INBLCT	.BYTE 0
INST	.WORD 0
INPAGE	.WORD 0
	JMP INERR	; INPUT ERROR
;
	SEC
	LDA INLEN
	SBC INBLCT
	STA INLEN
	LDA INLEN+1
	SBC #0
	STA INLEN+1
;
	LDA INST	; RESET POINTER
	STA INPTR
	LDA INST+1
	STA INPTR+1
	CLC		; INC BLOCK POINTER
	LDA INPAGE
	ADC INBLCT
	STA INPAGE
	BCC GOTPAG
	INC INPAGE+1
;
GOTPAG	LDA (INPTR),Y	; GET CHAR
	CMP #26		; ^Z?
	BNE NOTEOF
	INC GOTEOF
	JMP ADPAGE	; YES- ADD PREVIOUS CHARS
;
NOTEOF	CMP #12		; FORM FEED?
	BNE NOTFF
	JSR ADPAGE	; YES- ADD PREVIOUS CHRS
	INC FFFLAG
	JMP INCIN	; IGNORE FF AND RETURN
;
NOTFF	STA TEMP1+1
	JSR INCCNT
	CMP #10
	BNE NOTLF
	LDA COLONA	; :A?
	BNE ADPAGE	; YES- APPEND 1 LINE
;
NOTLF	JSR CKINFL	; AT END OF INPUT BUFFER?
	BCC NOPGFL
	JSR ADPAGE	; YES- ADD TO END OF BUFFER
;
NOPGFL	CLC		; COMPUTE # CHARS IN
	LDA BUFEND	; BUFFER
	ADC CHRCNT
	STA TEMP
	LDA BUFEND+1
	ADC CHRCNT+1
	STA TEMP+1
;
	SEC		; BUFFER 3/4 FULL?
	LDA BUFTHQ
	SBC TEMP
	LDA BUFTHQ+1
	SBC TEMP+1
	BCS JPGTPG
;
CKFULL	CLC		; YES- COMPLETELY FULL?
	LDA MAXEND
	SBC TEMP
	LDA MAXEND+1
	SBC TEMP+1
	BCS NOFULL
;
	JSR ADPAGE	; YES- FILL UP TO END &
	JSR INUP
	LDA #5		; ?MEM ERROR
	JMP ERROR
;
NOFULL	LDA TEMP1+1	; NO- WAS CHAR A LF?
	CMP #10
	BEQ ADPAGE	; YES- END OF PAGE
JPGTPG	JMP GETPAG
;
;    ADD INPUT BUFFER FROM INPTR, CHRCNT CHARS TO TEXT BUFFER
ADPAGE	JSR PTRSAV	; POINT TO END OF BUFFER
	JSR GETEND
	LDA ENDBUF
	STA BUFPTR
	LDA ENDBUF+1
	STA BUFPTR+1
	SEC
	LDA INPTR
	SBC CHRCNT
	STA TXTPTR
	LDA INPTR+1
	SBC CHRCNT+1
	STA TXTPTR+1
	JSR INSERT	; INSERT TEXT
	JSR RESPTR	; RESTORE POINTER
	STY CHRCNT
	STY CHRCNT+1
	RTS
;
INERR	JSR INUP	; ?INP ERROR
	LDA #30
	JMP ERROR
;
INCCNT	INC CHRCNT
	BNE INCIN
	INC CHRCNT+1
;
INCIN	INC INPTR
	BNE NCRTRN
	INC INPTR+1
NCRTRN	RTS
;
;    RETURN CARRY SET IF INPUT BUFFER EMPTY
CKINFL	SEC
	LDA INPTR
	SBC OUTST
	LDA INPTR+1
	SBC OUTST+1
	RTS
;
ZERPAG	LDA BUFSIZ	; ZERO BUFFER
	STA CHRCNT
	LDA BUFSIZ+1
	STA CHRCNT+1
	LDA BUFST
	STA BUFPTR
	LDA BUFST+1
	STA BUFPTR+1
	JMP DELETE
;
;	SCAN FOLLOWING FILE NAME.  SCNOUT POINTS TO
;	RETURNED DATA.
GETFIL	JSR FNDESC	; DO SCAN
	LDA CHRCNT
	ORA CHRCNT+1
	BNE GTFIL1
	CLC		; FLAG NO NAME (En$)
	RTS
;
GTFIL1	LDA TXTPTR
	STA FNMPTR
	LDA TXTPTR+1
	STA FNMPTR+1
;
	JSR USR
	.BYTE SCAN
	.WORD FNMPTR
SCNOUT	.WORD 0
	JMP SCNERR
;
	CLC
	LDA SCNOUT	; POINT TO NEXT CHAR
	STA TEMPTR
	ADC #14
	STA FETOUT
	LDA SCNOUT+1
	STA TEMPTR+1
	ADC #0
	STA FETOUT+1
;
	LDY #13		; WILD CHAR SPECIFIED?
	LDA (TEMPTR),Y
	BEQ WILDOK
NAMERR	LDA #20		; ?IFN ERROR
	JMP ERROR
;
WILDOK	LDY #10		; NEXT CHAR MUST BE ESC
	LDA (TEMPTR),Y
	CMP CHRCNT
	BNE NAMERR
;
	INY		; FETCH HANDLER
	LDA (TEMPTR),Y
	STA FETIN+1
;
	JSR USR
	.BYTE FETCH
	.WORD FETIN
FETOUT	.WORD 0
	JMP BADHLR	; CAN'T FIND IT
;
	JSR SAVNAM	; SET UP FILESPEC BUFFER
	LDY #8		; ZERO NEW POINTER FOR
	LDA #0		; LOOKUP
	STA (TEMPTR),Y
	INY
	STA (TEMPTR),Y
	TAY
	SEC
	RTS
;
SCNERR	CMP #0		; NAME OR DEVICE ERROR?
	BEQ NAMERR
BADHLR	LDA #21		; ?DEV ERROR
	JMP ERROR
;
SAVNAM	LDX #0		; PUT NAME IN FILESPEC BUFFER
	LDY #8		; PUT DEVICE NAME
	JSR ADDRAD
	LDY #12
	LDA (TEMPTR),Y	; GET UNIT #
	CLC
	SED
	ADC #'0
	CLD
	STA FILSPC,X
	INX
	LDA #':
	STA FILSPC,X
	INX
;
	LDY #0		; AND NAME AND EXTENSION
SAVNM1	JSR ADDRAD
	CPY #6
	BNE SAVNM2
	LDA #'.
	STA FILSPC,X
	INX
SAVNM2	CPY #8
	BNE SAVNM1
;
	CPX #6		; EMPTY FILENAME?
	BNE SAVNM3
	DEX		; YES- EAT '.'
SAVNM3	STX FSPCSZ	; SAVE SIZE
	LDY #0
	RTS
;
ADDRAD	LDA (TEMPTR),Y	; GET RAD50 WORD
	STA RADWRD
	INY
	LDA (TEMPTR),Y
	STA RADWRD+1
	INY
	JSR USR		; CONVERT TO ASCII
	.BYTE RD2ASC
	.WORD RADWRD
	.WORD CHAR
;
	TYA		; ADD 3 CHARS TO BUFFER
	PHA
	LDY #0
ADDRD1	LDA CHAR,Y
	CMP #$20	; IGNORE BLANKS
	BEQ ADDRD2
	STA FILSPC,X
	INX
ADDRD2	INY
	CPY #3
	BNE ADDRD1
;
	PLA
	TAY
	RTS
;
GETANS	LDX #0		; GET YES OR NO ANSWER
	JSR BINPUT	; GET CHAR
	CMP #'Y
	BEQ GOTYES
	CMP #$79
	BNE ANSOUT
GOTYES	LDX #3		; YES
ANSOUT	LDA ANSMES,X	; PRINT YES OR NO
	BEQ GOTANS
	JSR CONOUT
	INX
	BNE ANSOUT
;
GOTANS	JSR CRLF
	DEX		; X=0 -> NO ELSE YES
	DEX
	RTS
;
PTRSAV	LDA BUFPTR	; SAVE BUFPTR
	STA BUFTMP
	LDA BUFPTR+1
	STA BUFTMP+1
	RTS
;
RESPTR	LDA BUFTMP	; RESTORE BUFPTR
	STA BUFPTR
	LDA BUFTMP+1
	STA BUFPTR+1
	RTS
;
MCMD	JSR GTQREG	; M COMMAND
	TXA
	PHA
	LDA #1
	JSR PUSH	; PUSH COMMAND POINTER ON STACK
	PLA
	TAX
	LSR A		; POINT TO NEW COMMAND
	STA CMDREG
	LDA QRGCNT,X
	STA CMDCNT
	LDA QRGCNT+1,X
	STA CMDCNT+1
	JSR GETQST
	LDA QSTART
	STA CMDPTR
	LDA QSTART+1
	STA CMDPTR+1
	JMP NXTCMD
;
UCMD	LDA GOTHI	; U COMMAND
	BNE UCMDOK
	LDA #32		; ?NAU ERROR
	JMP ERROR
;
UCMDOK	JSR DOOPER
	JSR GTQREG
	LDA LSTARG
	STA QVAL,X
	LDA LSTARG+1
	STA QVAL+1,X
	LDA GOTLO	; m,nU?
	BNE UCMD1
	JMP PROCMD
;
UCMD1	LDA LOARG	; YES- PUT LOARG IN HIARG
	STA HIARG
	LDA LOARG+1
	STA HIARG+1
	STY GOTLO
NEWVAL	INC GOTHI
	JMP PRCMD3
;
QCMD	JSR GTQREG	; Q COMMAND
	LDA GOTCLN
	BNE COLONQ
	LDA QVAL,X
	STA HIARG
	LDA QVAL+1,X
	STA HIARG+1
	JMP VALRTN
;
COLONQ	LDA QRGCNT,X
	STA HIARG
	LDA QRGCNT+1,X
	STA HIARG+1
	JMP VALRTN
;
PERCMD	JSR CHKARG	; % COMMAND
	JSR GTQREG
	CLC
	LDA QVAL,X
	ADC LSTARG
	STA QVAL,X
	STA HIARG
	LDA QVAL+1,X
	ADC LSTARG+1
	STA QVAL+1,X
	STA HIARG+1
	JMP NEWVAL
;
CARETE	LDA FFFLAG	; ^E COMMAND
	BEQ SETVAL
NOTZRO	LDA #$FF
SETVAL	STA HIARG
	STA HIARG+1
	JMP VALRTN
;
CARETN	LDA GOTEOF	; ^N COMMAND
	BEQ SETVAL
	BNE NOTZRO
;
CLNCMD	INC GOTCLN	; : COMMAND
CLNRTN	JSR GTCMCH
	BCC CLNDON
	JMP EXECMD
CLNDON	JMP CMDONE
;
ATCMD	INC GOTAT	; @ COMMAND
	BNE CLNRTN
;
SRHCMD	LDA GOTCLN	; S COMMAND
	CMP #2		; ::S?
	BCC SRHCM1
	BNE ISAERR
	LDA GOTHI	; YES- ARGS SPECIFIED?
	BNE ISAERR	; YES- ERROR
	LDA #1		; NO- MAKE 1,1:S
	STA LOARG
	STA GOTLO
;
SRHCM1	TYA
DOSRCH	STA PAGSRH
	JSR CHKARG
	JSR CHKCLN
	JSR SEARCH	; PERFORM SEARCH
	PHA
	BNE SRHFND	; SUCCEEDED?
SRHEND	LDA GOTCLN	; NO- RETURN VALUE?
	BNE SRHNXT
	JMP SRHERR	; NO- PRINT ?SRH MES
;
SRHFND	LDA PSHCNT	; DURING MACRO OR ITERATION?
	BNE SHFND1	; YES
	LDA ESFLAG	; NO- CHECK FOR ES
	STA VERFLG
	LDA ESFLAG+1
	STA VERFLG+1
	JSR EDTVER
;
SHFND1	LDA GOTCLN
	BEQ SRHPRO	; NO VALUE RETURNED
SRHNXT	PLA		; :S COMMAND
	JMP PRCMD2
SRHPRO	JMP PROCMD	; STANDARD SEARCH RETURN
;
ISAERR	LDA #12		; ?ISA ERROR
	JMP ERROR
;
NCMD	LDA #1		; N COMMAND
	BNE DOSRCH
;
YSRCH	LDA #$FF	; _ COMMAND
	BNE DOSRCH
;
EDTVER	LDA VERFLG	; EDIT VERIFY CHECK
	ORA VERFLG+1	; FOR ES OR EV FLAGS
	BEQ EVDONE
	STY SRHCNT	; ASSUME 0T
	STY SRHCNT+1
	LDA VERFLG
	AND VERFLG+1
	CMP #$FF
	PHP
	BEQ EDVER0
	SEC		; GET -HI BYTE
	TYA
	SBC VERFLG+1
	STA SRHCNT
	DEC SRHCNT+1
;
EDVER0	JSR LFFIND	; DO -nT
	JSR NEGARG
	JSR TYPCHK
;
	STY SRHCNT+1	; ASSUME 1T
	LDA #1
	STA SRHCNT
	PLP		; PRINT POINTER CHAR?
	BEQ EDVER2	; NO
	LDA VERFLG	; YES- 1-31?
	AND #$7F
	CMP #$20
	BCS EDVER1	; NO- CHAR OK
	LDA #$0A	; YES- USE LF INSTEAD
;
EDVER1	JSR CONOUT
	LDA VERFLG+1	; DO 1T?
	BEQ EDVER2
	STA SRHCNT	; NO
	INC SRHCNT
;
EDVER2	JSR LFFIND	; DO nT
	JSR FNDRG1
	JSR TYPCHK
EVDONE	RTS
;
CARETU	JSR GTQREG	; ^U COMMAND
	STX TEMPX
	LDA GOTCLN	; :^U?
	BEQ NOCLNU
	INX		; YES- POINT TO END OF Q
	INX		; REG
NOCLNU	JSR GETQST
	LDX TEMPX
	JSR QBFPTR
	LDA GOTCLN
	BNE NOUZRO
	JSR QZERO
;
NOUZRO	LDA GOTHI
	BEQ CTUINS
	JSR GETCHR	; N^U$ COMMAND
	CMP #$1B	; NEXT CHAR MUST BE ESC
	BEQ CTLUOK
	JMP IIAERR
;
CTLUOK	JSR DOOPER
	LDA LSTARG
	STA TEMBUF
	JSR SETEMP
	JMP INQTXT
;
CTUINS	JSR FNDESC	; ^UTEXT$ COMMAND
	JMP INQTXT
;
XCMD	JSR CHKARG	; X COMMAND
	JSR FNDARG
	LDA TEMPTR	; SAVE TEMPTR
	STA TXTPTR
	LDA TEMPTR+1
	STA TXTPTR+1
	JSR GTQREG
	STX TEMPX
	LDA GOTCLN	; :X COMMAND?
	BEQ NOCLNX
	INX		; YES- APPEND TO Q REG
	INX
NOCLNX	JSR GETQST	; POINT TO Q REG START
	LDX TEMPX
	JSR QBFPTR
	LDA GOTCLN
	BNE NOZERO
	JSR QZERO
;
NOZERO	SEC		; COMPUTE # CHARS
	LDA LSTARG
	SBC TXTPTR
	STA CHRCNT
	LDA LSTARG+1
	SBC TXTPTR+1
	STA CHRCNT+1
INQTXT	CLC		; UPDATE Q REG SIZE
	LDA QRGCNT,X
	ADC CHRCNT
	STA QRGCNT,X
	LDA QRGCNT+1,X
	ADC CHRCNT+1
	STA QRGCNT+1,X
	JSR INTEXT	; INSERT TEXT
	JSR RESPTR	; RESTORE BUF POINTER
	JMP PROCMD
;
GCMD	JSR GTCMCH	; G COMMAND
	JSR GTQRG2	; GET Q REG # AND START
	JSR GTQST0
	LDA QRGCNT,X
	STA CHRCNT
	LDA QRGCNT+1,X
	STA CHRCNT+1
;
GCMD3	LDA GOTCLN
	BNE QRGOUT
	LDA QSTART
	STA TXTPTR
	LDA QSTART+1
	STA TXTPTR+1
	JSR INSERT
GDONE	JMP PROCMD
;
QRGOUT	LDA CHRCNT	; PRINT Q REG N
	ORA CHRCNT+1
	BEQ GDONE
	LDA (QSTART),Y
	JSR TTYOUT
	INC QSTART
	BNE DCOUNT
	INC QSTART+1
DCOUNT	JSR DECCNT
	JMP QRGOUT
;
QBFPTR	JSR PTRSAV
	LDA QSTART
	STA BUFPTR
	LDA QSTART+1
	STA BUFPTR+1
	RTS
;
QZERO	LDA QRGCNT,X	; ZERO Q REGISTER
	STA CHRCNT
	ORA QRGCNT+1,X	; =0?
	BEQ NOQZRO
	LDA QRGCNT+1,X
	STA CHRCNT+1
	STA CHRCNT+1
	JSR DLTEXT
	TYA
	STA QRGCNT,X
	STA QRGCNT+1,X
NOQZRO	RTS
;
;	GET START OF Q REGISTER QRGNUM
GTQST0	CPX #74		; * OR _ Q REGS?
	BCC GETQST
	LDA FLSPTR-74,X	; YES- GET START OF REG
	STA QSTART
	LDA FLSPTR-73,X
	STA QSTART+1
	RTS
;
GETQST	STX TEMP
	JSR GETEND	; ADD SIZE OF PREVIOUS Q
	LDA ENDBUF	; REG'S TO ENDBUF
	STA QSTART
	LDA ENDBUF+1
	STA QSTART+1
;
ADDQST	CPX #0
	BEQ QSTDON
	DEX
	DEX
	CLC
	LDA QSTART
	ADC QRGCNT,X
	STA QSTART
	LDA QSTART+1
	ADC QRGCNT+1,X
	STA QSTART+1
	JMP ADDQST
QSTDON	LDX TEMP
	RTS
;
;	GET Q REGISTER #*2 IN QRGNUM
GTQREG	JSR GTCMCH
GTQRG1	JSR DIGCHK	; 0..9?
	BCS QREGOK
	BMI IQNJMP
	SBC #6		; A..Z?
	CMP #10
	BCC IQNJMP
	CMP #36
	BCC QREGOK
IQNJMP	JMP IQNERR
;
QREGOK	ASL A
	TAX
	RTS
;
GTQRG2	CMP #'*		; FILE SPEC BUFFER?
	BNE GTQRG3
	LDX #74		; YES- CALL IT Q REG 37
	RTS
;
GTQRG3	CMP #'_
	BNE GTQRG1
	LDX #76		; YES- CALL IT Q REG 38
	RTS
;
PUSHQ	JSR GTQREG	; [q COMMAND
	JSR GETQST
	CLC		; COMPUTE # BYTES TO USE
	LDA QRGCNT,X
	ADC #4
	STA TEMP
	LDA QRGCNT+1,X
	ADC #0
	STA TEMP+1
;
	SEC		; POINT TO NEW TOP OF STACK
	LDA MAXEND
	SBC TEMP
	STA TMPTR1
	LDA MAXEND+1
	SBC TEMP+1
	STA TMPTR1+1
;
	LDA TMPTR1	; ENOUGH ROOM?
	SBC BUFEND
	LDA TMPTR1+1
	SBC BUFEND+1
	BCS PUSHQ1
ERR5	LDA #5		; NO- ?MEM ERROR
	JMP ERROR
;
PUSHQ1	LDA TMPTR1	; SAVE NEW MAXEND
	STA MAXEND
	LDA TMPTR1+1
	STA MAXEND+1
;
	LDA QRGCNT,X	; PUSH LENGTH
	JSR PUSHIT
	LDA QRGCNT+1,X
	JSR PUSHIT
	LDA QVAL,X	; PUSH NUMERIC
	JSR PUSHIT
	LDA QVAL+1,X
	JSR PUSHIT
	BEQ PSHDON
;
PUSHQ2	LDA (QSTART),Y	; PUSH TEXT
	INC QSTART
	BNE PUSHQ3
	INC QSTART+1
PUSHQ3	JSR PUSHIT
	BNE PUSHQ2
;
PSHDON	INC QDEPTH
	BNE PSHDN1
	INC QDEPTH+1
PSHDN1	JMP NXTCMD
;
PUSHIT	JSR INCTM1
	STA (TMPTR1),Y
	SEC		; DEC COUNT
	LDA TEMP
	SBC #1
	STA TEMP
	LDA TEMP+1
	SBC #0
	STA TEMP+1
	ORA TEMP
	RTS
;
POPQ	JSR GTQREG	; ]q COMMAND
	LDA QDEPTH	; ANYTHING ON STACK?
	ORA QDEPTH+1
	BNE POPQ1
	LDA GOTCLN	; NO- :]q?
	BNE POPRT1	; YES- RETURN -1
	LDA #41		; NO- ?CPQ ERROR
	JMP ERROR
;
POPRT1	TYA
	JMP SETVAL
;
POPQ1	JSR GETQST	; FIND START
	JSR QBFPTR	; POINT BUFPTR THERE
	JSR QZERO	; ZERO IT
;
	LDA MAXEND	; POINT TO TOP OF STACK
	STA TXTPTR
	LDA MAXEND+1
	STA TXTPTR+1
;
	JSR POPIT	; GET LENGTH
	STA CHRCNT
	JSR POPIT
	STA CHRCNT+1
;
	SEC		; ENOUGH ROOM?
	LDA MAXEND
	SBC CHRCNT
	PHA
	LDA MAXEND+1
	SBC CHRCNT+1
	STA TEMP+1
;
	PLA
	SBC BUFEND
	LDA TEMP+1
	SBC BUFEND+1
	BCS POPQ2
	JMP ERR5	; NO- ERROR
;
POPQ2	JSR POPIT	; YES- POP NUMERIC
	STA QVAL,X
	JSR POPIT
	STA QVAL+1,X
	LDA CHRCNT	; INSERT SIZE
	STA QRGCNT,X
	LDA CHRCNT+1
	STA QRGCNT+1,X
;
	CLC		; UPDATE MAXEND
	LDA TXTPTR
	ADC CHRCNT
	STA MAXEND
	LDA TXTPTR+1
	ADC CHRCNT+1
	STA MAXEND+1
	JSR POPIT	; POINT TXTPTR TO TEXT
	SEC		; INTEXT ADDS CHRCNT TO TXTPTR
	LDA TXTPTR
	SBC CHRCNT
	STA TXTPTR
	LDA TXTPTR+1
	SBC CHRCNT+1
	STA TXTPTR+1
;
	JSR INTEXT	; INSERT TEXT
	JSR RESPTR	; RESTORE POINTER
	LDA QDEPTH	; DEC QDEPTH
	BNE POPQ3
	DEC QDEPTH+1
POPQ3	DEC QDEPTH
;
	LDA GOTCLN	; :]q?
	BEQ POPQ4
	JMP NOTZRO	; YES- RETURN -1
;
POPQ4	JMP NXTCMD	; NO- NO VALUE RETURNED
;
POPIT	INC TXTPTR	; POP CHAR FROM STACK
	BNE POPIT1
	INC TXTPTR+1
POPIT1	LDA (TXTPTR),Y
	RTS
;
FCMD	JSR GTCMCH	; GET NEXT CHAR
	CMP #'R
	BNE NOTFR
	JSR FRCMD	; FR COMMAND
	JSR FNDESC
	JSR INSERT
	JMP PROCMD
;
NOTFR	CMP #'S
	BNE NOTFS
	TYA
FSCMD	STA PAGSRH
	JSR CHKARG	; FS COMMAND
	JSR FNDESC
	JSR SEARCH	; SEARCH FOR STRING
	PHA		; SAVE STATUS
	STY CHRCNT
	STY CHRCNT+1
	JSR SAVPTR	; FIND CLOSING $
	JSR CHKCL1
	PLA		; SUCCEEDED?
	PHA
	BEQ FSFAIL
	LDA CHRCNT
	PHA
	LDA CHRCNT+1
	PHA
	JSR FRCMD	; DELETE SEARCHED CHARS
	SEC		; FIX TXTPTR
	LDA TXTPTR
	SBC CHRCNT
	STA TXTPTR
	LDA TXTPTR+1
	SBC CHRCNT+1
	STA TXTPTR+1
	PLA
	STA CHRCNT+1
	PLA
	STA CHRCNT
	JSR INSERT	; NOW INSERT NEW TEXT
	JMP SRHFND
;
FSFAIL	JMP SRHEND
;
FRCMD	SEC		; DO -<STRSIZ>C
	LDA BUFPTR
	SBC STRSIZ
	STA CHRPTR
	LDA BUFPTR+1
	SBC STRSIZ+1
	STA CHRPTR+1
;
	JSR CHKPTR
	BEQ FROK
	JMP DTBERR
FROK	LDA ENDLIM
	STA BUFPTR
	LDA ENDLIM+1
	STA BUFPTR+1
	LDA STRSIZ	; DO <STRSIZ>D
	STA CHRCNT
	LDA STRSIZ+1
	STA CHRCNT+1
	JSR DELETE
	RTS
;
NOTFS	CMP #'N
	BNE NOTFN
	LDA #1		; FN COMMAND
	JMP FSCMD
;
NOTFN	CMP #'_
	BNE IFCERR
	LDA #$FF	; F_ COMMAND
	JMP FSCMD
;
IFCERR	LDA #14		; ?IFC ERROR
	JMP ERROR
;
CHKCLN	JSR FNDESC	; CHECK FOR STEXT$;
CHKCL1	LDA (CMDPTR),Y	; NEXT CHAR = ';'?
	CMP #';
	BNE NOTSEM
	INC GOTCLN	; YES- TREAT AS :S CMD
NOTSEM	RTS
;
;	Takes char in A, saves in TSTCHR and returns in A:
;	BIT 7 = Upper case A-Z
;	BIT 6 = Lower case A-Z
;	BIT 5 = Numeric 0-9
;
CHRTST	STA TSTCHR
	CMP #'0
	BCS CHTST1
CHRTN	TYA		; NONE OF ABOVE- RETURN 0
	RTS
;
CHTST1	CMP #$3A	; NUMERIC?
	BCS CHTST2
	LDA #$20	; YES
	RTS
;
CHTST2	CMP #'A		; UPPER CASE ALPHA?
	BCC CHRTN
	CMP #'[
	BCS CHTST3
	LDA #$80	; YES
	RTS
;
CHTST3	CMP #'a		; LOWER CASE ALPHA?
	BCC CHRTN
	CMP #$7B
	BCS CHRTN
	LDA #$40	; YES
	RTS
;
;
;	SEARCH FOR CHRCNT CHARS POINTED TO BY SRHPTR,
;	FROM POINTER TO END (BEGINNING) OF BUFFER,
;	ABS(LSTARG) TIMES IN SGN(LSTARG) DIRECTION.
SEARCH	STY NOFAIL
	LDA #$FF
	STA BOUNDS
	STA BOUNDS+1
	LDA GOTLO	; ARGS OF FORM M,N?
	BEQ SRHOK
;
	LDA LOARG	; YES- 0,NS?
	ORA LOARG+1
	BNE BNDSRH
	LDA BUFPTR	; YES- RESTORE BUFPTR ON
	STA OLDPTR	; SEARCH FAILURE
	LDA BUFPTR+1
	STA OLDPTR+1
	INC NOFAIL
	BNE SRHOK
;
BNDSRH	SEC		; NO- BOUNDED SEARCH
	LDA LOARG+1	; GET ABS(LOARG)-1
	BMI NEGBND	; NEGATIVE
	STA BOUNDS+1
	LDA LOARG
	SBC #1
	STA BOUNDS
	BCS SRHOK
	DEC BOUNDS+1
	JMP SRHOK
;
NEGBND	EOR #$FF
	STA BOUNDS+1
	LDA LOARG
	EOR #$FF
	STA BOUNDS
;
SRHOK	LDA CHRCNT+1	; >255 CHARS?
	BEQ CNTOK
STLERR	LDA #13		; NO- ?STL ERROR
	JMP ERROR
;
CNTOK	LDX #0
	LDA CHRCNT	; SEARCH STRING GIVEN?
	STA SRHLEN	; SAVE LENGTH OF SEARCH
	BNE SAVSRH
	JMP GOTST1
;
SAVSRH	LDA SRHLEN
	BNE SAVSR1
GOTST0	JMP GOTSTR
;
SAVSR1	JSR GETSRH	; SAVE SEARCH STRING
	CMP #'^		; CONTROL CHAR CONVERSION?
	BNE NOCTL
	LDA SRHLEN
	BEQ NOCTL1
	LDA EDFLAG	; YES IF EDFLAG=0 OR -1
	CMP EDFLAG+1
	BNE NOCTL1
	CMP #0
	BEQ MAKCTL
	CMP #$FF
	BNE NOCTL1
;
MAKCTL	LDA (TXTPTR),Y	; CHAR AFTER ^ ALPHA?
	JSR CHRTST
	STA TEMP+1
	LDA TSTCHR
	BIT TEMP+1
	SEC
	BMI MKCTL1	; YES- UPPER CASE
	BVC NOCTL2
;
	SBC #$20	; LOWER CASE
MKCTL1	SBC #$40
	INY
	DEC SRHLEN
;
NOCTL	CMP #$11	; ^Q?
	BNE NOCTL0
	CPY SRHLEN	; YES- MAKE SURE CHAR AFTER ^Q
	BEQ NOCTL2
	JSR GETSRH	; YES- TREAT NEXT CHAR LITERALLY
	JMP NOCTL2
;
NOCTL1	LDA #'^
NOCTL0	CMP #5		; ^E?
	BEQ CTRLE
	CMP #$16	; ^V?
	BEQ CTRLV
	CMP #$17	; ^W?
	BEQ CTRLW
NOCTL2	STA SRHBUF,X	; ADD TO BUFFER
	INX
	BEQ STLERR
	BNE SAVSRH
;
CTRLV	LDA #$80	; CONVERT NEXT CHAR TO LOWER CASE
	BNE CVCASE
;
CTRLW	LDA #$40	; CONVERT NEXT CHAR TO UPPER CASE
CVCASE	STA TEMP+1
	LDA (TXTPTR),Y	; NEXT CHAR PROPER CASE?
	JSR CHRTST
	AND TEMP+1
	BNE CVCAS1
;
	LDA #$16	; NO- CONVERT BACK TO ^V OR ^W
	ASL TEMP+1
	BCS NOCTL2
	ADC #1
	BNE NOCTL2
;
CVCAS1	JSR GETSRH
	LDA TSTCHR	; YES- CONVERT CASES
	EOR #$20
	BNE NOCTL2
;
GETSRH	LDA (TXTPTR),Y	; GET CHAR FROM SEARCH BUFFER
	INY
	DEC SRHLEN
	RTS
;
CTRLE	LDA (TXTPTR),Y	; ^EQn?
	CMP #'Q
	BEQ CTRLE1
	CMP #'q
	BEQ CTRLE1
	LDA #5		; NO
	BNE NOCTL2
;
CTRLE1	JSR GETSRH	; YES- ADD Q REG n TO
	BNE CTRLE0
	JMP IQNERR
;
CTRLE0	JSR GETSRH	; SEARCH BUFFER
	STX TEMP1
	STY TEMP1+1
	LDY #0
	JSR GTQRG2
	JSR GTQST0	; POINT TO START OF Q REG
	LDA QRGCNT+1,X
	BNE STLJMP
	LDA QRGCNT,X
	STA CHRCNT
	LDX TEMP1
	CMP #0
	BEQ CTRLE3
;
CTRLE2	LDA (QSTART),Y
	STA SRHBUF,X
	INY
	INX
	BEQ STLJMP
	DEC CHRCNT
	BNE CTRLE2
;
CTRLE3	LDY TEMP1+1	; CONTINUE WITH SEARCH STRING
	JMP SAVSRH
;
STLJMP	JMP STLERR
;
GOTSTR	LDY #0
	STX LSTCNT
MOVSRH	LDA SRHBUF,X	; MOVE SEARCH STRING
	STA LSTSRH,X
	DEX
	BPL MOVSRH
;
GOTST1	LDA LSTCNT
	STA STRSIZ
	STY STRSIZ+1
	BNE GOTST2	; 0 LENGTH STRING? (^EQn - Qn EMPTY)?
	JMP SRHDN1	; YES- ALWAYS SUCCESS
;
GOTST2	LDA LSTARG
	STA SRHCNT
	LDA LSTARG+1
	STA SRHCNT+1
	JSR GETEND
;
	LDA SRHCNT+1	; FORWARD SEARCH?
	BMI NEGJMP
	ORA SRHCNT	; YES.	CHECK FOR 0 ARG
	BNE SRHFWD
	JMP ISAERR	; YES- ERROR
;
NEGJMP	JMP SRHNEG
;
SRHFWD	SEC		; CHECK FOR END OF BUF
	LDA ENDBUF
	SBC BUFPTR
	LDA ENDBUF+1
	SBC BUFPTR+1
	BCC PSFAIL
;
	JSR STRCMP	; COMPARE STRINGS
	BEQ POSFND	; FOUND MATCH
SRHFD1	SEC		; DEC BOUND COUNT
	LDA BOUNDS
	SBC #1
	STA BOUNDS
	LDA BOUNDS+1
	SBC #0
	BCC PSFAIL
	STA BOUNDS+1
;
	JSR INCPTR
	JMP SRHFWD
;
POSFND	SEC		; DONE WITH SEARCH?
	LDA SRHCNT
	SBC #1
	STA SRHCNT
	LDA SRHCNT+1
	SBC #0
	STA SRHCNT+1
	ORA SRHCNT
	BEQ SRHDON
	BNE SRHFD1	; NO- FIND ANOTHER MATCH
;
PSFAIL	LDX PAGSRH	; SEARCH FAILURE- ACROSS PAGES?
	BEQ SRFAIL	; NO- SEARCH FAILURE
	LDA GOTEOF	; YES- END OF INPUT FILE?
	BEQ NXTPAG
SRPGFL	JSR SRHUP	; YES- SEARCH FAILURE
;
SRFAIL	LDA NOFAIL	; 0,NS?
	BNE SRFL1
	JSR BPTR	; NO- MOVE TO TOP OF BUFFER
	TYA		; SEARCH FAILURE
	RTS		; RETURN = 0
;
SRFL1	LDA OLDPTR	; YES- RESTORE BUFPTR
	STA BUFPTR
	LDA OLDPTR+1
	STA BUFPTR+1
	TYA
	RTS
;
NXTPAG	JSR BPTR	; NO- GET NEXT PAGE
	DEX
	BNE YNKSRH
	JSR PAGOUT
	JSR ZERPAG
YNKSRH	JSR YANK
	JSR GETEND	; GET NEW BUFFER END
	JMP SRHFWD	; CONTINUE SEARCH
;
SRHDON	LDA TMPTR1	; SEARCH SUCCEEDED-
	STA BUFPTR	; SET BUFPTR AND RETURN
	LDA TMPTR1+1
	STA BUFPTR+1
	LDX PAGSRH	; SEARCH ACROSS PAGE?
	BEQ SRHDN1
	JSR SRHUP	; YES- RAISE HEADS
SRHDN1	LDA #$FF	; YES- RETURN = -1
	RTS
;
SRHUP	DEX		; RAISE HEADS
	BNE YANKUP
	JSR OUTUP
YANKUP	JMP INUP
;
SRHNEG	SEC		; NEGATIVE SEARCH
	LDA BUFPTR	; AT START OF BUFFER?
	SBC BUFST
	LDA BUFPTR+1
	SBC BUFST+1
	BCC SRFAIL
;
	SEC		; DEC BOUNDS COUNT
	LDA BOUNDS
	SBC #1
	STA BOUNDS
	BCS SRHNG0
	DEC BOUNDS+1
;
SRHNG0	JSR DECPTR
	JSR STRCMP	; COMPARE STRINGS
	BEQ SRHNG1
;
SRHNG2	LDA BOUNDS
	ORA BOUNDS+1
	BEQ SRFAIL
	BNE SRHNEG
;
SRHNG1	INC SRHCNT	; FOUND MATCH
	BNE SRHNG2
	INC SRHCNT+1
	BNE SRHNG2
	BEQ SRHDON
;
ENDCHK	SEC		; TMPTR1>ENDBUF?
	LDA ENDBUF
	SBC TMPTR1
	LDA ENDBUF+1
	SBC TMPTR1+1
	RTS
;
SRHERR	LDX #0		; PRINT ERROR MESSAGE
ERROUT	LDA SRHMES,X
	BEQ MESDON
	JSR TTYOUT
	INX
	BNE ERROUT
;
MESDON	TAX
	INC LSTERR
	JSR CHKITR	; ERROR DURING ITERATION?
	BCC NOTITR
ITRMES	LDA SRHMS2,X	; YES- PRINT ITER MSG
	BEQ MS2DON
	JSR TTYOUT
	INX
	BNE ITRMES
MS2DON	JMP GETCMD
;
NOTITR	LDA SRHMS1,X	; NO- PRINT SEARCH STRNG
	BEQ OUTSTR
	JSR TTYOUT
	INX
	BNE NOTITR
;
OUTSTR	CPY LSTCNT
	BEQ OUTST1
	LDA LSTSRH,Y
	JSR TTYOUT
	INY
	BNE OUTSTR
;
OUTST1	LDY #0
	LDA #'"		; PRINT CLOSING QUOTE
	JSR CONOUT
	JMP GETCMD
;
;	COMPARE LSTCNT CHARS AFTER BUFPTR WITH SEARCH BUFFER.
STRCMP	LDA LSTCNT
	STA SRHSIZ
	LDA BUFPTR
	STA TMPTR1
	LDA BUFPTR+1
	STA TMPTR1+1
	LDX #0
;
CHRCMP	DEC SRHSIZ
	LDA LSTSRH,X	; COMPARE CHARS
	CMP #$18	; ^X?
	BNE NOTCTX	; YES- AUTOMATIC MATCH
NXTJMP	JMP NXTCMP
;
NOTCTX	STY NEGATE
	CMP #$0E	; ^N?
	BNE NOTCTN
	JSR GTSRCH	; YES- NEXT CHAR SPECIAL?
	BCC NTCTX1
	JMP CHCMP0	; NO CHAR AFTER ^N!
;
NTCTX1	CMP #$13	; ^S?
	BEQ SPCLN
	CMP #5		; ^E?
	BEQ SPCLN
	CMP (TMPTR1),Y	; NO- MAKE SURE NO MATCH
	BNE NXTJMP
	JMP NOTEQL
;
SPCLN	DEC NEGATE	; SPECIAL- NEGATE NEXT RESULT
;
NOTCTN	CMP #$13	; ^S?
	BNE NOTCTS
	LDA (TMPTR1),Y	; YES- SEPARATOR?
	JSR CHRTST
	BEQ SJMP	; YES
NJMP	JMP NMATCH
;
NOTCTS	CMP #5		; ^E?
	BNE NOCTLE
	JSR GTSRCH	; YES- GET NEXT CHAR
	BCC NOCTS1
	JMP CHCMP0	; NO CHAR AFTER ^E!
;
NOCTS1	CMP #'A
	BNE NOTEA
	LDA #$C0	; ALPHA?
TYPTST	STA TEMP+1
	LDA (TMPTR1),Y
	JSR CHRTST
	AND TEMP+1
	BEQ NJMP
SJMP	JMP SMATCH
;
NOCTLE	STA TSTCHR	; PERFORM COMPARISON
	CMP #$60	; IF XFLAG=0, MAKE BOTH
	BCC CASTST	; LOOK UPPER CASE
	LDA XFLAG
	ORA XFLAG+1
	BNE CASTST
	LDA TSTCHR	; MAKE UPPER CASE
	EOR #$20
	STA TSTCHR
;
CASTST	LDA (TMPTR1),Y
	PHA
	CMP #$60
	BCC CSTST1
	LDA XFLAG
	ORA XFLAG+1
	BNE CSTST1
	PLA		; MAKE UPPER CASE
	EOR #$20
	PHA
;
CSTST1	PLA		; NOW COMPARE
	CMP TSTCHR
	JMP CHCMP1
;
NOTEA	CMP #'C
	BNE NOEC
	LDA (TMPTR1),Y	; RAD40?
	CMP #'.
	BEQ SJMP
	CMP #'_
	BEQ SJMP
GOTER	LDA #$E0
	BNE TYPTST
;
NOEC	CMP #'D
	BNE NOTED
	LDA #$20	; DIGIT?
	BNE TYPTST
;
NOTED	CMP #'R		; ALPHA OR DIGIT?
	BEQ GOTER
;
	CMP #'L
	BNE NOTEL
	LDA (TMPTR1),Y	; LF, VT, FF?
	CMP #$0A
	BCC NMATCH
	CMP #$0D
	BCS NMATCH
	BCC SMATCH
;
NOTEL	CMP #'X
	BEQ NXTCMP	; ANY MATCHES
;
	CMP #'G
	BNE NOTEG
	JSR GTSRCH	; ^EGn
	BCC GOTEGN
	JMP IQNERR	; NO CHAR AFTER ^EG!
;
GOTEGN	STX TEMPX
	JSR GTQRG2	; YES- GET n
	JSR GTQST0
	LDA QRGCNT,X
	LDX TEMPX
	STA QRGTMP
	CMP #0
	BEQ NMATCH
;
EGTEST	LDA (QSTART),Y	; CHAR IN Q REG?
	CMP (TMPTR1),Y
	BEQ SMATCH
	DEC QRGTMP
	BEQ NMATCH
	INC QSTART
	BNE EGTEST
	INC QSTART+1
	BNE EGTEST
;
NOTEG	CMP #'S
	BNE NOTES
	STY QRGTMP	; ^ES
GOTES	LDA (TMPTR1),Y	; SEARCH FOR STRING OF SPACES
	CMP #$20	; OR TABS
	BEQ GOTES1
	CMP #9
	BNE NOESCH
;
GOTES1	STA QRGTMP	; FLAG WE GOT ONE
	JSR INCTM1
	JMP GOTES
;
NOTES	DEX		; JUST PLAIN ^E
	INC SRHSIZ
	LDA #5
	BNE CHCMP0
;
NOESCH	LDA QRGTMP	; DID WE FIND ONE?
	BEQ NEGTST	; NO
	JSR DECTM1	; YES- FIX POINTER
;
SMATCH	LDA #$FF	; MATCH- CHECK FOR NEGATE
	BNE NEGTST
;
NMATCH	LDA #0
NEGTST	EOR NEGATE
	BEQ NOTEQL
	BNE NXTCMP
;
CHCMP0	CMP (TMPTR1),Y
CHCMP1	BNE NOTEQL
NXTCMP	JSR INCTM1
	INX
	LDA SRHSIZ
	BEQ STREQL
	JMP CHRCMP
;
STREQL	JSR ENDCHK	; STRINGS EQUAL
	BCC NOTEQL	; IF SEARCHED PAST END, NO MATCH
	LDY #0		; RETURN = 0
	RTS
;
NOTEQL	LDY #0		; STRINGS NOT EQUAL
	LDA #1		; RETURN <> 0
	RTS
;
GTSRCH	CPY SRHSIZ	; ANOTHER CHAR IN BUFFER?
	BEQ GTSRH2	; NO
	INX		; YES- GET IT
	DEC SRHSIZ
	LDA LSTSRH,X
	CMP #$60	; LOWER CASE?
	BCC GTSRH1
	EOR #$20	; YES- MAKE UPPER
	CLC		; FLAG NORMAL RETURN
GTSRH1	RTS
;
GTSRH2	SEC		; NO CHAR AVAILABLE!
	RTS
;
TTYIN	LDA EIOPEN	; GET CHAR
	BNE TTYIN2	; GET FROM INDIRECT BUFFER
TTYIN0	LDY TINSIZ	; SOMETHING IN BUFFER?
	BNE TTYIN1
	JMP CONIN	; NO- GET FROM CONSOLE
;
TTYIN1	STX TEMPX1
	LDA TINBUF	; GET CHAR FROM BUFFER
	PHA
	LDX #0
TBFMOV	LDA TINBUF+1,X	; MOVE REMAINDER OF BUFFER DOWN
	STA TINBUF,X
	INX
	DEY
	BNE TBFMOV
	PLA
	DEC TINSIZ
	LDX TEMPX1
	RTS
;
TTYIN2	JSR TINTST	; ANYTHING IN BUFFER?
	BCC TTYIN0	; NO- GET CHAR FROM CONSOLE
	LDA (EIPTR),Y	; YES- GET FROM BUFFER
	INC EIPTR
	BNE TTYIN3
	INC EIPTR+1
TTYIN3	RTS
;
TINTST	LDA EIPTR	; RETURN CARRY CLEAR IF BUFFER EMPTY
	CMP EIEND	; BUFFER EMPTY?
	BNE TNTST2
	LDA EIPTR+1
	CMP EIEND+1
	BNE TNTST2
;
	LDA EILEN	; YES- ANYTHING LEFT?
	BNE TNTST1
TINMT	STY EIOPEN	; NO- CLOSE INDIRECT FILE
	CLC		; FLAG NOTHING LEFT
	RTS
;
TNTST1	CMP EISIZE	; YES- GET UP TO EISIZE BLOCKS
	BCC STEISZ
	LDA EISIZE
STEISZ	STA EIBLCT
	LDA EIUNIT
	ORA #$40
	TAX
	JSR EIHLR
EIBLCT	.BYTE 0
	.WORD EIBUF
EIPAGE	.WORD 0
	JMP INERR
;
	SEC		; UPDATE REMAINDER
	LDA EILEN
	SBC EIBLCT
	STA EILEN
	LDA EIST	; RESET POINTER
	STA EIPTR
	LDA EIST+1
	STA EIPTR+1
	CLC		; UPDATE CURRENT BLOCK
	LDA EIPAGE
	ADC EIBLCT
	STA EIPAGE
	BCC TNTST2
	INC EIPAGE+1
;
TNTST2	LDA (EIPTR),Y	; GET CHAR FROM INDIRECT BUFFER
	AND #$7F
	CMP #26		; ^Z?
	BEQ TINMT	; YES- CLOSE FILE
	SEC		; FLAG SOMETHING LEFT
	RTS
;
TTYOUT	PHA		; OUTPUT CHAR
	LDA ETFLAG	; USE IMAGE MODE?
	LSR A
	PLA
	BCC TOUT0
	JMP BINOUT	; YES
;
TOUT0	CMP #$40	; CHECK CASE FOR EU
	BCC TOUT3
	BIT EUFLAG
	BMI TOUT3
	CMP #$60	; UPPER CASE?
	BCS TOUT1
	CPY EUFLAG
	BNE FLGCHR
	CPY EUFLAG+1
	BEQ TOUT3
FLGCHR	PHA
	LDA #''
	JSR CONOUT
	PLA
TOUTUC	AND #$5F	; MAKE UPPER CASE
TOUT3	JMP CONOUT
;
TOUT1	CPY EUFLAG
	BNE TOUTUC
	CPY EUFLAG+1
	BNE TOUTUC
	BEQ FLGCHR
;
;
;	COMMAND DISPATCH TABLE
JMPTBL	.WORD BADCMD	; ^@
	.WORD CARETA	; ^A
	.WORD CARETB	; ^B
	.WORD CARETC	; ^C
	.WORD DRADIX	; ^D
	.WORD CARETE	; ^E
	.WORD BADCMD	; ^F
	.WORD BADCMD	; ^G
	.WORD HRADIX	; ^H
	.WORD TABCMD	; TAB
	.WORD NXTCMD	; LF
	.WORD BADCMD	; ^K
	.WORD BADCMD	; ^L
	.WORD NXTCMD	; RETURN
	.WORD CARETN	; ^N
	.WORD ORADIX	; ^O
	.WORD BADCMD	; ^P
	.WORD CARETQ	; ^Q
	.WORD BADCMD	; ^R
	.WORD CARETS	; ^S
	.WORD CARETT	; ^T
	.WORD CARETU	; ^U
	.WORD BADCMD	; ^V
	.WORD BADCMD	; ^W
	.WORD CTXCMD	; ^X
	.WORD CARETY	; ^Y
	.WORD CARETZ	; ^Z
	.WORD PROCMD	; ESCAPE
	.WORD BADCMD	; ^\
	.WORD BADCMD	; ^]
	.WORD ASCCMD	; ^^
	.WORD CMPCMD	; ^_
	.WORD NXTCMD	; SPACE
	.WORD TAGCMD	; !
	.WORD QUOCMD	; "
	.WORD NEWOP	; #
	.WORD HEXCMD	; $
	.WORD PERCMD	; %
	.WORD NEWOP	; &
	.WORD NXTCMD	; '
	.WORD LPAR	; (
	.WORD RPAR	; )
	.WORD NEWOP	; *
	.WORD NEWOP	; +
	.WORD COMMA	; ,
	.WORD NEWOP	; -
	.WORD DOTVAL	; .
	.WORD NEWOP	; /
	.WORD DIGIT	; 0
	.WORD DIGIT	; 1
	.WORD DIGIT	; 2
	.WORD DIGIT	; 3
	.WORD DIGIT	; 4
	.WORD DIGIT	; 5
	.WORD DIGIT	; 6
	.WORD DIGIT	; 7
	.WORD DIGIT	; 8
	.WORD DIGIT	; 9
	.WORD CLNCMD	; :
	.WORD SEMCMD	; ;
	.WORD ITERST	; <
	.WORD EQUAL	; =
	.WORD ITREND	; >
	.WORD TRACE	; ?
	.WORD ATCMD	; @
	.WORD ACMD	; A
	.WORD BVALUE	; B
	.WORD CMOVE	; C
	.WORD DELCMD	; D
	.WORD ECMD	; E
	.WORD FCMD	; F
	.WORD GCMD	; G
	.WORD HVALUE	; H
	.WORD INSCMD	; I
	.WORD JMOVE	; J
	.WORD KILL	; K
	.WORD LMOVE	; L
	.WORD MCMD	; M
	.WORD NCMD	; N
	.WORD OCMD	; O
	.WORD PCMD	; P
	.WORD QCMD	; Q
	.WORD RMOVE	; R
	.WORD SRHCMD	; S
	.WORD TYPE	; T
	.WORD UCMD	; U
	.WORD VERIFY	; V
	.WORD PROCMD	; W
	.WORD XCMD	; X
	.WORD YCMD	; Y
	.WORD ZVALUE	; Z
	.WORD PUSHQ	; [
	.WORD BKSLSH	; \
	.WORD POPQ	; ]
	.WORD UPAROW	; ^
	.WORD YSRCH	; _
;
;	**** ERROR PRINTOUT ROUTINE ***
;
ERROR	LDY #0
	STY EIOPEN	; STOP ANY INDIRECT FILE
	STA TEMP
	ASL A
	TAX
	STY CNCTLO
	LDA #'?		; PRINT '?ERR'
	JSR CONOUT
	LDA ERRTBL,X	; GET RAD40 ERROR MES
	STA RADWRD
	LDA ERRTBL+1,X
	STA RADWRD+1
;
	JSR USR		; CONVERT TO ASCII
	.BYTE RD2ASC
	.WORD RADWRD
	.WORD CHAR
;
	LDX #0		; NOW PRINT ERROR MSG
PRTERR	LDA CHAR,X
	JSR CONOUT
	INX
	CPX #3
	BNE PRTERR
	INC LSTERR
;
	LDA EHFLAG	; PRINT EXTENDED MESAGE?
	BEQ PRTEXT
	JMP GETCMD
;
PRTEXT	LDA #'-		; PRINT '- 'EXTENDED MSG
	JSR CONOUT
	LDA #$20
	JSR CONOUT
	LDA EXTPTR	; FIND EXTENDED MESSAGE
	STA TEMPTR
	LDA EXTPTR+1
	STA TEMPTR+1
	LDX TEMP
	BEQ EXTFND
;
FNDEXT	CLC
	LDA (TEMPTR),Y
	ADC TEMPTR
	STA TEMPTR
	BCC NXTEXT
	INC TEMPTR+1
;
NXTEXT	DEX
	BNE FNDEXT
;
EXTFND	LDA (TEMPTR),Y	; GET COUNT
	TAX
	DEX
EXTOUT	INY		; PRINT EXTENDED MESSAGE
	LDA (TEMPTR),Y
	JSR TTYOUT
	DEX
	BNE EXTOUT
	LDY #0
	JMP GETCMD
;
EXTPTR	.WORD EXTMES
;
ERRTBL	.RAD40 'ILL'	; ILLEGAL COMMAND
	.RAD40 'ILN'	; ILLEGAL NUMBER
	.RAD40 'IEX'	; ILLEGAL EXPRESSION
	.RAD40 'NAE'	; NO ARG BEFORE =
	.RAD40 'DIV'	; DIVIDE BY 0
	.RAD40 'MEM'	; MEMORY OVERFLOW
	.RAD40 'IIA'	; ILLEGAL INSERT ARG
	.RAD40 'POP'	; POINTER OFF PAGE
	.RAD40 'PDO'	; PUSH-DOWN LIST OVERFLOW
	.RAD40 'BNI'	; > NOT IN ITERATION
	.RAD40 'DTB'	; DELETE TOO BIG
	.RAD40 'UTC'	; UNTERMINATED CMD
	.RAD40 'ISA'	; ILLEGAL SEARCH ARG
	.RAD40 'STL'	; STRING TOO LONG
	.RAD40 'IFC'	; ILLEGAL F CHAR
	.RAD40 'SNI'	; ; NOT IN ITERATION
	.RAD40 'NAS'	; NO ARG BEFORE ;
	.RAD40 'IQR'	; ILLEGAL Q REGISTER
	.RAD40 'NAC'	; NO ARG BEFORE ,
	.RAD40 'OUT'	; OUTPUT ERROR
	.RAD40 'IFN'	; ILLEGAL FILE NAME
	.RAD40 'DEV'	; ILLEGAL DEVICE
	.RAD40 'DIR'	; DIRECTORY ERROR
	.RAD40 'IEC'	; ILLEGAL E CHAR
	.RAD40 'NFO'	; NO FILE FOR OUTPUT
	.RAD40 'OFO'	; OUTPUT FILE OPEN
	.RAD40 'IPC'	; ILLEGAL PAGE COUNT
	.RAD40 'FNF'	; FILE NOT FOUND
	.RAD40 'NFI'	; NO FILE FOR INPUT
	.RAD40 'EOF'	; END OF FILE
	.RAD40 'INP'	; INPUT ERROR
	.RAD40 'YCA'	; Y COMMAND ABORTED
	.RAD40 'NAU'	; NO ARG BEFORE U
	.RAD40 'XAB'	; EXECUTION ABORTED
	.RAD40 'FUL'	; OUTPUT DEVICE FULL
	.RAD40 'ICN'	; ILLEGAL CONDITIONAL NESTING
	.RAD40 'IIN'	; ILLEGAL ITERATION NESTING
	.RAD40 'NAQ'	; NO ARGUMENT BEFORE "
	.RAD40 'IQC'	; ILLEGAL CHAR AFTER "
	.RAD40 'TAG'	; ILLEGAL TAG
	.RAD40 'IHC'	; ILLEGAL HEX CHAR
	.RAD40 'CPQ'	; CAN'T POP Q REGISTER
	.RAD40 'MRP'	; MISSING )
	.RAD40 'ERP'	; EXTRA )
	.RAD40 'NAP'	; NO ARG BEFORE )
;
;	EXPANDED ERROR MESSAGES
EXTMES	.BYTE 16,'Illegal command'
	.BYTE 15,'Illegal number'
	.BYTE 19,'Illegal expression'
	.BYTE 16,'No arg before ='
	.BYTE 12,'Divide by 0'
	.BYTE 16,'Memory overflow'
	.BYTE 19,'Illegal insert arg'
	.BYTE 17,'Pointer off page'
	.BYTE 24,'Push-down list overflow'
	.BYTE 19,'> not in iteration'
	.BYTE 15,'Delete too big'
	.BYTE 21,'Unterminated command'
	.BYTE 19,'Illegal search arg'
	.BYTE 16,'String too long'
	.BYTE 20,'Illegal F character'
	.BYTE 19,'; not in iteration'
	.BYTE 16,'No arg before ;'
	.BYTE 19,'Illegal Q-register'
	.BYTE 16,'No arg before ,'
	.BYTE 13,'Output error'
	.BYTE 18,'Illegal file name'
	.BYTE 15,'Invalid device'
	.BYTE 16,'Directory error'
	.BYTE 20,'Illegal E character'
	.BYTE 19,'No file for output'
	.BYTE 25,'Output file already open'
	.BYTE 19,'Illegal page count'
	.BYTE 15,'File not found'
	.BYTE 18,'No file for input'
	.BYTE 12,'End of file'
	.BYTE 12,'Input error'
	.BYTE 18,'Y command aborted'
	.BYTE 16,'No arg before U'
	.BYTE 18,'Execution aborted'
	.BYTE 17,'Output file full'
	.BYTE 28,'Illegal conditional nesting'
	.BYTE 26,'Illegal iteration nesting'
	.BYTE 16,'No arg before "'
	.BYTE 21,'Illegal char after "'
	.BYTE 12,'Illegal tag'
	.BYTE 17,'Illegal hex char'
	.BYTE 16,'Can''t pop Q-reg'
	.BYTE 10,'Missing )'
	.BYTE 8,'Extra )'
	.BYTE 16,'No arg before )'
;
TECEND	.BYTE 0		; END OF TECO
	.END TECO