perm filename TECO[CS,SYS] blob sn#029541 filedate 1973-03-16 generic text, type T, neo UTF8
     

00100	TITLE TECO   V.001   6 MAY 1967
00200	SUBTTL   TAPE EDITOR AND CORRECTOR(V21)  DON WITCRAFT
00300	
00400	REPEAT 0,<
00500	
00600	I.  GENERAL DESCRIPTION
00700		TECO (TAPE EDITOR AND CORRECTOR) IS A SCOPE-KEYBOARD TEXT EDITOR.
00800	IT USES AN ON-LINE COMMAND LANGUAGE (WHICH PERMITS MACRO-DEFINITIONS,
00900	CONDITIONALS,ETC.) TO CONTROL INPUT-OUTPUT (PAPER AND MAGNETIC TAPES,
01000	SCOPE,ETC.) AS WELL AS TEXT OPERATIONS.  THE MACRO LANGUAGE PERMITS THE
01100	MOST SOPHISTICATED SEARCH, MATCH, AND SUBSTITUTION OPERATIONS AS WELL AS
01200	SIMPLE TYPOGRAPHICAL CORRECTIONS TO TEXT.  ALTHOUGH TECO IS DESIGNED
01300	TO BE USED WITH A DISPLAY, IT MAY BE USED WITHOUT ONE.
01400	
01500		THE ORIGINAL TECO WAS A PDP-1 PROGRAM WRITTEN BY DANIEL L.
01600	MURPHY.  PDP-6 TECO WAS WRITTEN BY STEWART NELSON, JACK HOLLOWAY, AND
01700	RICHARD GREENBLATT.  PDP-10 TIMESHARING TECO WAS ADAPTED FROM PDP-6 TECO
01800	BY ROBERT CLEMENTS.  THE CURRENT VERSION IS AN ATTEMPT TO MAKE THE LATTER
01900	REENTRANT.
02000		THERE ARE THREE KINDS OF STORAGE AREAS WITHIN TECO:
02100			(1)  THE BUFFER
02200			(2)  THE 36 Q-REGISTERS; DESIGNATED 0,1,...,9,A,B,...,Z
02300			(3)  THE COMMAND STRING AREA.
02400	THE BUFFER AT ALL TIMES CONTAINS A (POSSIBLY NULL) CHARACTER STRING,
02500	GENERALLY CONSTITUTING A PAGE OF THE TEXT BEING EDITED.  AT CERTAIN TIMES
02600	THE COMMAND-STRING AREA CONTAINS A STRING OF CHARACTERS WHICH TECO INTERPRETS
02700	AS A SERIES OF COMMANDS.  EACH Q-REGISTER MAY:
02800				(A) BE UNDEFINED,
02900				(B) CONTAIN A POSITIVE OR NEGATIVE INTEGER, OR
03000				(C) CONTAIN A CHARACTER STRING.
03100	THE BUFFER IS THAT AREA WHERE TEXT TO BE EDITED IS EXAMINED AND MODIFIED;
03200	THE Q-REGISTERS ARE LOCATIONS FOR REMEMBERING QUANTITIES, OR STRINGS OF TEXT,
03300	FOR LATER USE; THE COMMAND STRING IS THE AREA FROM WHICH TECO TAKES
03400	INSTRUCTIONS.
03500		ASSOCIATED WITH THE BUFFER IS THE "POINTER": THIS IS A
03600	MOVABLE FLAG WHICH ALWAYS SITS BETWEEN TWO ADJACENT CHARACTERS IN THE
03700	BUFFER (OR AT EITHER END OF THE BUFFER).  THE POINTER HAS A NUMERIC VALUE
03800	EQUAL TO THE NUMBER OF CHARACTERS TO ITS LEFT IN THE BUFFER.
03900	IF AT THE MOMENT THERE ARE N CHARACTERS IN THE BUFFER, THE POINTER'S
     

00100	VALUE MAY RANGE FROM 0 TO N.
00200		A GENERAL DESCRIPTION OF THE USAGE OF TECO IS AS FOLLOWS:
00300	THE USER GETS TECO INTO THE COMPUTER; TYPES IN COMMANDS TO DESCRIBE WHERE
00400	THE MATERIAL TO BE EDITED (THE "INPUT") IS.  BY FURTHER COMMANDS, HE
00500	READS THE FIRST PAGE INTO THE BUFFER; INSPECTS IT ON THE DISPLAY AND
00600	MAKES CHANGES BY TYPING IN COMMANDS; OUTPUTS THE PAGE ONTO PAPER TAPE OR
00700	DECTAPE, AND READS IN THE NEXT PAGE; ETC.; AFTER OUTPUTTING THE LAST
00800	PAGE, HE CLOSES THE OUTPUT FILE, THEREBY RELEASING THE OUTPUT DEVICE.
00900	THIS IS BY NO MEANS THE ONLY WAY ONE MAY PROCEED, BUT IT IS THE MOST COMMON.
01000	
01100	
01200	
01300	II.	LOADING TECO
01400		TO LOAD TECO, TYPE THE MONITOR COMMAND:
01500			R TECO
01600	>
     

00100	;ACCUMULATOR ASSIGNMENTS
00200	
00300		FF←0		;CONTROL FLAGS
00400		P←1		;PUSH DOWN POINTER
00500	;*** A, AA AND B MUST BE CONTIGUOUS AND IN THAT ORDER ***
00600		A←2
00700		AA←3		;BYTE POINTER TO COMMAND BUFFER
00800	;*** B AND E MUST BE ADJACENT AND B<11 ***
00900		B←4		;COMMAND BUFFER END ADDRESS
01000		E←5
01100		C←6
01200		D←7
01300		F←10
01400		T←11
01500	;*** TT AND TT1 MUST BE ADJACENT ***
01600		TT←12
01700		TT1←13
01800		IN←14
01900		OUT←15
02000		CH←16
02100		PF←17
02200		R←0		;DATA AREA RELOCATION.  XWD RELOC,RELOC
02300	
02400	EXTERN JOBREL,JOBSYM,JOBDDT,JOBFF,JOB41,JOBREN
02500	
02600	;CONTROL FLAGS
02700	;RIGHT HALF
02800	
02900		ALTF←1		;ALT-MODE SEEN
03000				;LI1(0),GO1+2(0),LI4+2(1)
03100		ARG2←2		;THERE IS A SECOND ARGUMENT
03200				;GO1+2(0),CD+3(0),COMMA+2(1),HOLE+1(1)
03300		ARG←4		;THERE IS AN ARGUMENT
03400				;GO1+2(0),CD+3(0),CD7(1),COMMA+1(0),CHK2(1),BAKSL(0),BAKSL2(0),
03500				;BAKSLM(1),LSSTH+5(0),GETARG+2(1)
03600		ITERF←10	;INSIDE AN ITERATION
03700				;GO1+2(0),OPEN+2(0),CLOSE+5(1),CLOSE+7(1),GRCH+2(0),LSSTH1(1)
03800		SLSL←20		;@ SEEN
03900				;GO1+2(0),INSERT+3(0),ATSIGN(1),SERCH+3(0)
04000		PCHFLG←40	;N SEARCH
04100				;GO1+2(0),CD+3(0),SERCHP(1),BEGIN2(0)
04200		COLONF←100	;COLON SEEN
04300				;GO1+2(0),COLON(1),FND+5(0),BEGIN1(0)
04400		SYLF←200	;GO1+2(0),CD6+2(0),CD7(1)
04500		FINF←1000	;GO1+2(0),CD5+1(0),YANK3+12(1)
04600		FINDR←2000	;LEFT ARROW SEARCH
04700				;GO1+2(0),CD+3(0),LARR(1),BEGIN2(0)
04800		QMFLG←4000	;LI3+5(0),ERR+4(1)
04900		NOTF←10000	;↑N SEARCH MODIFIER
05000				;GO1+2(0),CD6+5(0),SERCH4(0),CNTRN(1)
05100		TRACEF←20000	;? SEEN
05200				;QUESTN(R)
05300		SEQF←40000	;SEQUENCE NUMBER
05400				;YNKSEQ(1),YANK5+5(0)
05500		BELLF←100000	;↑G SEEN
05600				;GO1+2(0),LI1(0),LI5+2(1)
05700	
     

00100	;LEFT HALF
00200	
00300		UREAD←200	;INPUT FILE IS OPEN
00400				;YANK3+11(0),OPNRD(1)
00500		UWRITE←400	;OUTPUT FILE IS OPEN
00600				;OUTERR+4(0),OPNW1(1),CLOSEF(0)
00700		FILWD←2000	;FILE WORD BEING ASSEMBLED.
00800				;FILSPC(0),FILSPL+20(1),FILLS1+3(0),FILLS1+4(0)
00900		FEXTF←4000	;FILE EXT EXPECTED (.TYPED).
01000				;FILLS1(0),FILSP3+2(1)
01100	
01200	OPDEF	TYPR1 [30B8]
01300	
01400	OPDEF	OPEN [50B8]
01500	
01600	;CALLI UUOS
01700		RESET←0
01800	
01900		DDTIN←1
02000		TYIN←DDTIN
02100		DDTOUT←3
02200		TYOUT←DDTOUT
02300		EXIT←12
02400		TIMER←22
02500		SWITCH←20
02600		UTPCLR←13
02700		INCHN←2
02800		OUTCHN←3
02900		LPDL←75
03000		GCTBL←100
03100		LPF←40
03200		BUFSIZ←205
03300	IFE <R>,<
03400	DEFINE U'(A,B)
03500	<	A:	BLOCK B>
03600	>
03700	
03800	IFN <R>,
03900	<		ZZ←CODEND
04000		DEFINE U'(A,B),<XLIST
04100			A←ZZ
04200			ZZ←ZZ+B
04300	LIST>
04400	>
04500	
     

00100	;STARTUP TIME INITIALIZATION
00200	
00300		INTERNAL TECO
00400	TECO:
00500	INIT:	CALLI RESET		;INITIALIZE ALL IO
00600		MOVE A,LOC41			;SETUP UUO TRAP  JOB41:=JSR ETYPER
00700		MOVEM A,JOB41(R)
00800	 	MOVE P,[XWD -LPDL,PDL-1]
00900	IFN <R>,<	ADDI P,(R)		;RELOCATE PUSH DOWN LIST>
01000		HRRZ A,JOBREL(R)		;IF JOBDDT=0, JOBFF:=C(JOBREL)-202
01100	IFE <R>,<	SKIPE JOBDDT			;OTHERWISE, JOBFF:=C(JOBSYM)-202
01200		HRRZ A,JOBSYM>
01300		MOVEM A,JOBFF(R)
01400		IMULI A,5
01500		MOVEM A,MEMSIZ(R)		;MEMSIZ:=C(JOBFF)*5
01600		MOVE A,TTYPT			;INITIALIZE TTY BUFFER
01700		MOVEM A,TYIPT(R)
01800		MOVEM A,TYOPT(R)
01900		SETZM TTYBUF(R)
02000		MOVE A,[XWD TTYBUF,TTYBUF+1]
02100	IFN <R>,<	ADD A,R			;RELOCATE>
02200		BLT A,TTYBUF+24(R)
02300		SETZM SFINDF(R)
02400		MOVEI A,GOX			;SET FOR REENTER AT GOX
02500		MOVEM A,JOBREN(R)
02600		MOVSI A,263000+P*40
02700		MOVEM A,TRACS(R)		;TRACS:=POPJ P,
02800		SETZM OPNR1(R)			;CLEAR INPUT DEVICE NAME
02900		MOVEI A,CBUF+200
03000		IMULI A,5
03100		MOVEM A,BEG(R)			;BEG:=(CBUF+200)*5
03200		MOVEM A,PT(R)			;PT:=(CBUF+200)*5
03300		MOVEM A,Z(R)			;Z:=(CBUF+200)*5
03400		MOVEM A,QRBUF(R)		;QRBUF:=(CBUF+200)*5
03500		MOVEI A,CBUF+77
03600		MOVEM A,CBUFH(R)		;CBUFH:=CBUF+77
03700		MOVEI A,SYL
03800		MOVEM A,DLIM(R)			;DLIM:=SYL
03900		MOVE A,[XWD 10014,-1]
04000		MOVEM A,NROOM2(R)		;NROOM2:=XWD 10014,-1
04100		MOVE A,[JRST CNTRB2]		;CNTRB1+1:=JRST CNTRB2
04200		MOVEM A,CNTRB1+1(R)
04300		MOVEI FF,0			;CLEAR FLAG REGISTER
     

00100	;REENTER COMMAND INITIALIZATION
00200	;FROM ETYPER+10
00300	
00400	GOZ:
00500	
00600	;FROM LI5+4,OUTERR+5
00700	
00800	GOX:	PUSHJ P,CRR			;TYPE CRLF
00900	
01000	;FROM ALTMOD+4,ERR+12
01100	
01200	GO:	MOVE P,[XWD -LPDL,PDL-1]	;INITIALIZE PUSHDOWN LIST
01300	IFN <R>,<	ADDI P,(R)		;RELOCATE POINTER>
01400		MOVE T,[JRST DQT2]		;INITIALIZE CONTROL B DISPATCH
01500		MOVEM T,CNTRB1(R)		;CNTRB1:=JRST DQT2
01600	GO1:	SETZM ,LEV(R)
01700		MOVE PF,[XWD -LPF,PFL-1]
01800	IFN <R>,<	ADDI PF,(R)		;RELOCATE POINTER>
01900		TRZ FF,777777-TRACEF-QMFLG
02000		JRST LIS
02100	
02200	
02300	LOC41:	JSR ETYPER
02400	
     

00100	;ROUTINE TO RETURN NON-NULL TTY CHARACTER IN CH.
00200	;CALL	PUSHJ PDP,TYI
00300	;	RETURN
00400	;FROM LI3+1
00500	
00600	TYI:	MOVE T,TTYPT
00700		CAMN T,TYIPT(R)		;IS TTY BUFFER EMPTY?
00800	TYI1:	CALLI T,TYIN		;YES. GET A CHARACTER
00900		ILDB CH,TYIPT(R)
01000		JUMPN CH,CPOPJ		;IF NOT NULL CHARACTER, RETURN
01100		MOVE T,TTYPT		;NULL. RESET INPUT POINTER AND GET ANOTHER CHARACTER
01200		MOVEM T,TYIPT(R)
01300		JRST TYI1
01400	
01500	
01600	
01700	
01800	;ROUTINE TO TYPE A CHARACTER.
01900	;CALL	MOVE CH,CHARACTER
02000	;	PUSHJ P,TYO
02100	;	RETURN
02200	;CONTROL CHARACTERS ARE TYPED WITH "↑" FOLLOWED BY THE CORRESPONDING
02300	;PRINTING CHARACTER.
02400	;FROM CRR1+1,CRR1+3,LI3+1,LI3+23,ERRTYP+5,ERRMES+1,CONMES+3,SIXBMS+5,LIS+1
02500	;ERR+2,LKUPER+7,ETYPER+11,FORM,COMMENT+3
02600	
02700	TYO:	PUSH P,CH		;NULL/IDLE,START OF MESSAGE,END OF ADDRESS, END OF
02800					;TRANSMISSION,WRU,ARE YOU OR BELL?
02900		CAIL CH,7
03000		CAIN CH,10
03100		JRST TYO1		;YES.
03200		CAIG CH,15		;NO. HORIZONTAL TAB,LINE FEED,VERTICAL TAB
03300					;FORM FEED OR CARRIAGE RETURN?
03400		JRST TYOB		;YES. TYPE IT AND RETURN
03500		CAIGE CH,40		;NO. ANY OTHER CONTROL CHARACTER?
03600		JRST TYO1		;YES.
03700		CAIN CH,175		;NO. ALT-MODE?
03800		MOVEI CH,"$"		;YES. CONVERT IT TO $.
03900	TYOB:	PUSHJ P,TYOA		;TYPE CH.
04000		POP P,CH		;RESTORE CH
04100		POPJ P,0		;RETURN
04200	
     

00100	TYOA:	MOVE T,TTYPT		;INITIALIZE OUTPUT POINTER
00200		MOVEM T,TYOPT(R)
00300		IDPB CH,TYOPT(R)	;STORE CH IN TTYBUF
00400	TOUTCL:	MOVEI T,0		;TERMINATE OUTPUT STRING WITH A NULL
00500		IDPB T,TYOPT(R)
00600		MOVE T,TTYPT		;RESET OUTPUT POINTER.
00700		MOVEM T,TYOPT(R)
00800		HRRZ T,T
00900		CALLI T,TYOUT		;TYPE CH
01000		POPJ P,0
01100	
01200	TYO1:	PUSH P,CH		;TYPE CONTROL CHARACTER IN FORM "↑CH"
01300		MOVEI CH, "↑"
01400		PUSHJ P,TYOA		;TYPE ↑
01500		POP P,CH
01600		ADDI CH,100		;CONVERT TO PRINTING CHARACTER
01700		JRST TYOB		;AND TYPE IT.
01800	
01900	U TYIPT,1			;INIT+16(TTYPT),TYI1+4(TTYPT)
02000	U TYOPT,1			;INIT+17(TTYPT),TYOA+1(TTYPT),TOUTCL+3(TTYPT)
02100	TTYPT:	XWD 440700,TTYBUF(R)
02200	U TTYBUF,25			;INIT+20(0)
02300	
     

00100	;ROUTINE TO TYPE "? ERROR MESSAGE"
00200	;CALL	JSP A,ERRMES
00300	;	ASCIZ /ERROR MESSAGE/
00400	;	RETURN
00500	;FROM PPA09,OUTERR,YANK09+2,INERR,ININER,LKUPER,ENTERR
00600	
00700	
00800	ERRMES:	MOVEI CH,"?"
00900		PUSHJ P,TYO
01000	
01100	;ROUTINE TO TYPE "MESSAGE"
01200	;CALL JSP A,CONMES
01300	;	ASCIZ /MESSAGE/
01400	;	RETURN
01500	;FROM ININER+4,LKUPE1,LSTDIR+1
01600	
01700	CONMES:	HRLI A,440700
01800		ILDB CH,A
01900		JUMPE CH,1(A)
02000		PUSHJ P,TYO
02100		JRST .-3
02200	
02300	
02400	;ROUTINE TO TYPE C(A) IN SIXBIT
02500	;CALL	MOVE A,[SIXBIT /MESSAGE/]
02600	;	PUSHJ P,SIXBMS
02700	;	RETURN
02800	;FROM ININER+3,LKUPER+3,LKUPER+10
02900	
03000	
03100	SIXBMS:	MOVNI B,6
03200		MOVE E,[XWD 440600,A]
03300		ILDB CH,E
03400		JUMPE CH,CPOPJ
03500		ADDI CH,40
03600		PUSHJ P,TYO
03700		AOJL B,.-4
03800		POPJ P,0
03900	
04000	U STOPF,1
04100	
04200	U INBUF,3		;YANK3+2,OPNRD+14(SETZ IBUF1+1(R)),OPNRD+16,
04300				;OPNRD+20,OPNRD+23
04400	U OUTBUF,3		;PPA+2,OPNW1+12,OPNW1+13,OPNW1+22
04500	
04600	U IBUF1,2*BUFSIZ+1
04700	U OBUF1,2*BUFSIZ+1
04800	
     

00100	;ROUTINE TO OUTPUT DECIMAL INTEGER
00200	;CALL	MOVE B, DECIMAL INTEGER
00300	;	MOVEI A,ADDRESS OF OUTPUT ROUTINE
00400	;	HRRM A,LISTF5(R)
00500	;	PUSHJ P,DPT
00600	;	RETURN
00700	
00800	;FROM PRNT+4,BAKSL1+4
00900	
01000	DPT:	JUMPGE B,.+3		;NUMBER > 0?
01100		MOVEI CH,"-"		;NO. OUTPUT -
01200		PUSHJ P,@LISTF5(R)
01300		MOVMS B			;B:=ABSOLUTE VALUE OF B
01400		IDIVI B,12		;E:=DIGIT
01500		HRLM E,(P)		;PUT DIGIT ON LEFT HALF OF TOP OF PUSH DOWN LIST
01600		JUMPE B,.+2		;DONE?
01700		PUSHJ P,.-3		;NO. PUSH THIS DIGIT AND PRINT RETURN ADDRESS.
01800		HLRZ CH,(P)		;YES. CH:=DIGIT
01900		ADDI CH,60		;CONVERT IT TO ASCII.
02000		JRST @LISTF5(R)		;PRINT IT
02100	
02200	
02300	
02400	;ROUTINE TO TYPE CARRIAGE RETURN LINE FEED
02500	;CALL	PUSHJ P,CRR
02600	;	RETURN
02700	;FROM GOX+1,LI4+11,CLIS,PRNT+5,ERR+3,GRTH+12
02800	
02900	CRR:	MOVEI CH,TYO		;SET OUTPUT DISPATCH TO TTY AND
03000		HRRM CH,LISTF5(R)
03100	
03200	CRR1:	MOVEI CH,15		;OUTPUT CRLF
03300		PUSHJ P,@LISTF5(R)
03400		MOVEI CH,12
03500		JRST @LISTF5(R)
03600	
     

00100	;ROUTINE TO RETURN NEXT CHARACTER FROM COMMAND BUFFER AND ERROR IF EMPTY.
00200	;CALL	PUSHJ P,SKRCH
00300	;	RETURN WITH CHARACTER IN CH
00400	;GOES TO ERR IF COMMAND BUFFER IS EMPTY
00500	;FROM FILSPL,INSERT+10,SERCH2,SERCH2+12,EXCLAM,OGNF+5,UAR,FILS4L,FILS5L,COMMENT
00600	
00700	SKRCH:	SKIPN COMCNT(R)		;COMMAND BUFFER EMPTY?
00800		JSR ERR			;YES. SKRCH SHOULDN'T RUN OUT.
00900	
01000	;ROUTINE TO RETURN NEXT CHARACTER FROM COMMAND BUFFER.
01100	;CALL	PUSHJ P,RCH
01200	;	RETURN ALWAYS WITH CHARACTER IN CH
01300	
01400	;FROM CD5,INSERT+4,SERCH+4,QREG+1,DQUOTE+2,CNTRUP,ECMD
01500	
01600	RCH:	SOSGE COMCNT(R)		;DECREMENT COMMAND BUFFER CHARACTER COUNT
01700					;IS COMMAND BUFFER EMPTY?
01800		JRST RCH2		;YES. POP UP TO HIGHER MACRO LEVEL.
01900		ILDB CH,CPTR(R)		;NO. GET COMMAND CHARACTER IN CH
02000		XCT TRACS(R)		;RETURN OR JRST TYO IN TRACE MODE
02100	RCH2:	POP P,CH		;SAVE RETURN FOR POPJ IN CH
02200		POP P,COMCNT(R)		;GET COUNT FROM NEXT MACRO LEVEL
02300		POP P,CPTR(R)		;POINTER TOO.
02400		POP P,COMAX(R)		;NUMBER OF COMMANDS.
02500		PUSH P,CH		;GET RETURN BACK ON PDL.
02600		JRST RCH		;TRY AGAIN.
02700	
02800	U TRACS,1			;INIT+26(POPJ P,),QUESTN+3
02900	
03000	;FROM NOGO+1,OG5+2,INCMA1
03100	
03200	SKRCH1:	SOSGE COMCNT(R)		;ANY CHARACTERS LEFT?
03300		JSR ERR			;NO. SUPPOSEDLY CAN'T RUN OUT OF
03400					;COMMANDS AT THIS ROUTINE.
03500		ILDB CH,CPTR(R)		;YES. GET A CHARACTER.
03600		POPJ P,			;RETURN.
03700	
     

00100	REPEAT 0,<
00200	
00300	III.	TYPING IN COMMANDS
00400		TECO INDICATES ITS READINESS TO ACCEPT COMMANDS BY TYPING
00500	AN ASTERISK (*).  NEARLY ANY STRING OF CHARACTERS MAY BE TYPED IN.
00600	IF CAR RET IS TYPED, TECO IMAGINES THAT THE USER TYPED A LINE FEED
00700	FOLLOWING IT.  ALL CHARACTERS TYPED IN ARE ECHOED BACK OUT BY TECO
00800	(INCLUDING THE IMAGINED LINE FEED) UNCHANGED EXCEPT AS FOLLOWS:
00900		(1)  ALT MODE IS TYPED OUT AS $.
01000		(2)  ON OUTPUT ONLY, CHARACTERS WHICH HAVE NO VISIBLE EFFECT
01100			AND ARE TYPED IN VIA THE CTRL SHIFT KEY COME OUT AS ↑
01200			FOLLOWED BY THE APPROPRIATE UN-CTRL CHARACTER.
01300		(3)  RUBOUT DOES NOT GO IN, BUT INSTEAD ERASES THE LAST CHARACTER
01400			THAT DID GO IN.  THIS ECHOES OUT THE CHARACTER THAT HAS
01500			JUST BEEN ERASED.  RUBOUT MAY BE USED ANY NUMBER OF TIMES
01600			IN A ROW; IF THERE ARE NO CHARACTERS LEFT TO ERASE,
01700			RUBOUT ECHOES AS CARRIAGE RETURN---LINE FEED FOLLOWED BY
01800			AN ASTERISK.
01900		(4)  TWO SUCCESSIVE ALT MODES INDICATE THE END OF THE STRING TYPED IN.
02000			WHEN THESE ARE ENCOUNTERED, TECO ECHOES THEM AS $S, TYPES
02100			CARRIAGE RETURN---LINE FEED, COPIES THE ENTIRE STRING OF
02200			CHARACTERS TYPED (EXCEPT THOSE ERASED) INTO THE COMMAND
02300			STRING AREA, AND STARTS TO INTERPRET AND PERFORM THESE
02400			NEW COMMANDS.
02500		(5)  CTRL C RETURNS CONTROL TO THE TIME SHARING EXEC AT ONCE,
02600			WITHOUT WAITING FOR I/O TO FINISH.
02700		(6)  TWO SUCCESSIVE CTRL G'S (BELL) WILL DELETE THE ENTIRE
02800			COMMAND STRING WITHOUT EXECUTING IT.  TECO THEN
02900			TYPES RETURN-LINE FEED FOLLOWED BY AN ASTERISK.
03000		(7)  THE COMMAND ↑G (BELL) WILL, WHEN PERFORMED, RETURN
03100			TO THE TIME SHARING EXEC BUT IT WILL HAVE WAITED
03200			FOR ALL TECO'S OUTPUT TO BE DONE.
03300	THE FORMAT IN WHICH TECO EXPECTS THESE COMMANDS, AND THE ACTIONS THEY
03400	DIRECT IT TO TAKE, COMPRISE THE BULK OF KNOWLEDGE THE USER SHOULD
03500	HAVE ABOUT TECO.
03600	>
     

00100	;FROM LI3+21
00200	
00300	CLIS:	PUSHJ P,CRR		;TYPE CRLF
00400	
00500	;FROM GO1+3
00600	
00700	LIS:	MOVEI CH,"*"
00800		PUSHJ P,TYO		;TYPE *
00900		SETZM  COMCNT(R)	;COMCNT:=0
01000		SETZM  INTDPH(R)	;INTDPH:=0
01100		SETZM  SYMS(R)
01200		MOVE T,[XWD SYMS,SYMS+1]
01300	IFN <R>,<	ADD T,R>
01400		BLT T,SYMEND-1(R)
01500		MOVE AA,[XWD 700,CBUF-1(R)]
01600		MOVE B,CBUFH(R)
01700	
01800	;FROM LI3+26,LI5+1
01900	
02000	LI1:	TRZ FF,ALTF+BELLF
02100	
02200	;FROM LI4+3,LI5+3
02300	
02400	LI2:	CAILE B,(AA)		;COMMAND BUFFER EXCEEDED?
02500		JRST LI3		;NO
02600		ADDI B,100		;YES. EXPAND COMMAND BUFFER 100 WORDS.
02700		MOVE C,Z(R)
02800		IDIVI C,5		;C:=DATA BUFFER END WORD ADDRESS.
02900		MOVE D,QRBUF(R)
03000		IDIVI D,5		;D:=Q-REG BUFFER BASE WORD ADDRESS.
03100		SUBM C,D		;D:=NO. OF WORDS IN Q-REG BUFFER AND DATA BUFFER.
03200		MOVE CH,(C)
03300		MOVEM CH,100(C)		;MOVE Q-REG AND DATA BUFFERS UP 100 WORDS.
03400		SOS C
03500		SOJGE D,.-3
03600		MOVEI C,500
03700		ADDM C,BEG(R)		;BEG:=C(BEG)+500
03800		ADDM C,PT(R)		;PT:=C(PT)+500
03900		ADDM C,Z(R)		;Z:=C(Z)+500
04000		ADDM C,QRBUF(R)		;QRBUF:=C(QRBUF)+500
04100		MOVE D,Z(R)
04200		CAML D,MEMSIZ(R)	;HAVE BUFFERS EXCEEDED MEMORY CAPACITY?
04300		JRST GC1		;YES. GARBAGE COLLECT.
     

00100	
00200	;FROM LI2+1
00300	
00400	LI3:	MOVEM B,CBUFH(R)	;NO. RESET HIGH END OF COMMAND BUFFER.
00500		PUSHJ P,TYI		;GET A NON-NULL CHARACTER IN CH
00600		CAIE CH,33		;IS IT AN OLD ALT-MODE CODE?
00700		CAIN CH,176
00800		MOVEI CH,175		;YES. CONVERT TO NEW ALT-MODE CODE.
00900		TRZE FF,QMFLG		;CLEAR ? FLAG. WAS IT ON?
01000		CAIE CH,"?"		;YES. IS THIS A "?"?
01100		AOSA COMCNT(R)		;NO. INCREMENT COMMAND CHARACTER COUNT
01200		JRST ERRTYP		;YES. TYPE BAD STRING
01300		IDPB CH,AA		;NO. STORE CHARACTER IN COMMAND BUFFER.
01400		CAIE CH,177		;IS IT A RUBOUT?
01500		JRST LI4		;NO.
01600	
01700	;DELETE A CHARACTER FROM THE COMMAND BUFFER.
01800		IBP AA			;YES. BACKUP BYTE POINTER TWO BYTES
01900		IBP AA
02000		IBP AA
02100		SOS D,AA
02200		CAMN AA,[XWD 100700+R,CBUF-1]	;DID IT GO PAST THE BEGINNING
02300					;OF THE BUFFER
02400		JRST CLIS		;YES. TYPE *
02500		ILDB CH,D		;NO. TYPE DELETED CHARACTER
02600		PUSHJ P,TYO
02700		SOS COMCNT(R)		;REMOVE TWO CHARACTERS FROM COMMAND COUNT.
02800		SOS COMCNT(R)
02900		JRST LI1		;AND GET ANOTHER COMMAND CHARACTER
03000	
03100	;FROM LI3+13
03200	
03300	LI4:	CAIE CH,175		;ALT-MODE?
03400		JRST LI5		;NO
03500		TRON FF,ALTF		;YES. SET ALT-MODE FLAG. WAS IT ON?
03600		JRST LI2		;NO
03700		MOVEI CH,141		;YES. TWO SUCCESSIVE ALT-MODES. END OF COMMAND.
03800		AOS A,COMCNT(R)		;MARK END OF COMMAND STRING WITH ASCII 141
03900		IDPB CH,AA
04000		MOVE AA,[XWD 700+R,CBUF-1]	;INITIALIZE COMMAND BYTE POINTER
04100		MOVEM AA,CPTR(R)
04200		PUSHJ P,CRR		;TYPE CRLF
04300		MOVEM A,COMAX(R)	;SET COMMAND CHARACTER ADDRESS UPPER BOUND
04400		JRST CD			;DECODE COMMAND
04500	
     

00100	;FROM LI4+1
00200	
00300	LI5:	CAIE CH,7		;BELL?
00400		JRST LI1		;NO. GET MORE CHARACTERS.
00500		TRON FF,BELLF		;YES. SET BELL FLAG. TWO SUCCESSIVE BELLS?
00600		JRST LI2		;NO.
00700		JRST GOX		;YES. CLEAR COMMAND BUFFER.
00800	
     

00100	
00200	REPEAT 0,<
00300	
00400	IV.	QUANTITIES
00500		MANY TECO COMMANDS TAKE ARGUMENTS WITH NUMERIC VALUES, AND SOME
00600	COMMANDS TAKE DIFFERENT ACTION DEPENDING ON WHETHER ARGUMENTS ARE
00700	GIVEN OR NOT.  THE FOLLOWING CHARACTERS MAY APPEAR IN COMMAND STRINGS TO
00800	DEVELOP NUMERIC VALUES.  FURTHERMORE, SOME COMMANDS, BESIDES DIRECTING
00900	ACTION ON TECO'S PART, HAVE A NUMERIC VALUE THEMSELVES AND SO MAY ACT
01000	AS AN ARGUMENT TO A SUBSEQUENT COMMAND.  IF A COMMAND MAY HAVE A VALUE,
01100	THIS WILL BE STATED IN ITS DESCRIPTION.  IN ALL COMMAND DESCRIPTIONS,
01200	$ MEANS ALT-MODE AND ↑X MEANS X WITH THE CTRL KEY HELD.  ALL CTRL
01300	CHARACTERS WHICH ARE TO BE INTERPRETED AS COMMANDS MAY BE TYPED IN BY
01400	TYPING UP ARROW ↑ FOLLOWED BY THE CORRESPONDING PRINTING CHARACTER.
01500	
01600		0-9	DIGITS FORM DECIMAL INTEGERS.
01700		B	=0 (I.E. RETURNS THE NUMERIC VALUE 0).
01800		Z	=NUMBER OF CHARACTERS IN THE BUFFER.
01900		.	=NUMBER OF CHARACTERS TO LEFT OF THE POINTER.
02000		QI	(WHERE I IS A DIGIT OR LETTER) = NUMERIC VALUE MOST
02100			RECENTLY PUT INTO Q-REGISTER NAMED I.
02200		NA	(WHERE N IS A NUMERIC ARGUMENT) = VALUE IN 7-BIT ASCII OF
02300			THE CHARACTER TO THE RIGHT OF THE POINTER.
02400		↑H	HAS THE VALUE OF ELAPSED TIME, IN 60THS OF A SECOND, SINCE MIDNITE.
02500		↑F	HAS THE VALUE OF THE CONSOLE DATA SWITCHES.
02600		↑↑	HAS THE VALUE OF THE NEXT CHARACTER IN THE COMMAND STRING.
02700		↑T	CAUSES COMMAND INTERPRETATION TO STOP UNTIL THE USER
02800			TYPES A CHARACTER ON THE TELETYPE AND THEN HAS THE
02900			ASCII VALUE OF THE CHARACTER TYPED IN.
03000		\	HAS THE VALUE OF THE NUMBER REPRESENTED BY THE DIGITS
03100			(OR MINUS SIGN) FOLLOWING THE POINTER IN THE BUFFER.
03200			THE SCAN TERMINATES ON ANY OTHER CHARACTER.  THE POINTER
03300			IS MOVED OVER THE NUMBER FOUND (IF ANY).
03400		M+N	ADD	TAKES 1 OR 2 ARGUMENTS. SPACE IS EQUIVALENT TO +.
03500		M-N	SUBTRACT	TAKES 1 OR 2 ARGUMENTS.
03600		M*N	MULTIPLY	TAKES 2 ARGUMENTS.
03700		M/N	DIVIDE (TRUNCATES)	TAKES 2 ARGUMENTS.
03800		M&N	LOGICAL AND: BITWISE AND OF BINARY REPRESENTATION OF M
03900			AND N.
04000		M#N	LOGICAL IOR: BITWISE INCLUSIVE OR OF BINARY REPRESENTATION
     

00100			OF M AND N.
00200	
00300			OPERATORS +,-,*,/,# AND & ARE PERFORMED FROM LEFT TO RIGHT.
00400			THIS MAY BE OVERRULED BY USE OF
00500		( )	NUMERIC PARENTHESIS.
00600		N=	CAUSES THE VALUE OF N TO BE TYPED OUT.
00700		NUI	PUTS QUANTITY N IN Q-REGISTER NAMED I.
00800		M,N	IF A COMMAND TAKES TWO NUMERIC ARGUMENTS, COMMA IS USED TO
00900			SEPARATE THEM.
01000		H	AN ABBREVIATION FOR B,Z WHICH IS A FREQUENTLY USED PAIR
01100			OF ARGUMENTS FOR COMMANDS.
01200	>
     

00100	;FROM LI4+15,CD9(↑J,↑M,',W),ALTMOD+5,INCMA
00200	
00300	CD:
00400	
00500	;FROM CD6+10,OPEN+6,APPEND+4,JMP1+2,KILL+4,JRET,COLON+1,FND+6,
00600	;FND1+1,USEA+2,NOGO+5,EXCLAM+3,DQT1+1,OG3+4,OGFND+4,QUESTN+4,BAKSL1+12,
00700	;OPENB+6,INCMA2+3,LSSTH1+1,LINE+4,QGET1
00800	
00900	RET:	TRZ FF,ARG2+ARG+FINDR+PCHFLG
01000	
01100	;FROM COMMA+4
01200	
01300	CD1:	SETZM  NUM(R)
01400	
01500	;CD9(SPACE,+),OPENB+5
01600	;ADD TAKES ONE OR TWO ARGUMENTS
01700	
01800	CD2:	MOVSI A,270000+B*40+R	;DELIM:=ADD B,(R)
01900	
02000	;FROM CAND+1,COR+1,MINUS+1,TIMES+1,SLASH+1
02100	
02200	CD3:	HLLM A,DLIM(R)
02300	CD4:	SETZM  SYL(R)
02400	
02500	;FROM CD7+1,MAC+31
02600	
02700	CD5:
02800		PUSHJ P,RCH
02900		TRZ FF,FINF
03000	CD9:	XCT DTB(CH)		;A:=XWD VALUE FLAG,DISPATCH ADDRESS
03100					;OR DISPATCH DIRECTLY
03200	CD6:	MOVE B,NUM(R)
03300		TRZE FF,SYLF		;DID LAST CHARACTER RETURN A VALUE OR WAS IT A DIGIT?
03400		XCT DLIM(R)		;YES. NUM:=NUM (DLIM OPERATOR) SYL
03500		MOVEM B,NUM(R)
03600		MOVE C,SARG(R)		;SAVE SECOND ARGUMENT IN C.
03700		TRZ FF,NOTF
03800		JUMPGE A,(A)		;DISPATCH IF VALUE RETURN COMMAND.
03900		PUSHJ P,(A)		;DISPATCH FOR NON-VALUE RETURN COMMANDS.
04000		JRST RET
04100	
04200	
04300	
04400	U DLIM,1			;INIT+41(SYL),CD3,CLOSE+4
04500	U NUM,1				;CD1(0),CD6+3,CLOSE+10,APPND2(0),SERCH+1(0)
04600	U SYL,1				;CD4(0),VALRET,CLOSE+2,BAKSLA+11,BAKSLA+13,BAKSL2+1
04700	U SARG,1			;COMMA,HOLE(0)
     

00100	;CD9(0,1,2,3,4,5,6,7,8,9)
00200	;DIGITS FORM DECIMAL INTEGERS.
00300	
00400	CDNUM:	MOVE A,SYL(R)
00500		IMULI A,12
00600		ADDI A,-60(CH)
00700	
00800	;SOME COMMANDS HAVE A NUMERIC VALUE
00900	;FROM END1+2,APPND2+1,FND+10,BEGIN+1,PCNT+2,CNTRUP+2,GTIME+1,LAT+1
01000	
01100	VALRET:	MOVEM A,SYL(R)
01200	
01300	;FROM CLOSE+11,BAKSL2+3
01400	
01500	CD7:	TRO FF,ARG+SYLF
01600		JRST CD5
01700	
01800	
01900	;CD9(ALT-MODE)
02000	
02100	ALTMOD:	MOVE T,CPTR(R)		;IF NEXT COMMAND CHARACTER IS ALT-MODE,
02200					;OR END OF COMMAND BUFFER, GO;ELSE CD.
02300		ILDB CH,T
02400		CAIE CH,175
02500		CAIN CH,141
02600		JRST GO
02700		JRST CD
02800	
02900	
03000	;CD9(↑)
03100	;↑ MEANS THAT THE NEXT CHARACTER IS A CONTROL CHARACTER.
03200	
03300	UAR:	PUSHJ P,SKRCH		;GET NEXT COMMAND CHARACTER.
03400		TRZ CH,100		;CHANGE IT TO CONTROL CHARACTER
03500		JRST CD9		;DISPATCH
03600	
03700	
03800	
03900	;CD9(↑G)
04000	;FINISH OUTPUT AND RETURN TO THE TIME-SHARING EXEC.
04100	
04200	DECDMP:	CALLI EXIT
04300	
     

00100	;CD9(,)
00200	;IF A COMMAND TAKES TWO NUMERIC ARGUMENTS, COMMA IS USED TO SEPARATE THEM
00300	
00400	COMMA:	MOVEM B,SARG(R)		;SAVE CURRENT ARGUMENT IN SARG.
00500		TRZE FF,ARG		;WAS THERE A CURRENT ARGUMENT?
00600		TROE FF,ARG2		;YES. WAS THERE ALREADY A SECOND ARGUMENT?
00700		JSR ERR			;NO. EITHER NO ARGUMENT OR MORE THAN TWO ARGUMENTS.
00800		JRST CD1		;YES. CLEAR CURRENT ARGUMENT.
00900	
01000	;CD9(&)
01100	;LOGICAL AND
01200	
01300	CAND:	MOVSI A,404000+B*40+R		;DLIM:=AND B,(R)
01400		JRST CD3
01500	
01600	;CD9(#)
01700	;LOGICAL OR
01800	
01900	COR:	MOVSI A,43400+B*40+R		;DLIM:=OR B,(R)
02000		JRST CD3
02100	
02200	;CD9(-)
02300	;SUBTRACT TAKES ONE OR TWO ARGUMENTS
02400	
02500	MINUS:	MOVSI A,274000+B*40+R		;DLIM:=SUB B,(R)
02600		JRST CD3
02700	
02800	;CD9(*)
02900	;MULTIPLY TAKES TWO ARGUMENTS
03000	
03100	TIMES:	MOVSI A,220000+B*40+R		;DLIM:=IMUL B,(R)
03200		JRST CD3
03300	
03400	;CD9(/)
03500	;DIVIDE (TRUNCATES) TAKES TWO ARGUMENTS
03600	
03700	SLASH:	MOVSI A,230000+B*40+R		;DLIM:=IDIV B,(R)
03800		JRST CD3
03900	
     

00100	;CD9(B)
00200	;RETURNS THE NUMERIC VALUE 0.
00300	
00400	BEGIN:	MOVEI A,0
00500		JRST VALRET
00600	
00700	
00800	;CD9(H)
00900	;AN ABBREVIATION FOR B,Z
01000	
01100	HOLE:	SETZM  SARG(R)		;SET SECOND ARGUMENT TO 0.
01200		TROA FF,ARG2
01300	
01400	;CD9(.)
01500	;.=NUMBER OF CHARACTERS TO THE LEFT OF THE POINTER
01600	
01700	PNT:	SKIPA A,PT(R)
01800	
01900	;CD9(Z)
02000	;Z=NUMBER OF CHARACTERS IN THE BUFFER
02100	
02200	END1:	MOVE A,Z(R)
02300		SUB A,BEG(R)
02400		JRST VALRET
02500	
02600	;CD9(()
02700	;() MAY BE USED TO OVERRIDE LEFT TO RIGHT OPERATOR SCAN FOR +,-,*,/,& AND #.
02800	
02900	OPEN:	PUSH P,NUM(R)		;PUSH CURRENT ARGUMENT.
03000		HLLZ A,DLIM(R)		;GET CURRENT OPERATOR.
03100		TRZE FF,ITERF		;ARE WE INSIDE AN ITERATION?
03200		IORI A,1		;YES. MARK OPERATOR AS BEING WITHIN AN ITERATION.
03300		PUSH P,A		;PUSH CURRENT OPERATOR.
03400		AOS LEV(R)		;INCREMENT ( LEVEL.
03500		JRST RET
03600	
03700	;CD9())
03800	CLOSE:	SOSGE LEV(R)		;IS THERE A (?
03900		JSR ERR			;NO.
04000		MOVEM B,SYL(R)		;YES. SAVE CURRENT ARGUMENT.
04100		POP P,CH		;RESTORE OPERATOR.
04200		HLLM CH,DLIM(R)
04300		TRZ FF,ITERF
04400		TRNE CH,1
04500		TRO FF,ITERF		;RESTORE ITERATION FLAG FOR THIS OPERATOR.
04600		POP P,NUM(R)		;RESTORE ARGUMENT.
04700		JRST CD7
04800	
04900	
05000	
05100	
05200	U LEV,1				;GO1(0),OPEN+5,CLOSE
     

00100	;CD9(=)
00200	;N=	CAUSES THE VALUE OF N TO BE TYPED OUT.
00300	
00400	PRNT:	TRNN FF,ARG		;HERE ON "=" COMMAND
00500		JSR ERR			;MUST HAVE ARG
00600		MOVEI A,TYO
00700		HRRM A,LISTF5(R)	;CONSOLE
00800		PUSHJ P,DPT
00900		JRST CRR		;CRLF AND RETURN TO CALLER
01000	
01100	
01200	
01300	;CD9(↑T)
01400	;CAUSES COMMAND INTERPRETATION TO STOP UNTIL THE USER TYPES A CHARACTER
01500	;ON THE TELETYPE AND THEN HAS THE ASCII VALUE OF THE CHARACTER TYPED IN.
01600	
01700	
01800	SPTYI:	PUSHJ P,TYI
01900		SKIPA A,CH
02000	
02100	
02200	;CD9(↑H)
02300	;HAS THE VALUE OF ELAPSED TIME, IN 60THS OF A SECOND, SINCE MIDNITE.
02400	
02500	GTIME:	CALLI A,TIMER
02600		JRST VALRET
02700	
02800	
02900	;CD9(↑F)
03000	;HAS THE VALUE OF THE CONSOLE DATA SWITCHES.
03100	
03200	LAT:	CALLI A,SWITCH
03300		JRST VALRET
03400	
03500	
03600	
03700	;CD9(↑↑)
03800	;HAS THE VALUE OF THE NEXT CHARACTER IN THE COMMAND STRING.
03900	
04000	CNTRUP:	PUSHJ P,RCH	;↑↑ HAS VALUE OF CHAR FOLLOWING IT
04100		MOVE A,CH
04200		JRST VALRET
04300	
04400	
04500	
     

00100	;CD9(BACKSLASH)
00200	;HAS THE VALUE OF THE NUMBER REPRESENTED BY THE DIGITS (OR MINUS SIGN)
00300	;FOLLOWING THE POINTER IN THE BUFFER.  THE SCAN TERMINATES ON ANY OTHER
00400	;CHARACTER.  THE POINTER IS MOVED OVER THE NUMBER FOUND (IF ANY).
00500	
00600	
00700	BAKSL:	TRZE FF,ARG	;WHICH KIND OF BACKSLASH?
00800		JRST BAKSL1	;ARG TO MEMORY
00900		MOVE IN,PT(R)	;MEMORY TO VALRET
01000	BAKSLA:	CAML IN,Z(R)	;OVERDID IT ?
01100		JRST BAKSL3	;YES. EXIT
01200		PUSHJ P,GETINC	;NO. GET A CHAR
01300		CAIN CH,"-"	;MINUS SIGN?
01400		JRST BAKSLM	;YES. GO MARK IT.
01500		CAIG CH,"9"	;DIGIT?
01600		CAIGE CH,"0"	;DIGIT?
01700		SOJA IN,BAKSL2	;NOT A DIGIT. BACKUP AND LEAVE LOOP
01800		SUBI CH,"0"	;CONVERT TO NUMBER
01900		EXCH CH,SYL(R)
02000		IMULI CH,12
02100		ADDM CH,SYL(R)	;SYL:= 10.*SYL+CH
02200		JRST BAKSLA	;LOOP
02300	
02400	BAKSL3:	MOVE IN,Z(R)	;HERE ON OVERFLOW
02500	BAKSL2:	TRZE FF,ARG	;MINUS SIGN SEEN?
02600		MOVNS SYL(R)	;YES. NEGATE
02700		MOVEM IN,PT(R)	;MOVE POINTER PAST #
02800		JRST CD7	;DONE
02900	
03000	
03100	BAKSLM:	TRO FF,ARG
03200		JRST BAKSLA
03300	
03400	
03500	
03600	
03700	;CD9(A)
03800	;NA (WHERE N IS A NUMERIC ARGUMENT) = VALUE IN 7-BIT ASCII OF THE
03900	;CHARACTER TO THE RIGHT OF THE POINTER.
04000	
04100	ACMD:	TRNN FF,ARG		;DOES AN ARGUMENT PRECEED A?
04200		JRST APPEND		;NO. THIS IN AN APPEND COMMAND.
04300		MOVE IN,PT(R)		;YES.
04400		PUSHJ P,GET		;CH:=CHARACTER TO THE RIGHT OF PT.
04500		MOVE A,CH		;RETURN CH AS VALUE.
04600	APPND2:	SETZM  NUM(R)
04700		JRST VALRET
     

00100	REPEAT 0,<
00200	
00300	V.	USE OF Q-REGISTERS
00400	
00500	NUI	PUTS THE NUMERIC VALUE N IN Q-REGISTER NAMED I (WHERE I IS
00600			A CHARACTER 0,1,...,9,A,B,...,Z.)
00700	QI	HAS THE VALUE OF THE LATEST QUANTITY PUT INTO Q-REGISTER I.
00800	%I	ADDS 1 TO THE QUANTITY IN Q-REGISTER I AND STANDS FOR THE NEW VALUE.
00900	M,NXI	COPIES A PORTION OF THE BUFFER INTO Q-REGISTER I.  IT SETS
01000		Q-REGISTER I TO A DUPLICATE OF THE (M+1)TH THROUGH NTH CHARACTERS
01100		IN THE BUFFER.  THE BUFFER IS UNCHANGED.  (FOR EXAMPLE:  HXA
01200		PUTS A REPLICA OF THE ENTIRE BUFFER INTO Q-REGISTER A.)
01300	NXI	INTO Q-REGISTER I IS COPIED THE STRING OF CHARACTERS STARTING
01400		IMMEDIATELY TO THE RIGHT OF THE POINTER AND PROCEEDING THROUGH
01500		THE NTH LINE FEED.
01600	GI	THE TEXT IN Q-REGISTER I IS INSERTED INTO THE BUFFER AT THE CURRENT
01700		LOCATION OF THE POINTER.  THE POINTER IS THEN PUT JUST TO THE RIGHT
01800		OF THE INSERTION.  THE Q-REGISTER IS NOT CHANGED.
01900	[I	PUSHES Q-REGISTER I ONTO THE Q-REGISTER PUSHDOWN LIST.
02000	]I	POPS Q-REGISTER I OFF THE Q-REGISTER PUSHDOWN LIST.  THE
02100		Q-REGISTER PUSHDOWN LIST IS CLEARED EACH TIME $$ IS TYPED.
02200	
02300		IT DOES NOT MAKE SENSE TO TECO TO "G" A Q-REGISTER GIVEN A
02400	NUMBER BY "U" NOR TO "Q" OR "%" ONE GIVEN TEXT BY "X".
02500	>
02600	;CD9(U)
02700	;NUI	PUTS THE NUMERIC VALUE N IN Q-REGISTER I.
02800	
02900	USE:	TRNN FF,ARG		;DID AN ARGUMENT PRECEED U?
03000		JSR ERR			;NO.
03100	
03200	;FROM X2+4
03300	
03400	USEA:	PUSHJ P,QREGVI		;YES. CH:=Q-REGISTER INDEX.
03500		MOVEM B,QTAB-"0"(CH)	;STORE ARGUMENT IN SELECTED Q-REG.
03600		JRST RET
03700	
03800	;CD9(Q)
03900	;QI	HAS THE VALUE OF THE LATEST QUANTITY PUT INTO Q-REGISTER I.
04000	
04100	QREG:	PUSH P,USE1		;SET RETURN ADDRESS TO VALRET AND FALL INTO QREGVI.
04200	
04300	;ROUTINE TO RETURN Q-REGISTER INDEX IN CH AND CONTENT IN A.
04400	;CALL	PUSHJ P,QREGVI
04500	;	RETURN
04600	;ASSUMES COMCNT,CPTR AND COMAX ARE SET UP.
04700	;IF NEXT CHARACTER IN COMMAND STRING IS NOT A LETTER OR A DIGIT, DOES NOT RETURN.
04800	;FROM USEA,PCNT,OPENB+1,MAC,QGET
04900	
05000	QREGVI:	PUSHJ P,RCH		;CH:=NEXT COMMAND STRING CHARACTER.
05100		CAIL CH,"0"		;LETTER OR DIGIT?
05200		CAILE CH,"Z"
05300		JSR ERR			;NO
05400		CAIL CH,1+"9"		;YES. DIGIT?
05500		SUBI CH,"A"-"9"-1	;NO. TRANSLATE LETTERS DOWN BY NUMBER OF
05600					;CHARACTERS BETWEEN 9 AND A. ONLY 36 Q REG'S
05700		MOVE A,QTAB-"0"(CH)	;A:=CONTENTS OF Q-REGISTER.
05800	USE1:	POPJ P,VALRET
05900	
06000	
06100	;CD9(%)
06200	;%I	ADDS 1 TO THE QUANTITY IN Q-REGISTER I AND STANDS FOR THE
06300	;	NEW VALUE
06400	
06500	PCNT:	PUSHJ P,QREGVI		;CH:=Q-REGISTER INDEX.
06600		AOS A,QTAB-"0"(CH)	;INCREMENT Q-REG.
06700		JRST VALRET		;RETURN NEW VALUE.
06800	
     

00100	;CD9(X)
00200	;M,NXI	COPIES A PORTION OF THE BUFFER INTO Q-REGISTER I.
00300	;	IT SETS Q-REGISTER I TO A DUPLICATE OF THE (M+1)TH
00400	;	THROUGH NTH CHARACTERS IN THE BUFFER.  THE BUFFER IS UNCHANGED.
00500	;NXI	INTO Q-REGISTER I IS COPIED THE STRING OF CHARACTERS STARTING
00600	;	IMMEDIATELY TO THE RIGHT OF THE POINTER AND PROCEEDING THROUGH
00700	;	THE NTH LINE FEED.
00800	
00900	X:	PUSHJ P,GETARG		;C:=FIRST STRING ARGUMENT ADDRESS
01000					;B:=SECOND STRING ARGUMENT ADDRESS.
01100		CAMLE C,B		;IS SECOND ARG. ADDR. > FIRST ARG. ADDR.?
01200		JSR ERR			;NO.
01300		EXCH B,C		;YES.
01400		SUBI C,-3(B)		;C:=LENGTH OF STRING+3.
01500		ADD B,C			;B:=FIRST ARG ADDR + LENGTH OF STRING + 3
01600		PUSH P,PT(R)
01700		ADDM C,(P)		;(P):=PT + LENGTH OF STRING + 3.
01800		MOVE D,BEG(R)
01900		MOVEM D,PT(R)		;PT:=BEG
02000		PUSHJ P,NROOM		;INSERT STRING AT BEG
02100		MOVE OUT,RREL(R)	;RREL CONTAINS RELOCATION CONSTANT IF
02200					;GARBAGE COL. OCCURRED.
02300		ADDM OUT,(P)		;RELOCATE TOP OF STRING POINTER.
02400		ADD B,OUT		;B:=FIRST ARG ADDR + LENGTH OF STRING + 3 + RREL
02500		MOVE OUT,BEG(R)		;OUT:=ADDRESS OF Q-REG BUFFER
02600		ADDM C,BEG(R)		;BEG:=C(BEG)+LENGTH OF STRING + 3
02700		MOVEI CH,141		;FIRST CHARACTER OF BUFFER := 141
02800		PUSHJ P,PUT
02900		AOS OUT
03000		MOVE CH,C		;SECOND CHAR OF BUFFER :=LEAST SIGNIFICANT 7 BITS
03100					;OF LENGTH OF STRING + 3
03200		PUSHJ P,PUT
03300		ROT CH,-7
03400		MOVE IN,B		;THIRD CHAR OF BUFFER := MOST SIGNIFICANT 7 BITS
03500					;OF LENGTH OF STRING + 3
03600		AOS OUT
03700	X1:	PUSHJ P,PUT		;MOVE STRING TO Q-REG BUFFER.
03800		AOS OUT
03900		CAIN C,3
04000		JRST X2
04100		PUSHJ P,GETINC
04200		SOJA C,X1
04300	X2:	MOVE B,PT(R)		;QTAB ENTRY :=XWD 400000,Q-REG BUFFER
04400					;ADDRESS RELATIVE TO C(QRBUF)
04500		SUB B,QRBUF(R)
04600		TLO B,400000
04700		POP P,PT(R)		;MOVE PT PAST STRING.
04800		JRST USEA		;MAKE QTAB ENTRY.
04900	
     

00100	;CD9(G)
00200	;GI	THE TEXT IN Q-REGISTER I IS INSERTED INTO THE BUFFER AT THE
00300	;	CURRENT LOCATION OF THE POINTER.  THE POINTER IS THEN PUT JUST
00400	;	TO THE RIGHT OF THE INSERTION.  THE Q-REGISTER IS NOT CHANGED.
00500	
00600	QGET:	PUSHJ P,QREGVI		;A:=QTAB ENTRY, CH:=Q-REG INDEX
00700		MOVE B,A
00800		TLZN B,377777		;DOES Q-REG CONTAIN TEXT?
00900		TLZN B,400000
01000		JSR ERR			;NO
01100		ADD B,QRBUF(R)		;YES
01200		MOVE IN,B		;IN:=Q-REG BUFFER ADDRESS
01300		MOVE B,CH		;SAVE INDEX
01400		PUSHJ P,GETINC		;IS FIRST CHARACTER IN BUFFER 141?
01500		CAIE CH,141
01600		JSR ERR			;NO
01700		PUSHJ P,GETINC		;C:=LENGTH OF STRING
01800		MOVEM CH,C
01900		PUSHJ P,GETINC
02000		ROT CH,7
02100		IORM CH,C
02200		SUBI C,3
02300		PUSHJ P,NROOM		;MOVE FROM PT THROUGH Z UP C POSITIONS
02400		MOVE OUT,PT(R)
02500		HRRZ IN,QTAB-"0"(B)
02600		ADD IN,QRBUF(R)
02700		ADDI IN,3
02800	QGET1:	JUMPE C,RET		;MOVE STRING INTO DATA BUFFER
02900		PUSHJ P,GETINC
03000		PUSHJ P,PUT
03100		AOS OUT,PT(R)
03200		SOJA C,QGET1
03300	
     

00100	;CD9(])
00200	;]I	POPS Q-REGISTER I OFF THE Q-REGISTER PUSHDOWN LIST.
00300	;	THE Q-REGISTER PUSHDOWN LIST IS CLEARED EACH TIME $$ IS TYPED.
00400	
00500	CLOSEB:	SKIPA C,[POP PF,]
00600	
00700	;CD9([)
00800	;[I	PUSHES Q-REGISTER I ONTO THE Q-REGISTER PUSHDOWN LIST.
00900	
01000	OPENB:	MOVSI C,261000+PF*40+R
01100		PUSHJ P,QREGVI
01200		HRRI C,QTAB-"0"(CH)	;C:=Q-REGISTER INDEX.
01300		XCT C			;PUSH OR POP Q-REGISTER.
01400		TRNE FF,ARG		;IS THERE AN ARGUMENT?
01500		JRST CD2		;YES. DON'T DESTROY IT.
01600		JRST RET		;NO. CLEAR FLAGS.
01700	
     

00100	REPEAT 0,<
00200	
00300	VI	INPUT-OUTPUT SELECTION
00400	
00500	ERDEV:NAME.EXT[PROJNO,PROGNO]$
00600		SELECTS THE INPUT DEVICE, WHERE
00700		DEV:	IS THE DEVICE NAME, SUCH AS DTA6 OR PTR
00800		NAME:	IS THE NAME (IF ANY) OF THE FILE
00900		EXT	IS THE FILE NAME EXTENSION (IF ANY)
01000		PROJNO,PROGNO ARE THE PROJECT AND PROGRAMMER NUMBERS
01100			ASSOCIATED WITH THE FILE IN A SYSTEM WITH A DISC.
01200	EWDEV:NAME.EXT[PROJNO,PROGNO]$
01300		SELECTS THE OUTPUT DEVICE AND OPENS THE FILE SPECIFIED (IF ANY).
01400	EZDEV:NAME.EXT[PROJNO,PROGNO]$
01500		SELECTS THE OUTPUT DEVICE, ISSUES A REWIND COMMAND TO IT,
01600		ISSUES A COMMAND TO ZERO ITS DIRECTORY, AND OPENS THE
01700		FILE SPECIFIED (IF ANY).
01800	EF	FINISHES OUTPUT ON THE CURRENT OUTPUT FILE WITHOUT
01900		SELECTING A NEW OUTPUT FILE.
02000	
02100	EM	REWINDS THE CURRENTLY SELECTED INPUT DEVICE.
02200	NEM	EXECUTES THE MTAPE UUO ON THE CURRENTLY SELECTED INPUT DEVICE
02300		USING N AS THE ADDRESS FIELD OF THE MTAPE.  NOTE THAT N, AS
02400		USUAL, IS A DECIMAL NUMBER.
02500	>;CD9(E)
02600	;E COMMANDS SELECT AND CONTROL FILE INPUT-OUTPUT MEDIA
02700	
02800	ECMD:	PUSHJ P,RCH
02900		CAIN CH,"R"		;NO. ER?
03000		JRST OPNRD		;YES. NEW INPUT FILE.
03100		CAIN CH,"W"		;NO. EW?
03200		JRST OPNWR		;YES. NEW OUTPUT FILE.
03300		CAIN CH,"F"		;NO. EF?
03400		JRST CLOSEF		;YES. CLOSE OUTPUT FILE.
03500		CAIN CH,"Z"		;NO. EZ?
03600		JRST ZERDIR		;YES. CLEAR DIRECTORY.
03700		CAIN CH,"M"		;NO. EM?
03800		JRST EMTAPE		;YES. EXECUTE MTAPE UUO.
03900		JSR ERR			;NO. COMMAND ERROR.
04000	
04100	
04200	
04300	
04400	
04500	
04600	
04700	
04800	U FILDEV,1	;FILSPC+1(0),FILSP1+1	
04900	U FILNAM,4	;NAME IN SIXBIT.  FILSPC+2(0),FILLS1+5
05000			;(EXT)BLK #.  FILSPC+3(0),FILLS1+2
05100			;PROT,DATE.  FILSPC+4(0)
05200			;(PROJ)PROG.  FILSPC+5(0),FILSPS,FILSP6
05300	
     

00100	;ER	PREPARE TO READ FILE
00200	;FROM ECMD+4
00300	
00400	OPNRD:	TLOE FF,UREAD		;SET INPUT FILE OPEN FLAG. WAS IT ON?
00500		RELEAS INCHN,0		;YES. RELEASE IT BEFORE OPENING NEW FILE.
00600		PUSHJ P,FILSPC		;GET FILE SPEC
00700		MOVEI E,1
00800		MOVEM E,OPNRI(R)
00900		MOVE E,FILDEV(R)	;INITIALIZE OPEN UUO ARGUMENTS
01000		MOVEM E,OPNR1(R)
01100		MOVEI E,INBUF
01200		MOVEM E,OPNRB(R)
01300		OPEN INCHN,OPNRI(R)	;OPEN INPUT FILE
01400		JRST ININER
01500		MOVE E,[SETZ IBUF1+1(R)]
01600		MOVEM E,INBUF(R)
01700		MOVSI E,440700
01800		MOVEM E,INBUF+1(R)
01900		MOVE T,JOBFF(R)
02000		MOVEI E,IBUF1
02100		MOVEM E,JOBFF(R)
02200		INBUF INCHN,2
02300		MOVEM T,JOBFF(R)
02400		SETZM INBUF+2(R)
02500		LOOKUP INCHN,FILNAM(R)
02600		JRST LKUPER
02700		POPJ P,
02800	
02900	
03000	U OPNRI,1		;INPUT FILE OPEN ARGUMENTS. OPNRD+4(1)
03100	U OPNR1,1		;INPUT DEVICE.  INIT+27(0),OPNRD+6
03200	U OPNRB,1		;INITIALIZE TO XWD 0,INBUF. OPNRD+10
     

00100	
00200	;FROM OPNRD+10,OPNW1+10
00300	
00400	ININER:	JSP A,ERRMES
00500		ASCIZ /DEVICE /
00600		MOVE A,FILDEV(R)
00700		PUSHJ P,SIXBMS
00800		JSP A,CONMES
00900		ASCIZ / NOT AVAILABLE
01000	/
01100		JSR ERR
01200	
01300	
01400	
01500	;FROM OPNRD+24
01600	
01700	LKUPER:	JSP A,ERRMES
01800		ASCIZ /FILE /
01900		MOVE A,FILNAM(R)
02000		PUSHJ P,SIXBMS
02100		HLLZ A,FILNAM+1(R)
02200		JUMPE A,LKUPE1
02300		MOVEI CH,"."
02400		PUSHJ P,TYO
02500		PUSHJ P,SIXBMS
02600	LKUPE1:	JSP A,CONMES
02700		ASCIZ / NOT FOUND
02800	/
02900		JSR ERR
03000	
     

00100	;EW	SELECTS THE OUTPUT DEVICE AND OPENS THE FILE SPECIFIED (IF ANY)
00200	;FROM ECMD+6
00300	
00400	OPNWR:	PUSHJ P,OPNW1
00500	
00600	;FROM ZERDIR+3
00700	
00800	OPNW2:	ENTER OUTCHN,FILNAM(R)
00900		JRST ENTERR
01000		POPJ P,
01100	
01200	
01300	;FROM OPNWR,ZERDIR
01400	
01500	OPNW1:	TLOE FF,UWRITE
01600		RELEAS OUTCHN,0
01700		PUSHJ P,FILSPC
01800		MOVEI E,1
01900		MOVEM E,OPNWI(R)
02000		MOVE E,FILDEV(R)
02100		MOVEM E,OPNWD(R)
02200		HRLZI E,OUTBUF
02300		MOVEM E,OPNWB(R)
02400		OPEN OUTCHN,OPNWI(R)
02500		JRST ININERR
02600		MOVE E,[SETZ OBUF1+1(R)]
02700		MOVEM E,OUTBUF(R)
02800		MOVSI E,440700
02900		MOVEM E,OUTBUF+1(R)
03000		MOVE T,JOBFF(R)
03100		MOVEI E,OBUF1
03200		MOVEM E,JOBFF(R)
03300		OUTBUF OUTCHN,2
03400		MOVEM T,JOBFF(R)
03500		SETZM OUTBUF+2(R)
03600		POPJ P,0
03700	
03800	U OPNWI,1		;OUTPUT FILE OPEN ARGUMENTS. OPNW1+4(1)
03900	U OPNWD,1		;OUTPUT DEVICE.  OPNW1+6
04000	U OPNWB,1		;OUTBUT BUFFER HEADER ADDRESS. OPNW1+10(OUTBUF)
04100	
04200	
04300	
     

00100	;FROM OPNW2+1
00200	
00300	ENTERR:	JSP A,ERRMES
00400		ASCIZ /DIRECTORY FULL ON OUTPUT
00500	/
00600		JSR ERR
00700	
00800	
00900	
01000	;EZ	SELECTS THE OUTPUT DEVICE, ISSUES A REWIND COMMAND TO IT,
01100	;	ISSUES A COMMAND TO ZERO ITS DIRECTORY, AND OPENS THE FILE
01200	;	SPECIFIED (IF ANY).
01300	;FROM ECMD+12
01400	
01500	ZERDIR:	PUSHJ P,OPNW1		;DETERMINE OUTPUT DEVICE
01600		CALLI OUTCHN, UTPCLR	;CLEAR DIRECTORY OF OUTPUT DEVICE
01700		MTAPE OUTCHN,1		;REWIND OUTPUT DEVICE
01800		JRST OPNW2		;ENTER FILE
01900	
02000	
02100	
02200	
02300	;EF	FINISHES OUTPUT ON THE CURRENT OUTPUT FILE WITHOUT
02400	;	SELECTING A NEW OUTPUT FILE.
02500	;FROM ECMD+10
02600	
02700	CLOSEF:	TLZN FF,UWRITE
02800		POPJ P,
02900		CLOSE OUTCHN,2
03000		STATZ OUTCHN,740000
03100		JRST OUTERR
03200		RELEAS OUTCHN,0
03300		POPJ P,
03400	
03500	
03600	
03700	
03800	
03900	
04000	;EM	EXECUTE MTAPE UUO.
04100	;FROM ECMD+14
04200	
04300	EMTAPE:	TLNN FF,UREAD
04400		JSR ERR
04500		PUSHJ P,CHK2
04600		CAIGE B,20
04700		CAIGE B,1
04800		JSR ERR
04900		MTAPE INCHN,0(B)
05000		POPJ P,
05100	
     

00100	
00200	;ROUTINE TO PARSE FILE DESIGNATOR
00300	;FROM OPNRD+2,OPNW1+2,LSTDIR
00400	
00500	FILSPC:	TLZ FF,FILWD
00600		MOVSI E,'DSK'
00700		MOVEM E,FILDEV(R)
00800		HLLZS FILNAM+1(R)
00900		SETZM FILNAM+2(R)
01000		SETZB E,FILNAM+3(R)
01100	
01200	;FROM FILSPL+21,FILSP1+3,FILSP3+3,FILSP6+1
01300	FILSPL:	PUSHJ P,SKRCH		;GET NEXT COMMAND CHARACTER. ERROR IF COMMAND BUFFER EMPTY.
01400		CAIN CH,175
01500		JRST FILSP2		;ALT MODE
01600		CAIN CH,":"
01700		JRST FILSP1		;DEVICE
01800		CAIN CH,"."
01900		JRST FILSP3		;EXTENSION MARK
02000		CAIN CH,"["
02100		JRST FILSP4		;PROJ PROG PAIR
02200		PUSHJ P,DQT2		;LETTER OR DIGIT?
02300		TRZA B,777700		;YES. DQT2 LEAVES CHARACTER IN B AND CH.
02400		JSR ERR			;NO
02500		TRC B,40		;CONVERT TO SIXBIT.
02600		ROT B,-6
02700		TLNN E,770000		;SIX CHARACTERS YET?
02800		ROTC B,6		;NO. PACK IT INTO E
02900		TLO FF,FILWD		;YES.
03000		JRST FILSPL
03100	
03200	;END OF DESIGNATOR.  STORE FILE NAME OR EXTENSION AND RETURN
03300	
03400	FILSP2:
03500	
03600	;ROUTINE TO LEFT JUSTIFY E AND STORE IN FILE NAME OR FILE EXTENSION.
03700	;CALL	MOVE E,SIXBIT NAME RIGHT JUSTIFIED
03800	;	SET FILWD OR FEXTF FLAG
03900	;	PUSHJ P,FILLSH
04000	;	RETURN
04100	;FROM FILSP1,FILSP3,FILSP4
04200	
04300	FILLSH:	SKIPE E			;NULL NAME?
04400		TLNE E,770000		;NO. LEFT JUSTIFIED?
04500		JRST FILLS1		;YES.
04600		LSH E,6			;NO.
04700		JRST .-3
04800	FILLS1:	TLZN FF,FEXTF		;EXTENSION?
04900		JRST .+3		;NO.
05000		HLLZM E,FILNAM+1(R)	;YES. STORE IT.
05100		TLZ FF,FILWD
05200		TLZE FF,FILWD		;FILE NAME?
05300		MOVEM E,FILNAM(R)	;YES. STORE IT.
05400		POPJ P,0		;NO. RETURN.
05500	
     

00100	;DEVICE NAME
00200	
00300	FILSP1:	PUSHJ P,FILLSH		;LEFT JUSTIFY IT.
00400		MOVEM E,FILDEV(R)
00500	FILS1A:	MOVEI E,0
00600		JRST FILSPL
00700	
00800	;FILE NAME EXTENSION FOLLOWS
00900	
01000	FILSP3:	PUSHJ P,FILLSH		;STORE FILE NAME.
01100		TLO FF,FEXTF		;GET EXTENSION.
01200		JRST FILS1A
01300	
01400	;PROJECT-PROGRAMMER PAIR
01500	
01600	FILSP4:	PUSHJ P,FILLSH		;STORE NAME OR EXTENSION.
01700		MOVEI B,","		;SCAN FOR ,
01800		PUSHJ P,FILSPP
01900	FILSP5:	HRLZM E,FILNAM+3(R)	;STORE PROJECT NUMBER.
02000		MOVEI B,"]"		;SCAN FOR ]
02100		PUSHJ P,FILSPP
02200	FILSP6:	HRRM E,FILNAM+3(R)
02300		JRST FILSPL
02400	
02500	FILSPP:	MOVEI E,0
02600	FILS4L:	PUSHJ P,SKRCH		;GET NEXT COMMAND CHARACTER.
02700		CAIN CH,(B)		;DELIMITER?
02800		POPJ P,		;YES
02900		TRNE E,770000
03000		JRST FILS4L
03100		LSH E,6
03200		ADDI E,-40(CH)
03300		JRST FILS4L
     

00100	REPEAT 0,<
00200	
00300	VII.	INPUT COMMANDS
00400	
00500	Y	RENDER THE BUFFER EMPTY.  READ INTO THE BUFFER UNTIL
00600		(A) A FORM FEED CHARACTER IS READ, OR
00700		(B) THE BUFFER IS WITHIN 128 CHARACTERS OF CAPACITY AND A LINE-FEED IS READ, OR
00800		(C) AND END OF FILE IS READ OR
00900		(D) THE BUFFER IS COMPLETELY FULL.
01000		THE FORM FEED (IF PRESENT) DOES NOT ENTER THE BUFFER.
01100	A	APPEND TO THE END OF THE BUFFER FROM THE SELECTED INPUT
01200		TERMINATING THE READ IN THE SAME MANNER AS Y.  THE POINTER
01300		IS NOT MOVED BY A.
01400	ITEXT$	INSERT, AT THE CURRENT POINTER LOCATION, THE TEXT FOLLOWING
01500		THE I UP TO BUT NOT INCLUDING THE FIRST ALT. MODE.
01600		THE POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
01700	N\	INSERT AT THE CURRENT POINTER LOCATION THE ASCII NUMBERS
01800		EQUAL TO N.  FOR EXAMPLE, 69\ IS EQUIVALENT TO I69$.  THE
01900		POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
02000	↑ITEXT$		INSERTS AT THE CURRENT POINTER LOCATION THE ↑I (TAB) AND THE
02100		TEXT FOLLOWING THE ↑I UP TO BUT NOT INCLUDING THE
02200		ALT MODE.  THE POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
02300	@IJTEXTJ	INSERT, AT THE CURRENT POINTER POSITION, THE TEXT
02400		SURROUNDED BY THE INSTANCES OF THE TERMINATOR J, WHICH MAY BE AT
02500		THE USER'S CHOICE ANY CHARACTER NOT APPEARING IN THE TEXT.  THE
02600		POINTER IS PUT TO THE RIGHT OF THE INSERTION.
02700	NI	INSERT AT THE POINTER A CHARACTER WHOSE 7-BIT ASCII CODE IN N
02800		(BASE 10).  THE POINTER IS MOVED TO THE RIGHT OF THE NEW CHARACTER.
02900	>
     

00100	;CD9(Y)
00200	;Y	RENDER THE BUFFER EMPTY.  READ INTO THE BUFFER UNTIL
00300	;	(A)  A FORM FEED CHARACTER IS READ, OR
00400	;	(B)  THE BUFFER IS WITHIN 128 CHARACTERS OF CAPACITY AND A LINE FEED IS READ, OR
00500	;	(C)  AN END OF FILE IS READ, OR
00600	;	(D)  THE BUFFER IS COMPLETELY FULL.
00700	;THE FORM FEED (IF PRESENT) DOES NOT ENTER THE BUFFER.
00800	
00900	YANK:
01000	
01100	;FROM NOFND1+7,PUN1+3
01200	
01300	YANK1:	MOVE OUT,BEG(R)
01400		MOVEM OUT,PT(R)		;PT:=BEG
01500	
01600	;FROM APPEND+3
01700	
01800	YANK2:
01900	YANK3:	TLNN FF,UREAD		;HAS AN INPUT FILE BEEN SPECIFIED?
02000		JRST YANK09		;NO.
02100		SOSLE INBUF+2(R)	;YES. IS DEVICE BUFFER EMPTY?
02200		JRST YANK5		;NO.
02300		INPUT INCHN,0		;YES. FILL IT.
02400		STATZ INCHN,740000	;ERROR?
02500		JRST INERR		;YES.
02600		STATO INCHN,20000	;NO. END OF FILE?
02700		JRST YANK5		;NO.
02800		TLZ FF,UREAD		;YES. DE-SELECT INPUT FILE.
02900		TRO FF,FINF
03000		JRST YANK51		;CLEAR BUFFER AND RETURN.
03100	YANK5:	ILDB CH,INBUF+1(R)	;CH:=NEXT CHARACTER.
03200		JUMPE CH,YANK3		;IF NULL, IGNORE IT.
03300		MOVE T,@INBUF+1(R)
03400		TRNE T,1		;SEQUENCE NUMBER?
03500		JRST YNKSEQ		;YES. IGNORE THEM.
03600		PUSHJ P,PUT		;NO. PUT CHARACTER IN DATA BUFFER.
03700		CAIE CH,14		;FORM FEED?
03800		AOJA OUT,YANK4		;NO. UPDATE DATA BUFFER POINTER AND CHECK FOR OVERFLOW.
03900	YANK51:	MOVEM OUT,Z(R)		;YES. SET END OF DATA BUFFER AND RETURN
04000		POPJ P,0
04100	YANK09:	SKIPE OPNR1(R)		;INPUT DEVICE SPECIFIED?
04200		JRST YANK51		;YES. CLEAR BUFFER.
04300		JSP A,ERRMES		;NO.
04400		ASCIZ /NO FILE FOR INPUT
04500	/
04600		JSR ERR
04700	
04800	
04900	YNKSEQ:	MOVNI T,5		;IGNORE SEQ. NO. AND FOLLOWING TAB
05000		ADDM T,INBUF+2(R)	;DECREASE CHAR COUNT BY 5
05100		AOS	INBUF+1(R)	;INCREMENT POINTER OVER SEQ. NO., & TAB
05200		JRST YANK3
     

00100	;FROM YANK3+6
00200	
00300	INERR:	JSP A,ERRMES
00400		ASCIZ /ERROR ON INPUT DEVICE
00500	/
00600		JSR ERR
00700	
00800	;FROM YANK5+11
00900	
01000	YANK4:	MOVE T,MEMSIZ(R)
01100		CAIL T,200(<OUT>)		;WITHIN 128 CHARACTERS FROM TOP OF MEMORY?
01200		JRST YANK3		;NO. GET MORE.
01300		CAILE T,0(<OUT>)		;YES. FULL?
01400		CAIN CH,12		;NO. LINE FEED?
01500		JRST YANK51		;YES. THAT'S ALL.
01600		JRST YANK3		;NO. GET MORE.
01700	
01800	
01900	
02000	;A   APPEND TO THE END OF THE BUFFER FROM THE SELECTED INPUT
02100	;	TERMINATING THE READ IN THE SAME MANNER AS Y.  THE POINTER
02200	;	IS NOT MOVED BY A.
02300	
02400	APPEND:	MOVE OUT,Z(R)		;STORE DATA AT END OF BUFFER.
02500		PUSHJ P,YANK2
02600		JRST RET
02700	
02800	
     

00100	;CD9(↑I)
00200	;↑ITEXT$	INSERTS AT THE CURRENT POINTER LOCATION THE ↑I (TAB)
00300	;	AND THE TEXT FOLLOWING THE ↑I UP TO BUT NOT INCLUDING THE
00400	;	ALT MODE.  THE POINTER IS PUT TO THE RIGHT OF THE INSERTED
00500	;	MATERIAL.
00600	
00700	TAB:	PUSHJ P,TAB2		;INSERT TAB
00800	
00900	;CD9(I)
01000	;ITEXT$	INSERT, AT THE CURRENT POINTER LOCATION, THE TEXT FOLLOWING
01100	;	THE I UP TO BUT NOT INCLUDING THE FIRST ALT. MODE.  THE
01200	;	POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
01300	
01400	INSERT:	TRNE FF,ARG		;IS THERE AN ARGUMENT?
01500		JRST INS1A		;YES. NI COMMAND.
01600		MOVEI CH,175		;NO. CH:=ALT-MODE.
01700		TRZE FF,SLSL		;DID @ PRECEED I?
01800		PUSHJ P,RCH		;YES. CH:=USER SELECTED TERMINATOR.
01900		MOVEM CH,A		;A:=INSERTION TERMINATOR.
02000					;EITHER ALT-MODE OR USER CHOICE.
02100		MOVE B,CPTR(R)		;SAVE CURRENT POSITION OF CPTR.
02200		MOVEI C,0		;COUNT # CHARACTERS TO INSERT IN C AND
02300					;MOVE CPTR TO END OF STRING.
02400		PUSHJ P,SKRCH		;GET NEXT CHARACTER
02500		CAME CH,A		;IS IT THE TERMINATOR?
02600		AOJA C,.-2		;NO. TRY AGAIN.
02700		PUSHJ P,NROOM		;YES. MOVE FROM PT THROUGH Z UP C POSITIONS.
02800		ADD B,CRREL(R)		;RELOCATE INITIAL VALUE OF CPTR IN CASE OF GARB. COL.
02900	
03000	;MOVE INSERTION INTO DATA BUFFER
03100	;FROM BAKSL1+11
03200	
03300	INS1B:	MOVE OUT,PT(R)
03400		ILDB CH,B		;CH:=CHARACTER FROM COMMAND STRING.
03500		CAMN CH,A		;IS IT THE TERMINATOR?
03600		POPJ P,			;YES. DON'T STORE IT.
03700		PUSHJ P,PUT		;NO. STORE CHARACTER IN DATA BUFFER TO RIGHT OF PT.
03800		AOS PT(R)		;PT:=PT+1
03900		JRST INS1B		;LOOP
04000	
04100	
     

00100	;NI	INSERT AT THE POINTER A CHARACTER WHOSE 7-BIT ASCII CODE IS N
00200	;	(BASE 10).  THE POINTER IS MOVED TO THE RIGHT OF THE NEW CHARACTER.
00300	;FROM INSERT+1
00400	
00500	INS1A:
00600	TAB1:	MOVE CH,NUM(R)		;CH:=NUM
00700	
00800	;INSERT CH IN DATA BUFFER AT PT
00900	;FROM TAB,TYOM+4
01000	
01100	TAB2:	MOVEI C,1		;MOVE FROM PT THROUGH Z UP 1 POSITION.
01200		PUSHJ P,NROOM
01300		AOS OUT,PT(R)		;PT:=PT+1
01400		SOJA OUT,PUT		;STORE CH AT PT-1
01500	
01600	
01700	
01800	
01900	;CD9(@)
02000	;@IJTEXTJ	INSERT, AT THE CURRENT POINTER POSITION, THE TEXT
02100	;	SURROUNDED BY THE INSTANCES OF THE TERMINATOR J, WHICH MAY BE AT
02200	;	THE USER'S CHOICE ANY CHARACTER NOT APPEARING IN THE TEXT.
02300	;	THE POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
02400	
02500	ATSIGN:	TRO FF,SLSL		;SLSL:=1
02600		JRST RET
02700	
02800	
02900	;NBACKSLASH	INSERT AT THE CURRENT POINTER LOCATION THE ASCII NUMBERS
03000	;	EQUAL TO N.
03100	
03200	;FROM BAKSL+1
03300	
03400	BAKSL1:	MOVE T,[XWD 700+R,BAKTAB-1]
03500		MOVEI C,0		;COUNT # DIGITS IN C.
03600		MOVEI CH,BAKSL4		;SET DPT TO RETURN TO BAKSL4
03700		HRRM CH,LISTF5
03800		PUSHJ P,DPT		;CONVERT C(B) TO ASCII AND STORE STRING IN BAKTAB.
03900		MOVEI A,141		;MARK END OF STRING IN BAKTAB
04000		IDPB A,T
04100		MOVE B,[XWD 700+R,BAKTAB-1]
04200		PUSHJ P,NROOM		;MOVE FROM PT THROUGH Z UP C POSITIONS.
04300		PUSHJ P,INS1B		;INSERT STRING IN BAKTAB INTO DATA BUFFER AT PT.
04400		JRST RET
04500	
04600	BAKSL4:	IDPB CH,T		;STORE DIGIT IN BAKTAB
04700		AOJA C,CPOPJ		;C:=C+1. RETURNS TO DPT CALL + 1 ON COMPLETION.
04800	
     

00100	REPEAT 0,<
00200	
00300	VIII.	OUTPUT COMMANDS
00400	
00500	NV	DISPLAYS ON THE SCOPE THE N LINES TO THE RIGHT OF THE
00600		POINTER, I.E., FROM THE POINTER THROUGH THE NTH FOLLOWING LINE
00700		FEED.  IF N IS NEGATIVE, N LINES TO THE LEFT OF THE POINTER ARE
00800		DISPLAYED.
00900	V	SAME AS 1V.
01000	I,JV	DISPLAY THE (I+1)TH THROUGH JTH CHARACTERS IN THE BUFFER.
01100	
01200	NOTES ON THE V COMMAND:  THE DISPLAY CEASES IF THE V IS NOT THE LAST
01300	COMMAND OF THE COMMAND STRING, AND WHEN A NEW COMMAND STRING IS ENTERED.
01400	USUALLY V IS NOT NEEDED, SINCE WHENEVER NOT PROCESSING COMMANDS TECO
01500	AUTOMATICALLY DISPLAYS 10 LINES ON EACH SIDE OF THE POINTER (EXCEPT IF
01600	THE LAST COMMAND IT SAW WAS V).  IN ALL DISPLAYS OF THE BUFFER, THE
01700	POINTER IS DISPLAYED AS A VERTICAL BAR, UNLESS IT IS NOT IN THE RANGE
01800	BEING DISPLAYED OR IS AT THE END OF THE BUFFER.  NON-PRINTING CHARACTERS
01900	ARE DISPLAYED AS FOLLOWS: SPACE, TAB, CARRIAGE RETURN, AND LINE FEED
02000	HAVE THEIR USUAL EFFECT.  CTRL CHARACTERS ARE DISPLAYED AS AN UP ARROW (↑)
02100	FOLLOWED BY THE CORRESPONDING PRINTING CHARACTERS; ALT MODE IS
02200	DISPLAYED AS $; AND OTHER CHARACTERS ARE DISPLAYED AS A DOWNWARD
02300	POINTING ARROW FOLLOWED BY A SUBSCRIPT WHICH IS THEIR 7-BIT ASCII CODE IN OCTAL.
02400	
02500	N↑N	SET NUMBER OF LINES AUTOMATICALLY DISPLAYED ON EACH SIDE OF POINTER
02600		TO N.
02700	N↑D	SET DISPLAY SIZE TO N.  LEGAL SIZES ARE 0, 1, 2, AND 3: 1 IS
02800		THE USUAL SIZE, 2 IS APPROPRIATE TO DEMOSNSTRATIONS TO GROUPS,
02900		0 IS TOO SMALL AND 3 IS TOO BIG.
03000	NVW	SAME AS SIMILAR FOR OF V EXCEPT: WHEN THIS COMMAND IS ENCOUNTERED
03100	VW	THE DISPLAY IS MAINTAINED AND FURTHER COMMANDS IN THE STRING
03200	I,JVW	ARE NOT INTERPRETED UNTIL THE USER TYPES IN A CHARACTER.  THEN
03300		THE DISPLAY CEASES, THE VW IS TREATED AS A NUMERIC QUANTITY
03400		EQUAL TO THE 7-BIT ASCII CODE OF THE CHARACTER JUST TYPED IN, 
03500		AND COMMAND INTERPRETATION RESUMES.  (SEE EXAMPLE 8.)
03600	NT	TYPE OUT THE STRING OF CHARACTERS STARTING AT THE RIGHT OF THE
03700		POINTER AND CONTINUING THROUGH THE NTH LINE FEED ENCOUNTERED.
03800		IF N IS NEGATIVE, N LINES TO THE LEFT OF THE POINTER ARE TYPED.
     

00100	T	SAME AS 1T.
00200	I,JT	TYPE OUT THE (I+1)TH THROUGH THE JTH CHARACTER OF THE BUFFER.
00300	
00400	NOTICE THAT T IS IDENTICAL TO V, EXCEPT THAT IS USES THE TELETYPE INSTEAD
00500	OF THE SCOPE.
00600	
00700	PW	OUTPUT THE ENTIRE BUFFER, FOLLOWED BY A FORM FEED CHARACTER,
00800		TO THE SELECTED OUTPUT DEVICE.  BUFFER IS UNCHANGED AND POINTER
00900		IS UNMOVED.
01000	P	IS IDENTICAL TO PWY.
01100	NP	IS IDENTICAL TO PP...P (P PERFORMED N TIMES).
01200	I,JP	OUTPUTS (I+1)TH THROUGH JTH CHARACTERS OF BUFFER.  NO
01300		FORM FEED IS PUT AT THE END.  BUFFER UNCHANGED; POINTER UNMOVED.
01400	>;CD9(T)
01500	;NT	TYPE OUT THE STRING OF CHARACTERS STARTING AT THE RIGHT OF THE
01600	;	POINTER AND CONTINUING THROUGH THE NTH LINE FEED ENCOUNTERED.
01700	;	IF N IS NEGATIVE, N LINES TO THE LEFT OF THE POINTER ARE TYPED.
01800	;T	SAME AS 1T.
01900	;I,JT	TYPE OUT THE (I+1)TH THROUGH THE JTH CHARACTER OF THE BUFFER.
02000	
02100	TYPE:
02200	TYPE4:	MOVEI D,TYO		;D:=ADDRESS OF OUTPUT ROUTINE.
02300	
02400	;FROM PUNCH+2
02500	TYPE0:	PUSHJ P,GETARG		;C:=FIRST STRING ARGUMENT ADDRESS.
02600					;B:=SECOND STRING ARGUMENT ADDRESS.
02700	
02800	;FROM PUNCHR+3
02900	
03000	TYPE1:	PUSHJ P,CHK1		;C:=MAX(C(C),BEG), B:=MIN(C(B),Z)
03100		MOVE IN,C		;START GETTING CHARACTERS AT C.
03200	TYPE3:	CAML IN,B		;DONE?
03300		JRST TYPE5		;YES.
03400		PUSHJ P,GETINC		;NO. CH:=NEXT CHARACTER.
03500		PUSHJ P,(D)		;OUTPUT IT
03600		JRST TYPE3		;LOOP
03700	TYPE5:	MOVEI A,PPA
03800		MOVEI CH,14		;IF PUNCHING, APPEND FF.
03900		CAIE A,(D)		;D=PPA?
04000		POPJ P,			;NO
04100	CPPA:	JRST PPA		;YES. APPEND FF.
04200	
04300	
     

00100	PPA:	TLNN FF,UWRITE		;OUTPUT FILE OPEN?
00200		JRST PPA09		;NO.
00300		SOSLE OUTBUF+2(R)	;YES. IS OUTPUT BUFFER FULL?
00400		JRST PPA01		;NO.
00500		OUTPUT OUTCHN,0		;YES. WRITE IT
00600		STATZ OUTCHN,740000	;ERROR?
00700		JRST OUTERR		;YES.
00800	PPA01:	IDPB CH,OUTBUF+1(R)	;NO. CH TO OUTPUT BUFFER.
00900		POPJ P,0		;RETURN
01000	
01100	PPA09:	JSP A,ERRMES
01200		ASCIZ /NO FILE FOR OUTPUT
01300	/
01400		JRST ERRA
01500	
01600	;FROM PPA+6
01700	
01800	OUTERR:	JSP A,ERRMES
01900		ASCIZ /ERROR ON OUTPUT DEVICE; FILE CLOSED
02000	/
02100		RELEAS OUTCHN,0		;CLOSE FILE AND RELEASE OUTPUT DEVICE.
02200		TLZ FF,UWRITE		;CLEAR OUTPUT FILE OPEN INDICATOR.
02300		JRST GOX		;CLEAR COMMAND BUFFER AND WAIT FOR NEXT COMMAND.
02400	
02500	
     

00100	
00200	;CD9(P)
00300	;PW	OUTPUT THE ENTIRE BUFFER, FOLLOWED BY A FORM FEED CHARACTER.
00400	;	TO THE SELECTED OUTPUT DEVICE.  BUFFER IS UNCHANGED AND POINTER
00500	;	IS UNMOVED.
00600	;P	IS IDENTICAL TO PWY.
00700	;NP	IS IDENTICAL TO PP...P (P PERFORMED N TIMES).
00800	;I,JP	OUTPUTS (I+1)TH THROUGH JTH CHARACTERS OF BUFFER.  NO FORM
00900	;	FEED IS PUT AT THE END.  BUFFER UNCHANGED; POINTER UNMOVED.
01000	
01100	PUNCH:
01200	
01300	;FROM NOFND1+5
01400	
01500	PUNCHA:	MOVEI D,CPPA		;SELECT PPA FOR OUTPUT.
01600		TRNE FF,ARG2		;I,JP?
01700		JRST TYPE0		;YES. GET STRING ARGUMENTS AND OUTPUT.
01800		MOVE E,B		;NO. E:=N
01900		MOVE B,CPTR(R)
02000		ILDB T,B		;T:=COMMAND CHARACTER FOLLOWING P.
02100		JUMPL E,CPOPJ		;IF N<0, IGNORE P.
02200	PUN1:	PUSHJ P,PUNCHR		;PUNCH OUT BUFFER
02300		SKIPE COMCNT(R)		;IF NO COMMANDS LEFT
02400		CAIE T,"W"		;OR COMMAND IS NOT W
02500		PUSHJ P,YANK1		;RENEW BUFFER
02600		MOVE C,Z(R)
02700		CAMN C,BEG(R)		;EMPTY BUFFER?
02800		TRNN FF,FINF		;NO. QUIT ON EOF
02900		SOJG E,PUN1		;YES. E:=E-1. DONE?
03000					;YES
03100	
03200	;FROM TYI1+2,SIXBMS+3,CHK2+4,PUNCH+6,BAKSL4+1,GCM2+6
03300	
03400	CPOPJ:	POPJ P,0
03500	
03600	;FROM PUN1
03700	
03800	PUNCHR:	MOVE C,BEG(R)		;OUTPUT DATA BUFFER.
03900		MOVE B,Z(R)
04000		MOVEI D,PPA
04100		JRST TYPE1
04200	
     

00100	REPEAT 0,<
00200	
00300	IX.	BASIC EDITING COMMANDS
00400	
00500	NJ	MOVE THE POINTER TO THE RIGHT OF THE NTH CHARACTER IN THE
00600		BUFFER. (I.E., GIVE "." THE VALUE N.)
00700	J	SAME AS 0J.
00800	NC	SAME AS .+NJ.  NOTE THAT N MAY BE NEGATIVE.
00900	NR	SAME AS .-NJ.
01000	NL	IF N IS GREATER THAN 0:	MOVE POINTER TO THE RIGHT, STOPPING WHEN IT HAS
01100					PASSED OVER N LINE FEEDS.
01200		IF N IS LESS THAN 0:	MOVE POINTER TO THE LEFT; STOP WHEN IT HAS PASSED
01300					OVER N+1 LINE FEEDS AND THEN MOVE IT TO THE RIGHT
01400					OF THE LAST LINE FEED PASSED OVER.
01500	L	SAME AS 1L.
01600	ND	DELETE N CHARACTERS FROM THE BUFFER: IF N IS POSITIVE, DELETE
01700		THEM JUST TO THE RIGHT OF THE POINTER; IF N IS NEGATIVE, DELETE
01800		THEM JUST TO ITS LEFT.
01900	NK	PERFORM NL BUT DELETE EVERYTHING THE POINTER MOVES OVER.
02000	M,NK	DELETE THE (M+1)TH THROUGH NTH CHARACTER FROM THE BUFFER.
02100		THE POINTER IS THEN PUT WHERE THE DELETION TOOK PLACE.
02200	M,NXI	THE STRING FROM CHARACTER (M+1)TH THROUGH NTH CHARACTER OF THE
02300		BUFFER IS COPIED INTO Q-REGISTER I.
02400	ITEXT$	INSERTS TEXT IN BUFFER AT POINTER; PUTS POINTER TO RIGHT
02500	@IJTEXTJ	OF INSERTION.
02600	NI	INSERTS CHARACTER WHOSE ASCII CODE IS N AT
02700		POINTER; PUTS POINTER AT RIGHT OF NEW CHARACTER.
02800	GI	INSERTS AT THE POINTER A COPY OF THE TEXT IN Q-REGISTER I.  THE
02900		POINTER IS SET AT THE RIGHT OF THE INSERTION.
03000	>
     

00100	;CD9(J)
00200	;NJ	MOVE THE POINTER TO THE RIGHT OF THE NTH CHARACTER IN THE
00300	;	BUFFER. (I.E., GIVE "." THE VALUE N.)
00400	;J	SAME AS 0J.
00500	
00600	JMP:	ADD B,BEG(R)		;PT:=N+BEG
00700		JRST JMP1
00800	
00900	
01000	
01100	;CD9(R)
01200	;NR	SAME AS .-NJ.
01300	
01400	REVERS:	PUSHJ P,CHK2		;MAKE SURE THERE IS AN ARGUMENT
01500		MOVNS B			;B:=-C(B)
01600		SKIPA
01700	
01800	;CD9(C)
01900	;NC	SAME AS .+NJ.  NOTE THAT N MAY BE NEGATIVE.
02000	
02100	CHARAC:	PUSHJ P,CHK2		;MAKE SURE THERE IS AN ARGUMENT
02200		ADD B,PT(R)		;B:=PT+C(B)
02300	
02400	;IF B LIES BETWEEN BEG AND Z, STORE IT IN PT.
02500	;FROM JMP+1
02600	
02700	JMP1:	PUSHJ P,CHK		;IS C(B) WITHIN DATA BUFFER?
02800		MOVEM B,PT(R)		;YES. PT:=C(B)
02900		JRST RET
03000	
03100	;CD9(L)
03200	;NL	IF N>0:	MOVE POINTER TO THE RIGHT, STOPPING WHEN IT HAS
03300	;		PASSED OVER N LINE FEEDS.
03400	;	IF N<0:	MOVE POINTER TO THE LEFT; STOP WHEN IT HAS PASSED
03500	;		OVER N+1 LINE FEEDS AND THEN MOVE IT TO THE RIGHT OF
03600	;		THE LAST LINE FEED PASSED OVER.
03700	;L	SAME AS 1L.
03800	
03900	LINE:	TRNE FF,ARG2		;IS THERE A SECOND ARGUMENT?
04000		JSR ERR			;YES. TOUGH
04100		PUSHJ P,GETARG		;NO. C:=FIRST STRING ARGUMENT ADDRESS,
04200					;B:=SECOND STRING ARGUMENT ADDRESS.
04300		XOR B,C
04400		XORM B,PT(R)
04500		JRST RET
04600	
     

00100	;ROUTINE TO RETURN CURRENT ARGUMENT IN B
00200	;ASSUMES A VALUE OF 1 WITH SIGN OF LAST OPERATOR IF THERE IS NO CURRENT ARGUMENT
00300	;CALL	PUSHJ P,CHK2
00400	;	RETURN WITH B:=CURRENT ARG.,+1 OR -1
00500	;FROM REVERS,CHARAC,DELETE,EMTAPE+2
00600	
00700	CHK2:	TROE FF,ARG		;IS THERE AN ARGUMENT?
00800		POPJ P,			;YES. IT'S ALREADY IN B.
00900					;NO
01000	
01100	;FROM GETARG+3
01200	CHK22:	LDB B,[XWD 340200+R,DLIM]	;B:=1 WITH SIGN OF LAST OPERATOR.
01300		MOVNS B
01400		AOJA B,CPOPJ
01500	
01600	;CD9(K)
01700	;NK	PERFORM NL BUT DELETE EVERYTHING THE POINTER MOVES OVER.
01800	;M,NK	DELETE THE (M+1)TH THROUGH THE NTH CHARACTER FROM THE BUFFER.
01900	;	THE POINTER IS THEN PUT WHERE THE DELETION TOOK PLACE.
02000	;K	SAME AS 1K
02100	
02200	KILL:	PUSHJ P,GETARG		;C:=FIRST STRING ARG. ADDRESS
02300					;B:=SECOND STRING ARG. ADDRESS
02400		PUSHJ P,CHK1		;C:=MAX(C(C),BEG), B:=MIN(C(B),Z)
02500		MOVEM C,PT(R)		;PT:=C(C)
02600		SUB B,C		;B:=NO. OF CHARACTERS TO KILL.
02700		JUMPE B,RET		;IF NONE, RETURN. OTHERWISE, FALL INTO DELETE
02800	
     

00100	;CD9(D)
00200	;ND	DELETE N CHARACTERS FROM THE BUFFER: IF N IS POSITIVE, DELETE
00300	;	THEM JUST TO THE RIGHT OF THE POINTER; IF N IS NEGATIVE, DELETE
00400	;	THEM JUST TO ITS LEFT.
00500	;D	SAME AS 1D
00600	
00700	DELETE:	PUSHJ P,CHK2		;MAKE SURE B CONTAINS AN ARGUMENT
00800		MOVM C,B
00900		MOVNS C			;C:=-ABS(B)
01000		ADD B,PT(R)		;B:=PT+B
01100		PUSHJ P,CHK		;STILL IN DATA BUFFER?
01200		CAMGE B,PT(R)		;YES. IS N NEGATIVE?
01300		MOVEM B,PT(R)		;YES. MOVE PT BACK FOR DELETION.
01400		PUSHJ P,NROOM		;MOVE FROM PT+ABS(C) THROUGH Z DOWN ABS(C) POSITIONS
01500	DEL2:
01600	JRET:	JRST RET
01700	
01800	
01900	
02000	;ROUTINE TO CHECK DATA BUFFER POINTER
02100	;CALL	MOVE B,POINTER
02200	;	PUSHJ P,CHK
02300	;	RETURN IF B LIES BETWEEN BEG AND Z
02400	;FROM;FROM JMP1,DELETE+4
02500	
02600	CHK:	CAMG B,Z(R)
02700		CAMGE B,BEG(R)
02800		JSR ERR
02900		POPJ P,
03000	
03100	;ROUTINE TO PUT STRING ARGUMENT ADDRESSES WITHIN DATA BUFFER
03200	;BOUNDS AND CHECK ORDER RELATION.
03300	;CALL	MOVE C,FIRST STRING ARGUMENT ADDRESS
03400	;	MOVE B,SECOND STRING ARGUMENT ADDRESS
03500	;	PUSHJ P,CHK1
03600	;	RETURN
03700	;C:=MAX*←xC),BEG), B:=MIN(C(B),Z)
03800	;IF C>B, DOES NOT RETURN.
03900	;FROM KILL+1,TYPE1
04000	
04100	CHK1:	CAMG C,BEG(R)		;C:=MAX(C(C),BEG)
04200		MOVE C,BEG(R)
04300		CAML B,Z(R)		;B:=MIN(C(B),Z)
04400		MOVE B,Z(R)
04500		CAMLE C,B		;C>B?
04600		JSR ERR			;YES.
04700		POPJ P,			;NO
04800	
     

00100	REPEAT 0,<
00200	
00300	X.	SEARCH COMMANDS
00400	
00500		THERE ARE THREE SEARCH COMMANDS: S, N, AND LEFT ARROW.  EACH OF THESE
00600	MAY BE PRECEDED BY EITHER OR BOTH OF THE MODIFIER CHARACTERS : AND @.
00700	PRECEDING THE COMMAND LETTER, BUT FOLLOWING ANY MODIFIERS,
00800	MAY BE A NUMERIC ARGUMENT;  IF THIS IS NOT SUPPLIED, ONE IS ASSUMED.
00900	FOLLOWING THE COMMAND LETTER IS A TEXT ARGUMENT IN THE SAME FORMAT
01000	AS FOR THE I OR @I COMMAND, DEPENDING ON THE ABSENCE OR PRESENCE OF THE
01100	@ MODIFIER.  IF THE : MODIFIER IS NOT USED, A SEARCH COMMAND HAS NO
01200	NUMERIC VALUE.  IF : IS USED, THE VALUE IS -1 IF THE SOUGHT MATERIAL IS 
01300	FOUND AND 0 OTHERWISE.
01400		THE SEARCH COMMANDS ATTEMPT TO FIND IN THE BUFFER A MATCH TO THEIR
01500	TEXT ARGUMENT.  THE SEARCH IS BEGUN AT THE LOCATION OF THE POINTER
01600	JUST PRIOR TO THE SEARCH, AND PROCEEDS TO THE RIGHT UNTIL EITHER A MATCH
01700	IS FOUND OR THE END OF THE BUFFER IS REACHED.  IF THE MATCH IS FOUND,
01800	THE POINTER IS MOVED TO THE RIGHT OF THE STRING FOUND IN THE BUFFER AND
01900	THE COMMAND IS FINISHED.  IF THE MATCH HAS NOT BEEN FOUND, THE ACTION
02000	DEPENDS ON WHETHER  THE COMMAND WAS S, N, OR LEFT ARROW.  THE S COMMAND IN SUCH A
02100	CIRCUMSTANCE IS SAID TO FAIL; THE N COMMAND PERFORMS A P AND THEN
02200	RESUMES SEARCHING; THE LEFT ARROW COMMAND PERFORMS A Y AND RESUMES THE SEARCH.
02300	IF N OR LEFT ARROW REACHES THE END OF THE FILE WITHOUT FINDING THE MATCH, THEY
02400	FAIL.  IF A SEARCH FAILS (S REACHES THE END OF THE BUFFER; OR N OR LEFT ARROW
02500	REACHES THE END OF THE FILE), THE POINTER IS SET TO THE BEGINNING OF
02600	THE BUFFER.  THEN IF THE : MODIFIER WAS NOT SPECIFIED, TECO TYPES OUT
02700	A QUESTION MARK AND IGNORES THE REMAINDER OF THE COMMAND STRING.
02800		SHOULD A NUMERIC ARGUMENT PRECEDE THE COMMAND LETTER, THIS IS
02900	EQUIVALENT TO WRITING OUT THE ENTIRE SEARCH COMMAND A NUMBER OF TIMES
03000	EQUAL TO THE VALUE OF THE ARGUMENT.  IN OTHER WORDS, IF THE NUMBER
03100	IS N IT SEARCHES FOR THE NTH FOLLOWING INSTANCE OF THE TEXT.
03200		WITHIN A SEARCH FOUR CTRL CHARACTERS TAKE EFFECT.  CTRL S
     

00100	MATCHES ANY SEPARATOR CHARACTER (I.E., ANY CHARACTER NOT A LETTER,
00200	NUMBER, PERIOD, DOLLAR SIGN, OR PERCENT SYMBOL.)  CTRL X MATCHES ANY
00300	ARBITRARY CHARACTER.  CTRL N NEGATES THE SENSE OF THE SEARCH FOR THE
00400	NEXT CHARACTER (E.G., CTRL NA FINDS ANY CHARACTER EXCEPT A.)  CTRL Q
00500	TAKES THE NEXT CHARACTER LITERALLY EVEN IF IT IS ONE OF THESE FOUR
00600	CHARACTERS.  (E.G., S CTRL N CTRL Q CTRL Q $$ FINDS ANY CHARACTER NOT
00700	A CTRL Q.)
00800		SINCE THESE CTRL CHARACTERS ARE PART OF A TEXT STRING RATHER
00900	THAN COMMANDS TO TECO, THEY MUST BE TYPED USING THE CTRL KEY.  THE
01000	OPTION OF TYPING ↑ FOLLOWED BY THE CHARACTER DOES NOT APPLY
01100	
01200	SEARCH SUMMARY
01300		ALL SEARCHES BEGIN AT THE CURRENT LOCATION OF THE POINTER.
01400	THEY MAY INCLUDE A NUMERIC ARGUMENT N SAYING TO SEARCH FOR THE NTH
01500	OCCURRENCE OF THE TEXT.  THE POINTER IS LEFT FO THE RIGHT OF THE
01600	STRING FOUND IF THE SEARCH IS SUCCESSFUL, OTHERWISE AT THE END OF THE
01700	BUFFER.  USE OF THE @ MODIFIER DETERMINES THE FORM OF THE TEXT ARGUMENT
01800	WHICH FOLLOWS THE COMMAND:
01900		IF @JTEXTJ	J IS ANY CHARACTER NOT IN TEXT.
02000		IF NO A TEXT$	TEXT CONTAINS NO ALT MODE.
02100	>
     

00100	;CD9(BACKSLASH)
00200	
00300	LARR:	TROA FF,FINDR		;FINDR:=1 FOR LEFT ARROW SEARCH
00400	
00500	;CD9(N)
00600	
00700	SERCHP:	TRO FF,PCHFLG		;PCHFLG:=1 FOR N SEARCH
00800	
00900	;CD9(S)
01000	
01100	SERCH:	MOVE E,B		;E:=ARGUMENT (IF ANY)
01200		SETZM  NUM(R)		;NUM:=0
01300		MOVEI CH,175		;USE ALT-MODE DELIMITER IF NO @ SEEN
01400		TRZE FF,SLSL		;@ SEEN?
01500		PUSHJ P,RCH		;YES. CH:=USER SPECIFIED DELIMITER.
01600		MOVEM CH,B		;B:=SEARCH STRING DELIMITER
01700		HRLZI F,STAB-STABP	;F:=XWD -LENGTH OF SEARCH TABLE,0
01800	
01900	;SET UP SEARCH TABLE
02000	;FROM CNTRN+1
02100	
02200	SERCH2:	PUSHJ P,SKRCH		;CH:=NEXT COMMAND STRING CHARACTER.
02300		CAIN CH,(B)		;DELIMITER?
02400		JRST SERCH1		;YES. DONE.
02500		CAIN CH,30		;NO. ↑X?
02600		JRST CNTRX		;YES
02700		CAIN CH,16		;NO. ↑N?
02800		JRST CNTRN		;YES.
02900		CAIN CH,23		;NO. ↑S?
03000		JRST CNTRB		;YES
03100		CAIN CH,21		;NO. ↑Q?
03200		PUSHJ P,SKRCH		;YES. ↑Q TAKES THE NEXT CHARACTER.
03300		HRLI CH,306000+CH*40	;CH:=CAIN CH,CHARACTER
03400	
03500	;FROM CNTRX+1
03600	
03700	SERCH4:	TRZE FF,NOTF		;SEARCH SENSE REVERSED?
03800		TLC CH,4000		;YES. CH:=CAIE CH,CHARACTER
03900					;PUSHJ P,CNTRB1(R), OR CAIA
04000		MOVEI TT,STAB(F)	;RELOCATE
04100		HRLI TT,R
04200		MOVEM CH,@TT		;SAVE IN SEARCH TABLE
04300		AOBJN F,SERCH2		;GET NEXT CHARACTER
04400		JSR ERR			;SEARCH TABLE IS FULL
04500	
     

00100	;START SEARCHING
00200	;FROM NOFND1+11,FND1
00300	
00400	
00500	SERCH1:	MOVE IN,PT(R)		;START SEARCHING AT PT
00600		TRNE FF,ARG		;IS THERE AN ARGUMENT?
00700		JUMPLE E,FND		;YES. SEEN STRING N TIMES?
00800		CAML IN,Z(R)		;NO. REACHED TOP OF BUFFER?
00900		JRST NOFND		;YES.
01000		MOVEI D,STAB
01100	SERCH3:	CAIN D,STAB(F)		;END OF SEARCH TABLE?
01200		JRST FND		;YES.
01300		PUSHJ P,GETINC		;NO. CH:=NEXT DATA BUFFER CHARACTER.
01400		HRRI TT,(D)		;GETINC LEAVES R IN INDEX OF TT
01500		XCT @TT
01600	
01700	;FROM CNTRX+7
01800	
01900	SERCH5:	AOJA D,SERCH3		;MATCH FOUND. GO TO NEXT TABLE ENTRY.
02000	
02100	;FROM CNTRX+6
02200	
02300	SRCH5A:	AOS PT(R)		;NO MATCH. PT:=PT+1
02400		JRST SERCH1		;KEEP LOOKING
02500	
02600	;FROM SERCH1+2,SERCH3+1
02700	
02800	FND:	CAMLE IN,Z(R)		;REACH TOP OF BUFFER?
02900		JRST NOFND		;YES. SEARCH FAILED.
03000		SETOM SFINDF(R)		;NO. SFINDF:=-1
03100		MOVEM IN,PT(R)		;MOVE PT PAST THE STRING
03200		SOJG E,SERCH1		;FIND IT N TIMES?
03300		TRZN FF,COLONF		;YES. COLON MODIFIER?
03400		JRST RET		;NO. DONE
03500		MOVNI A,1		;YES. RETURN VALUE OF -1
03600		JRST VALRET
03700	
     

00100	
00200	;FROM SERCH1+4,FND+1
00300	
00400	NOFND:	MOVE IN,BEG(R)		;SEARCH FAILED
00500		MOVEM IN,PT(R)		;PT:=BEG
00600		SETZM  SFINDF(R)		;SFINDF:=0
00700		TRNE FF,PCHFLG+FINDR	;S SEARCH?
00800		JRST NOFND1		;NO.
00900	
01000	;FROM NOFND1+1
01100	
01200	BEGIN1:	TRZN FF,COLONF		;YES. COLON MODIFIER?
01300		JRST NOFND2		;NO
01400	
01500	;FROM NOFND2+1
01600	
01700	BEGIN2:	TRZ FF,PCHFLG+FINDR	;YES.
01800		JRST BEGIN		;RETURN VALUE OF 0
01900	
02000	
02100	;FROM NOFND+4
02200	
02300	NOFND1:	TRNE FF,FINF		;INPUT FILE SELECTED?
02400		JRST BEGIN1		;NO. DONE.
02500		PUSH P,E		;YES. SAVE SEARCH COUNT
02600		MOVEI B,1		;PUNCH 1 PAGE ONLY
02700		TRNE FF,PCHFLG		;N SEARCH?
02800		PUSHJ P,PUNCHA		;YES. PUNCH THIS BUFFER AND REFILL IT.
02900		TRNE FF,FINDR		;LEFT ARROW SEARCH?
03000		PUSHJ P,YANK1		;YES. FILL BUFFER.
03100		POP P,E			;RESTORE SEARCH COUNT.
03200		JRST SERCH1		;RESUME SEARCH
03300	
03400	;FROM BEGIN1+1
03500	
03600	NOFND2:	TRNE FF,ITERF		;IN AN ITERATION?
03700		JRST BEGIN2		;YES. RETURN VALUE OF 0
03800		JSP A,ERRMES
03900		ASCIZ /SEARCH/
04000		JSR ERR			;NO. SEARCH FAILED.
04100	
     

00100	;CNTR S MATCHES ANY SEPARATOR CHARACTER (I.E., ANY CHARACTER NOT
00200	;A LETTER, NUMBER, PERIOD, DOLLAR SIGN OR PER CENT SYMBOL)
00300	;FROM SERCH2+10
00400	
00500	CNTRB:	SKIPA CH,[JSR P,CNTRB1(R)]	;CH:=JSR P,CNTRB1(R)
00600	
00700	;CNTR X MATCHES ANY ARBITRARY CHARACTER
00800	;FROM SERCH2+4
00900	
01000	CNTRX:	MOVSI CH,300000		;CH:=CAI
01100		JRST SERCH4
01200	
01300	;HERE ON CNTR N CNTR S
01400	CNTRB2:	MOVE A,[JRST DQT2]	;CNTRB1:=JRST DQT2
01500		MOVEM A,CNTRB1(R)
01600		PUSHJ P,DQT2		;IS CH A TERMINATOR?
01700		JRST SRCH5A		;NO
01800		JRST SERCH5		;YES
01900	
02000	;CNTR N REVERSES THE SENSE OF THE SEARCH FOR THE NEXT CHARACTER
02100	;FROM SERCH2+6
02200	
02300	CNTRN:	TRO FF,NOTF
02400		JRST SERCH2
02500	
02600	U CNTRB1,2			;INITIALIZE TO JRST DQT2
02700					;INITIALIZE TO JRST CNTRB2
02800	
02900	
03000	;CD9(:)
03100	
03200	COLON:	TRO FF,COLONF
03300		JRST RET
03400	
     

00100	REPEAT 0,<
00200	
00300	XI.	MACROS, ITERATIONS AND CONDITIONALS
00400	
00500	MI	PERFORM NOW THE TEXT IN Q-REGISTER I AS A SERIES OF COMMANDS.
00600	<>	ITERATION BRACKETS.   COMMAND INTERPRETATION IS SENT BACK TO THE <,
00700		WHEN THE > IS ENCOUNTERED.
00800	N;	IF NOT IN AN ITERATION, GIVES AN ERROR.  IF IN AN ITERATION AND
00900		IF THE VALUE OF N IS NEGATIVE, THIS COMMAND HAS NO EFFECT.  IF
01000		N IS 0 OR GREATER, COMMAND INTERPRETATION IS SENT JUST PAST THE
01100		MATCHING RIGHT-ANGLE BRACKET TO THE RIGHT.  OTHERWISE, NO EFFECT.
01200	;	IF NOT IN AN ITERATION, GIVES AN ERROR.  IF IN AN ITERATION AND
01300		IF THE MOST RECENT SEARCH FAILED, SEND COMMAND TO FIRST UNMATCHED
01400		RIGHT-ANGLE BRACKET TO THE RIGHT.  OTHERWISE, NO EFFECT.
01500	!TAG!	TAG DEFINITION.  THE TAG IS A NAME FOR THE LOCATION IT APPEARS
01600		IN IN A MACRO, ITERATION OR COMMAND STRING.
01700	OTAG$	GO TO THE TAG NAMED TAG.  THE TAG MUST APPEAR IN THE CURRENT
01800		MACRO,ITERATION OR COMMAND STRING.
01900	N"G	HAS NO EFFECT IF N IS GREATER THAN 0.  OTHERWISE, SEND COMMAND INTERPRETATION
02000		TO NEXT MATCHING '.  THE " AND ' MATCH SIMILAR TO ( AND ).
02100	N"L	SEND COMMAND TO MATCHING ' UNLESS N IS LESS THAN 0.
02200	N"N	SEND COMMAND TO MATCHING ' UNLESS N NOT = 0.
02300	N"E	SEND COMMAND TO MATCHING ' UNLESS N=0.
02400	N"C	SEND COMMAND TO MATCHING ' UNLESS THE VALUE OF N AS AN ASCII
02500		CHARACTER IS A LETTER, NUMBER, PERIOD (.), DOLLAR SIGN ($),
02600		OR PER CENT (%).
02700	>;CD9(M)
02800	;MI	PERFORM NOW THE TEXT IN Q-REGISTER I AS A SERIES OF COMMANDS.
02900	
03000	MAC:	PUSHJ P,QREGVI		;A:=C(Q-REG)
03100		PUSH P,COMAX(R)		;SAVE CURRENT COMMAND STATE
03200		PUSH P,CPTR(R)
03300		PUSH P,COMCNT(R)
03400		TLZE A,400000		;MAKE SURE Q-REG CONTAINS TEXT
03500		TLZE A,377777
03600		JSR ERR			;Q-REG DOES NOT CONTAIN TEXT
03700		ADD A,QRBUF(R)
03800		MOVE IN,A
03900		PUSHJ P,GETINC		;GET FIRST CHARACTER OF MACRO
04000		CAIE CH,141		;IT SHOULD BE FLAG
04100		JSR ERR			;OOPS
04200		PUSHJ P,GETINC		;GET NUMBER OF CHARACTERS IN MACRO
04300		MOVE A,CH
04400		PUSHJ P,GET
04500		ROT CH,7
04600		IOR A,CH
04700		SUBI A,3		;-FLAG AND COUNT
04800		MOVEM A,COMCNT(R)	;THAT MANY COMMANDS TO COUNT
04900		MOVEM A,COMAX(R)	;AND MAX.
05000		IDIVI IN,5
05100		MOVE OUT,BTAB(<OUT>)	;MAKE A BYTE POINTER
05200		HRR OUT,IN
05300		MOVEM OUT,CPTR(R)	;PUT IT IN CPTR
05400		JRST CD5		;DON'T FLUSH ANY ARGUMENTS
     

00100	;CD9(<)
00200	;<>	ITERATION BRACKETS.  COMMAND INTERPRETATION IS SENT
00300	;	BACK TO THE < WHEN THE > IS ENCOUNTERED.
00400	
00500	LSSTH:	AOS INTDPH(R)
00600		PUSH P,ITERCT(R)	;SAVE ITERATION COUNT
00700		PUSH P,CPTR(R)		;SAVE COMMAND STATE
00800		PUSH P,COMCNT(R)
00900		SETOM ITERCT(R)		;ITERCT:=-1
01000		TRZE FF,ARG		;IS THERE AN ARGUMENT?
01100		MOVEM B,ITERCT(R)	;YES. ITERCT:=ARGUMENT
01200		JRST LSSTH1
01300	
01400	
01500	;CD9(>)
01600	
01700	GRTH:	SKIPG INTDPH(R)		;IS THERE A LEFT ANGLE BRACKET?
01800		JSR ERR			;NO.
01900		TRZ FF,ITERF		;YES
02000		SOSN ITERCT(R)		;ITERCT:=ITERCT-1. DONE?
02100		JRST INCMA2		;YES
02200		MOVE A,-1(P)		;NO. RESTORE COMMAND STATE TO START OF ITERATION.
02300		MOVEM A,CPTR(R)
02400		MOVE A,(P)
02500		MOVEM A,COMCNT(R)
02600		TRNE FF,TRACEF		;TRACING?
02700		PUSHJ P,CRR		;YES. OUTPUT CRLF
02800	
02900	
03000	;FROM LSSTH+7
03100	
03200	LSSTH1:	TRO FF,ITERF
03300		JRST RET
03400	
03500	
03600	
03700	
03800	
03900	
04000	
04100	U ITERCT,1			;INCMA2+2,GRTH+3,LSSTH+4(-1),LSSTH+6
04200	U INTDPH,1			;LIS+3(0),INCMA2
04300	U SFINDF,1			;INIT+21(0),FND+2(-1),NOFND+2(0),SEMICL+3
     

00100	;CD9(;)
00200	;;	IF NOT IN AN ITERATION, GIVES ERROR.  IF IN AN ITERATION AND
00300	;	IF THE MOST RECENT SEARCH FAILED, SEND COMMAND TO FIRST UNMATCHED
00400	;	> TO THE RIGHT.  OTHERWISE, NO EFFECT.
00500	
00600	SEMICL:	TRNN FF,ITERF		;IN < > ?
00700		JSR ERR			;NO. LOSE.
00800		TRNN FF,ARG		;YES. IF NO ARG,
00900		MOVE B,SFINDF(R)	;USE LAST SEARCH SWITCH (0 OR -1).
01000	
01100	INCMA:	JUMPL B,CD		;IF ARG <0, JUST RET + EXECUTE LOOP
01200		MOVEI A,0		;INIT COUNT OF <>
01300	INCMA1:	PUSHJ P,SKRCH1		;GET A CHAR
01400		CAIN CH,"<"		;<?
01500		AOJA A,INCMA1		;YES. COUNT AND LOOP.
01600		CAIE CH,">"		;>?
01700		JRST INCMA1		;NO. LOOP.
01800		SOJGE A,INCMA1		;YES. LOOP IF MORE TO GO. COUNT.
01900	
02000	;FROM GRTH+4
02100	
02200	INCMA2:	SOS INTDPH(R)		;POP OUT A LEVEL
02300		SUB P,[XWD 2,2]
02400		POP P,ITERCT(R)
02500		JRST RET
02600	
02700	
02800	
02900	;CD9(!)
03000	;!TAG!	TAG DEFINITION.  THE TAG IS A NAME FOR THE LOCATION IT
03100	;	APPEARS IN IN A MACRO, ITERATION OR COMMAND STRING.
03200	
03300	EXCLAM:	PUSHJ P,SKRCH		;EXCLAM JUST INCREMENTS PAST ANOTHER !-5
03400		CAIE CH,"!"
03500		JRST .-2
03600		JRST RET
03700	
03800	
03900	
04000	
     

00100	;CD9(O)
00200	;OTAG$	GO TO THE TAG NAMED TAG.  THE TAG MUST APPEAR IN THE 
00300	;	CURRENT MACRO OR COMMAND STRING.
00400	
00500	OG:	MOVE A,CPTR(R)
00600		MOVE AA,A
00700		IDIVI AA,17
00800		CAMN A,SYMS(B)
00900		JRST OGFND
01000		SKIPN SYMS(B)
01100		JRST OGNF
01200		CAMN A,SYMS+1(B)
01300	
01400	;FROM ES2+2
01500	
01600	ES1:	AOJA B,OGFND
01700		SKIPN SYMS+1(B)
01800	ES2:	AOJA B,OGNF
01900		CAMN A,SYMS+2(B)
02000		AOJA B,ES1
02100		SKIPN SYMS+2(B)
02200		ADDI B,2
02300	
02400	;FROM OG+6,ES2
02500	
02600	OGNF:	PUSH P,CPTR(R)
02700		PUSH P,B
02800		MOVEI D,STAB+1
02900		MOVEI A,41
03000		MOVEM A,-1(D)	;STAB←"!"
03100		PUSHJ P,SKRCH
03200		MOVEM CH,(D)	;STAB+1 ... ← TAG
03300		CAIE CH,175
03400		AOJA D,.-3
03500		MOVEM A,(D)	;ALTMODE: STAB+N←"!"
03600		MOVE B,COMCNT(R)
03700		SUB B,COMAX(R)	;# REMAINING COMMANDS
03800		IDIVI B,5
03900		ADD B,CPTR(R)	;MAKE A COMMAND POINTER
04000		JUMPE E,OG2
04100		SOS B
04200		MOVMS E
04300		JRST .(E)
04400		IBP B
04500		IBP B
04600		IBP B
04700		IBP B
     

00100	OG2:	MOVE AA,COMAX(R)	;ALL COMMANDS
00200	OG4:	MOVEM B,CPTR(R)
00300		MOVEM AA,COMCNT(R)
00400		MOVEI E,STAB	;INIT SEARCH STRING TO "!"
00500	OG5:	CAIN E,1(D)	;OVER STRING?
00600		JRST OG3	;YES
00700		PUSHJ P,SKRCH1	;NO. GET A CHAR
00800		CAMN CH,(E)	;MATCH ?
00900		AOJA E,OG5	;YES. MOVE ON.
01000		IBP B	;NO. TRY A NEW STARTING PT
01100		SOJA AA,OG4	;COUNT DOWN COMMANDS
01200	
01300	
01400	
01500	
01600	OG3:	POP P,A
01700		POP P,SYMS(A)
01800		MOVEM AA,CNTS(A)
01900		MOVEM B,VALS(A)
02000		JRST RET
02100	
02200	
02300	
02400	
02500	;FROM OG+4,ES1
02600	
02700	OGFND:	MOVE A,VALS(B)
02800		MOVEM A,CPTR(R)
02900		MOVE A,CNTS(B)
03000		MOVEM A,COMCNT(R)
03100		JRST RET
03200	
03300	
     

00100	;CD9(")
00200	;N"G	HAS NO EFFECT IF N IS GREATER THAT 0.  OTHERWISE,
00300	;	SEND COMMAND INTERPRETATION TO NEXT MATCHING '.
00400	;	THE " AND ' MATCH SIMILAR TO ( AND ).
00500	;N"L	SEND COMMAND TO MATCHING ' UNLESS N<0.
00600	;N"N	SEND COMMAND TO MATCHING ' UNLESS N NOT = 0.
00700	;N"E	SEND COMMAND TO MATCHING ' UNLESS N=0.
00800	;N"C	SEND COMMAND TO MATCHING ' UNLESS THE VALUE OF N AS AN ASCII
00900	;	CHARACTER IS A LETTER, NUMBER, PERIOD (.), DOLLAR SIGN ($),
01000	;	OR PER CENT (%).
01100	
01200	DQUOTE:	TRNN FF,ARG
01300		JSR ERR
01400		PUSHJ P,RCH
01500		MOVSI A,0
01600		CAIN CH,"G"
01700		MOVSI A,327000+B*40	;A:=JUMPG B,
01800		CAIN CH,"L"
01900		MOVSI A,321000+B*40	;A:=JUMPL B,
02000		CAIN CH,"N"
02100		MOVSI A,326000+B*40	;A:=JUMPN B,
02200		CAIN CH,"E"
02300		MOVSI A,322000+B*40	;A:=JUMPE B,
02400		CAIN CH,"C"
02500		JRST DQT1
02600		JUMPE A,ERRA
02700		HRRI A,RET
02800		XCT A
02900	
03000	;FROM DQT1+2
03100	
03200	NOGO:	MOVEI A,0		;NOGO INCREMENTS COMMAND POINTER OVER
03300					;A SINGLE QUOTE,SKIPPING PAIRS OF " & '.
03400		PUSHJ P,SKRCH1
03500		CAIN CH,42		;DOUBLE QUOTE
03600		AOJA A,.-2
03700		CAIN CH,"'"		;SINGLE QUOTE
03800		SOJL A,RET
03900		JRST .-5
04000	
04100	
     

00100	;FROM DQUOTE+15
00200	
00300	DQT1:	PUSHJ P,DQT3
00400		JRST RET
00500		JRST NOGO
00600	
00700	;FILSFL+11,CNTRX+5
00800	
00900	DQT2:	MOVE B,CH
01000	
01100	;ROUTINE TO TEST CHARACTER FOR $,%,.,0-9,A-Z
01200	;CALL	MOVE B,CHARACTER
01300	;	PUSHJ P,DQT3
01400	;	RETURN IF $,%,.,0-9,A-Z
01500	;	RETURN ON ALL OTHER CHARACTERS
01600	
01700	;FROM DQT1
01800	
01900	DQT3:	CAIE B,"$"		;$ OR %?
02000		CAIN B,"%"
02100		POPJ P,			;YES
02200		CAIN B,"."		;NO. POINT?
02300		POPJ P,			;YES.
02400		CAIGE B,"0"		;NO. DIGIT OR LETTER?
02500		JRST POPJ1		;NO
02600		CAIG B,"9"		;MAYBE. DIGIT?
02700		POPJ P,			;YES.
02800		CAIGE B,"A"		;NO. LETTER?
02900		JRST POPJ1		;NO.
03000		CAIG B,"Z"
03100		POPJ P,			;YES.
03200	POPJ1:	AOS 0(P)		;NO.
03300		POPJ P,0
03400	
     

00100	REPEAT 0,<
00200	
00300	XII.	SOME SIMPLE EXAMPLES OF EDITING
00400	
00500	1.	TO COPY THE ASCII FILE PGM.MAC ON DECTAPE 3, PUTTING THE NEW VERSION
00600		ON TAPE 2 WITH THE FILE NAME PGM2.MAC:
00700		ERDTA3:PGM.MAC$EWDTA2:PGM2.MAC$Y1000PEF$$
00800	
00900	2.	SAME AS (1), BUT IN THE NEW COPY CHANGE THE TITLE LINE FROM
01000		TITLE PGM1 J. SMITH TO TITLE PGM2 W. JONES.
01100		ERDTA3:PGM.MAC$EWDTA2:PGM2.MAC$
01200		YNTITLE PGM$KI2 W. JONES$-1LT$$
01300		(TECO WILL TYPE OUT THE CORRECTED LINE)
01400		1000PEF$$
01500	
01600	3.	TO COUNT LINE FEEDS IN THE BUFFER:
01700		J0UN<S
01800			$;%N>QN=$$
01900	
02000	4.	TO REPLACE ALL INSTANCES OF JUMPA WITH JRST
02100		J<SJUMPA$;-4DIJRST$>$$
02200	
02300	5.	TO CHANGE, THROUGHOUT THE BUFFER, A TO B, WHEREVER THE A
02400		IS FOLLOWED BY A DIGIT (ASCII CODE 48(BASE 10) THROUGH
02500		57(BASE 10)):
02600		J<SA$; 1A-47"G1A-58"L-1DIB$''>$$
02700	
02800	6.	TO MOVE THE POINTER TO THE LEFT OF THE FIRST CHARACTER THAT IS
02900		NOT A SPACE (I.E., TO SPACE IT OVER A ROW OF SPACES):
03000		!BK!1A-32"E1COBK$'
03100	
03200	7.	TO READ AND PERFORM A COMMAND STRING:
03300		YHXZMZ$$
03400	
03500		WITH COMPLICATED LOOPS AND ITERATIONS IT IS GENERALLY WISE TO
03600		PERFORM THEM AS MACROS SO THAT THEIR TEXT IS IN Q-REGISTERS
03700		FOR DEBUGGING AND EDITING.
03800	8.	TO MOVE ON TO A PAGE WHICH ONE WOULD RECOGNIZE BUT CANNOT
03900		DESCRIBE IN SUFFICIENT DETAIL TO USE N :
04000		<HVW-127;P>$$
04100		AS EACH PAGE APPEARS ON THE SCOPE, TYPE IN ANY CHARACTER
04200		EXCEPT RUBOUT (=127(BASE 10)) TO PROCEED TO THE NEXT PAGE, OR
04300		IF THIS IS A PAGE TO BE EDITED TYPE RUBOUT TO LEAVE THE
04400		ITERATION.
04500	>
     

00100	REPEAT 0,<
00200	
00300	XIII.	ERRORS
00400	
00500		IT IS CONCEDED THAT TECO'S ERROR MESSAGES ARE NOT OVERLY
00600	INFORMATIVE.  FOR ALL ILLEGAL OR MEANINGLESS COMMANDS TECO TYPES OUT
00700	? AND IGNORES THE REMAINDER OF THE COMMAND STRING, RETURNING TO THE
00800	IDLE STATE.  AT THIS POINT THE USER MAY TYPE ? BACK IN, AND TECO
00900	WOULD THEN RESPOND BY TYPING OUT 10 CHARACTERS OF THE COMMAND STRING,
01000	ENDING WITH THE BAD COMMAND.  SEARCH COMMANDS ARE "BAD" IF THEY FAIL AND
01100	THE : MODIFIER WAS NOT USED.
01200	
01300	>
01400	
01500	 
01600	;FROM LI3+10
01700	
01800	ERRTYP:	MOVE AA,ERR2(R)		;VALUE OF CPTR WHEN LAST ERROR OCCURRED.
01900		MOVEI B,12
02000		SUBI AA,2		;BACK POINTER UP 10 CHARACTERS.
02100		ILDB CH,AA		;GET CHARACTER
02200		CAMG B,ERR1(R)		;WAS IT IN THE COMMAND BUFFER?
02300		PUSHJ P,TYO		;YES. TYPE IT.
02400		CAME AA,ERR2(R)		;HAVE WE REACHED THE BAD COMMAND?
02500		SOJA B,.-4		;NO. DO IT AGAIN.
02600		JSR ERR			;YES. TYPE ? CRLF AND WAIT FOR NEXT COMMAND.
02700	
02800	;FROM INI,SKRCH+1,SKRCH1,COMMA+3,CLOSE+1,CHK+2,CHK1+5,YANK09+4,
02900	;INERR+2,SERCH4+4,NOFND2+2,USE+1,QREG+4,PRNT+1,DQUOTE+1,CALDDT+2,SEMICL+1,
03000	;GRTH+1,LINE+1,MAC+6,MAC+14,X+2,QGET+4,ECMD+15,
03100	;EMTAPE+1,EMTAPE+5,ININER+6,LKUPE+2,FILSPL+13,FILS4L+5,FILS5L+5,ENTERR+2
03200	
03300	ERR:	0
03400	
03500	;CD9(↑B,↑C,↑E,↑H,↑K,↑L,↑N,↑O,↑P,↑Q,↑R,↑S,↑T,↑U,↑V,↑W,↑X,↑Y
03600	;↑Z,↑[,↑\,↑],↑←,$,V,130-134,136,137),DQUOTE+16,PPA09+2
03700	
03800	ERRA:
03900		MOVEI CH,"?"		;TYPE ? CRLF
04000		PUSHJ P,TYO
04100		PUSHJ P,CRR
04200		TRO FF,QMFLG		;SET ? FLAG.
04300		MOVE A,COMAX(R)
04400		SUB A,COMCNT(R)
04500		MOVEM A,ERR1(R)		;ERR1:=COMAX-COMCNT
04600		MOVE A,CPTR(R)
04700		MOVEM A,ERR2(R)		;ERR2:=CPTR
04800		JRST GO			;GET NEXT COMMAND
04900	
05000	
05100	
05200	U ERR1,1			;ERRA+6
05300	U ERR2,1			;ERRA+10
     

00100	;UUO HANDLER
00200	;HALTS ON UNDEFINED UUO
00300	;CALL	TYPR1	X
00400	;PRINTS STRING AT X TERMINATED BY ! AND REINITIALIZES AT GOZ.
00500	
00600	ETYPER:	0
00700		HLRZ B,40
00800		CAIE B,30000		;TYPR1?
00900		JRST 4,.		;NO. OOPS
01000		HRLZI B,440700		;YES. ADDRESS POINTS TO MESSAGE TERMINATED BY !
01100		HRR B,40
01200		ILDB CH,B
01300		CAIN CH,"!"		;END OF MESSAGE?
01400		JRST GOZ		;YES. REINITIALIZE
01500		PUSHJ P,TYO		;NO. PRINT A CHARACTER
01600		JRST .-4
01700	
01800	U LISTF5,1			;OUTPUT DISPATCH
01900	
02000	
02100	
02200	XXTY01:	ASCII /STORAGE CAPACITY EXCEEDED
02300	!/
02400	XXTY02:	ASCII /GC ERROR
02500	!/
02600	
02700	
02800	
02900	ILMEM:	REPEAT 0,<
03000		JRST .		;THIS SHOULD BE FIXED UP
03100		CONSO 200000
03200		MOVEI B,10
03300		MOVE P,[XWD -LPDL,PDL]
03400		MOVEI CH,7
03500		PUSHJ P,TYO
03600		SOJG B,.-1
03700		JRST 10,ERR+1
03800	>
     

00100	REPEAT 0,<
00200	
00300	XIV.	DEBUGGING FEATURES
00400	
00500		AS AN AID TO DEBUGGING MACROS AND ITERATIONS, TECO WILL
00600	WHEN IN TRACE MODE TYPE ON THE TELETYPE EACH COMMAND AS IT IS INTERPRETED,
00700	INTERSPACED WITH REQUESTED TELETYPE OUTPUT.  TRACE MODE IS CONTROLLED
00800	BY A FLIP-FLOP WHICH IS CONTROLLED AS FOLLOWS:
00900	
01000	?	WHEN NOT THE FIRST COMMAND OF A COMMAND STRING, COMPLEMENTS
01100		THE TRACE FLIP-FLOP.
01200	TECO  ALSO ALLOWS THE USER TO INSERT COMMENNTS:
01300	
01400	↑ATEXTCTRL A
01500		OUTPUTS TO THE TELETYPE THE TEXT UP TO BUT NOT INCLUDING THE
01600		TERMINATING CTRL A.  THE TEXT IS OTHERWISE IGNORED AND COMMAND
01700		INTERPRETATION RESUMES AFTER THE TERMINATING CTRL A.  SINCE
01800		THE TERMINATOR IS NOT A COMMAND, IT MUST BE TYPED WITH THE
01900		CTRL KEY AND MAY NOT BE TYPED AS ↑A.
02000	
02100	LASTLY, IF DDT HAS BEEN LOADED WITH TECO,
02200	↑D	TRANSFERS CONTROL TO DDT.
02300	>
02400	
02500	
02600	
     

00100	;CD9(?)
00200	
00300	QUESTN:	MOVE A,[JRST TYO]
00400		TRCE FF,TRACEF
00500		MOVSI A,263000+P*40	;TRACS:=POPJ P,
00600		MOVEM A,TRACS(R)
00700		JRST RET
00800	
00900	
01000	COMMENT:	PUSHJ	P,SKRCH	;GET A COMMENT CHAR
01100		CAIN	CH,1		;↑A
01200		POPJ	P,0		;DONE
01300		PUSHJ	P,TYO		;TYPE IT
01400		JRST	COMMENT		;AND LOOP
01500	
01600	
01700	
01800	
01900	
02000	;CD9(↑D)
02100	
02200	CALDDT:	SKIPE T,JOBDDT(R)
02300		JRST (T)
02400		JSR ERR
02500	
02600	
02700	
02800	
02900	
     

00100	;ROUTINE TO RETURN STRING OPERATION STRING ARGUMENTS.
00200	;ARGUMENTS ARE CHARACTER ADDRESSES IN THE DATA BUFFER.
00300	;TRANSFORMS M,N OR N, WHERE THE LATTER SPECIFIES A NUMBER OF LINES,
00400	;TO ARGUMENTS.
00500	;CALL	PUSHJ P,GETARG
00600	;	RETURN WITH FIRST ARGUMENT ADDRESS IN C, SECOND IN B.
00700	
00800	
00900	
01000	;FROM KILL,TYPE+1,LINE+2,X
01100	
01200	GETARG:	TRNE FF,ARG2		;IS THERE A SECOND ARGUMENT?
01300		JRST GETAG6		;YES
01400	
01500	;N	SIGN INDICATES DIRECTION RELATIVE TO PT.
01600		TRON FF,ARG		;NO. IS THERE AN ARGUMENT?
01700		PUSHJ P,CHK22		;NO. B:=1 IS LAST ARGUMENT FUNCTION WAS +,*,OR /
01800					;B:=-1, IF &,#, OR -
01900					;IE, ASSUME AN ARGUMENT OF 1 AND RETAIN SIGN
02000		MOVE IN,PT(R)		;IN:=PT
02100	GETAG4:	JUMPLE B,GETAG2		;WAS LAST ARGUMENT FUNCTION -?
02200		CAMN IN,Z(R)		;NO. ARGUMENT IS LOCATION OF NTH LINE
02300					;FEED FORWARD FROM PT.
02400					;IS PT AT END OF BUFFER?
02500		JRST GETAG1		;YES.
02600		PUSHJ P,GETINC		;NO. CH:=NEXT DATA BUFFER CHARACTER, IN:=IN+1
02700		CAIE CH,12		;LINE FEED?
02800		JRST GETAG4		;NO. TRY AGAIN.
02900		SOJG B,GETAG4		;YES. NTH LINE FEED?
03000	
03100	
03200	GETAG1:	MOVE B,IN		;YES. RETURN FIRST ARGUMENT IN C
03300		MOVE C,PT(R)		;SECOND IN B.
03400		POPJ P,
03500	
03600	;M,N
03700	GETAG6:	ADD B,BEG(R)		;C:=M+BEG
03800		ADD C,BEG(R)		;B:=N+BEG
03900		POPJ P,
04000	
04100	GETAG2:	SOS IN			;ARGUMENT IS POSITION OF NTH LINE FEED TO LEFT OF PT.
04200					;N:=N-1
04300		CAMG IN,BEG(R)		;PASSED BEGINNING OF BUFFER?
04400		JRST GETAG3		;YES. IN:=BEG
04500		PUSHJ P,GETINC		;NO. CH:=NEXT DATA BUFFER CHARACTER. IN:=IN+1
04600		CAIE CH,12		;LINE FEED?
04700		SOJA IN,GETAG2		;NO. BACK UP ONE POSITION AND TRY AGAIN.
04800		AOJLE B,.-1		;YES. NTH LINE FEED?
04900	
05000	GETAG3:	CAMGE IN,BEG(R)		;YES. PASSED BEGINNING OF BUFFER?
05100		MOVE IN,BEG(R)		;YES. RESET TO BEGINNING.
05200		MOVE C,IN		;NO. RETURN FIRST ARGUMENT IN C.
05300		MOVE B,PT(R)		;SECOND IN B
05400		POPJ P,
05500	
05600	
05700	
     

00100	;ROUTINE TO RETURN IN CH THE CHARACTER TO THE RIGHT OF THE POINTER
00200	;AND INCREMENT THE POINTER.
00300	;CALL	MOVE IN,POINTER (AS A CHARACTER ADDRESS)
00400	;	PUSHJ P,GETINC
00500	;	RETURN WITH CHARACTER IN CH AND POINTER TO CHARACTER IN IN.
00600	
00700	;FROM SERCH3+2,TYPE3+2,BAKSLA+2,MAC+12,MAC+15,X1+4,QGET+10,QGET+12,
00800	;QGET1+1,GETAG4+3,GETAG2+3,GCS4A+1,GCERR+1,GCERR+3
00900	
01000	GETINC:	PUSHJ P,GET
01100		AOJA IN,CPOPJ
01200	
01300	;FROM APPND1+1,MAC+17,GETINC,GCM2+2
01400	
01500	GET:	MOVE TT,IN
01600		IDIVI TT,5
01700		HLL TT,BTAB(TT1)
01800		LDB CH,TT
01900		POPJ P,
02000	
02100	;FROM YANK5+7,INS1B+4,TAC2+3,X+21,X+24,X1,QGET1+2
02200	
02300	PUT:	MOVE TT,OUT
02400		IDIVI TT,5
02500		HLL TT,BTAB(TT1)
02600		DPB CH,TT
02700		POPJ P,
02800	
02900	;CHARACTER TRANSLATION BYTE POINTER TABLE
03000	;TRANSLATES 1 CHARACTER POSITION TO THE RIGHT OF A CHARACTER ADDRESS POINTER
03100	
03200	BTAB:	XWD 350700+R,0
03300		XWD 260700+R,0
03400		XWD 170700+R,0
03500		XWD 100700+R,0
03600		XWD 10700+R,0
03700	
03800	
03900	
04000	
04100	TYOM:	PUSH P,C	;TYO TO MEMORY
04200		PUSH P,OUT
04300		PUSH P,TT
04400		PUSH P,TT1
04500		PUSHJ P,TAB2
04600		POP P,TT1
04700		POP P,TT
04800		POP P,OUT
04900		POP P,C
05000		POPJ P,
05100	
     

00100	
00200	;FROM DELETE+7,INSERT+13,TAB2+1,BAKSL1+10,X+12,QGET+21
00300	
00400	NROOM:	MOVEM 17,AC2+15(R)	;SAVE 17
00500		MOVE 17,PT(R)
00600		CAMN 17,Z(R)		;PT=Z? I.E., DATA BUFFER EXPANSION?
00700		JRST NROOM1		;YES.
00800		MOVE 17,[XWD 2,AC2]	;NO. SAVE ACS 2 THROUGH 16.
00900	IFN <R>,<	ADDI 17,(R)		;RELOCATE BLT POINTER ADDRESS.>
01000		BLT 17,AC2+14(R)
01100		JUMPL C,NROOM6		;DELETION?
01200		SETOM GCFLG(R)		;NO.
01300		SETZM  CRREL(R)
01400		SETZM  RREL(R)
01500	
01600	;MOVE STRING STORAGE UP C CHARACTERS STARTING AT PT.
01700	;FROM GC+26,GCS2+2
01800	
01900	NROOM9:	MOVE 17,Z(R)
02000		ADD 17,C
02100		CAML 17,MEMSIZ(R)	;WILL REQUEST OVERFLOW MEMORY?
02200		JRST GC			;YES. GARBAGE COLLECT.
02300	;MOVE FROM PT THROUGH Z UP C POSITIONS
02400		MOVE 14,C		;NO.
02500		IDIVI 14,5		;AC14:=Q(REQ/5), AC15:=REM(REQ/5)
02600		IMULI 15,7		;AC15:=(REM(REQ/5))*7
02700		MOVN 13,15		;AC13:=-(REM(REQ/5))*7
02800		MOVEI 15,-43(15)	;AC15:=(REM(REQ/5))*7-43
02900		MOVE 11,PT(R)
03000		IDIVI 11,5		;AC11:=Q(PT/5), AC12:=REM(PT/5)
03100		MOVNI 16,-5(12)
03200		IMULI 16,7		;AC16:=-(REM(PT/5)-5)*7
03300		DPB 16,[XWD 300600+R,NROOM2]	;SET SIZE FIELD OF LAST PARTIAL WORD POINTER.
03400		ADDI 14,1(11)		;AC14:=Q(REQ/5)+Q(PT/5)+1
03500		MOVE 16,Z(R)
03600		IDIVI 16,5		;AC16:=Q(Z/5)
03700		MOVEI B,1(16)
03800		SUB B,11		;B:=Q(Z/5)+1-Q(PT/5)=NO. OF WORDS TO MOVE.
03900	;PUT MOVE ROUTINE IN FAST ACS
04000		HRLI 11,200000+B+A*40	;AC11:=MOVE A,[Q(PT/5)](B)
04100		HRLOI 12,241000+A*40	;AC12:=ROT A,-1
04200		HRLI 13,245000+A*40	;AC13:=ROTC A,-(REM(REQ/5))*7
04300		HRLI 14,202000+B+AA*40	;AC14:=MOVEM AA,[Q(PT/5)+1](B)
04400		HRLI 15,245000+A*40	;AC15:=ROTC A,(REM(REQ/5))*7-43
04500		MOVE 17,[JRST,NROOM7]	;AC16:=SOJGE B,11
04600		MOVE 16,.+1		;AC17:=JRST NROOM7
04700		SOJGE B,11		;B:=B-1. DONE?
04800	NROOM7:	ROTC A,43(13)		;YES. STORE LAST PARTIAL WORD.
04900		DPB A,NROOM2(R)
05000		ADDM C,Z(R)		;Z:=Z+REQ
05100	
     

00100	;FROM NROOM3+1
00200	
00300	NROOM5:	MOVE 17,[XWD 2,AC2]	;RESTORE ACS AND RETURN.
00400	IFN <R>,<		ADDI 17,(R)		;RELOCATE BLT POINTER ADDRESS>
00500		MOVSS 17
00600		BLT 17,17
00700		POPJ P,
00800	
00900	
01000	U NROOM2,1			;POINTER TO LAST PARTIAL WORD ON UPWARD MOVE.
01100	
01200	;EXPAND DATA BUFFER
01300	;FROM NROOM+3
01400	
01500	NROOM1:	ADDM C,Z(R)		;PT=Z.  Z:=Z+REQ
01600		PUSH P,C		;SAVE REQUEST
01700		MOVE C,Z(R)
01800		CAML C,MEMSIZ(R)	;DID WE OVERFLOW MEMORY?
01900		JRST GC1		;YES. GARBAGE COLLECT.
02000		POP P,C			;GARBAGE COLLECTION WAS SUCCESSFUL. RESTORE REQUEST.
02100		MOVE 17,AC2+15(R)	;RESTORE 17
02200		POPJ P,			;RETURN
02300	
     

00100	;MOVE FROM PT+ABS(C) THROUGH Z DOWN ABS(C) POSITIONS.
00200	;FROM NROOM+6
00300	
00400	NROOM6:	MOVE 14,PT(R)		;INITIALIZE PARTIAL WORD POINTER.
00500		IDIVI 14,5		;AC14:=Q(PT/5), AC15:=REM(PT/5)
00600		MOVEM 14,B		;B:=Q(PT/5)
00700		HRRM 14,NROOM4(R)
00800		IMULI 15,7
00900		DPB 15,[XWD 300600+R,NROOM4]	;SIZE:=(REM(PT/5))*7
01000		MOVNI 15,-44(15)
01100		DPB 15,[XWD 360600+R,NROOM4]	;POSITION:=44-(REM(PT/5))*7
01200		MOVE 11,Z(R)
01300		IDIVI 11,5		;AC11:=Q(Z/5)+1, AC12:=REM(Z/5)
01400		ADDI 11,1
01500		MOVE 13,C
01600		IDIVI 13,5
01700		ADDI 13,-1(11)		;AC13:=Q(Z/5)-Q(REQ/5)
01800		MOVNM 14,12		;AC12:=(REM(REQ/5))*7
01900		IMULI 12,7
02000		MOVNI 15,-43(12)	;AC15:=43-(REM(REQ/5))*7
02100		SUBI B,1(13)		;B:=Q(PT/5)+Q(REQ/5)-Q(Z/5)-1:=# WORDS TO MOVE
02200	
02300	NROOM8:	HRLI 11,200000+B+AA*40	;AC11:=MOVE AA,[Q(Z/5)+1](B)
02400		HRLI 12,245000+A*40	;AC12:=ROTC A,(REM(REQ/5))*7
02500		HRLI 13,202000+B+A*40	;AC13:=MOVEM A,[Q(Z/5)-Q(REQ/5)](B)
02600		MOVE 14,[ADDM A,@13]	;AC14:=ADDM A,@13
02700		HRLI 15,245000+A*40	;AC15:=ROTC A,43-(REM(REQ/5))*7
02800		MOVE 17,[JRST NROOM3]	;AC16:=AOJLE B,11
02900		ADDM C,Z(R)		;AC17:=JRST NROOM3
03000		LDB C,NROOM4(R)
03100		MOVE A,@11		;Z:=C(Z)-REQ
03200		ROT A,-1		;A:=Q(PT/5)+Q(REQ/5) RIGHT JUSTIFIED.
03300		MOVE 16,.+1
03400		AOJLE B,11		;B:=B+1.  DONE?
03500	
03600	NROOM3:	DPB C,NROOM4(R)		;YES. DEPOSIT PARTIAL WORD.
03700		JRST NROOM5
03800	
03900	U NROOM4,1			;PARTIAL WORD POINTER FOR DOWNWARD MOVE
04000					;NROOM6+3
     

00100	
00200	;FROM NROOM9+3
00300	
00400	GC:	AOSE GCFLG(R)		;FIRST ATTEMPT?
00500	
00600	;FROM LI2+23,NROOM1+4
00700	GC1:	TYPR1 XXTY01		;NO. TYPE "STORAGE CAPACITY EXCEEDED"
00800	
00900		SETOM GCPTR(R)		;YES. GCPTR:=-1
01000		SETZM  SYMS(R)		;CLEAR SYMS,VALS AND CNTS TABLES
01100		MOVE T,[XWD SYMS,SYMS+1]
01200	IFN <R>,<	ADD T,R>
01300		BLT T,SYMEND-1(R)
01400		MOVEI T,CPTR(R)		;COMMAND BUFFER
01500		PUSHJ P,GCMA
01600		HRRZ T,P
01700		SUBI T,(R)
01800		CAIL T,PDL(R)		;PUSHDOWN LIST EMPTY?
01900		PUSHJ P,GCMA		;NO. GARBAGE COLLECT ALL BYTE POINTERS ON IT.
02000		CAILE T,PDL(R)
02100		SOJA T,.-2
02200		HRRZ T,AC2+PF-2(R)	;GARBAGE COLLECT Q-REG PUSHDOWN LIST.
02300		CAIL T,PFL(R)
02400		PUSHJ P,GCM
02500		CAILE T,PFL(R)
02600		SOJA T,.-2
02700		MOVE T,[XWD -44,QTAB]	;GARBAGE COLLECT Q-REGISTERS.
02800		PUSHJ P,GCM
02900		AOBJN T,.-1
03000		SKIPGE GCPTR(R)		;ANYTHING TO COLLECT?
03100		JRST NROOM9		;NOPE.
     

00100	
00200	GCS:	MOVE IN,QRBUF(R)
00300	
00400	;FROM GCERR+7
00500	
00600	GCS1A:	MOVSI TT,1*5		;TT>MAX. NO. CHARACTERS IN WORLD
00700		MOVE OUT,GCPTR(R)	;GO BACKWARDS THROUGH GCTAB
00800	GCS1:	HRRZI A,GCTAB(<OUT>)	;RELOCATE
00900		TLO A,R
01000		HRRZ A,@A
01100		ADD A,QRBUF(R)
01200		CAMGE A,IN
01300		JRST GCS2
01400		CAMGE A,TT		;SET TT TO HIGHEST CHARACTER POSITION
01500		MOVE TT,A
01600	GCS2:	SOJGE OUT,GCS1
01700		TRNN TT,-1		;ANYTHING TO COLLECT?
01800		JRST NROOM9		;NOPE.
01900		MOVE F,TT		;HIGHEST CHARACTER.
02000		IDIVI IN,5		;C(QRBUF)/5
02100		IDIVI F,5		;HIGH CHAR/5
02200		AOS IN			;C(QRBUF)/5+1
02300		MOVS OUT,F
02400		MOVE T,F
02500		SUB T,IN		;HIGH CHAR/5-C(QRBUF)/5+1
02600		JUMPLE T,GCS4A		;ANYTHING TO GET?
02700		HRR OUT,IN		;XWD HIGH CH/5,HIGH CH/5-C(QRBUF)/5+1=NREG
02800		MOVE B,Z(R)
02900		IDIVI B,5
03000		SUB B,T			;Z/5-NREG
03100		HRLI B,R
03200	IFN <R>,<	ADD OUT,R>
03300		BLT OUT,@B		;MOVE STUFF DOWN
03400		MOVNS OUT,T
03500		IMULI OUT,5		;OUT:=-5*NREG
03600		ADDM OUT,BEG(R)		;BEG:=C(BEG)-5*NREG
03700		ADDM OUT,PT(R)		;PT:=C(PT)-5*NREG
03800		ADDM OUT,Z(R)		;Z:=C(Z)-5*NREG
03900		ADDM OUT,RREL(R)	;RREL:=C(RREL)-5*NREG
04000		MOVE CH,GCPTR(R)	;UPDATE INSERTER
04100		HRLI TT1,R
     

00100	
00200	;FROM GCS4
00300	
00400	GCS3:	HRRI TT1,GCTAB(CH)
00500		HRRZ A,@TT1
00600		ADD A,QRBUF(R)
00700		CAMGE A,TT
00800		JRST GCS4
00900		ADDM OUT,@TT1
01000		HLRZ A,@TT1
01100		CAIN A,CPTR(R)		;IN COMMAND BUFFER?
01200		ADDM OUT,CRREL(R)	;YES. UPDATE COMMAND POINTER RELOCATION
01300		HRLI A,R
01400		SKIPL @A		;Q-REG?
01500		ADDM T,@A		;NO
01600		SKIPGE @A		;Q-REG?
01700		ADDM OUT,@A		;YES. RELOCATE BASE POINTER.
01800	
01900	;FROM GCS3+3
02000	
02100	GCS4:	SOJGE CH,GCS3		;DONE?
02200		ADD TT,OUT		;YES. IN:=C(TT)-5*NREG
02300	
02400	;FROM GCS2+12
02500	
02600	GCS4A:	MOVE IN,TT		;IN SHOULD POINT TO AN END OF STRING FLAG (141)
02700		PUSHJ P,GETINC
02800		CAIE CH,141
02900	
03000	;FROM GCM2+11
03100	
03200	GCERR:	TYPR1 XXTY02		;STRANGE LOSS
03300	
03400		PUSHJ P,GETINC
03500		MOVE A,CH
03600		PUSHJ P,GETINC
03700		ROT CH,7
03800		IOR A,CH
03900		ADDI IN,-3(A)
04000		JRST GCS1A
04100	
     

00100	;FROM GC+17,GC+23
00200	
00300	GCM:	MOVE IN,(T)
00400		TLZE IN,400000		;DOES Q-REG CONTAIN TEXT?
00500		TLZE IN,377777
00600		POPJ P,			;NO
00700		ADD IN,QRBUF(R)		;YES. ENTER POINTER IN GCTAB
00800	
00900	;FROM GCMA+15
01000	
01100	GCM2:	CAML IN,BEG(R)		;REGION BEFORE TEXT BUFFER?
01200		POPJ P,			;NO. FORGET IT.
01300		PUSHJ P,GET		;YES. CHECK FOR MARK.
01400		CAIE CH,141		;END OF STRING?
01500		POPJ P,			;NO.
01600		SUB IN,QRBUF(R)		;YES. IN:=# CHARACTERS TO RETREIVE.
01700					; IN Q-REG BUFFER AREA?
01800		JUMPL IN,CPOPJ		;NO. FORGET IT.
01900		AOS TT,GCPTR(R)		;YES. TO BE GRABBED.
02000		CAIL TT,GCTBL		;AM I WINNING?
02100		JRST GCERR		;NO. VERY BAD.
02200		HRL IN,T		;XWD ADDRESS OF BYTE POINTER,NO. CHARACTERS
02300		ADDI TT,GCTAB		;RELOCATE
02400		HRLI TT,R
02500		MOVEM IN,@TT		;SAVE DATA
02600		POPJ P,			;DONE THIS POINTER
02700	
02800	;IF T POINTS TO AN ASCII BYTE POINTER, IN:=CHARACTER ADDRESS OF TOP
02900	;OF STRING - NO. OF CHARACTERS.
03000	;FROM GC+7,GC+12
03100	
03200	GCMA:	HRLI TT1,R
03300		HRR TT1,T
03400		LDB TT,[XWD 221420,TT1]	;BYTE SIZE + XR
03500		TRC TT,700		;DOES T POINT TO A TEXT BYTE POINTER?
03600		TRCE TT,700
03700		POPJ P,			;NO
03800		SOS TT1
03900		MOVE IN,@TT1		;MAYBE. GET WORD BEFORE POINTER. (MAX)
04000		ADDI TT1,2
04100		SUB IN,@TT1		;MAX-CT
04200		SOS TT1
04300		LDB TT,[XWD 360620,TT1]	;BYTE POSITION
04400		IDIVI TT,7		;NO. OF CHARACTERS
04500		MOVEI TT1,4-3+1		;2
04600		SUB TT1,TT		;2-NO. OF CHARACTERS
04700		HRRZ TT,(T)		;POINTER WORD ADDRESS (UNRELOCATED)
04800		IMULI TT,5		;5*ADDRESS
04900		ADD TT,TT1
05000		SUBM TT,IN		;5*ADDRESS-NO. CHARS+2+MAX-CT
05100		JRST GCM2
05200	
05300	
05400	
     

00100	U BEG,1			;INIT+32,LI2+15,X+17,GCS2+22
00200	U PT,1			;INIT+33,LI2+16,YANK1+1,JMP1+1,KILL+2,DELETE+6,
00300				;INS1B+5,TAB2+2,SRCH5A,FND+3,NOFND+1,BAKSL2+2
00400				;LINE+4,X+11,X2+3,QGET+3,GCS2+23
00500	U Z,1			;INIT+34,LI2+17,YANK51,NROOM9+35,NROOM1,NROOM8+6,GCS2+24
00600	U QRBUF,1		;INIT+35,LI2+20
00700	;*** DO NOT SEPARATE ***
00800	U COMAX,1		;NO. CHARACTERS IN COMMAND BUFFER AT START  OF EXECUTION
00900				;RCH2+2,LI4+12,OG4,MAC+23
01000	U CPTR,1		;COMMAND BUFFER BYTE POINTER
01100				;RCH2+2,LI4+10,OGFND+1,GRTH+6,MAC+30
01200	U COMCNT,1		;NO. CHARACTERS REMAINING IN COMMAND BUFFER
01300				;RCH,RCH2+1,SKRCH1,LI3+2(0),LI3+7,LI3+23,LI4+5,OG4+1
01400				;OGFND+4,GRTH+10,MAC+22
01500	;*** DO NOT SEPARATE ***
01600	U CBUFH,1		;INIT+37,LI3
01700	U MEMSIZ,1		;INIT+13
01800	U GCPTR,1		;GC+2(-1)
01900	U CRREL,1		;NROOM+10(0),GCS3+7
02000	U GCFLG,1		;NROOM+7(-1),GC
02100	U RREL,1		;NROOM+11(0),GCS2+25
     

00100	;COMMAND DISPATCH TABLE
00200	;DISPATCH IS BY XCT DTB(CH)
00300	;FORMAT:
00400	;	MOVEI A,X	;IF X RETURNS A VALUE
00500	;	HRROI A,X	;IF X DOES NOT RETURN A VALUE AND EXITS WITH POPJ
00600	;	JRST X		;IF X DOES NOT RETURN A VALUE AND EXITS TO A
00700	;			;FIXED LOCATION.
00800	
00900	DTB:	
01000		HRROI A,ERRA	;↑@
01100		HRROI A,COMMENT	;↑A
01200		HRROI A,ERRA	;↑B
01300		HRROI A,ERRA	;↑C
01400		MOVEI A,CALDDT	;↑D
01500		HRROI A,ERRA	;↑E
01600		MOVEI A,LAT	;↑F
01700		MOVEI A,DECDMP	;↑G
01800		MOVEI A,GTIME	;↑H
01900		HRROI A,TAB	;↑I
02000		MOVEI A,CD	;↑J
02100		HRROI A,ERRA	;↑K
02200		HRROI A,TYO	;↑L
02300		MOVEI A,CD	;↑M
02400		HRROI A,ERRA	;↑N
02500		HRROI A,ERRA	;↑O
02600		HRROI A,ERRA	;↑P
02700		HRROI A,ERRA	;↑Q
02800		HRROI A,ERRA	;↑R
02900		HRROI A,ERRA	;↑S
03000		MOVEI A,SPTYI	;↑T
03100		HRROI A,ERRA	;↑U
03200		HRROI A,ERRA	;↑V
03300		HRROI A,ERRA	;↑W
03400		HRROI A,ERRA	;↑X
03500		HRROI A,ERRA	;↑Y
03600		HRROI A,ERRA	;↑Z
03700		HRROI A,ERRA	;↑[
03800		HRROI A,ERRA	;↑BACKSLASH
03900		HRROI A,ERRA	;↑]
04000		MOVEI A,CNTRUP	;↑↑
04100		HRROI A,ERRA	;↑LEFT ARROW
04200	
     

00100	
00200		MOVEI A,CD2	;SPACE
00300		MOVEI A,EXCLAM	;!
00400		MOVEI A,DQUOTE	;"
00500		MOVEI A,COR	;#
00600		HRROI A,ERRA	;$
00700		MOVEI A,PCNT	;%
00800		MOVEI A,CAND	;&
00900		MOVEI A,CD	;SINGLE QUOTE
01000		MOVEI A,OPEN	;(
01100		MOVEI A,CLOSE	;)
01200		MOVEI A,TIMES	;*
01300		MOVEI A,CD2	;+
01400		MOVEI A,COMMA	;,
01500		MOVEI A,MINUS	;-
01600		MOVEI A,PNT	;.
01700		MOVEI A,SLASH	;/
01800		JRST CDNUM	;0
01900		JRST CDNUM	;1
02000		JRST CDNUM	;2
02100		JRST CDNUM	;3
02200		JRST CDNUM	;4
02300		JRST CDNUM	;5
02400		JRST CDNUM	;6
02500		JRST CDNUM	;7
02600		JRST CDNUM	;8
02700		JRST CDNUM	;9
02800		MOVEI A,COLON	;:
02900		MOVEI A,SEMICL	;;
03000		MOVEI A,LSSTH	;<
03100		HRROI A,PRNT	;=
03200		MOVEI A,GRTH	;>
03300		MOVEI A,QUESTN	;?
     

00100	
00200		MOVEI A,ATSIGN	;@
00300		MOVEI A,ACMD	;A
00400		MOVEI A,BEGIN	;B
00500		MOVEI A,CHARAC	;C
00600		MOVEI A,DELETE	;D
00700		HRROI A,ECMD	;E
00800		JRST RET	;F
00900		MOVEI A,QGET	;G
01000		MOVEI A,HOLE	;H
01100		HRROI A,INSERT	;I
01200		MOVEI A,JMP	;J
01300		MOVEI A,KILL	;K
01400		MOVEI A,LINE	;L
01500		JRST MAC	;M
01600		MOVEI A,SERCHP	;N
01700		MOVEI A,OG	;O
01800		HRROI A,PUNCH	;P
01900		MOVEI A,QREG	;Q
02000		MOVEI A,REVERS	;R
02100		MOVEI A,SERCH	;S
02200		HRROI A,TYPE	;T
02300		MOVEI A,USE	;U
02400		HRROI A,ERRA	;V
02500		MOVEI A,CD	;W
02600		MOVEI A,X	;X
02700		HRROI A,YANK	;Y
02800		MOVEI A,END1	;Z
02900		MOVEI A,OPENB	;[
03000		MOVEI A,BAKSL	;BACKSLASH
03100		MOVEI A,CLOSEB	;]
03200		MOVEI A,UAR	;↑
03300		MOVEI A,LARR	;LEFT ARROW
     

00100	
00200		REPEAT 175-137-1,<HRROI A,ERRA>
00300		MOVEI A,ALTMOD	;ALT MODE
00400		HRROI A,ERRA
00500		HRROI A,ERRA
     

00100	U STAB,0		;SEARCH TABLE
00200				;SERCH4+2,OGNF+4,OGNF+6,OGFN+11
00300	U AC2,16		;SAVE AC2-AC17 IN NROOM ROUTINE
00400				;NROOM,NROOM5
00500	U BAKTAB,40-3-16	;RECEIVES ASCII CONVERSION OF NUMERICAL ARGUMENT
00600				;BAKSL4
00700	
00800	CFIL1←STAB
00900	CFIL2←STAB+1
01000	U STABP,0
01100	U SYMS,22		;LIS+4(0),OG3+1,GC+3(0)
01200	U VALS,22		;LIS+4(0),OG3+3,GC+3(0)
01300	U CNTS,22		;LIS+4(0),OG3+2,GC+3(0)
01400	U SYMEND,0
01500	U PFL,LPF
01600	U GCTAB,GCTBL		;GCS3+4,GCM2+13
01700	U QTAB,45		;Q-REGISTER TABLE
01800				;USEA+1,PCNT+1
01900	U PDL,LPDL
02000	U UAC,17
02100	
02200	
02300	
02400	PATCH:	BLOCK 10
     

00100	
00200	LIT
00300	U CBUF,0
00400	U TOP,0
00500	CODEND:	END INIT
00600