Google
 

Trailing-Edge - PDP-10 Archives - BB-M836B-BM - tools/sed/sed.mac
There are 2 other files named sed.mac in the archive. Click here to see a list.
TITLE	SED - TOPS10/TOPS20 SCREEN EDITOR
SUBTTL	A CHRISTOPHER HALL FECIT

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1981,1982 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	SEARCH	SEDSYM
	SALL
IF1,<
IFN TOPS10,<PRINTX ASSEMBLING SED FOR TOPS10>
IFE TOPS10,<PRINTX ASSEMBLING SED FOR TOPS20>
IFE NEWTAB,<PRINTX USING OLD COMMAND TABLES>
IFN FTDDT,<PRINTX DDT SWITCH IS ON>
>
;TREATMENT BY TOPS10:
;	PIM MODE: NO CODES ECHOED; INTERRUPT ON EVERY CHARACTER
;	<C> IS A LEGAL COMMAND DISPATCHING TO ROUTINE "ABORT"
;TREATMENT BY TOPS20:
;	ALL CODES ARE SENT TO PROGRAM WITH NO ECHO
;	MONITOR SENDS A <J> AFTER A <M>
;	<C> IS JUST ANOTHER CHARACTER

IFN TOPS10,<
	TWOSEG
	LOC	134
	INTERR
	LOC	137
	BYTE	(3)CUSTVR (9)HALVER (6)HALMVR (18)HALEVR
	RELOC	400000

	SEARCH	UUOSYM
>
IFE TOPS10,<
ENTVEC:	JRST	START		;START ADDR, REEENT ADDR, AND VERSION
	JRST	START
	BYTE	(3)CUSTVR (9)HALVER (6)HALMVR (18)HALEVR
ENTLEN==.-ENTVEC

	SEARCH	MONSYM
>
	EXTERN	TERMNL
	INTERN	PUTSEQ,PUTSTG,PUTNUM,PUTSQ1,PUTTYP,TRMNAM,TYPBUF,HOMPOS
	INTERN	CHOME,CDOWN,CRIGHT,CPOPJ
	EXTERN	.JBREL,.JBAPR,.JBTPC,.JBREN,.JBFF

START:	JFCL			;(TO ACCOUNT FOR CCL ENTRY)
	RESET			;MAKE SURE THE WORLD IS RIGHT
STARTR:	MOVE	P,[IOWD STKSIZ,STACK]
	SETOM	STTFLG		;SAY SED IS INITIALIZING
IFE TOPS10,<
IFN FTECHO,<
	HRRZM	P,EKOFLG	;MAKE SURE THE ECHO
	HRRZM	P,BRKFLG	;  AND BREAK FLAGS ARE POSITIVE
>
	MOVEI	T1,PARBUF+37	;MAKE SURE THE BUFFER IS HIGH ENOUGH
	CAIGE	T1,BUFBLK_11	;IS IT?
	JRST	START0		;YES - PROCEED
	HRROI	T1,[ASCIZ /?FATAL GLITCH: Add 1 to BUFBLK and reassemble SED
/]
	PSOUT
	HALTF			;THE WORLD WON'T BE RIGHT UNTIL IT'S FIXED
START0:
IFN FTSTSN,<
	MOVE	T1,[SIXBIT /SED/] ;ENTER SED IN THE SUBSYSTEM TABLE
	MOVE	T2,T1
	SETSN
	  JFCL
>
	HRRZ	T1,.JBREL	;FIND BLOCK SIZE OF STARTING FILE BUFFER
	SUBI	T1,BUFFER-1000	;  PLUS SYMBOL TABLE, ETC.
	LSH	T1,-11		;(EXPRESS IT IN BLOCKS)
	MOVEM	T1,FILBSZ	;SAVE IT
>
	MOVE	TY,TYPPTR	;SET UP TYPE BUFFER POINTER
	PUSHJ	P,INITTY	;MAKE THE EDITOR RECEIVE WHAT'S REALLY TYPED
	MOVEI	T1,XBFNUM-1	;MAKE LAST (NULL) EXECUTE BUFFER ACTIVE
	MOVEM	T1,XCTACW
	MOVE	T1,[010700,,XCTFRE-1]
	MOVEM	T1,XCFPTR	;SAVE POINTER TO START OF FREE SPACE
	ADDI	T1,XCFSIZ	;AND END OF F.S. FOR OVERFLOW CHECKING
	MOVEM	T1,XCTOVF
	MOVEI	T1,1		;SET UP NOMINAL FOR EXECUTE COUNTER
	MOVEM	T1,XCTSNM
	MOVEM	T1,XCTITR	;SET UP NUMBER OF TIMES TO ITERATE AN EXECUTE
	SETZM	CLSBUF+400	;CLEAR COUNT OF /DC SETTINGS
	SETOM	ISVNUM
	SETOM	SAVNUM
	SETOM	SLDFLG
	SETOM	BAKFLG
	SETOM	GOPRCT
	SETZB	F,UPPFLG	;UPPER CASE FLAG IS INITIALLY OFF
	SETZB	TM,PREDP	;SAY THERE'S NO PRE-SET DISPLAY POINTER
	MOVE	EN,[350700,,BUFFEN] ;SET UP THAT "WELCOME TO SED" MESSAGE
	SETZ	SL,		;CLEAR SLIDE OFFSET
IFN TOPS10,<
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,DEFPTH]
	PATH.	T1,		;READ STARTING PATH
	  JFCL
	MOVEI	T1,SFDLVL
START1:	MOVE	T2,DEFPTH+2(T1)	;SET UP AS DEFAULT FILE PATH
	MOVEM	T2,FILPTH+2(T1)	;AND AS CURRENT PATH
	MOVEM	T2,OLDPTH+2(T1)	;AND AS ALTERNATE PATH
	MOVEM	T2,SVAPTH+2(T1)	;AND AS SAVED PATH
	SOJGE	T1,START1
>
	SETZ	T4,
	GETPPN	T1,		;GET USER'S PPN
	  JFCL
	MOVEM	T1,USRPPN	;SAVE IT FOR FUTURE REFERENCE
	PJOB	T1,		;GET JOB NUMBER FOR .TMP FILES
	MOVE	PT,[POINT 6,T4,17]
	IDIVI	T1,^D100	;CONVERT NUMBER TO 3 SIXBIT DIGITS
	IDIVI	T2,^D10		;IN RH OF T4
	IDPB	T1,PT
	IDPB	T2,PT
	IDPB	T3,PT
	ADDI	T4,'000'
	HRLM	T4,PIKFIL	;SET UP AS PICK FILE NAME (nnnPIK)
	HRLM	T4,CLSFIL	;AND AS CLOSE FILE NAME   (nnnCLS)
	HRLM	T4,SEDFIL	;AND AS STAT FILE NAME	  (nnnSED)
>
IFE TOPS10,<
	GJINF			;GET T2/DIRECTORY NUMBER, T3/JOB NUMBER
	MOVE	T2,T1		;TRANSLATE DIRECTORY NUMBER INTO A STRING
	HRROI	T1,USRNAM	;  IN USRNAM
	DIRST
	  JFCL			;FAILED - NO PROBLEM
	SETZ	T4,
	MOVE	T1,T3		;MOVE JOB NUMBER TO T1
	MOVE	PT,[POINT 7,T4]
	IDIVI	T1,^D100	;CONVERT NUMBER TO 3 ASCII DIGITS
	IDIVI	T2,^D10		;IN LH OF T4
	IDPB	T1,PT
	IDPB	T2,PT
	IDPB	T3,PT
	ORM	T4,PIKFIL	;SET UP AS PICK FILE NAME (nnnPIK)
	ORM	T4,CLSFIL	;AND AS CLOSE FILE NAME   (nnnCLS)
	ORM	T4,SEDFIL	;AND AS STAT FILE NAME	  (nnnSED)
>
	HRRZM	P,SAVEAC+11	;SET SET-FILE'S R-W FLAG POSITIVE (IE, NONE)
	PUSHJ	P,TABINI	;INITIALIZE THE TAB TABLE
	MOVE	TM,TERMNL	;SET UP THE RIGHT TYPE OF TERMINAL
	PUSHJ	P,REDSWH	;READ SWITCH.INI, IF INI
	PUSHJ	P,REDTMP	;AND nnnSED.TMP, IF ANY
	PUSHJ	P,RSCANL	;IF USER ENTERED WITH FILESPECS SET THEM UP

;THE ERROR ROUTINE JUMPS TO INIERR WHEN THERE IS AN ERROR IN THE COMMAND
;LINE (LIKE A BAD SWITCH). IT GOES TO REDNO (BELOW) WHEN THE USER HAS ERRED
;WHILE EDITING THE CHEERY MESSAGE.

INIERR:	PUSHJ	P,@RTE(TM)	;CALL TERMINAL'S ENTRY ROUTINE
	HRLZ	T1,TCH(TM)	;GET TERMINAL-SPECIFIC FLAGS
	OR	TM,T1		;SET THEM UP
	SKIPN	RUP(TM)		;CAN TERMINAL ROLL UP?
	TRO	F,NRC		;NO - DON'T AUTOMATICALLY ROLL FROM LAST LINE
IFN FTJOUR,<
	SETZM	JRNBIT		;MAKE SURE JOURNAL FLAG IS CLEAR
	SKIPN	JRNFLG		;WANT TO RESTORE A JOURNAL?
	JRST	JRSTNO		;NO - SKIP THIS
	TLO	TM,JRC		;YES - SAY JOURNAL RESTORE IS HAPPENING
	SKIPN	XSHFLG		;WANT TO DISPLAY THE EXECUTE?
	TROA	F,XCT		;NO - JUST DISPLAY WHEN DONE
	TRO	F,XBN		;YES - SET UP SHOW IT ALL
	SETZM	XSHFLG		;CLEAR EXECUTE DISPLAY FLAG
	TLZE	TM,JRW		;DON'T JOURNAL WHILE RECOVERING - WANT TO?
	SETOM	JRNBIT		;YES - REMEMBER FOR LATER
	PUSHJ	P,JRNGET	;SET UP AND READ THE JOURNAL
JRSTNO:
>
	PUSHJ	P,INITT1	;DO TTY INIT STUFF WHICH COMES AFTER ENTRY RTN
	MOVE	T1,LPP(TM)	;GET LINES PER ROLL
	MOVEM	T1,LPP.0	;SAVE IN CASE OF CHANGE
	PUSHJ	P,SETLPP
	MOVE	T1,CPL(TM)	;SET UP CHARACTERS PER LINE VARIABLES
	MOVEM	T1,CPL.0	;SAVE IN CASE OF CHANGE
	SOJ	T1,
	MOVEM	T1,CPL.1
	SKIPN	RMARGN		;HAS THE USER SET THE RIGHT MARGIN?
	MOVEM	T1,RMARGN	;NO - SET IT AT THE RIGHT OF THE SCREEN
	MOVEM	TM,SAVFLG	;SAVE TERMINAL FLAGS

	HRRE	T3,STTFLG	;HAS THE TERMINAL LENGTH CHANGED?
	JUMPL	T3,.+2
	PUSHJ	P,SWHLPP	;YES - SET IT IN THE RIGHT TABLE
	HLRE	T3,STTFLG	;HAS THE TERMINAL WIDTH CHANGED?
	JUMPL	T3,.+2
	PUSHJ	P,SWHWID	;YES - SET IT IN THE RIGHT TABLE
	SETZM	STTFLG		;SAY NO LONGER INITIALIZING
	PUSHJ	P,CMDSET	;SET UP CHANGES TO COMMAND TABLE, IF ANY
	PUSHJ	P,SETXCB	;LIKEWISE EXECUTE BUTTONS, IF ANY, IN NEW TABLE

IFE TOPS10,<
IFN FTECHO,<
	MOVE	T3,RMARGN	;GET THE REAL RIGHT MARGIN
	PUSHJ	P,SWHRM1	;SET UP THE FIELD WIDTH
>>
	PUSHJ	P,RSTNOM	;SET UP DEFAULT PARAMETERS
	SKIPE	RSCANF		;GOT A FILE FROM RESCAN?
	JRST	SETSCN		;YES - SET IT UP AND GO TO LOOP1
	SKIPN	FILSPC		;GOT A FILE FROM nnnSED.TMP?
	JRST	REDNO		;NO - START OUT WITH CHEERY MESSAGE
INDIRE:	PUSH	P,TM		;YES - DISABLE ERROR MESSAGES
	SETZ	TM,
	PUSHJ	P,PARSEF	;PARSE THE FILESPECS
	POP	P,TM
	MOVE	DO,[400000,,$SETFI]
	JRST	SETFL1		;AND GO SET UP THAT FILE

REDNO:	PUSHJ	P,PNTSTT	;ELSE DISPLAY CHEERY MESSAGE
NEWFIL:	TLZ	F,ENT!CHG	;FILE UNCHANGED; ENTER OFF
	TLO	F,XPB		;LAST-LINE POINTER IS INVALID
IFE TOPS10,<
	SKIPN	ITTFLG		;HAS CHARACTER TRAPPING BEEN TURNED OFF?
	PUSHJ	P,INITTF	;NO - DO IT NOW
>
	DMOVE	T1,ISVNUM	;SET UP # OF COMMANDS BETWEEN ISAVES
	DMOVEM	T1,ISVCNT	;AND # OF TYPEIN CHARS BETWEEN SAVES
	MOVEI	T1,SQZVAL	;SET UP # OF COMMANDS TO SKIP BETWEEN SQUEEZES
	MOVEM	T1,SQZCNT
	CAMN	EN,[010700,,BUFFER-1] ;ANYTHING IN THE BUFFER?
	JRST	LOOP		;NO - DON'T TRY TO DISPLAY IT
	SKIPL	T1,GOPRCT	;YES - WANT TO START SOME PERCENT IN?
	JRST	[MOVEM T1,GOPERC ;YES - SET UP THE RIGHT PERCENT
		 SETOM GOPRCT	 ;FORGET THAT IT WAS GIVEN
		 SETZ  DO,
		 JRST  PERNPM]	 ;AND LET THE PERCENT COMMAND DO THE DISPLAY
NEWFL0:	SKIPN	DSPFLG		;WANT TO OMIT STARTING DISPLAY?
	PUSHJ	P,DISPLL	;NO - DISPLAY A SCREENFUL
	SETZM	DSPFLG		;CLEAR OMIT-DISPLAY FLAG
	PUSHJ	P,POSCUR	;POSITION THE CURSOR

;NOW ACCEPT CHARACTERS AND DO THINGS
;ALL COMMANDS EVENTUALLY LOOP BACK TO LOOP

LOOP:
IFE TOPS10,<
IFN FTECHO,<
	TLZE	TM,ANM		;WAS A CHARACTER JUST TYPED?
	JRST	LOOP0		;YES - DON'T SET THE FIELD WIDTH
	MOVEI	T1,.PRIOU	;NO - SET THE FIELD WIDTH TO BE
	MOVEI	T2,.MOSFW	;  THE REMAINDER OF THE LINE
	MOVE	T3,FLDWTH
	SUB	T3,CM
	MTOPR
LOOP0:
>>
	SKIPE	SAVCNT		;TIME TO DO AN INCREMENTAL SAVE?
	SKIPN	ISVCNT
	PUSHJ	P,INCSAV	;YES - DO IT
	SETZ	DO,		;SAY NO COMMAND IS BEING HANDLED
	TDNE	F,[CWT,,XCT!XBN] ;ANYTHING SPECIAL?
	JRST	LOPSPC		;YES - DO IT SPECIALLY (MAYBE GO TO LOOP0)
	GETCHR			;READ A CHARACTER FROM THE TERMINAL IN T1

LOOP1:	TLNE	F,CCH		;CANCEL ENTER-CONTROL-CHAR FLAG - ON?
	JRST	LOOPCC		;YES - CHECK FOR AN ESCAPE (FLOW OR ALPNUM)
LOOPC2:	CAIL	T1," "		;SOME CONTROL CHARACTER?
	JRST	ALPNUM		;NO - JUST PUT IT IN FILE OR BUFFER
LOOPC3:	MOVE	PT,[POINT 7,COMAND]
	SETZM	COMAND
	IDPB	T1,PT		;SAVE START OF COMMAND
	TLZ	F,ERF!CCH	;CLEAR CONSECUTIVE ERROR FLAG
	ADD	T1,ITB(TM)	;GET OFFSET IN TERMINAL TABLE
	SKIPGE	T1,(T1)		;IS IT A NORMAL COMMAND?
	JRST	[PUSHJ P,SUBTAB	;NO - READ MORE CHARACTERS
		 JRST  ILCERR	;ILLEGAL COMMAND - ERROR
		 JRST  .+1]	;LEGAL - CONTINUE

LOOP2:	TRNE	T1,200000	;IS THIS COMMAND REALLY AN EXECUTE BUFFER?
	JRST	ILCERT		;YES - SET BUFFER UP
	TRNE	F,XSV		;SAVE COMMAND IN EXECUTE BUFFER?
	JRST	[MOVEI T2,"^"	 ;YES - DO SO
		 CAIGE T1," "	 ;GOT A HIGH-NUMBERED COMMAND,
		 CAIN  T1,0	 ;  OR RESET (==0)?
		 IDPB  T2,XCTPTW ;YES - SAVE UP-ARROW AS FLAG
		 IDPB  T1,XCTPTW ;SAVE COMMAND
		 MOVE  T2,XCTPTW ;SEE IF BUFFER WILL OVERFLOW
		 CAME  T2,XCTOVF
		 JRST  .+1	 ;NO OVERFLOW - CONTINUE
		 JRST  XCTERR]	 ;ELSE GIVE ERROR MESSAGE
	TLNN	F,ENT		;ENTERING A PARAMETER?
	SKIPA	T2,CMDTBL(T1)	;NO - GET PROPER DISPATCH ADDRESS
	HLRZ	T2,CMDTBL(T1)	;YES - GET PROPER DISPATCH ADDRESS
	MOVE	DO,T1		;SAVE COMMAND THAT WAS TYPED
IFN FTJOUR,<
	TLNE	TM,JRW		;SAVING A JOURNAL?
	PUSHJ	P,JRNSVC	;YES - SAVE THE COMMAND
>
IFN FTIMD,<
	TLZE	TM,TIM		;IS THE TERMINAL IN INSERT MODE?
	PUSHJ	P,IMDOFN	;NO - TURN INSERT MODE OFF NOW
>
	JUMPN	T2,(T2)		;IF THERE IS AN ADDRESS, GO TO IT AND DO IT
	JRST	ILCER1		;ELSE IT'S AN ILLEGAL COMMAND

LOOPCC:	CAIE	T1,33		;CCH IS ON - WAS AN ESCAPE TYPED?
	JRST	LOOPC1		;NO - CONTINUE
	MOVEI	T1,"["		;YES - HANDLE IT LIKE ECC "["
	JRST	ALPNUM
LOOPC1:
IFE TOPS10,<
IFN FTECHO,<
	MOVEM	T1,SAVEAC
	PUSHJ	P,EKONPT	;TURN ON ECHO AND BREAK ON NONPRINTING CHARS
	MOVE	T1,SAVEAC
>>
	JRST	LOOPC2		;BACK TO THE FLOW

;HERE IF COMMAND SEQUENCE IS NOT FOUND IN TERMINAL INPUT TABLE
;SCAN THE EXECUTE BUFFERS TO SEE IF IT IS ONE OF THEM

ILCERR:	MOVEI	T3,4		;CONVERT LOWER CASE TO UPPER IN COMAND STRING:
	MOVE	T2,[POINT 7,COMAND,6]
ILCCAP:	ILDB	T1,T2		;GET THE NEXT CHARACTER
	JUMPE	T1,ILCCP2	;DONE IF NULL
	CAIGE	T1,"a"		;LOWER CASE?
	JRST	ILCCP1		;NO - LOOP
	CAIG	T1,"z"		;IS IT REALLY LOWER?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	DPB	T1,T2		;STORE THE CORRECTED CHARACTER
ILCCP1:	SOJG	T3,ILCCAP	;LOOP THROUGH THE COMMAND CHARACTERS

ILCCP2:	LDB	T2,[POINT 6,PT,5] ;ELSE SEE IF CMND MATCHES AN XCT SEQUENCE
	SUBI	T2,43		;GET CHARACTER MASK
	MOVSI	T4,400000
	ASH	T4,(T2)
	MOVEI	T2,XBFNUM-1	;LOOK AT ALL EXECUTE BUFFERS
ILCXLP:	MOVE	T1,XCTKEY(T2)	;GET A BUFFER NAME
	AND	T1,T4		;MASK OFF THE UNREAD CHARACTERS
	CAME	T1,COMAND	;IS THIS WHAT THE USER TYPED?
	SOJGE	T2,ILCXLP	;NO - TRY ANOTHER
	JUMPL	T2,ILCER1	;NO MATCH - COMMAND IS ILLEGAL
	CAMN	T1,XCTKEY(T2)	;GOT THE ENTIRE COMMAND SEQUENCE?
	JRST	ILCE00		;YES - EXECUTE THE BUFFER
IFE TOPS10,<
IFN FTECHO,<
	MOVEM	T2,SAVEAC	;SAVE T2
	PUSHJ	P,EKOALL	;NO - ECHO OFF; BREAK ON ALL CHARACTERS
	MOVE	T2,SAVEAC	;GET T2 BACK
>>
	GETCHR			;NO - READ A CHARACTER FROM THE TERMINAL IN T1
	CAIL	T1,"a"		;LOWER CASE?
	CAILE	T1,"z"
	CAIA			;NO - O.K.
	SUBI	T1,40		;YES - CONVERT TO UPPER
	IDPB	T1,PT		;SAVE CHARACTER IN COMAND
	ASH	T4,-7		;INCLUDE ANOTHER CHARACTER IN MASK
	JRST	ILCXLP		;GO FIND LONGER SEQUENCE

;HERE IF COMMAND IS AN EXECUTE BUFFER - GO DO IT

IFN TOPS10,<
ILCE00:	MOVE	T1,T2		;GET EXECUTE INDEX
>
IFE TOPS10,<
IFN FTECHO,<
ILCE00:	MOVEM	T2,SAVEAC	;SAVE THE EXECUTE INDEX
	PUSHJ	P,EKONPT	;ECHO ON; BREAK ON NON-PRINTING CHARACTERS
	MOVE	T1,SAVEAC	;RESTORE THE INDEX TO T1
>
IFE FTECHO,<
ILCE00:	MOVE	T1,T2		;GET EXECUTE INDEX
>>
ILCER0:
IFE TOPS10,<
	MOVE	T2,COMAND	;GET THE COMMAND SEQUENCE
	CAMN	T2,[BYTE (7) 15] ;IS IT A CARRIAGE RETURN?
	PBIN			;YES - BURN THE FOLLOWING LINEFEED
>
	ANDI	T1,77		;KEEP ONLY GOOD INDEX BITS
	MOVE	T2,XCTADR(T1)	;GET POINTER TO THIS BUFFER
	MOVEM	T2,XCTPTR	;SAVE AS ACTIVE POINTER
	MOVE	DO,T1		;SAVE EXECUTE INDEX FOR JOURNALING

;IF THERE'S ONLY ONE COMMAND IN THE BUFFER, TREAT IT LIKE A COMMAND, NOT
;AN EXECUTE, SO IT RUNS FAST. THIS PROVIDES A CHEAP POOR-MAN'S WAY OF
;REDEFINING THE KEYBOARD.

	ILDB	T1,T2		;GET FIRST CHARACTER FROM BUFFER
	CAIN	T1,"^"		;SPECIAL CHARACTER FLAG?
	JRST	ILCE0S		;YES - SEE IF IT'S THE ONLY COMMAND THERE
	ILDB	T0,T2		;NO - GET NEXT COMMAND
	JUMPE	T0,XCTGTE	;IF ONLY ONE COMMAND DISPATCH TO LOOP2 OR ALPNUM

;HERE IF THERE'S MORE THAN ONE COMMAND IN THE BUFFER

ILCE0A:
IFN FTJOUR,<
	TLNE	TM,JRW		;WRITING A JOURNAL?
	PUSHJ	P,JRNSVX	;YES - SAVE THE EXECUTE INDEX
>
	MOVEI	T1,1		;SET TO DO ONE ITERATION OF BUFFER
	MOVEM	T1,XCTNUM
	MOVE	T1,[PARAMS,,SAVPRM]
	BLT	T1,SAVPRM+SAVPML-1 ;SAVE SOME PARAMETERS AND FLAGS
	HRRM	F,SAVFGS	;ALSO SAVE RH OF F
	HLLM	TM,SAVFGS	;  AND LH OF TM
	TRZ	F,XCT		;CLEAR JOURNAL-RESTORE FLAGS
	TLZ	TM,JRC
	TRO	F,XBN		;SET TO EXECUTE AND DISPLAY
	TLNN	F,ENT		;GOT A PARAMETER?
	JRST	LOOP		;NO - GO TAKE COMMANDS FROM BUFFER
	PUSHJ	P,ERSPM0	;YES - CLEAN UP SCREEN; DON'T CLEAR FLAG
	PUSHJ	P,PUTTYP	;OUTPUT EVERYTHING NOW
	JRST	LOOP		;GO TAKE COMMANDS FROM BUFFER

;HERE IF THE FIRST COMMAND IN THE BUFFER HAS A CODE ABOVE 37

ILCE0S:	ILDB	T1,T2		;GET COMMAND FROM EXECUTE BUFFER
	CAIGE	T1,CMDLEN	;IS IT A REAL COMMAND?
	CAIG	T1,37
	JRST	ILCE0A		;NO (AN EXECUTE CONSTRUCT) - HANDLE NORMALLY
	CAIN	T1,77		;GOT A RESET COMMAND?
	SETZ	T1,		;YES - GET THE REAL CODE
	ILDB	T0,T2		;GET NEXT COMMAND FROM THE BUFFER
	JUMPE	T0,LOOP2	;IF THERE'S ONLY ONE COMMAND GO USE IT
	JRST	ILCE0A		;ELSE HANDLE NORMALLY

;HERE IF COMMAND REALLY IS ILLEGAL - GIVE ERROR

ILCER1:
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKONPT	;ECHO ON; BREAK ON NON-PRINTING CHARACTERS
>>
	TLNN	F,ENT		;IS THERE A PARAMETER TO CLEAN UP?
	JRST	ILCER2		;NO - JUST OUTPUT MESSAGE
	SETZ	T1,		;YES - GET A NULL
	IDPB	T1,PARPTR	;SAVE IT AT THE END OF THE PARAMETER
	PUSHJ	P,ERSPM2	;RESTORE SAVED POSITION
ILCER2:	MOVEI	T1,[ASCIZ /#########Illegal command/]
	JRST	ERROR

ILCERT:	TRNE	T1,100000	;GOT ENOUGH TYPE-IN?
	JRST	ILCERR		;NO - GET MORE
	JRST	ILCER0		;YES - GO EXECUTE BUFFER

;HERE FOR SPECIAL HANDLING: RESTORE NOMINALS, READ FROM EXECUTE BUFFER,
;OR GET TYPED-AHEAD (OR JOURNALED) CHARACTER

LOPSPC:	TRNE	F,XCT!XBN	;EXECUTE BUFFER OR JOURNAL RESTORE?
	JRST	XCTGET		;YES - TAKE COMMANDS FROM AN EXECUTE BUFFER
	TLZ	F,CWT		;NO - SAY NO CHARACTER IS WAITING
	MOVE	T1,TYPCHR	;PICK UP TYPED CHARACTER
	JRST	LOOP1		;AND USE IT AS CURRENT TERMINAL INPUT

;SUBROUTINE TO RESTORE NOMINALS, IF RST FLAG IS SET

RSTNOM:	MOVEI	T1,1
	SETZM	GOPERC		;GO TO 0 PERCENT
	MOVEM	T1,SUBCNT	;DO ONE SUBSTITUTE
	MOVEM	T1,ADDLNS	;INSERT LINES DOES ONE LINE
	SETZM	ADDLSP		;  AND 0 SPACES
	MOVEM	T1,ADDSPC	;INSERT SPACES DOES ONE SPACE
	MOVEM	T1,PICKLN	;PICK DOES ONE LINE
	SETZM	PICKSP		;  AND 0 SPACES
	MOVEM	T1,ROLPGS	;ROLL ONE PAGE
	MOVEM	T1,CASSPS	;CHANGE THE CASE OF ONE CHARACTER
	SETZM	CASLNS		;  AND 0 SPACES
	MOVE	T1,LINROL
	MOVEM	T1,ROLLIN	;SET THE NUMBER OF LINES TO ROLL
	MOVEI	T1,10		;GET DEFAULT SLIDE NOMINAL
	MOVEM	T1,SLIDES	;  AND AS CURRENT SLIDE SETTING
	POPJ	P,

;SUBROUTINE TO REFERENCE A TERMINAL'S SUBTABLES
;SKIP RETURN IF SEQUENCE FOUND, ELSE ERROR RETURN

SUBTAB:	MOVE	T4,T1		;SET UP ADDRESS OF SUBTABLE
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKOALL	;ECHO OFF; BREAK ON EVERYTHING
>>
	GETCHR			;READ A CHARACTER FROM THE TERMINAL IN T1
	IDPB	T1,PT		;SAVE CHARACTER
SUBTB2:	SKIPN	T2,(T4)		;GET A SUBTABLE ENTRY - END?
IFN TOPS10,<
	POPJ	P,		;YES - INPUT SEQUENCE NOT FOUND
>
IFE TOPS10,<
IFN FTECHO,<
	JRST	SUBTBR
>
IFE FTECHO,<
	POPJ	P,		;YES - INPUT SEQUENCE NOT FOUND
>>
	TRNN	T2,-1		;MATCH ON ANY CHARACTER?
	JRST	SUBTB3		;YES - SET UP REAL COMMAND NOW
	CAIE	T1,(T2)		;DO USER'S AND TABLE'S CHARS MATCH?
	AOBJN	T4,SUBTB2	;NO - LOOP ON THE TABLE
	JUMPG	T4,CPOPJ	;ERROR IF END OF TABLE AND NOT FOUND
SUBTB3:	CAMLE	T2,[137,,0]	;ELSE FOUND - WANT ANOTHER LEVEL?
	JRST	SUBTBS		;YES - SET IT UP
	HLRZ	T1,T2		;NO - SET UP REAL COMMAND
	AOS	(P)		;GIVE SKIP RETURN
IFE TOPS10,<
IFN FTECHO,<
SUBTBR:	MOVEM	T1,SAVEAC
	PUSHJ	P,EKONPT	;ECHO ON; BREAK ON NON-PRINTING CHARACTERS
	MOVE	T1,SAVEAC
>>
	POPJ	P,		;RETURN

SUBTBS:	TLNE	T2,200000	;GOT AN EXECUTE COMMAND?
	JRST	SUBTB3+2	;YES - SET IT UP AFTER ALL
	HLRZ	T4,T2		;POINT TO NEW SUBTABLE
	HRLI	T4,-^D40
	JRST	SUBTAB+1	;READ ANOTHER CHARACTER FROM TERMINAL

;HERE IF USER TYPED RUBOUT DURING A SEARCH OR EXECUTE - ABORT IT

RUBEXC:	SKIPA	T1,[[ASCIZ /#########Execution stopped/]]
RUBSRC:	MOVEI	T1,[ASCIZ /##########Search aborted/]
	JRST	ERROR

;**********************************************************************
;HERE IF A NON-CONTROL CHARACTER WAS TYPED - PUT IT IN FILE OR
;PARAMETER BUFFER, AND ADJUST CURSOR POSITION ONE TO THE RIGHT

ALPNUM:	CAIL	T1,173		;GOT A HIGH CHARACTER?
	JRST	ALPHGH		;YES - MAYBE IT'S A COMMAND
ALPNU0:
IFE TOPS10,<
IFN FTECHO,<
	TLO	TM,ANM		;NOTE THAT A CHARACTER WAS TYPED
>>
IFN FTJOUR,<
	TLNE	TM,JRW		;WRITING A JOURNAL?
	PUSHJ	P,JRNSVA	;YES - SAVE THE CHARACTER
>
	SETO	DO,		;NOTE THAT A COMMAND IS ACTIVE
	SKIPE	UPPFLG		;WANT UPPER CASE ALPHABETICS?
	JRST	[CAIGE T1,"a"	;YES - IS CHARACTER LOWER CASE?
		 JRST  .+1	;NO - O.K.
		 CAIG  T1,"z"
		 SUBI  T1,40	;YES - CONVERT TO LOWER
		 JRST  .+1]	;CONTINUE
	TRNE	F,XSV		;SAVE COMMAND IN EXECUTE BUFFER?
	JRST	[IDPB T1,XCTPTW	;YES - DO SO
		 CAIN T1,"^"	;IS CHARACTER A REAL UP-ARROW?
		 IDPB T1,XCTPTW	;YES - SAVE TWO OF THEM
		 MOVE T2,XCTPTW	;SEE IF BUFFER WILL OVERFLOW
		 CAME T2,XCTOVF
		 JRST .+1	;NO OVERFLOW - CONTINUE
		 JRST XCTERR]	;AND GIVE ERROR MESSAGE
	TLZE	F,CCH		;WANT A CONTROL CHARACTER?
IFN TOPS10,<
	ANDI	T1,37		;YES - MAKE IT ONE
>
IFE TOPS10,<
IFN FTECHO,<
	JRST	[MOVEM T1,SAVEAC ;YES - SAVE THE USER'S CHARACTER
		 PUSHJ P,EKONPT	 ;ECHO ON; BREAK ON NON-PRINTING CHARACTERS
		 MOVE  T1,SAVEAC ;GET THE CHARACTER BACK
		 ANDI  T1,37	 ;MAKE IT A CONTROL CHARACTER
		 JRST  .+1]	 ;BACK TO THE FLOW
>
IFE FTECHO,<
	ANDI	T1,37
>>
ALPNU1:	TLNE	F,ENT		;ENTERING A PARAMETER?
	JRST	ALPENT		;YES - HANDLE SEPARATELY

	TRNE	F,RDO		;NO - IS FILE READ-ONLY?
	JRST	ALPERR		;YES - COMMAND IS ILLEGAL
	SOS	SAVCNT		;DEBUMP TYPEIN SAVE COUNTER
	TLO	F,CHG!INS	;LET LINE BE EXTENDED IF NECESSARY
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	TLZ	F,INS!PCM
	TRNE	F,IMD		;IN INSERT MODE?
	JRST	ALPIMD		;YES - HANDLE SEPARATELY

;HERE TO PUT CHARACTER IN FILE (NON-INSERT-MODE)

	SETZ	T4,		;CLEAR (MAYBE) POINTER TO FIRST NULL
ALPNM2:	ILDB	T2,CHRPTR	;GET CHARACTER THAT WILL BE OVERWRITTEN
	JUMPE	T2,ALPNUL	;IF NULL, SAVE POINTER
	CAIN	T2,11		;TAB?
	JRST	ALPTAB		;YES - NEED TO BREAK THE TAB APART
	CAIN	T2,15		;CARRIAGE RETURN?
	PUSHJ	P,ALPEXT	;YES - MAY NEED TO EXTEND LINE
ALPNM3:	DPB	T1,CHRPTR	;SAVE CHARACTER IN BUFFER
	CAMN	EN,CHRPTR	;AT THE END OF FILE?
	IBP	EN		;YES - INCREASE FILE SIZE BY ONE CHARACTER

;HERE TO DISPLAY CHARACTER, FROM REPLACE MODE OR PARAMETER

ALPDIS:	MOVEM	T1,CHARAC	;SAVE USER'S CHARACTER
	TRNE	F,XCT		;EXECUTING?
	JRST	ALPDS1		;YES - POSITION, BUT NO ECHO
IFN TOPS10,<
	CAMN	RW,LPP.1	;AT LAST LINE?
	JRST	[TLZN  F,FNC	;YES - IS FENCE UP?
		 JRST  .+1	;NO - DRIVE ON
		 PUSH  P,T1	;YES - SAVE CHARACTER TYPED
		 PUSHJ P,CBOTOM ;TAKE FENCE DOWN
		 PUSHJ P,POSCUR ;RE-POSITION CURSOR
		 POP   P,T1	;GET CHARACTER BACK
		 JRST  .+1]	;CONTINUE
>
IFE TOPS10,<
IFE FTECHO,<
	CAMN	RW,LPP.1	;AT LAST LINE?
	JRST	[TLZN  F,FNC	;YES - IS FENCE UP?
		 JRST  .+1	;NO - DRIVE ON
		 PUSH  P,T1	;YES - SAVE CHARACTER TYPED
		 PUSHJ P,CBOTOM ;TAKE FENCE DOWN
		 PUSHJ P,POSCUR ;RE-POSITION CURSOR
		 POP   P,T1	;GET CHARACTER BACK
		 JRST  .+1]	;CONTINUE
>>
	CAIGE	T1," "		;GOT A CONTROL CHARACTER?
	JRST	ALPCCH		;YES - DISPLAY SPECIALLY
IFN TOPS10,<
	TYPCHA			;ECHO THE CHARACTER IN T1
>
IFE TOPS10,<
IFE FTECHO,<
	TYPCHA
>>
ALPDS1:	CAMGE	CM,RMARGN	;BEYOND THE RIGHT MARGIN?
	JRST	ALPPOS		;NO - GO FINISH UP
	SETZM	SAVEAC+2	;YES - CLEAR COUNT OF CHARACTERS BACKED OVER
IFE TOPS10,<
IFN FTECHO,<
	TLZ	TM,ANM		;MAKE THE FIELD WIDTH BE RESET IN THE NEXT LOOP
>>
	MOVE	PT,CHRPTR	;GET CURRENT CHARACTER POINTER
	LDB	T1,PT		;GET CURRENT CHARACTER
	CAIE	T1," "		;IS IT A SPACE,
	CAIN	T1,11		;  OR A TAB?
	JRST	ALPDS2		;YES - PUT NEW LINE HERE
	MOVEI	T2,1		;NO - SET NOT-SPACE FLAG
	PUSHJ	P,ALPBAK	;AND BACK UP OVER THE LAST WORD
	JUMPG	T2,.-1
	JUMPL	T2,ALPNSP	;IF NO SPACES IN LINE JUST WRAP LAST CHAR
	MOVE	T3,PT		;SAVE POINTER TO START OF WORD
	PUSHJ	P,ALPBKS	;SEE WHAT'S BEFORE THE SPACES
	JUMPE	T2,.-1
	JUMPL	T2,ALPNSP	;IF LINE STARTS WITH SPACES WRAP LAST CHAR
	MOVE	PT,T3		;ELSE GET BACK POINTER TO START OF WORD
	MOVEM	PT,CHRPTR	;SAVE POINTER TO START OF LAST WORD

ALPDS2:	MOVEI	T1,2		;SET TO INSERT TWO CHARACTERS:
	MOVEM	T1,NUMCHR	;  A RETURN AND A LINEFEED
	MOVEI	T1,12
	MOVEM	T1,CHARAC
	PUSHJ	P,MAKCHR	;INSERT TWO LINEFEEDS
	MOVEI	T1,15		;AND CHANGE ONE OF THEM TO A RETURN
	IDPB	T1,PT
	IBP	PT		;JUMP OVER THE LINEFEED, FOR RE-DISPLAY

	SKIPN	T1,LMARGN	;GET THE LEFT MARGIN OFFSET - ANY?
	JRST	ALPDS3		;NO - SKIP THIS
	MOVEM	T1,NUMCHR	;YES - ADD THAT MANY SPACES
	MOVEM	PT,CHRPTR	;  AT THE START OF THE NEW LINE
	PUSHJ	P,MAKSPC

ALPDS3:	SKIPN	T1,SAVEAC+2	;WAS ANYTHING MOVED?
	JRST	ALPDS4		;NO - DON'T ERASE
	SUB	CM,T1		;ELSE ERASE THE LAST WORD: POSITION TO IT
	PUSHJ	P,POSCUR
	PUSHJ	P,CLRLNR	;AND ERASE THE TO END OF THE LINE
ALPDS4:	AOS	T4,RW		;POSITION TO THE START OF THE NEXT LINE
	MOVE	CM,SAVEAC+2	;AND SET CURSOR POS'N TO END OF THE NEW LINE
	ADD	CM,LMARGN	;  (ADD IN MARGIN OFFSET)
	TLO	F,XPC!XPB	;CHARACTER AND BOTTOM POINTERS ARE BAD
	MOVEM	PT,LINPTR	;SAVE POINTER TO THE START OF THE NEW LINE
	CAML	RW,LPP(TM)	;ABOUT TO MOVE OFF THE SCREEN?
	JRST	RETROL		;YES - DO A ROLL
	PUSHJ	P,POSLIN	;ELSE POSITION TO START OF THE NEW LINE

	MOVEI	T4,1		;SET TO INSERT ONE LINE
	SKIPN	T1,ILN(TM)	;CAN TERMINAL TO AN INSERT-LINES?
	JRST	DISDWN		;RE-DRAW THE SCREEN FROM THERE DOWN; DONE
	PUSH	P,CM		;YES - FUDGE THE COLUMN POSITION TO ZERO
	SETZ	CM,
	PUSHJ	P,PUTSEQ	;YES - INSERT THE LINE
	POP	P,CM		;GET THE COLUMN POSITION BACK AGAIN
	PUSHJ	P,DISPLY	;DISPLAY THE OVERFLOW
	JRST	DISCUR		;POSITION TO THE END AND LOOP (WHEW)

ALPNSP:	SETZM	SAVEAC+2	;IF NO SPACES IN LINE JUST WRAP LAST CHAR
	MOVE	PT,CHRPTR
	JRST	ALPDS2

;SUBROUTINE TO READ THE CHARACTER PREVIOUS TO PT.
;RETURNS CHARACTER IN T1; T2/0 IF CHARACTER IS SPACE, TAB; -1 IF LF
;ALSO KEEPS A COUNT OF CHARACTERS BACKED OVER IN SAVEAC+2

ALPBKS:	MOVEI	T2,1		;SET FOUND-A-CHARACTER FLAG
ALPBAK:	ADD	PT,[70000,,0]	;BACK UP A NOTCH
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T1,PT		;GET THE PREVIOUS CHARACTER
	JUMPE	T1,ALPBAK	;SKIP IT IF NULL
	CAIE	T1," "		;SPACE,
	CAIN	T1,11		;  OR TAB?
	SETZ	T2,		;YES - MARK AS SUCH
	CAIN	T1,12		;HOW ABOUT A LINEFEED?
	SETO	T2,		;YES - MARK IT SPECIALLY
	JUMPLE	T2,CPOPJ	;GOT A REAL CHARACTER?
	AOS	SAVEAC+2	;YES - COUNT IT
	POPJ	P,		;DONE

;HERE TO SEE IF A HIGH CHARACTER IS REALLY A COMMAND

ALPHGH:	TLNN	TM,HTB		;GOT A HIGH TABLE TO USE?
	JRST	ALPHGR		;NO - JUST CHECK FOR RUBOUT
	MOVE	T2,T1		;SAVE CHARACTER
	ADD	T1,ITB(TM)	;GET TABLE ENTRY
	SKIPL	T1,-200(T1)	;IS THERE ONE?
	JRST	LOOPC3		;YES - HANDLE AS A COMMAND
	MOVE	T1,T2		;NO GET CHARACTER BACK
	JRST	ALPNU0		;AND GO PUT IT IN FILE

ALPHGR:	CAIE	T1,177		;GOT A RUBOUT?
	JRST	ALPNU0		;NO - TREAT LIKE A CHARACTER
	SETO	T1,		;YES - CHANGE INDEX TO -1
	JRST	LOOPC3		;AND PROCESS IT

;HERE TO OUTPUT A PROTECTED CONTROL CHARACTER

ALPCCH:	MOVE	T2,T1		;GET CHARACTER
	ADDI	T2,100		;  AS A REAL CHARACTER
	CAIN	T1,11		;GOT A TAB?
	JRST	ALPDTB		;YES - HANDLE SPECIALLY
	PUSH	P,T1		;SAVE KNOCKED CHARACTER
	PUSHJ	P,PROTON	;OUTPUT THE CHARACTER PROTECTED
	MOVE	T1,T2
	IDPB	T1,TY
	PUSHJ	P,PROTOF
	PUSHJ	P,PUTTYP	;OUTPUT IT NOW
	POP	P,T1		;GET CONTROL CHAR BACK AGAIN
	JRST	RIGHT+1

	MOVEI	DO,$CURHM	;CAUSE POSITIONING TO OCCUR
ALPDTB:	MOVSI	T1,70000	;MOVE POINTER BEHIND THE LATEST CHARACTER
	ADD	T1,CHRPTR
	JUMPGE	T1,.+2
	SUB	T1,[430000,,1]
	MOVEM	T1,CHRPTR	;SAVE CHARACTER POINTER
IFN FTIMD,<
	TLZE	TM,TIM		;TURN OFF INSERT MODE FLAG - ON?
	PUSHJ	P,IMODOF	;YES - TURN OFF INSERT MODE
>
	PUSHJ	P,DISLIN	;REWRITE REMAINDER OF LINE
	IBP	CHRPTR		;MAKE CHARACTER POINTER RIGHT
	MOVE	T1,CHARAC	;GET LATEST-TYPED CHARACTER
ALPPOS:	CAIE	T1,11		;TAB?
	JRST	RIGHT+1		;NO - MOVE TO THE RIGHT AND LOOP
	TRZ	CM,7		;YES - POINT TO CHARACTER AFTER TAB
	ADDI	CM,10
	JRST	DISCUR		;RE-POSITION AND LOOP

;HERE IF NULL FOUND WHERE CHARACTER POINTER POINTS

ALPNUL:	JUMPN	T4,.+2		;IF NOT FIRST NULL, DON'T SAVE POINTER
	MOVE	T4,CHRPTR	;ELSE SAVE POINTER TO FIRST NULL
	CAME	EN,CHRPTR	;AT END OF FILE?
	JRST	ALPNM2		;NO - LOOP
	MOVEM	T4,CHRPTR	;YES - POINT BACK TO FIRST NULL
	JUMPN	T4,ALPNM3	;O.K. IF A NULL WAS FOUND
	MOVEI	T1,[ASCIZ /########BUG - No null found/]
	JRST	ERROR		;ELSE IT'S AN ERROR (SHOULD NEVER HAPPEN)

;HERE IF CHARACTER TO OVERWRITE IS A TAB - PRECEDE IT WITH SPACES AND CHAR
;IF CHARACTER IS GOING INTO THE 7TH POSITION OF THE TAB, TAKE THE TAB OUT

ALPTAB:	PUSH	P,T1		;SAVE CHARACTER USER TYPED
	MOVE	T2,[70000,,0]	;ELSE BACK POINTER UP BEFORE THE TAB
	ADDB	T2,CHRPTR
	JUMPGE	T2,.+3
	MOVN	T2,[430000,,1]
	ADDM	T2,CHRPTR
ALPTB0:	AOS	T2,TABSPC	;GET SPACES (+ CHAR) TO ADD BEFORE TAB
	MOVEM	T2,NUMCHR	;ADD THAT MANY SPACES TO THE FILE
	PUSHJ	P,MAKSPC	;NOTE: T4 HAS PTR TO LAST THING ADDED

;MAKCHR POINTS TO START OF ADDED SPACES
;MAKPTR   "    "  LAST SPACE ADDED
;T4	  "    "  POINTS TO THE TAB

	SETZ	T1,		;NULL OUT THE FORMER TAB
	IDPB	T1,T4
	POP	P,T1		;GET USER'S CHARACTER BACK AGAIN
	MOVE	T4,MAKPTR
	DPB	T1,T4		;SAVE IT OVER THE LAST THING TYPED
	MOVEM	T4,CHRPTR	;SAVE AS CURRENT POSITION
	MOVN	T2,TABSPC
	ADDB	T2,TABSIZ	;SEE IF ENTIRE TAB HAS BEEN USED UP
	SETZM	TABSPC		;NO LONGER ANY SPACES TO LEFT OF TAB
	JUMPG	T2,.+2		;IS TAB NOW EXPRESSED ENTIRELY IN CHARS?
	TDZA	T2,T2		;YES - NULL OUT THE TAB
	MOVEI	T2,11		;NO - MOVE TAB OVER
	IDPB	T2,T4
	JRST	ALPDIS		;DONE - GO DISPLAY

;HERE IF IN INSERT MODE, AND INSERTING A CHARACTER IN THE MIDDLE OF A TAB

ALPTBI:	PUSH	P,T1		;SAVE CHARACTER USER TYPED
IFE TOPS10,<
IFN FTECHO,<
	TYPCHA			;ECHO THE CHARACTER
>>
	JRST	ALPTB0		;JUMP INTO THE BREAK-UP-TAB ROUTINE

;SUBROUTINE FOR IF GOING TO OVERWRITE A <CR>. IF IT'S <CRLF> EXTEND LINE
;HOWEVER, IF A NULL WAS PASSED OVER, SAVE CHARACTER THERE; LEAVE <CR> ALONE

ALPEXT:	JUMPN	T4,ALPEX1	;IF FOUND A NULL, SAVE CHARACTER THERE
	MOVE	T3,CHRPTR
	ILDB	T2,T3
	CAIE	T2,12		;IS IT A LINEFEED?
	POPJ	P,		;NO - JUST OVERWRITE THE LONE <CR>
	PUSH	P,T1		;YES - SAVE CHARACTER USER TYPED

	MOVSI	T1,70000	;MOVE POINTER BEHIND THE <CR>
	ADD	T1,CHRPTR
	JUMPGE	T1,.+2
	SUB	T1,[430000,,1]
	MOVEM	T1,CHRPTR	;SAVE IT AGAIN

	MOVEI	T1,12		;GO ADD 12 SPACES TO THE FILE
	MOVEM	T1,NUMCHR
;IFE FTNIH,<
;	PUSHJ	P,MAKSPC	;PUT IN THOSE SPACES
;>
;IFN FTNIH,<
	PUSHJ	P,MAKNUL	;PUT IN THOSE NULLS
;>
	POP	P,T1		;GET CHARACTER BACK
	IBP	CHRPTR		;POINT BACK TO REAL CHARACTER POSITION
	POPJ	P,		;AND GO PUT IT INTO BUFFER

ALPEX1:	MOVEM	T4,CHRPTR	;GO SAVE CHARACTER OVER THAT NULL
	POPJ	P,		;..

;HERE IF EDITOR IS IN INSERT MODE - ADD CHARACTER AT CURSOR; DON'T REPLACE

ALPIMD:	CAML	CM,CPL.1	;AT 80TH COLUMN?
	JRST	ALPIBP		;YES - INSERT NOT ALLOWED
	MOVE	PT,CHRPTR	;GET CHARACTER POINTER
	MOVEM	T1,CHARAC	;SAVE USER'S CHARACTER
	ILDB	T2,PT		;GET CHARACTER AT POINTER
	JUMPE	T2,ALPIM4	;IF NULL, SAVE NEW CHAR THERE
	CAIN	T2,11		;IS IT A TAB?
	JRST	ALPTBI		;YES - BREAK THE TAB APART
	LDB	T2,CHRPTR	;ELSE GET CHARACTER BEFORE POINTER
	JUMPE	T2,ALPIM5	;IF NULL, SAVE NEW CHAR THERE
				;ELSE NEED TO INSERT SOME SPACE:
	MOVEI	T1,1		;TELL MAKCHR TO INSERT ONE CHARACTER
	MOVEM	T1,NUMCHR
	PUSHJ	P,MAKCHR	;INSERT THAT CHARACTER
	IBP	CHRPTR		;POINT TO CHARACTER AFTER THIS ONE
ALPIM1:	MOVE	T1,CHARAC	;GET LATEST-TYPED CHARACTER
	CAIN	T1,11		;IS IT A TAB?
	JRST	ALPDTB		;YES - REWRITE REST OF LINE
IFN FTIMD,<
	SKIPN	T3,IMO(TM)	;CAN THE TERMINAL SET INSERT MODE?
	JRST	ALPIM2		;NO - INSERT THE CHARACTER SOME OTHER WAY

	MOVE	T2,CHRPTR	;YES - SEE IF THERE ARE TABS FROM HERE TO EOL
ALPI1A:	ILDB	T1,T2
	CAIN	T1,11		;TAB?
	JRST	ALPDTB-1	;YES - GO RE-DISPLAY ENTIRE REMAINDER OF LINE
	CAIE	T1,15		;END OF LINE?
	JRST	ALPI1A		;NO - KEEP LOOKING
	TLON	TM,TIM		;YES - IS THE TERMINAL ALREADY IN INSERT MODE?
	PUSHJ	P,IMODON	;NO - TURN ON INSERT MODE
	JRST	ALPIM3		;OUTPUT THE CHARACTER, ADJUST POSITION, & LOOP
>
ALPIM2:	MOVEI	T4,1		;SET TO OPEN LINE ONE CHARACTER
	SKIPE	T3,ISP(TM)	;CAN TERMINAL OPEN SPACES ON ITS OWN?
	PUSHJ	P,OPNSPI	;YES - OPEN UP THE LINE (SKIP RETURN)
	JRST	ALPDTB-1	;NO - REWRITE THE LINE CURSOR IS ON
	PUSHJ	P,POSCUR	;GET BACK TO START OF NEWLY-OPENED SPACE
ALPIM3:	MOVE	T1,CHARAC	;GET LATEST-TYPED CHARACTER
	CAIGE	T1," "		;GOT A CONTROL CHARACTER?
	JRST	ALPCCH		;YES - DISPLAY SPECIALLY
	IDPB	T1,TY		;DISPLAY IT
	AOJA	CM,DISCUR	;RE-DISPLAY THE CURSOR; DONE

ALPIBP:	TYPCHI	207		;IF AT 80TH COLUMN JUST BEEP
	JRST	LOOP

;HERE IF NULL FOUND AT (ALPIM4) OR BEFORE (ALPIM5) CURSOR POSITION
;SAVE NEW CHARACTER THERE; NO INSERT NECESSARY

ALPIM4:	IBP	CHRPTR		;SKIP OVER THIS NEW CHARACTER
ALPIM5:	MOVE	T1,CHARAC	;GET LATEST-TYPED CHARACTER
	DPB	T1,CHRPTR	;SAVE NEW CHARACTER JUST BEFORE POINTER
	JRST	ALPIM1		;GO DISPLAY WHAT HAPPENED

;HERE FOR A CHARACTER TYPED AS PART OF A PARAMETER

ALPENT:	TRZE	F,CMV		;DOING CURSOR MOVEMENT?
	JRST	CMXERR		;YES - CAN'T MIX CURSOR AND OTHERWISE
	HRRZ	PT,PARPTR	;GET POINTER INTO PARAMETER BUFFER
	CAIL	PT,PARBUF+PARBLN ;IS BUFFER ABOUT TO OVERFLOW?
	JRST	ALPIBP		;YES - BEEP AND DON'T SAVE THE CHARACTER
	IDPB	T1,PARPTR	;SAVE THIS CHARACTER IN PARAMETER BUFFER
	TRNE	F,XCT!XBN	;EXECUTING?
	JRST	LOOP		;YES - NO OUTPUT
	CAIGE	T1," "		;GOT A CONTROL CHARACTER?
	JRST	ALPENC		;YES - OUTPUT IT PROTECTED
IFN TOPS10,<
	TYPCHA			;ECHO THE CHARACTER IN T1
>
IFE TOPS10,<
IFN FTECHO,<
	TRNE	F,IMD		;IN INSERT MODE?
	TYPCHA			;YES - ECHO THE CHARACTER IN T1
>
IFE FTECHO,<
	TYPCHA			;ECHO THE CHARACTER IN T1
>>
	JRST	LOOP		;DONE

ALPENC:	MOVE	T4,T1		;SAVE CHARACTER
	PUSHJ	P,PROTON	;PROTECT CHARACTER
	MOVEI	T1,100(T4)	;GET REAL CHARACTER BACK
	IDPB	T1,TY		;SAVE IT
	PUSHJ	P,PROTOF
	PUSHJ	P,PUTTYP
	JRST	LOOP		;GET ANOTHER COMMAND

;**********************************************************************
;HERE FOR THE ILLEGAL COMMAND

ILLCMD:	PUSHJ	P,RESTPM	;CLEAR UP THE PARAMETER STUFF ON THE SCREEN
ICMNPM:	JRST	ILCER2		;SY THE COMMAND IS ILLEGAL AND LOOP

;**********************************************************************
;DISPATCH AREAS FOR CURSOR CONTROL CHARACTERS
;IF ENTER WAS TYPED, UP GOES TO UPARG; LEFT TO LFTARG

RGTARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
RIGHT:	TLO	F,XPC		;CHARACTER POINTER IS NO LONGER GOOD
	CAMGE	CM,CPL.1	;OFF THE RIGHT SIDE?
	AOJA	CM,AJDONE	;NO - JUST MOVE RIGHT
	MOVE	CM,LMARGN	;GO TO THE LEFT MARGIN
	TLO	F,XPL!XPC	;LINE POINTER IS NO GOOD EITHER
	CAMGE	RW,LPP.2	;AT BOTTOM?
	AOJA	RW,AJDON0	;NO - DROP DOWN ONE MORE
	AOJA	RW,RETROL	;YES - SEE IF SCREEN SHOULD BE ROLLED

DWNARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
DOWN:	TLO	F,XPL!XPC	;LINE POINTER IS NO LONGER GOOD
	CAMGE	RW,LPP.2	;AT BOTTOM?
	AOJA	RW,AJDONE	;NO - DROP DOWN ONE MORE
	TDZ	RW,RW		;WRAP - MOVE TO TOP
	JRST	AJDON0		;GO POSITION CURSOR ABSOLUTELY

LEFT0:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
LEFT:	TLO	F,XPC		;CHARACTER POINTER IS NO LONGER GOOD
	SOJGE	CM,AJDONE	;MOVE LEFT - OFF THE EDGE?
	MOVE	CM,CPL.1	;YES - SET TO RIGHT EDGE
				;AND GO UP ONE
	MOVEI	DO,$CURHM	;MAKE CURSOR POSITION ABSOLUTELY
UP:	TLO	F,XPL!XPC	;LINE POINTER IS NO LONGER GOOD
	SOJGE	RW,AJDONE	;MOVE UP - OFF THE TOP?
UPWRAP:	MOVE	RW,LPP.2	;WRAP - SET TO BOTTOM

AJDON0:	MOVEI	DO,$CURHM	;MAKE CURSOR POSITION ABSOLUTELY
AJDONE:	CAIN	DO,$CURLF	;ELSE WANT A CURSOR LEFT?
	JRST	[PUSHJ P,CLEFT	;YES - HANDLE SEPARATELY
		 JRST  AJDON1]
	CAIGE	DO,$ENTER+1	;GOT A REAL CURSOR MOVE?
	JRST	AJDON1+1	;NO - NO OUTPUT, THEN
	PUSHJ	P,@CMVTBL-34(DO) ;YES - MOVE THE CURSOR THE RIGHT WAY
AJDON1:	PUSHJ	P,PUTTYP
	TLNE	F,FLG		;WANT A SUBROUTINE RETURN?
CPOPJ:	POPJ	P,		;YES
	JRST	LOOP		;NO - GO GET MORE INPUT

HOMARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
HOME:	SETZB	RW,CM		;SET TO TOP AND LEFT MARGIN OF SCREEN
	TLO	F,XPL!XPC	;LINE AND CHARACTER POINTERS ARE INVALID
	PUSHJ	P,CHOME		;MOVE THE CURSOR HOME
	PUSHJ	P,PUTTYP	;ELSE OUTPUT IT NOW
	JRST	LOOP

UPARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
	JRST	UP

;LFTARG IS SPECIAL: IT OPERATES BOTH AS CURSOR MOVEMENT AND TO DELETE
;FROM THE PARAMETER BUFFER.

LFTAG0:	MOVEI	DO,$CURLF	;MAKE COMMAND LOOK LIKE A CURSOR LEFT
LFTARG:	TRNE	F,CMV		;DOING CURSOR MOVEMENT?
	JRST	LEFT		;YES - MOVE THE CURSOR
	MOVE	T2,PARPTR	;IS THIS THE 1ST CHARACTER OF THE PARAMETER?
	CAMN	T2,[POINT 7,PARBUF]
	JRST	LEFT0		;YES - START CURSOR MOVEMENT
	CAMN	T2,[010700,,PARBUF-1]
	JRST	LOOP		;SKIP, IF USER DELETED ALL OF PARM
	ADD	T2,[70000,,0]	;FUDGE A DECREMENT OF THE PARM POINTER
	JUMPGE	T2,.+2		;IE, DELETE THE LATEST CHARACTER
	SUB	T2,[430000,,1]
	MOVEM	T2,PARPTR	;SAVE IT AGAIN
	PUSHJ	P,CLEFT		;ERASE A CHARACTER OF PARAMETER
	MOVEI	T1," "
	IDPB	T1,TY
	PUSHJ	P,CLEFT
	PUSHJ	P,PUTTYP
	JRST	LOOP		;AND GET A NEW COMMAND

;HERE FOR <CR> - OUTPUT A CARRIAGE RETURN-LINEFEED

RETARG:
IFE TOPS10,<
	TRNN	F,XCT!XBN	;IN AN EXECUTE BUFFER?
	PBIN			;NO - EAT THE LF THAT'S SENT WITH THE RETURN
>
	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
	JRST	RETUR0		;IT'S NEVER INSERT MODE IN A PARAMETER

RETURN:
IFE TOPS10,<
	TRNN	F,XCT!XBN	;IN AN EXECUTE BUFFER?
	PBIN			;NO - EAT THE LF THAT'S SENT WITH THE RETURN
>
	TRNE	F,IMD		;IN INSERT MODE?
	JRST	RETIMD		;YES - ACT LIKE AN OPEN-LINE COMMAND

RETUR0:	MOVE	CM,LMARGN	;GO TO THE LEFT MARGIN
	AOJ	RW,		;AND DOWN ONE
	TLO	F,XPL!XPC	;LINE AND CHARACTER POINTERS ARE INVALID
	CAMLE	RW,LPP.2	;OFF THE BOTTOM?
	JRST	RETROL		;YES - MOVE TO THE TOP OR ROLL
RETUR1:	PUSHJ	P,POSCUR	;MOVE TO THE RIGHT LINE
IFN FTNIH,<
	MOVEI	T1,100		;DO A SHORT HIBER
	HIBER	T1,
	  JRST	LOOP
>
	JRST	LOOP		;AND GET ANOTHER COMMAND

;HERE FOR RETURN IN INSERT MODE: INSERT A LINE, THEN RETURN

RETIMD:	TRNE	F,NCR		;BEHAVE LIKE A NORMAL CR?
	JRST	RETUR0		;YES - GO BACK AND RETURN
	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	PUSHJ	P,CLRLNR	;CLEAR TO END OF PRESENT LINE
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	MOVEI	T4,2		;SET TO INSERT TWO LINEFEEDS
	MOVEM	T4,NUMCHR
	MOVEI	T1,12		;  (CHANGE ONE OF 'EM TO A <CR> LATER)
	MOVEM	T1,CHARAC
	PUSHJ	P,MAKCHR
	TLO	F,XPB!CHG	;SAY BOTTOM POINTER BAD; FILE MODIFIED

	MOVE	PT,CHRPTR	;GET POINTER TO CURSOR POSITION
	MOVEI	T1,15		;GET A CARRIAGE RETURN
	IDPB	T1,PT		;SET UP A NEW LINE
	IBP	PT		;SKIP OVER LINEFEED
	MOVEM	PT,CHRPTR	;SAVE CHARACTER POINTER AGAIN
	MOVEM	PT,LINPTR	;IT'S NOW THE LINE POINTER, TOO
	MOVE	CM,LMARGN	;GO TO THE LEFT MARGIN
	AOJ	RW,
	CAML	RW,LPP(TM)	;WORKING ON BOTTOM LINE?
	JRST	RETROL		;YES - MOVE TO THE TOP OR ROLL
	MOVEI	T4,1		;GET SIZE OF OPEN
	SKIPN	T3,ILN(TM)	;CAN TERMINAL OPEN ITS OWN LINES?
	JRST	DISDWN		;NO - GO REDISPLAY FROM HERE DOWN
	PUSHJ	P,OPENLD	;OPEN UP THE SCREEN
	PUSHJ	P,DISONE	;RE-WRITE LINE
	PUSHJ	P,POSCUR	;POSITION CURSOR AND OUTPUT
	JRST	LOOP		;DONE

;HERE IF RETURN TYPED AT BOTTOM OF SCREEN. IF NRC FLAG IS SET
;ROLL THE SCREEN ONE LINE, POSITION TO NEW BOTTOM. ELSE GO TO TOP

RETROL:	TRNE	F,NRC		;WANT TO ROLL?
	JRST	[SETZ RW,	;NO - MOVE TO THE TOP
		 JRST RETUR1]	;AND CONTINUE
	TLNE	F,ENT		;NO - ENTERING A PARAMETER?
	SOJA	RW,LOOP		;YES -  DO NOTHING
	MOVEI	T4,1		;NO - SET TO ROLL ONE LINE
	JRST	RFLNPM+1	;DO THE ROLL AND LOOP

;HERE FOR TAB - MOVE CURSOR POINTER AND CURSOR ON SCREEN

TABARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT

TAB:	TRNE	F,WTB		;WANT WORD-WISE TABS?
	JRST	WTAB		;YES - GO DO THEM
TAB0:	TLO	F,XPC		;MARK CHARACTER POINTER AS BAD
	TLNE	TM,STB		;WANT SETTABLE TABS?
	JRST	TABTB		;YES - GO DO THEM
	MOVE	T3,TABLEN	;GET LENGTH OF A TAB
	CAIE	T3,10		;IS IT THE USUAL?
	JRST	TAB0A		;NO - HANDLE IT SPECIALLY
	TRZ	CM,7		;YES - TAB OVER
	ADDI	CM,10
	JRST	TAB1

TAB0A:	MOVE	T1,CM		;MOVE TO NEXT USER-SET TAB STOP
	IDIV	T1,T3		;MOVE BACK TO PREVIOUS STOP
	IMUL	T1,T3
	ADD	T1,T3		;THEN JUMP TO NEXT ONE
	MOVE	CM,T1
TAB1:	CAML	CM,CPL.1	;OFF THE RIGHT SIDE?
	JRST	RETUR0		;YES - GO TO START OF NEXT LINE
	JRST	DISCUR		;NO - POSITION THE CURSOR AND GET NEW COMMAND

;HERE FOR DOING A TAB IN WORD-PROCESSING MODE: MOVE TO START OF NEXT WORD
;IE, LOOK FOR NEXT SPACE OR TAB; POINT TO NON- SPACE OR TAB AFTER THAT
;IF BEYOND END OF LINE JUST DO REGULAR TABS
;IF TAB WOULD GO OFF SCREEN MOVE TO START OF NEXT LINE

WTAB:	TLNE	F,XPC		;GOT POINTER TO CURRENT POSITION?
	PUSHJ	P,MAKCPT	;NO - RE-MAKE IT
	MOVE	PT,CHRPTR
	MOVE	T3,CM		;SAVE CURRENT POSITION
	ILDB	T1,PT		;GET FIRST CHARACTER
	JUMPE	T1,.-1		;IGNORE IF NULL
	CAIN	T1,15		;CARRIAGE RETURN?
	PUSHJ	P,ISCRLF	;YES - GOT A CRLF?
	JRST	.+2		;NO - CONTINUE
	JRST	WTABT		;YES - DO A NORMAL TAB AFTER END OF LINE
	CAIN	T1," "		;SPACE?
	AOJA	CM,WTABS	;YES - CHECK FOR TRAILING SPACES
	CAIN	T1,11		;TAB?
	JRST	WTABS1		;YES - CHECK FOR TRAILING SPACES

	AOSA	T3,CM		;BUMP AND GET POSITION NUMBER
WTABC:	MOVE	T3,CM		;SAVE POSITION NUMBER
	MOVE	T2,PT		;  AND CHARACTER POINTER
	ILDB	T1,PT		;GET NEXT CHARACTER
	JUMPE	T1,.-1		;IGNORE IF NULL
	CAIN	T1," "		;IS IT A SPACE?
	AOJA	CM,WTABCS	;YES - PHASE TWO
	CAIN	T1,11		;NO - IS IT A TAB?
	JRST	WTABCT		;YES - COUNT IT AND SKIP SPACES
	CAIN	T1,15		;CARRIAGE RETURN?
	PUSHJ	P,ISCRLF	;YES - GOT A CRLF?
	AOJA	CM,WTABC	;NO - SKIP THE CHARACTER

WTABX:	MOVE	CM,T3		;GET POSITION BEFORE TRAILING SPACES
WTABX0:	MOVEM	T2,CHRPTR	;SAVE CHARACTER POINTER
	JRST	TAB1		;AND FINISH OFF

WTABCT:	TRZ	CM,7		;TAB OVER
	ADDI	CM,10
WTABCS:	MOVEM	CM,SAVEAC	;SAVE POSITION
	MOVE	T4,PT		;AND CHARACTER POINTER
	ILDB	T1,PT		;GET NEXT CHARACTER
	JUMPE	T1,.-1		;IGNORE IF NULL
	CAIN	T1," "		;SPACE?
	AOJA	CM,WTABCS	;YES - SKIP UNTIL NOT ONE OF THOSE
	CAIN	T1,11		;TAB?
	JRST	WTABCT		;YES - COUNT THE TAB AND SKIP IT
	CAIN	T1,15		;CARRIAGE RETURN?
	PUSHJ	P,ISCRLF	;YES - GOT A CRLF?
	SKIPA	CM,SAVEAC	;NO - GET POINTER TO THIS CHARACTER
	JRST	WTABX		;YES - GO POSITION TO END OF LINE
	MOVEM	T4,CHRPTR
	JRST	TAB1		;MOVE CURSOR TO HERE

;HERE IF CHARACTER AT CURSOR IS SPACE OR TAB

WTABS:	MOVE	T2,PT		;SAVE POSITION
	ILDB	T1,PT		;GET CHARACTER AFTER <CR>
	JUMPE	T1,.-1		;IGNORE IF NULL
	CAIN	T1," "		;SPACE?
	AOJA	CM,WTABS	;YES - COUNT AND SKIP IT
	CAIN	T1,11		;TAB?
	JRST	WTABS1		;YES - TAB OVER
	CAIN	T1,15		;CARRIAGE RETURN?
	PUSHJ	P,ISCRLF	;YES - GOT A CRLF?
	JRST	WTABX0		;NO - POSITION TO CURRENT CHARACTER
WTABT:	MOVE	CM,T3		;YES - HERE IF AT EOL - GET STARTING CM
	JRST	TAB0		;GO MOVE TO NEXT TAB STOP

WTABS1:	TRZ	CM,7		;GOT A TAB - TAB OVER
	ADDI	CM,10
	JRST	WTABS		;AND KEEP SKIPPING

;SUBROUTINE FOR WHEN A CARRIAGE RETURN IS FOUND IN THE STRING AT (PT)
;IF THE NEXT CHARACTER IS A LINEFEED, GIVES A SKIP RETURN; ELSE NORMAL
;TYPICAL CALL: CAIN T1,15; PUSHJ P,ISCRLF; <NOT CRLF>; <GOT CRLF>
;PRESERVES EVERYTHING EXCEPT AC T0

ISCRLF:	MOVE	T0,PT		;GET THE CHARACTER AFTER THE CARRIAGE RETURN
	ILDB	T0,T0
	CAIN	T0,12		;IS IT A LINEFEED?
CPOPJ1:	AOS	(P)		;YES - GIVE A SKIP RETURN
	POPJ	P,		;NO - NORMAL RETURN

;HERE TO DO A TAB USING THE USER'S SETTINGS
;DOES A CARRIAGE RETURN IF NO TABS ARE LEFT ON THIS LINE

TABTB:	PUSHJ	P,TABSUB	;SET UP
	ASH	T4,(T2)		;SET ONES TO THE LEFT OF THE DESIRED BIT
	MOVE	T3,TABTBL(T1)	;GET THE RIGHT WORD OF THE TABLE
	TDZ	T3,T4		;CLEAR ALL BITS TO THE LEFT OF POSITION
TABTB1:	JFFO	T3,TABTB2	;FIND THE NEXT 1-BIT
	CAIL	T1,3		;NONE FOUND - ANY REMAINING?
	JRST	RETUR0		;NO - GO TO START OF NEXT LINE
	SKIPE	T3,TABTBL+1(T1)	;YES - PICK UP NEXT WORD - ANY TABS?
	AOJA	T1,TABTB1	;YES - FIND FIRST ONE
	AOJA	T1,TABTB1+1	;NO - SKIP IT AND CHECK NEXT ONE

BTBTBX:	JFFO	T3,.+1		;FIND INDEX OF PREVIOUS TAB
TABTB2:	IMULI	T1,^D36		;CONVERT WORD AND POSITION
	ADD	T1,T4		;  BACK TO CURSOR VALUE
	CAML	T1,CPL.1	;AT OR BEYOND THE END OF THE SCREEN?
	JRST	RETUR0		;YES - MOVE TO START OF NEXT LINE INSTEAD
	MOVE	CM,T1		;NO - CHANGE COLUMN POSITION
	JRST	DISCUR		;POSITION THE CURSOR; DONE

;HERE TO HANDLE A BACK-TAB - MOVE BACK TO THE NEAREST TAB STOP

BTBARG:	TRNE	F,CMV		;DOING CURSOR MOVEMENT?
	JRST	BAKTAB		;YES - MOVE THE CURSOR
	MOVE	T2,PARPTR	;IS THIS THE 1ST CHARACTER OF THE PARAMETER?
	CAMN	T2,[POINT 7,PARBUF]
	JRST	BAKTBA		;YES - START CURSOR MOVEMENT

	IBP	T2		;MAKE THE BYTE POINTER RIGHT FOR DECREMENTING
	MOVEI	T3,1		;AND SET UP COUNT OF CHARACTERS DELETED
BTBAG1:	PUSHJ	P,BTBGET	;GET NEXT-MOST-RECENT CHARACTER
	CAIE	T1," "		;SPACE,
	CAIN	T1,11		;  OR TAB?
	AOJA	T3,BTBAG1	;YES - SKIP OVER IT
IFN TOPS10,<
	CAIGE	T1,"0"		;NUMERIC?
	JRST	.+3		;NO - KEEP CHECKING
	CAIG	T1,"9"
	JRST	BTBAG2		;YES - PHASE TWO
	CAIL	T1,"A"		;ALPHABETIC?
	CAILE	T1,"Z"
	JRST	BTBGX0		;NO - STOP ON THE SPECIAL CHARACTER
>
BTBAG2:	PUSHJ	P,BTBGET	;GET NEXT-MOST-RECENT CHARACTER
	CAIGE	T1,"0"		;NUMERIC?
	JRST	.+3		;NO - KEEP CHECKING
	CAIG	T1,"9"
	AOJA	T3,BTBAG2	;YES - SKIP OVER IT
	CAIGE	T1,"A"		;ALPHABETIC?
	JRST	BTBAGX		;NO - STOP HERE
	CAIG	T1,"Z"
	AOJA	T3,BTBAG2	;YES - SKIP OVER IT
	JRST	BTBAGX		;NO - STOP HERE

BTBGX0:	PUSHJ	P,BTBGET	;BACK OVER ONE MORE CHARACTER
BTBAGX:	MOVEM	T2,PARPTR	;SAVE ADJUSTED PARAMETER POINTER
	MOVEI	T4," "
BTBGX1:	PUSHJ	P,CLEFT		;ERASE A CHARACTER OF PARAMETER
	IDPB	T4,TY
	PUSHJ	P,CLEFT
	SOJG	T3,BTBGX1	;LOOP THROUGH ALL CHARACTERS
	PUSHJ	P,PUTTYP
	JRST	LOOP		;THEN GET A NEW COMMAND

;BACKTAB SUBROUTINE TO GET THE NEXT-LATEST PARAMETER CHARACTER

BTBGET:	CAMN	T2,[010700,,PARBUF-1]
	JRST	KILPAR		;JUMP IF NOTHING LEFT IN THE BUFFER
	ADD	T2,[70000,,0]	;GET NEXT-MOST-RECENT CHARACTER
	JUMPGE	T2,.+2
	SUB	T2,[430000,,1]
	LDB	T1,T2
	CAIL	T1,"a"		;LOWER CASE (MAYBE)?
	SUBI	T1,40		;YES - CONVERT TO (MAYBE) UPPER
	POPJ	P,		;DONE

;HERE TO DO A BACKTAB ON THE SCREEN

BAKTBA:	TRO	F,CMV		;SET UP FOR CURSOR MOVEMENT
	PUSHJ	P,MARKUP

BAKTAB:	TRNE	F,WTB		;WANT WORD-WISE BACKTABS?
	JRST	WBTAB		;YES - GO DO THEM
	TLO	F,XPC		;MARK CHARACTER POINTER AS BAD
	TLNE	TM,STB		;WANT SETTABLE TABS?
	JRST	BTBTB		;YES - GO DO THEM
	MOVE	T3,TABLEN	;GET LENGTH OF A TAB
	CAIE	T3,10		;IS IT THE USUAL?
	JRST	BAKTB0		;NO - HANDLE IT SPECIALLY
	TRZN	CM,7		;YES - TAB BACKWARD
	SUBI	CM,10
	JRST	BAKTB1		;FINISH OFF

BAKTB0:	SOSGE	T1,CM		;GET AND DECREMENT POSITION. IF AT LEFT,
	JRST	BAKTB1+1	;  MOVE TO RIGHT OF PREVIOUS LINE
	IDIV	T1,T3		;ELSE MOVE TO PREVIOUS TAB STOP
	IMUL	T1,T3
	MOVE	CM,T1

BAKTB1:	JUMPGE	CM,DISCUR	;DONE, IF ON SCREEN
	MOVE	CM,CPL.1	;ELSE MOVE TO RIGHT
	SOJGE	RW,DISCUR	; OF NEXT HIGHER LINE
	MOVE	RW,LPP.2	;IF AT TOP, MOVE TO BOTTOM
	JRST	DISCUR

;HERE FOR DOING A BACK-TAB IN WORD-PROCESSING MODE
;MOVE TO START OF PREVIOUS WORD
;IE, LOOK FOR NEXT SPACE OR TAB; POINT TO NEXT NON- SPACE OR TAB
;IF AT START OF LINE, MOVE TO END OF PREVIOUS LINE (BUT NOT OFF SCREEN)

WBTAB:	TLNE	F,XPC		;GOT POINTER TO CURRENT POSITION?
	PUSHJ	P,MAKCPT	;NO - RE-MAKE IT
	TLNE	F,XPL		;IS CURSOR BEYOND END OF BUFFER?
	JRST	WBTABO		;YES - MOVE IT TO END OF LAST LINE
	JUMPE	CM,WBTABB	;IF AT START OF LINE, MOVE TO END OF PREVIOUS
	MOVE	PT,CHRPTR
	JRST	.+4		;START WITH CHARACTER AT CURSOR

WBTABS:	ADD	PT,[70000,,0]	;SKIP SPACES AFTER WORD
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T1,PT		;GET IT
	JUMPE	T1,WBTABS	;IGNORE IF NULL
	CAIE	T1," "		;SPACE
	CAIN	T1,11		;  OR TAB?
	JRST	WBTABS		;YES - SKIP UNTIL NOT ONE OF THOSE
	CAIN	T1,12		;NO - GOT A CARRIAGE RETURN?
	JRST	WBTABL		;YES - CHECK FOR END OF LINE

WBTABC:	ADD	PT,[70000,,0]	;SKIP TO BEGINNING OF PREVIOUS WORD
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T1,PT		;GET IT
WBTBC1:	CAIE	T1," "		;IS IT A SPACE
	CAIN	T1,11		;  OR A TAB?
	JRST	WBTABX		;YES - DONE
	CAIN	T1,12		;NO - GOT A LINEFEED?
	JRST	WBTABL		;YES - CHECK FOR END OF LINE
	JRST	WBTABC		;NO - KEEP SKIPPING

WBTABX:	MOVEM	PT,CHRPTR	;SAVE POINTER TO START OF NEXT WORD
	MOVE	PT,LINPTR	;GET POINTER TO START OF LINE
	JRST	WBTABE		;AND FINISH OFF

WBTABL:	ADD	PT,[70000,,0]	;POINT TO PREVIOUS CHARACTER
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T1,PT		;GET CHARACTER BEFORE <LF>
	CAIE	T1,15		;CARRIAGE RETURN?
	JRST	WBTBC1		;NO - KEEP LOOKING
WBTBL1:	SETZ	CM,		;YES - POSITION TO START OF THE LINE
	TLO	F,XPC		;MAKE CHAR PTR GET REMADE
	JRST	DISCUR		;POSITION CURSOR; DONE

WBTABB:	SOJL	RW,HOME		;MOVE UP A LINE - IF AT TOP, GO HOME
	MOVE	T3,LINPTR	;GET POINTER TO START OF LINE
	EXCH	T3,DISPTR	;FUDGE IT TO BE DISPLAY PTR
	MOVEI	T4,1		;BACK UP TO START OF PREVIOUS LINE
	JUMPN	SL,[MOVE  T1,LINPTR ;IF SLIDE, PRETEND POINTING
		    MOVEM T1,CHRPTR ;TO START OF LINE
		    JRST  .+1]
	PUSHJ	P,BAKDPT
	MOVEM	T3,DISPTR	;SAVE REAL DISPLAY POINTER AGAIN
	MOVEM	PT,LINPTR	;SAVE RE-DONE LINE POINTER

	MOVE	T4,CHRPTR	;NOW FIND END OF LINE
WBTBBN:	ADD	T4,[70000,,0]	;POINT TO PREVIOUS CHARACTER
	JUMPGE	T4,.+2
	SUB	T4,[430000,,1]
	LDB	T1,T4		;GET PREVIOUS CHARACTER
	JUMPE	T1,WBTBBN	;SKIP NULLS
	CAIN	T1,12		;LINEFEED?
	JRST	WBTBBN		;YES - SKIP IT, TOO
	JRST	WBTBB3		;NO - BACK TO THE FLOW

WBTBB1:	ADD	T4,[70000,,0]	;POINT TO PREVIOUS CHARACTER
	JUMPGE	T4,.+2
	SUB	T4,[430000,,1]
WBTBB2:	LDB	T1,T4		;GET PREVIOUS CHARACTER
	JUMPE	T1,WBTBB1	;SKIP NULLS (AND MAYBE LINEFEED)
WBTBB3:	CAIN	T1,15		;CARRIAGE RETURN?
	JRST	WBTBB1		;YES - SKIP IT
	CAIE	T1," "		;TRAILING SPACE
	CAIN	T1,11		;  OR TAB?
	JRST	WBTBB1		;YES - SKIP IT
	CAIN	T1,12		;NOTHING ON THIS LINE?
	JRST	[MOVE	T2,T4	;MAYBE - GET THE PREVIOUS CHARACTER
		 ADD	T2,[70000,,0]
		 CAIGE	T2,0
		 SUB	T2,[430000,,1]
		 LDB	T1,T2
		 CAIE	T1,15	 ;IS IT A CRLF PAIR?
		 JRST	.+1	 ;NO - CONTINUE
		 TLZE	F,FLG	 ;YES - WANT TO RE-DO RW?
		 PUSHJ	P,CALCRW ;YES (ONLY IF BEYOND END OF BUFFER)
		 JRST	WBTBL1]	 ;MOVE TO START OF LINE
	MOVEM	T4,CHRPTR	;SAVE CHARACTER POINTER
	TLZE	F,FLG		;WANT TO RE-DO RW?
	PUSHJ	P,CALCRW	;YES (ONLY IF BEYOND END OF BUFFER)
	MOVE	PT,LINPTR	;SAVE RE-DONE LINE POINTER

WBTABE:	SETZ	CM,		;CLEAR COLUMN NUMBER
WBTBE0:	CAMN	PT,CHRPTR	;UP TO CHARACTER POSITION?
	JRST	WBTBE1		;YES - FINISH OFF
	ILDB	T1,PT		;GET NEXT CHARACTER
	JUMPE	T1,WBTBE0	;IGNORE IF NULL
	CAIE	T1,11		;TAB?
	AOJA	CM,WBTBE0	;NO - COUNT AS ONE CHARACTER
	TRZ	CM,7		;YES - COUNT THE TAB
	ADDI	CM,10
	JRST	WBTBE0		;AND LOOP

WBTBE1:	SUB	CM,SL		;REMOVE THE SLIDE FROM THE COLUMN
	JUMPL	CM,WBTBE2	;JUMP IF OFF THE LEFT
	CAMG	CM,CPL.1	;OFF THE RIGHT?
	JRST	DISCUR		;NO - GO DISPLAY
	SKIPA	CM,CPL.1	;POSITION CURSOR AT RIGHT
WBTBE2:	SETZ	CM,		;POSITION CURSOR AT LEFT
	TLO	F,XPC		;COLUMN POINTER IS NOT GOOD
	JRST	DISCUR

WBTABO:	TLO	F,FLG		;SET FLAG SO RW WILL BE REMADE
	MOVE	T4,CHRPTR	;GET POINTER TO CURRENT CHARACTER
	JRST	WBTBB2		;BACK UP TO END OF LAST LINE

;HERE TO DO A TAB USING THE USER'S SETTINGS. IF NO TABS LEFT, GOES TO
;START OF LINE. IF AT START, GOES TO LAST TAB ON PREVIOUS LINE

BTBTB:	PUSHJ	P,TABSUB	;SET UP
	JUMPE	T2,BTBTB1	;IF AT POSITION 0 JUST CHECK PREVIOUS WORD
	ASH	T4,1(T2)	;CLEAR THE FLAGS TO THE RIGHT OF THE CURSOR
	AND	T4,TABTBL(T1)
	JUMPN	T4,BTBTB2	;JUMP IF THERE ARE TABS TO CHECK

BTBTB1:	SOJL	T1,BTBTB4	;IF NO PREVIOUS TAB, GO TO END OF PREV. LINE
	SKIPN	T4,TABTBL(T1)	;GET NEXT WORD OF TAB TABLE - ANY TABS SET?
	JRST	BTBTB1		;NO - CHECK PREVIOUS WORD

BTBTB2:	MOVEI	T3,1		;YES - ASSUME BIT IS ON IN RIGHT HALF
	TRNN	T4,777777	;IS THERE ONE IN THE RIGHT HALF?
	MOVSI	T3,1		;OF COURSE NOT - CHECK LEFT HALF
BTBTB3:	TDNE	T3,T4		;IS THIS THE 1-BIT?
	JRST	BTBTBX		;YES - SET UP RETURN VALUE AND RETURN
	LSH	T3,1		;NO - CHECK NEXT BIT
	JRST	BTBTB3

BTBTB4:	TDZE	CM,CM		;NO PREVIOUS TABS - MOVE TO START OF LINE
	JRST	DISCUR		;  IF NOT THERE ALREADY
	JUMPE	RW,DISCUR	;ELSE FREEZE ON HOME, IF THERE
	TLO	F,XPL		;ELSE MARK LINE POINTER AS BAD
	MOVE	CM,CPL.1	;AND FIND LAST TAB ON PREVIOUS LINE
	SOJA	RW,BTBTB+1

;**********************************************************************
;HERE FOR SETTABLE TAB STOPS - SET A STOP

TABSET:	PUSHJ	P,TABSUB	;SET UP
	LSH	T4,(T2)		;SHIFT RIGHT TO THE RIGHT POSITION
	ORM	T4,TABTBL(T1)	;SET THAT BIT
	TLO	TM,STB		;TURN ON SETTABLE TABS
	JRST	DISCUR		;DONE

;HERE TO CLEAR A TAB STOP OR DO SPECIAL FUNCTIONS

TABCLR:	DMOVE	RW,SAVPOS	;RESTORE SAVED POSITION
	TRZE	F,CMV		;DID USER USE CURSOR MOVEMENT?
	JRST	TBSERR		;YES - ERROR
	MOVE	T2,PARPTR	;GOT A PARAMETER?
	CAME	T2,[POINT 7,PARBUF]
	CAMN	T2,[010700,,PARBUF-1]
	JRST	TBCLR1		;NO - JUST CLEAR ONE TAB
	SETZ	T1,		;YES - END PARAMETER BUFFER WITH A NULL
	IDPB	T1,PARPTR
	LDB	T1,[POINT 7,PARBUF,6] ;GET 1ST CHARACTER OF PARAMETER
	CAIE	T1,"C"		;SOME TYPE OF "C"?
	CAIN	T1,"c"
	JRST	TBCLRC		;YES - CLEAR ALL TAB SETTINGS
	CAIE	T1,"D"		;WANT TO DISPLAY THE SETTINGS AND A RULER
	CAIN	T1,"d"
	JRST	TBCLRD		;YES - GO DO SO
TBSERR:	MOVEI	T1,[ASCIZ /####Bad parameter for <TAB-SET>/]
	JRST	ERROR		;ANYTHING ELSE IS AN ERROR

TBCLR1:	PUSHJ	P,TABSUB	;SET UP
	LSH	T4,(T2)		;SHIFT RIGHT TO THE RIGHT POSITION
	ANDCAM	T4,TABTBL(T1)	;CLEAR THAT BIT
TBCLX0:	TLO	TM,STB		;TURN ON SETTABLE TABS
TBCLRX:	PUSHJ	P,ERASPM	;ERASE THE PARAMETER
	JRST	LOOP		;DONE

TBCLRC:	SETZM	TABTBL		;ZERO THE ENTIRE TAB TABLE
	SETZM	TABTBL+1
	SETZM	TABTBL+2
	SETZM	TABTBL+3
	JRST	TBCLX0		;ERASE PARAMETER AND LOOP

;HERE TO DISPLAY THE CURRENT TAB SETTINGS AND A RULER
;ON THE BOTTOM LINE OF THE SCREEN

TBCLRD:	PUSHJ	P,SWHBOT	;SET UP THE BOTTOM LINE
	MOVEM	TY,SAVEAC	;SAVE POINTER TO START OF RULER
	MOVEI	T4,^D14		;OUTPUT 14 COPIES OF THE RULER
	MOVEI	T1,[ASCIZ /1234567890/]
	PUSHJ	P,PUTSTG
	SOJG	T4,.-2		;(NOTE: WHEN THIS IS DONE T4/ 0)
	MOVEI	T1,"-"		;GET THE TAB-MARKING CHARACTER

TBCRD0:	MOVEI	T3,^D36		;COUNT THROUGH ALL THE BITS IN THE WORD
	MOVE	T2,TABTBL(T4)	;GET A WORD OF THE TABLE
TBCRD1:	ROT	T2,1		;LOOK AT THE NEXT 1-BIT
	IBP	SAVEAC		;SKIP OVER THAT SPACE IN THE RULER
	TRNE	T2,1		;IS THERE A TAB THERE?
	DPB	T1,SAVEAC	;YES - MARK THAT SPACE AFTER ALL
TBCRD2:	SOJG	T3,TBCRD1	;LOOP THROUGH ALL THE BITS IN THE WORD
	CAIGE	T4,3		;ANY MORE WORDS IN THE TABLE?
	AOJA	T4,TBCRD0	;YES - LOOK AT THE NEXT ONE
	JRST	SWHNPE		;FINISH OFF, OUTPUT RULER, AND LOOP

;SUBROUTINE TO SET UP FOR THE TAB ROUTINES

TABSUB:	MOVE	T1,CM		;GET CURRENT COLUMN POSITION
        IDIVI	T1,^D36		;GET WORD AND POSITION IN WORD
	MOVN	T2,T2		;NEGATE POSITION
	MOVSI	T4,400000	;GET BIT FOR SHIFTING
	POPJ	P,

;SUBROUTINE TO SET UP CONSTANT-LENGTH TABS IN THE TAB TABLE

TABINI:	SETZB	T1,T2		;CLEAR OUT THE EXISTING TABS
	DMOVEM	T1,TABTBL
	DMOVEM	T1,TABTBL+2
	MOVN	T2,TABLEN	;GET THE NEGATIVE DISTANCE BETWEEN TABS
	JUMPE	T2,CPOPJ	;DONE IF DISTANCE IS ZERO
	MOVSI	T1,-4		;SET UP IOWD INTO TAB TABLE
	MOVSI	T3,400000	;AND STARTING TAB BIT

TABIN1:	LSHC	T3,(T2)		;SHIFT THE BIT OVER THE RIGHT AMOUNT
	JUMPN	T3,TABIN2	;JUMP IF STILL IN THE SAME WORD OF THE TABLE
	MOVE	T3,T4		;ELSE PUT THE BIT IN THE RIGHT AC
	AOBJP	T1,CPOPJ	;MOVE TO NEXT WORD; DONE IF COUNTED OUT
TABIN2:	ORM	T3,TABTBL(T1)	;SAVE THE BIT IN THE TAB TABLE
	JRST	TABIN1		;AND LOOP TO SET ANOTHER BIT

;**********************************************************************
;HERE ON LINEFEED, WHICH ERASES THE LINE THAT THE CURSOR GOES TO
;NOTE: this command is obsolete; replaced by ERASE-LINE

LNFPAR:	TLNN	TM,LSD		;IS LINEFEED REALLY A CURSOR DOWN?
	JRST	KILPAR		;NO - DELETE ENTIRE PARAMETER
	MOVEI	DO,$CURDN	;YES - DO A DOWN INSTEAD
	JRST	DWNARG

KILPAR:	MOVE	T1,[POINT 7,PARBUF] ;POINT TO START OF PARAMETER BUFFER
	MOVEM	T1,PARPTR
	TRZN	F,CMV		;CLEAR CURSOR MOVE FLAG - ON?
	JRST	ENTERM		;NO - CLEAR BOTTOM LINE, PROMPT, AND LOOP
	DMOVE	RW,SAVPOS	;YES - RESTORE SAVED POSITION
	JRST	ENTERM		;NOW CLEAR, PROMPT, AND LOOP

LNFEED:	TLNE	TM,LSD		;IS LINEFEED REALLY A CURSOR DOWN?
	JRST	[MOVEI DO,$CURDN;YES - DO A DOWN INSTEAD
		 JRST  DOWN]
	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	TLO	F,CHG		;SAY FILE HAS BEEN MODIFIED
	CAMN	RW,LPP.1	;AT BOTTOM OF SCREEN?
	JRST	LNFERR		;YES - ILLEGAL
	AOJ	RW,		;MOVE TO NEXT ROW
	MOVEI	T1,15		;MOVE TO START OF LINE
	IDPB	T1,TY
	PUSHJ	P,CDOWN		;MOVE DOWN ONE
	PUSHJ	P,CLRLNA	;ERASE THE ENTIRE LINE
	PUSHJ	P,POSCUR
	TLZ	F,XPL!PCM	;SAY LINE POINTER IS BE GOOD; KILL MARK
	PUSHJ	P,MAKLPT	;AND MAKE IT (IN LINPTR AND PT)
	SETZ	T2,		;GET A NULL
LNFED1:	ILDB	T1,PT		;GET A CHARACTER
	CAIN	T1,15		;CARRIAGE RETURN?
	JRST	LNFED3		;YES - CHECK FOR END OF LINE
LNFED2:	DPB	T2,PT		;ELSE NULL OUT THE CHARACTER
	JRST	LNFED1		;AND GET ANOTHER

LNFED3:	MOVE	T4,PT		;GET FRAGGABLE POINTER
	ILDB	T1,T4		;GET (MAYBE) LINEFEED
	CAIE	T1,12		;IS IT REALLY?
	JRST	LNFED2		;NO - JUST NULL OUT THE <CR>
	TLO	F,XPC		;SAY CHARACTER POINTER IS BAD
	JRST	LOOP		;DONE

LNFERR:	MOVEI	T1,[ASCIZ /#Can't erase last line of display/]
	JRST	ERROR

;HERE TO ERASE ALL CHARACTERS FROM THE CURSOR TO THE END OF THE LINE
;ENTER ERASE-LINE ERASES PARAMETER (KILPAR)

ERASLN:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	MOVEI	T1,^D1000	;SET TO CLOSE A LOT OF SPACES
	JRST	CLSNP0		;LET CLOSE-SPACES HANDLE IT

;**********************************************************************
;HERE TO MOVE TO THE BEGINNING OF THE LINE, UNLESS CURSOR IS AT BEGINNING,
;IN WHICH CASE IT MOVES TO THE END

LINARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT

LINE:	TDZN	CM,CM		;MOVE TO THE BEGINNING - ALREADY THERE?
	JRST	LINEND		;YES - MOVE TO END INSTEAD
	TLO	F,XPC		;CHARACTER POINTER IS BAD
	JRST	DISCUR		;DISPLAY THE CURSOR AND LOOP

LINEND:	TLO	F,XPC!XPL	;CHARACTER AND LINE POINTERS ARE BAD
	AOJA	RW,WBTAB	;GO DO A WORDWISE BACKTAB FROM NEXT LINE

;**********************************************************************
;HERE FOR THE SEARCH BACKWARD COMMAND

SRCBAK:	PUSHJ	P,SRGTKY	;SET UP THE NEW SEARCH KEY
SRBNPM:	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POINTER
	MOVE	T1,DISPTR	;GET POINTER TO TOP OF SCREEN
	MOVEM	T1,SAVEAC	;SAVE IT FOR REFERENCE
	MOVE	PT,CHRPTR	;GET POINTER TO CURRENT POSITION
	MOVE	T4,[350700,,SRCKEY] ;AND POINTER TO START OF SEARCH KEY
	LDB	T1,T4		;GET THE FIRST KEY CHARACTER
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	MOVE	T3,T1		;PUT CHARACTER IN THE RIGHT AC
	JUMPN	T3,SRCBK3	;O.K. IF SOMETHING TO SEARCH FOR
	JRST	SRXERR		;ELSE ERROR

SRCBK1:	ADD	PT,[70000,,0]	;NO - BACK POINTER UP A NOTCH
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
SRCBK3:	CAMN	PT,[010700,,BUFFER-1] ;AT START OF FILE YET?
	JRST	SRCERR		;YES - NOT-FOUND ERROR
	LDB	T1,PT		;GET A CHARACTER
	CAMN	PT,SAVEAC	;BACK TO START OF SCREEN?
	PUSHJ	P,SRCDKY	;YES - REMIND USER WHAT KEY IS
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	CAMN	T1,T3		;SAME AS FIRST CHAR OF KEY?
	JRST	SRCB2A		;YES - CHECK REST OF MATCH
	CAIE	T3,37		;GOT A WILD KEY CHARACTER?
	JRST	SRCBK1		;NO - KEEP GOING

SRCB2A:	MOVEM	PT,SRCPTR	;SAVE POINTER TO BUFFER
	PUSHJ	P,SRCIPT	;SEE IF USER WANTS TO INTERRUPT
SRCBK2:	ILDB	T1,T4		;GET NEXT CHARACTER OF KEY
	JUMPE	T1,SRCMAT	;IF NULL, GOT A MATCH
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	MOVE	T2,T1		;PET CHARACTER IN THE RIGHT AC
	ILDB	T1,PT		;GET ONE FROM THE BUFFER
	JUMPE	T1,.-1		;IGNORE IF NULL
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	CAME	T1,T2		;SAME?
	CAIN	T2,37		;  OR KEY CHAR IS WILD?
	JRST	SRCBK2		;YES - O.K. SO FAR

	MOVE	PT,SRCPTR	;NO - NO MATCH - RESTORE BUFFER POINTER
	MOVE	T4,[350700,,SRCKEY] ;AND POINTER TO START OF SEARCH KEY
	JRST	SRCBK1		;AND CONTINUE LOOKING FOR THE ENTIRE KEY

SRCUPP:	CAIGE	T1,"a"		;LOWER CASE?
	POPJ	P,		;NO - RETURN
	CAIG	T1,"z"		;MAYBE - IS IT?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	POPJ	P,		;DONE

SRCIPT:	GOTINP			;SKIP IF USER TYPED SOMETHING
	  POPJ	P,		;NO - CONTINUE
	GETCHR			;YES - READ THE CHARACTER INTO T1
	CAIN	T1,177		;IS IT A RUBOUT?
	JRST	RUBSRC		;YES - ABORT THE SEARCH
	POPJ	P,		;NO - CONTINUE

;SUBROUTINE TO SET UP A NEW SEARCH KEY

SRGTKY:	MOVE	T1,[SRCKEY,,SROKEY]
	BLT	T1,SROKEY+7	;SAVE CURRENT KEY AS PREVIOUS ONE
	MOVE	T3,[POINT 7,SRCKEY]
	PUSHJ	P,PELS.1	;GET SEARCH KEY
	MOVEM	T1,SRCKLN	;SAVE ITS LENGTH FOR THE SUBSTITUTE COMMAND
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	TLNN	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	POPJ	P,		;NO - RETURN
	POP	P,		;YES - DONE NOW
	JRST	LOOP

;HERE FOR THE SEARCH FORWARD COMMAND

SRCFWD:	PUSHJ	P,SRGTKY	;SET UP THE NEW SEARCH KEY
SRFNPM:	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POINTER
	CAMN	RW,LPP.1	;IS CURSOR ON THE BOTTOM LINE?
	JRST	[PUSHJ P,SRCDKY ;YES - SCREEN WILL BE RE-DONE
		 JRST  SRFNP1]
	TLZE	F,XPB		;GOT A VALID BOTTOM POINTER?
	PUSHJ	P,MAKBPT	;NO - RE-MAKE IT
	MOVE	T1,BOTPTR	;GET BOTTOM PTR TO SEE WHEN SRCH IS OFF SCREEN
	MOVEM	T1,SAVEAC	;SAVE IT FOR REFERENCE
SRFNP1:	MOVE	PT,CHRPTR	;GET POINTER TO CURRENT POSITION
	ILDB	T1,PT		;SKIP FIRST REAL CHARACTER
	JUMPE	T1,.-1		;  AT THIS LOCATION
	MOVE	T4,[350700,,SRCKEY] ;AND POINTER TO START OF SEARCH KEY
	LDB	T1,T4		;GET THE FIRST KEY CHARACTER
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	SKIPN	T3,T1		;PUT CHARACTER IN THE RIGHT AC - GOT ONE?
	JRST	SRXERR		;NO - ERROR IF NOTHING TO SEARCH FOR

SRCFW1:	CAMN	PT,EN		;AT END OF FILE YET?
	JRST	SRCERR		;YES - NOT-FOUND ERROR
	ILDB	T1,PT		;ELSE GET A CHARACTER
	CAMN	PT,SAVEAC	;GOING OFF THE BOTTOM OF THE SCREEN?
	PUSHJ	P,SRCDKY	;YES - REMIND USER WHAT KEY IS
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	CAMN	T1,T3		;SAME AS FIRST CHAR OF KEY?
	JRST	SRCF2A		;YES - CHECK REST OF KEY
	CAIE	T3,37		;WILD SEARCH CHARACTER?
	JRST	SRCFW1		;NO - KEEP GOING

SRCF2A:	MOVEM	PT,SRCPTR	;SAVE POINTER TO CURRENT POSITION
	PUSHJ	P,SRCIPT	;SEE IF USER WANTS TO INTERRUPT
SRCFW2:	ILDB	T1,T4		;GET NEXT CHARACTER OF KEY
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	SKIPN	T2,T1		;GET CHARACTER IN THE RIGHT AC - GOT ONE?
	JRST	SRCMTF		;NO - FOUND THE MATCH
SRCFW3:	ILDB	T1,PT		;NOW GET ONE FROM THE BUFFER
	JUMPE	T1,[CAMN PT,EN	;IF NULL, AT END OF FILE?
		    JRST SRCERR	;YES - NO MATCH
		    JRST SRCFW3];NO - SKIP THE NULL
	TRNE	F,NLC		;WANT CASE INDEPENDENCE?
	PUSHJ	P,SRCUPP	;YES - CHECK THE CASE
	CAME	T1,T2		;SAME?
	CAIN	T2,37		;  OR KEY CHAR IS WILD?
	JRST	SRCFW2		;YES - O.K. SO FAR

	MOVE	PT,SRCPTR	;NO - NO MATCH - RESTORE BUFFER POINTER
	MOVE	T4,[350700,,SRCKEY] ;AND POINTER TO START OF SEARCH KEY
	JRST	SRCFW1		;AND CONTINUE LOOKING FOR THE ENTIRE KEY

;SUBROUTINE FOR WHEN THE SEARCH HAS GONE BEYOND THE LIMITS OF THE SCREEN
;DISPLAY SEARCH KEY ON BOTTOM LINE AND SET SAVEAC TO 0
;(THUS SAVEAC/0 IF MATCH NOT ON SCREEN, ELSE NONZERO). FRAGS T1 ONLY.

SRCDKY:	SETZM	SAVEAC		;CLEAR ON-SCREEN INDICATOR
	TRNE	F,XCT		;EXECUTING?
	JRST	SRCDK1		;YES - DON'T DISPLAY
	MOVEI	T1,[ASCIZ /SEARCH FOR: /]
	PUSHJ	P,PUTBTM	;DISPLAY SEARCH KEY ON BOTTOM OF SCREEN
	MOVEI	T1,SRCKEY
	PUSHJ	P,PUTSTC
	PUSHJ	P,PROTOF	;TURN PROTECTION OFF
	JRST	PUTTYP		;OUTPUT ALL THIS AND RETURN

SRCDK1:	CAIN	DO,$SUBST	;DOING A SUBSTITUTE?
	SKIPE	SAVEAC+1	;YES - FIRST TIME THROUGH HERE?
	POPJ	P,		;NO - ONCE IS ENOUGH
	MOVEI	T1,[ASCIZ /SEARCH FOR: /]
	PUSHJ	P,PUTBTM	;DISPLAY SUBSTITUTE ON BOTTOM OF SCREEN
	MOVEI	T1,SRCKEY
	PUSHJ	P,PUTSTC
	MOVEI	T1,[ASCIZ / SUBSTITUTE: /]
	PUSHJ	P,PUTSTG
	MOVEI	T1,SUBSTG
	PUSHJ	P,PUTSTC
	PUSHJ	P,PROTOF	;TURN PROTECTION OFF
	JRST	PUTTYF		;FORCE ALL THIS OUT AND RETURN

;HERE WHEN A SEARCHER HAS FOUND A MATCH - DISPLAY A FEW LINES BEFORE MATCH

SRCMTF:	TLNE	F,FNC		;IF SEARCHING FORWARD, IS FENCE ON SCREEN?
	SETOM	SAVEAC		;YES - MATCH MUST BE, TOO
SRCMAT:	MOVE	PT,SRCPTR	;RESTORE POINTER TO START OF MATCH
	CAIN	DO,$SUBST	;DOING A SUBSTITUTE?
	JRST	SRCMT0		;YES - DON'T FUDGE THE LINEFEED, THEN
	LDB	T1,PT		;GET FIRST CHARACTER OF MATCH
	CAIN	T1,12		;LINEFEED?
	IBP	PT		;YES - POINT TO FIRST CHARACTER
	MOVEM	PT,SRCPTR	;SAVE ADJUSTED POINTER
SRCMT0:	SKIPN	SAVEAC		;IS MATCH ON SCREEN?
	JRST	SRCMT1		;NO - GO RE-DISPLAY

;HERE IF MATCH IS ON SCREEN - JUST POSITION CURSOR AT MATCH

	ADD	PT,[70000,,0]	;BACK IT UP A NOTCH
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	MOVEM	PT,CHRPTR	;CHARACTER POSITION WILL BE START OF THE MATCH
	PUSHJ	P,CALCRW	;CALCULATE PROPER VALUE OF RW
	PUSHJ	P,CALCML	;CALCULATE PROPER VALUE OF CM
	  PUSHJ	P,DISPLL	;RE-DISPLAY IF THERE WAS A SLIDE
	TLZ	F,XPL!XPC	;LINE AND CURSOR POINTERS ARE GOOD
	CAIE	DO,$SUBST	;DOING A SUBSTITUTE?
	JRST	DISCUR		;NO - POSITION CURSOR TO START OF MATCH; LOOP
        POPJ	P,		;YES - RETURN

;HERE IF MATCH IS NOT ON THE SCREEN

SRCMT1:	CAIN	DO,$SUBST	;DOING A SUBSTITUTE?
	JRST	SRCST0		;YES - SET POINTERS AND RETURN
	PUSHJ	P,SRCSET	;NO - SET UP THE RIGHT POINTERS
	JRST	DISALL		;RE-DISPLAY THE SCREEN AND LOOP

SRCST0:	SETOM	SAVEAC+1	;SAY THE DISPLAY HAS MOVED OVER THE FILE
SRCSET:	MOVE	T4,LINROL	;BACK UP ONE ROLL'S WORTH
	AOJ	T4,
	MOVEM	PT,DISPTR	;FROM THE MATCH
	ADD	PT,[70000,,0]	;BACK IT UP A NOTCH
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	MOVEM	PT,CHRPTR	;CHARACTER POSITION WILL BE START OF THE MATCH

	PUSHJ	P,BAKDPT
	MOVE	RW,LINROL	;POINT TO START OF LINE WITH MATCH
	SUB	RW,T4		;  (WHICH MAY NOT BE THE FULL DISTANCE DOWN)
	PUSHJ	P,MAKLPT	;MAKE LINE PTR (IN LINPTR AND PT)
	PUSHJ	P,CALCCM
	  TLZA	F,XPL!XPC!FBL	;ROW AND COLUMN POINTERS ARE RIGHT
	TLZ	F,XPL!XPC!FBL	;  AND BOTTOM LINE IS GOOD, TOO
	TLO	F,XPB		;BUT BOTTOM POINTER IS NOT GOOD
	POPJ	P,

SRXERR:	MOVEI	T1,[ASCIZ /#######Nothing to search for/]
	JRST	ERROR
SRCERR:	MOVEI	T1,[ASCIZ /##########Search failure/]
	TRNN	F,XBN!XCT	;EXECUTING?
	JRST	ERROR		;NO - REPORT THE ERROR
	ILDB	T2,XCTPTR	;YES - GET THE NEXT EXECUTE COMMAND
	CAIE	T2,"^"		;SPECIAL CHARACTER FLAG?
	JRST	ERROR		;NO - IT'S STILL AN ERROR
	ILDB	T1,XCTPTR	;YES - IS IT THE ON-SEARCH-ERROR CONSTRUCT
	CAIE	T1,21
	JRST	ERROR		;NO - IT'S STILL AN ERROR
	JRST	LOOP		;YES - CONTINUE PROCESSING COMMANDS

;**********************************************************************
;HERE ON ENTER-CONTROL-CHARACTER COMMAND. SET FLAG SO IF NEXT
;CHARACTER IS ASCII IT WILL BE MADE A CONTROL CHARACTER
;(ELSE THERE IS NO EFFECT)

ENTCCH:	TLO	F,CCH		;SET THAT OL' FLAG
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKOALL	;BREAK ON NEXT CHARACTER AND DON'T ECHO IT
>>
	JRST	LOOP		;THAT'S ALL

;**********************************************************************
;HERE ON INSERT MODE TOGGLE COMMAND. SET FLAG SO CHARACTERS TYPED
;WILL BE INSERTED AT CURSOR POSITION, AND NOT REPLACE THE EXISTING CHARACTER
;TYPING THE COMMAND AGAIN REVERSES THIS EFFECT

INSMOD:	TRNE	F,XCT!XBN	;EXECUTING?
	JRST	[TRC  F,IMD	;YES - JUST TOGGLE FLAG
		 JRST LOOP]
	TLNE	TM,BEP		;WANT TO BEEP INSTEAD OF WORKING WITH MESSAGE?
	JRST	INSBEP		;YES - GO DO SO
	TRCN	F,IMD		;TOGGLE THE INSERT MODE FLAG - JUST TURNED ON?
	JRST	INSMDO		;YES - DISPLAY MESSAGE AT BOTTOM
	PUSHJ	P,CBOTOM	;NO - MOVE TO BOTTOM LINE AND CLEAR IT
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKONPT	;NO ECHO; BREAK ON NON-PRINTING CHARACTERS
>>
	PUSHJ	P,MAKLPT	;GET CURRENT LINE POINTER
	TLZ	F,FBL		;BOTTOM LINE IS HEREBY GOOD
	TLZE	F,XPB		;ERASE MESSAGE AT BOTTOM
	PUSHJ	P,MAKBPT	;GET A VALID BOTTOM POINTER
	SKIPN	PT,BOTPTR	;  AT THE BOTTOM OF THE SCREEN
	JRST	INSMDF		;IF BEYOND FILE, PUT UP THE FENCE
	MOVEI	T4,1		;ELSE WRITE ONE LINE
	TLNN	TM,NEL		;LEAVE LAST LINE ALONE?
	PUSHJ	P,DISPLY	;NO - RE-DO IT
	PUSHJ	P,POSCUR	;REPOSITION THE CURSOR
	JRST	LOOP		;AND LOOP

INSMDF:	PUSHJ	P,FNCPUT	;DISPLAY THE FENCE
	PUSHJ	P,POSCUR	;REPOSITION THE CURSOR
	JRST	LOOP		;DONE

INSMDO:	PUSHJ	P,INSMSG	;OUTPUT INSERT MODE MESSAGE
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKOALL	;NO ECHO; BREAK ON ALL CHARACTERS
>>
	JRST	LOOP		;DONE

INSBEP:	TRCN	F,IMD		;TOGGLE THE INSERT MODE FLAG - JUST TURNED ON?
	JRST	INSBP1		;YES - BEEP ONCE
	TYPCHI	207		;BEEP ONCE
	SNOOZE	^D0400		;WAIT A WHILE
INSBP1:	TYPCHI	207		;BEEP AGAIN
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,INSBP2	;TURN ECHO ON OR OFF DEPENDING ON MODE
>>
	JRST	LOOP

IFE TOPS10,<
IFN FTECHO,<
INSBP2:	TRNN	F,IMD		;IN INSERT MODE?
	JRST	EKONPT		;NO - BREAK ON NON-PRINTING CHARACTERS
	JRST	EKOALL		;NO - NO ECHO; BREAK ON ALL CHARACTERS
>>
;SUBROUTINE TO OUTPUT INSERT MODE MESSAGE

INSMSG:	TLNE	TM,BEP		;BEEPING?
	POPJ	P,		;YES - NO MESSAGE
	MOVEI	T1,[ASCIZ / *** INSERT MODE *** /]
	PUSHJ	P,PUTBTM
	PUSHJ	P,PROTOF
	TLO	F,FBL		;MARK BOTTOM LINE AS FRAGGED
	JRST	POSCUR		;REPOSITION THE CURSOR AND RETURN

;**********************************************************************
;HERE TO GO TO SOME GIVEN PERCENT OF THE FILE
;EXCEPTION: GOTO 100% PUTS UP THE LAST LINROL LINES INVARIABLY

PERCEN:	MOVE	T4,GOPERC	;SET UP LAST TIME'S NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	JUMPE	T1,.+2		;JUMP IF JUST ENTER-PERCENT TYPED
	SKIPA	T4,PARG1	;ELSE GET PERCENT TO MOVE
	MOVEI	T4,^D100	;TREAT ENTER-PERCENT LIKE ENTER-100-PERCENT
	PUSHJ	P,RESTPM
	JUMPL	T4,PERERR	;ERROR IF NEGATIVE
	CAILE	T4,^D100	;OR LARGER THAN 100
	JRST	PERERR
	MOVEM	T4,GOPERC	;ELSE SAVE AS NEW NOMINAL
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
PERNPM:	MOVE	T4,GOPERC	;SET UP LAST TIME'S NOMINAL
	SETZB	RW,CM		;PUT CURSOR IN UPPER LEFT
	JUMPE	T4,PERCST	;IF GOTO 0 PERCENT, GO TO START
	TLO	F,XPL!XPC!XPB	;MARK NO POINTERS AS VALID
	CAIN	T4,^D100	;GOTO 100 PERCENT?
	JRST	PERCND		;YES - HANDLE SPECIALLY

	HRRZ	T1,EN		;GET SIZE OF FILE
	SUBI	T1,BUFFER
	IMUL	T1,T4		;TIMES DISTANCE USER WANTS TO GO
	IDIVI	T1,^D100	;DIVIDED INTO 100-WORD PIECES
	ADD	T1,[010700,,BUFFER-1] ;GIVES POINTER INTO FILE
	MOVEM	T1,DISPTR	;SAVE AS NEW DISPLAY POINTER
	MOVEI	T4,1		;GO TO THE START OF THE NEXT LINE
	CAME	T1,[010700,,BUFFER-1] ;DON'T BACK UP IF AT START
	PUSHJ	P,ADVDPT
	JRST	PERDIS		;RE-DISPLAY AND GET ANOTHER COMMAD

PERCND:	MOVEM	EN,DISPTR	;DISPLAY FROM ONE ROLLS-WORTH FROM END OF FILE
	MOVE	T4,LINROL
	PUSHJ	P,BAKDPT

	MOVE	T2,EN		;POINT TO LAST REAL FILE CHARACTER
PERCD1:	ADD	T2,[70000,,0]	;BACK IT UP A NOTCH
	JUMPGE	T2,.+2
	SUB	T2,[430000,,1]
	LDB	T1,T2		;GET CHARACTER
	CAIGE	T1," "		;IS IT A REAL CHARACTER?
	JRST	PERCD1		;NO - KEEP LOOKING

	HRRZ	T1,DISPTR	;IS CHARACTER POINTER ON SCREEN?
	CAIL	T1,(T2)
	JRST	[SETZB RW,CM	;NO - MOVE CURSOR HOME
		 TLO   F,XPC	;CHARACTER POINTER IS BAD
		 JRST  PERCD2]	;FINISH OFF
	MOVEM	T2,CHRPTR	;POSITION CURSOR TO VERY END OF FILE
	PUSHJ	P,CALCRW	;CALCULATE PROPER VALUE OF RW
	PUSHJ	P,CALCML	;CALCULATE PROPER VALUE OF CM
	  AOJA	RW,.+2		;IF SLIDE, MOVE TO START OF NEXT LINE
	AOJA	CM,PERCD2	;MOVE TWO COLUMNS AWAY FROM LAST CHARACTER
	SETZB	CM,SL		;ELSE MOVE TO START OF NEXT LINE
	TLOA	F,XPL!XPC!XPB	;AND MARK NO POINTERS AS VALID
PERCD2:	TLO	F,XPC!XPB	;LINE POINTER IS THE ONLY ONE O.K.
PERDIS:	TRNE	F,RST		;WANT TO RESTORE NOMINALS?
	SETZM	GOPERC		;YES - SET BACK TO ZERO PERCENT
	JUMPN	DO,DISALL	;IF USER COMMAND, RE-DISPLAY AND LOOP
	JRST	NEWFL0		;ELSE IF /GO SWITCH DO IT STARTUP-WISE

PERCST:	PUSHJ	P,PNTSTT	;SET UP POINTERS TO START OF FILE
	JRST	PERDIS		;RE-DISPLAY AND GET ANOTHER COMMAND

PERERR:	MOVEI	T1,[ASCIZ /#Percent must be between 0 and 100/]
	JRST	ERROR

;**********************************************************************
;SUBROUTINE TO DO AN INCREMENTAL SAVE

INCSAV:	DMOVE	T1,ISVNUM	;RESET COMMAND INCREMENTAL SAVE COUNT
	DMOVEM	T1,ISVCNT	;AND TYPEIN INCREMENTAL SAVE COUNT
	MOVEI	T1,SQZVAL	;RESET # OF COMMANDS TO SKIP BETWEEN SQUEEZES
	MOVEM	T1,SQZCNT
	TRNN	F,RDO		;IS FILE READ-ONLY?
	TLNN	F,CHG		;NO - HAS IT BEEN MODIFIED?
	POPJ	P,		;READ-ONLY OR NOT MODIFIED - DON'T SAVE FILE
	MOVEI	T1,[ASCIZ /SAVING FILE - WAIT/]
	PUSHJ	P,PUTBTM	;PUT MESSAGE ON BOTTOM LINE
	PUSHJ	P,PROTOF
	PUSHJ	P,PUTTYP
IFN TOPS10,<
	MOVEI	PT,FILBLK	;POINT TO NAME OF CURRENT FILE
>
	MOVEI	T4,FILSPC
	SKIPE	INJFN		;IS THERE A JFN?
	PUSHJ	P,SAVFLC	;YES - SAVE THE FILE
IFN FTJOUR,<
	TLNE	TM,JRW		;WRITING A JOURNAL?
	PUSHJ	P,JRNSTT	;YES - START UP A NEW ONE
>
IFN TOPS10,<
	TLO	F,XPL!XPC	;LINE AND CHARACTER PTRS ARE NOW BAD
	PUSHJ	P,FIXBLN	;REPAIR THE BOTTOM LINE
	JRST	POSCUR		;RE-POSITION THE CURSOR AND RETURN
>
IFE TOPS10,<
	TRO	F,GFL		;NOTE THAT FILE IS EXISTS
	TLO	DO,500000	;TELL SET-FILE THAT INCSAV CALLED IT
	POP	P,		;KILL CALL TO INCSAV
	JRST	SETFL1		;CONNECT TO THE FILE AGAIN; GET NEW COMMAND
>
;HERE TO HANDLE AN EXIT COMMAND

EXIPAR:	TLO	F,FLG		;SET FLAG TO DO A RUN ON COMPIL
EEXIT:	TLZE	TM,WDW		;WINDOWING?
	PUSHJ	P,WNCLST	;YES - STOP
IFN TOPS10,<
	RELEAS	1,		;GET RID OF THE TERMINAL
	MOVEI	PT,FILBLK	;POINT TO NAME OF CURRENT FILE
>
	MOVEI	T4,FILSPC
	SKIPE	INJFN		;IS THERE A JFN?
	PUSHJ	P,SAVFIL	;YES - SAVE THE FILE
IFN FTJOUR,<
	TLZN	TM,JRW		;WRITING A JOURNAL?
	JRST	EEXIT1		;NO - SKIP THIS
IFN TOPS10,<
	MOVEI	T1,.FODLT	;YES - DELETE THE JOURNAL FILE
	HRRM	T1,JRNFIL+.FOFNC
	MOVE	T1,[6,,JRNFIL]
	FILOP.	T1,		;DELETE IT
	  JFCL			;IGNORE ANY ERROR
>
IFE TOPS10,<
	TRZ	F,GFL		;NOTE THAT FILE IS NOT AROUND ANY MORE
	MOVE	T1,[GJ%SHT]	;GET A JFN FOR THE JOURNAL FILE
	HRROI	T2,JRNFIL
	GTJFN
	  JRST	EEXIT1		;FAILURE - DON'T TRY TO DELETE IT
	HRRZ	T1,T1		;DELETE THE JOURNAL FILE
	DELF
	  JFCL			;IGNORE ANY ERROR
>
EEXIT1:
>
	SKIPE	FILSPC		;GOT A CURRENT FILE?
	JRST	.+3		;YES - CONTINUE
	SKIPN	OLDSPC		;NO - GOT AN OLD FILE?
	JRST	ABORT		;NEITHER - DON'T WRITE nnnSED.TMP

	MOVE	TY,[POINT 7,PIKBUF+PCBSIZ-400]
	MOVEI	T1,FILSPC	;GET CURRENT FILE SPECS
	MOVE	T4,DISPTR	;AND DISPLAY POINTER
	PUSHJ	P,EXIFIL	;OUTPUT THE STATUS OF THE ACTIVE FILE
	SKIPN	OLDSPC		;IS THERE AN ALTERNATE FILE?
	JRST	EEXIT0		;NO - DON'T OUTPUT ITS STATUS
	EXCH	F,SAVEFG	;GET THE ALTERNATE FILE'S FLAGS
	MOVEI	T1,OLDSPC	;GET ALTERNATE FILE SPECS
	MOVE	T4,SAVEDP	;AND DISPLAY POINTER
	HRRZ	RW,SAVERW
	HLRZ	CM,SAVERW
	MOVE	SL,SAVESL
	PUSHJ	P,EXIFIL	;OUTPUT THE STATUS OF THE ALTERNATE FILE
	EXCH	F,SAVEFG	;GET THE CURRENT FLAGS (IN CASE OF REENTER)
EEXIT0:	SETZ	T1,		;MAKE SURE LAST WORD IS NULL
	IDPB	T1,TY
	IDPB	T1,TY
	IDPB	T1,TY
	IDPB	T1,TY
	IDPB	T1,TY
	HRRZS	TY		;FIND SIZE OF STUFF TO OUTPUT
	SUBI	TY,PIKBUF+PCBSIZ-400

IFN TOPS10,<
IFN FTTMPC,<
	MOVE	T1,[3,,TMPBLK]	;TRY TO SAVE IN TMPCOR
	TMPCOR	T1,
	  JRST	.+2		;FAILED - SAVE ON DISK
	JRST	ABORT1-1	;O.K. - CONTINUE
>
	SKIPE	T1,SAVSED	;HAS STAT FILE NAME BEEN DIDDLED?
	JRST	[MOVEM T1,SEDFIL ;YES - SAVE REAL NAME
		 MOVSI T1,'TMP'	 ;PUT EXTENSION IN, TOO
		 MOVEM T1,SEDFIL+1
		 JRST  .+1]	;CONTINUE
	HRROI	T2,SEDFIL	;SET UP nnnSED.TMP FILE FOR OUTPUT
	PUSHJ	P,SETOUT
	MOVNS	TY		;SAVE NEGATIVE WORDCOUNT IN COMMAND BLOCK
	HRLM	TY,SEDCCL
	OUTPUT	5,SEDCCL	;OUTPUT THE STATUS STUFF
	RELEAS	5,		;MAKE IT SOUP (YET)
	MOVE	TY,TYPPTR

ABORT1:	MOVEI	T1,1		;SET UP TTY PAGE
	MOVEM	T1,PAGADR+2
	MOVE	T1,[XWD 3,PAGADR]
	TRMOP.	T1,
	  HALT
	SKIPE	CRWADR+2	;SHOULD TERMINAL BE TTY CRLF?
	JRST	ABRT1A		;NO - LEAVE IT ALONE
	MOVE	T1,[XWD 3,CRWADR]
	TRMOP.	T1,		;ELSE SET TTY CRLF
	  HALT
ABRT1A:
IFN FTSFD,<
	SOS	DEFPTH		;SET USER'S STARTING PATH BACK UP
	MOVE	T1,[SFDLVL+4,,DEFPTH]
	PATH.	T1,
	  JFCL
	SETOM	DEFPTH
>
	PUSHJ	P,@RTX(TM)	;CALL USER'S EXIT ROUTINE
	MOVE	T1,[5,,SAVEAC]	;SAVE ACS IN CASE OF REENTER
	BLT	T1,SAVEAC+12
	MOVEI	T1,REEERR	;SET UP RE-ENTRY ADDRESS
	MOVEM	T1,.JBREN
	TLZE	F,FLG		;WANT TO EXIT AND GO?
	JRST	EXITGO		;YES
	EXIT	1,
	JRST	REEERR		;IS HE CONTINUES, REENTER

EXITGO:	MOVE	T1,[1,,GOBLK]	;CODE TO RUN COMPIL
	RUN	T1,		;LET COMPIL TAKE OVER
	JRST	REEERR		;IF HE CONTINUES, REENTER
>
IFE TOPS10,<
	SKIPE	T1,SAVSED	;HAS STAT FILE NAME BEEN DIDDLED?
	JRST	[MOVE   T2,[ASCII /D.TMP/]
		 DMOVEM T1,SEDFIL ;YES - SET UP REAL NAME AGAIN
		 SETZM  SEDFIL+2
		 JRST   .+1]	;CONTINUE
	HRROI	T2,SEDFIL	;SET UP nnnSED.TMP FILE FOR OUTPUT
	PUSHJ	P,SETOUT
	MOVE	T2,[POINT 7,PIKBUF+PCBSIZ-400]
	SETZ	T3,
	SOUT			;WRITE OUT THE STATUS
	PUSHJ	P,SETTMP	;MAKE THE FILE TEMPORARY AND CLOSE IT
	MOVE	TY,TYPPTR

ABORT1:	MOVEI	T1,.PRIIN
	MOVE	T2,FMDSAV	;GET BACK THE ORIGINAL FMOD WORD
	SFMOD
	STPAR
IFN FTECHO,<
	MOVEI	T3,SAVWKU	;RESTORE THE STARTING WAKE-UP SET
	PUSHJ	P,BRKSET
>
	PUSHJ	P,@RTX(TM)	;CALL USER'S EXIT ROUTINE
	MOVE	T1,[5,,SAVEAC]	;SAVE ACS IN CASE OF REENTER
	BLT	T1,SAVEAC+12
	MOVEI	T1,REEERR	;SET UP RE-ENTRY ADDRESS
	HRRM	T1,ENTVEC+1	;SAVE REAL RE-ENTRY ADDRESS IN ENTRY VECTOR
	MOVEI	T1,-5		;RE-ENABLE MONITOR INTERRUPTS
	SETO	T2,
	STIW
	SETZM	ITTFLG		;SAY INTERRUPTS HAVE BEEN RE-ENABLED
	MOVEI	T1,-1		;RESTORE THE CCOC WORDS
	DMOVE	T2,SAVCOC
	SFCOC

	TLZN	F,FLG		;WANT TO EXIT AND GO?
	JRST	ABORT2		;NO - IF HE CONTINUES, REENTER

	HLRZ	T1,GOBLK	;IS FILE AN ASCII NAME?
	JUMPN	T1,ABORT3	;YES - RUN THE PROGRAM, NOT COMPIL
	MOVE	T1,[.PRAST,,.FHSLF]
	MOVEI	T2,GOBLK	;YES - SET UP BUFFER ADDRESS
	MOVEI	T3,3		;SIZE OF ARG
	PRARG			;TELL EXEC TO DO A LOAD CLASS COMMAND
ABORT2:	HALTF			;  (TRY TO FIND that IN THE DOCUMENTATION)
	JRST	REEERR		;IS HE CONTINUES, REENTER

;HERE TO RUN THE PROGRAM IN GOBLK ON AN INFERIOR FORK.

ABORT3:	HRROI	T2,GOBLK	;CREATE A FORK AND RUN THE USER'S PROGRAM
	PUSHJ	P,RUNFRK
	KFORK			;WHEN IT EXITS, KILL THE FORK
	HALTF			;AND EXIT SED, TOO
	JRST	REEERR		;IS HE CONTINUES, REENTER
>
;HERE ON THE ABORT COMMAND - SAVE STATUS, ALLOW FOR A RE-ENTER
;AND EXIT WITHOUT SAVING THE FILE

ABOPAR:	TLO	F,FLG		;SET FLAG TO DO A RUN ON COMPIL
ABORT:	TLZE	TM,WDW		;WINDOWING?
	PUSHJ	P,WNCLST	;YES - STOP
	MOVEI	T4,FILSPC	;TELL USER THAT FILE IS NOT CHANGED
	PUSHJ	P,SAVMGN
IFN TOPS10,<
	CLRBFI			;MAKE SURE USER'S BUFFER IS EMPTY
>
	JRST	ABORT1		;THEN GO FINISH OFF

;SUBROUTINE TO OUTPUT A FILESPEC STATUS LINE.
;ENTER WITH T1/ADDR FILESPEC, T4/DISPTR; ALSO RW, CM, SL SET UP
;USES T0, T1, T2, T3

EXIFIL:	PUSHJ	P,PUTSTG	;PUT FILESPECS IN BUFFER
	JUMPE	T4,EXIFL1	;IF DISPLAY PTR ZERO, JUST END LINE
	HRRZ	T2,T4		;GET DISPLAY POINTER
	SUBI	T2,BUFFER	;CONVERT TO CHARACTER POSITION
	IMULI	T2,5
	HLRZ	T0,T4		;FIND CHARACTERS IN LAST WORD, TOO
	SETZ	T1,
	CAME	T0,PTRTBL(T1)
	AOJA	T1,.-1
	ADD	T2,T1
	MOVE	T1,[ASCII ?/FD:?]
	PUSHJ	P,EXINUM	;ALWAYS OUTPUT DISPLAY POINTER
	MOVE	T1,[ASCII ?/FR:?]
	SKIPE	T2,RW		;IS ROW ZERO?
	PUSHJ	P,EXINUM	;NO - OUTPUT IT
	SKIPE	T2,CM		;IS COLUMN ZERO?
	PUSHJ	P,EXICOL	;NO - OUTPUT IT
	SKIPE	T2,SL		;IS SLIDE ZERO?
	PUSHJ	P,EXISLI	;NO - OUTPUT IT
EXIFL1:	MOVEI	T1,15		;END LINE WITH A CARRIAGE RETURN
	IDPB	T1,TY
	MOVEI	T1,12
	IDPB	T1,TY
	POPJ	P,		;DONE

EXISLI:	SKIPA	T1,[ASCII ?/FS:?]
EXICOL:	MOVE	T1,[ASCII ?/FC:?]
EXINUM:	PUSHJ	P,PUTSQ1	;OUTPUT THE SWITCH NAME (IN T1)
	MOVE	T1,T2		;GET THE VALUE
	JRST	PUTNUM		;OUTPUT IT AND RETURN

;**********************************************************************
;HERE TO ADD BLANK LINES TO THE BUFFER

OPENLN:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	MOVE	T4,ADDLNS	;GET LAST TIME'S NOMINAL
	TLNN	F,ENT		;IS THERE A PARAMETER TYPED?
	JRST	OPLNPM		;NO - USE THE ONE ALREADY SET UP
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET LINES TO ADD
	MOVEM	T4,ADDLNS	;SAVE AS NEW NOMINAL
	TRNE	F,CMV		;CURSOR MOVEMENT?
	JRST	[MOVE  T1,PARG2    ;YES - GET SPACES TO OPEN, TOO
		 ADD   T1,SAVPOS+1 ;COUNT SPACES FROM LEFT MARGIN
		 ADD   T1,SL
		 MOVEM T1,ADDLSP
		 JRST  OPLNP0]
	SETZM	ADDLSP		;IF NO CURSOR MOVE, CLEAR EXTRA SPACES
OPLNP0:	PUSHJ	P,ERASPM	;RESET ENTER MODE
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
OPLNPM:	JUMPLE	T4,CLSLNE	;DONE, IF OPENING ZERO LINES
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	TLZ	F,PCM		;CANCEL THE PICK-CLOSE MARK, IF ANY
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	CAIN	T3,11		;IS CHARACTER AT CURSOR A TAB?
	PUSHJ	P,RPLTAB	;YES - REPLACE IT WITH SPACES

	MOVE	T4,ADDLNS	;GET LINES TO ADD
	LSH	T4,1		;MULTIPLY COUNT BY 2, FOR <CR><LF>
	MOVEM	T4,NUMCHR	;GO ADD THAT MANY <LF>S
	MOVEI	T1,12		;  (CHANGE HALF OF 'EM TO <CR>S LATER)
	MOVEM	T1,CHARAC
	PUSHJ	P,MAKCHR
	TLO	F,XPB!CHG	;SAY BOTTOM POINTER BAD; FILE MODIFIED

	MOVEI	T1,15		;NOW CHANGE HALF THE <LF>S TO <CR>S
	MOVE	PT,CHRPTR	;GET POINTER TO CURSOR POSITION
	MOVE	T4,ADDLNS	;AND NUMBER OF LINES TO ADD
	IDPB	T1,PT		;SET UP A NEW LINE
	IBP	PT
	SOJG	T4,.-2		;LOOP UNTIL ALL LINES SET UP
	SKIPG	T4,ADDLSP	;NOW GOT SOME SPACES TO ADD?
	JRST	OPNLD0		;NO - JUST RE-DISPLAY
	MOVEM	T4,NUMCHR
	EXCH	PT,CHRPTR
	PUSH	P,PT
	PUSHJ	P,MAKSPC	;ADD THE SPACES
	POP	P,PT		;RESTORE THE REAL CHARACTER POINTER
	EXCH	PT,CHRPTR
OPNLD0:	MOVE	T4,ADDLNS	;GET SIZE OF OPEN

	TRNN	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETERS?
	JRST	OPNLDA		;NO - SKIP THIS
	MOVEI	T1,1
	MOVEM	T1,ADDLNS	;YES - SET BACK TO ONE LINE
	SETZM	ADDLSP		;  AND NO SPACES

OPNLDA:	PUSHJ	P,OPENLD	;OPEN UP THE SCREEN **MAY NOT RETURN**
	JUMPN	CM,OPNLDX	;JUMP IF STARTING WITHIN A LINE
	SKIPN	ADDLSP		;WERE SPACES ADDED TOO?
	JRST	OPNLDX+1	;NO - JUST POSITION AND LOOP
	PUSHJ	P,CDOWN		;ELSE MOVE DOWN
OPNLDX:	PUSHJ	P,DISONE	;RE-DO THAT LINE
	TRNE	F,IMD		;IN INSERT MODE?
	PUSHJ	P,INSMSG	;YES - OUTPUT INSERT MESSAGE
	JRST	DISCUR		;RE-POSITION CURSOR AND LOOP

;SUBROUTINE TO OPEN (T4) LINES ON THE SCREEN (USED BY OPENLN, PUT)
;NOTE: WILL NOT RETURN IF REST OF SCREEN MUST BE DISPLAYED (JRSTS TO LOOP)

;IF INSERT IS LONGER THAN LINES BELOW THE CURSOR,
;  IF TERMINAL CAN CLEAR TO EOP, DO THE CLEAR (RETURN IF PUT, ELSE LOOP)
;    ELSE DISPLAY THE ENTIRE SCREEN (LOOP)
;ELSE IF INSERT FITS WITHIN THE SCREEN
;  IF TERMINAL CAN INSERT LINES, INSERT THEM (RETURN)
;    ELSE IF CURSOR IS HOME AND TERMINAL CAN ROLL DOWN, ROLL DOWN (RETURN)
;      ELSE DISPLAY FROM CURSOR TO END OF SCREEN (LOOP)

OPENLD:	MOVE	T1,LPP(TM)	;FIND NUMBER OF LINES BELOW CURSOR
	SUB	T1,RW
	CAMG	T1,T4		;ADDING MORE THAN THAT?
	JRST	OPNLD2		;YES - KILL THE RETURN
	SKIPN	T3,ILN(TM)	;CAN TERMINAL OPEN ITS OWN LINES?
	JRST	OPNLDR		;NO - GO REDISPLAY FROM HERE DOWN
	PUSHJ	P,POSCUR	;YES - POSITION THE CURSOR
	TLZ	F,FBL		;BOTTOM LINE WILL BE IN GOOD SHAPE
	JUMPE	CM,OPNLD1+1	;WITHIN A LINE?
	PUSHJ	P,CLRLNR	;YES - CLEAR TO END OF LINE
	MOVEI	T1,15		;DROP TO START OF NEXT LINE
	IDPB	T1,TY

OPNLD1:	PUSHJ	P,CDOWN
	MOVE	T1,T3		;OPEN UP ONE LINE
	PUSHJ	P,PUTSEQ
	SOJG	T4,OPNLD1	;LOOP THROUGH ALL LINES
	POPJ	P,		;DONE

OPNLD2:	SKIPN	CPG(TM)		;IS THERE A SEQUENCE FOR CLEAR-TO-EOP?
	JRST	DISALL		;NO - GO DISPLAY ENTIRE SCREENFUL
	PUSHJ	P,POSCUR	;YES - REPOSITION THE CURSOR
	PUSHJ	P,CLEARP	;CLEAR TO END OF SCREEN
	CAIN	DO,$PUT		;GOT A PUT COMMAND?
	POPJ	P,		;YES - RETURN TO PUT THE BUFFER
	POP	P,		;NO - KILL RETURN TO CALLER
	PUSHJ	P,PUTTYP	;OUTPUT ALL THIS
	JRST	LOOP		;AND GET A NEW COMMAND

OPNLDR:	JUMPN	RW,OPLDR1	;IF NOT HOME JUST DO DISPLAY
	JUMPN	CM,OPLDR1
	SKIPE	RLD(TM)		;NO ROLL DOWN SEQUENCE,
	CAML	T4,LPP(TM)	;  OR INSERTING LONGER THAN SCREEN SIZE?
	JRST	OPLDR1		;YES - DISPLAY ANYWAY
	PUSHJ	P,CHOME		;HOME THE CURSOR
	PUSHJ	P,ROLLDN	;ROLL AND CLEAR A LINE
	SOJG	T4,.-1		;DO THE PHYSICAL ROLL OF THE SCREEN
	POPJ	P,		;DONE

OPLDR1:	POP	P,		;DISPLAY FROM HERE DOWN AND LOOP
	JRST	DISDWN

;HERE TO REMOVE LINES FROM THE BUFFER (NULL THEM OVER, REALLY)

CLOSLN:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	MOVE	T4,ADDLNS	;SET UP LAST TIME'S NOMINAL
	TLNN	F,ENT		;IS THERE A PARAMETER TYPED?
	JRST	CLLNPM		;NO - USE THE ONE ALREADY SET UP
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET SPACES TO ADD
	MOVEM	T4,ADDLNS	;SAVE AS NEW NOMINAL
	TRNE	F,CMV		;CURSOR MOVEMENT?
	JRST	[MOVE  T1,PARG2 ;YES - GET SPACES TO CLOSE, TOO
		 ADD   T1,SAVPOS+1 ;COUNT SPACES FROM LEFT MARGIN
		 ADD   T1,SL
		 CAIN  T4,0	   ;CLOSING ZERO LINES?
		 MOVE  T1,PARG2    ;YES - COUNT ONLY SPACES PASSED OVER
		 MOVEM  T1,ADDLSP  ;SAVE NUMBER OF SPACES TO CLOSE
		 JRST  .+2]	   ;(SKIP THE SETZ)
	SETZM	ADDLSP		;IF NO CURSOR MOVE, CLEAR EXTRA SPACES
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW

CLLNPM:	DMOVE	T1,ADDLNS	;MOVE NOMINALS TO FRAGGABLE AREA
	DMOVEM	T1,ADDLNX
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	TRZ	F,COV		;ASSUME CLOSE BUFFER WILL NOT OVERFLOW
	TLNE	F,PCM		;HAS A MARK BEEN MADE?
	JRST	CLSMRK		;YES - DO THINGS DIFFERENTLY
	JUMPG	T4,.+3		;IF CLOSING SOME LINES, CONTINUE
	SKIPN	ADDLSX		;IF ZERO LINES, GOT ZERO SPACES TOO?
	JRST	CLSLNE		;YES - NOTHING TO DO
	MOVEM	T4,ROLLS	;SAVE NUMBER OF LINES FOR ROLLING AT END
	TLO	F,INS!XPB!CHG	;LET LINE BE EXTENDED; BOTPTR BAD; FILE MOD'D
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	TLZ	F,INS
	CAIN	T3,11		;IS CHARACTER AT CURSOR A TAB?
	PUSHJ	P,RPLTAB	;YES - REPLACE WITH SPACES BEFORE CURSOR
	MOVE	PT,CHRPTR	;GET CURRENT CURSOR POSITION
	SETZB	T2,CLSCNT	;AND A NULL, AND PTR TO CLOSE BUFFER
	MOVE	T3,[POINT 7,CLSBUF]
	SKIPN	T4,ADDLNX	;GET NUMBER OF LINES TO CLOSE - ANY?
	JRST	CLSLN3		;NO - JUST GO CLOSE SPACES

CLSLN1:	CAMN	EN,PT		;AT END OF USEABLE BUFFER?
	JRST	CLOSEN		;YES - DO END OF BUFFER-Y THINGS
	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CLSLN1	;IF NULL, GET ANOTHER ONE
	DPB	T2,PT		;REPLACE IT WITH A NULL
CLSLN2:	CAMN	T3,[010700,,CLSBUF+PCBSIZ-1]
	PUSHJ	P,CLSOVF	;IF ABOUT TO OVERFLOW, STORE ON DISK
	IDPB	T1,T3		;SAVE CHARACTER IN THE CLOSE BUFFER
	AOS	CLSCNT		;BUMP COUNT
	CAIE	T1,15		;CARRIAGE RETURN?
	JRST	CLSLN1		;NO - DRIVE ON

	ILDB	T1,PT		;YES - PICK UP THE <LF>
	DPB	T2,PT		;REPLACE IT WITH A NULL
	CAIE	T1,12		;IS IT REALLY A LINEFEED?
	JRST	CLSLN2		;NO - IT'S NOT THE END OF THE LINE
	SOJG	T4,CLSLN2	;YES - LOOP THROUGH DESIRED NUMBER OF ROWS
	CAMN	T3,[010700,,CLSBUF+PCBSIZ-1]
	PUSHJ	P,CLSOVF	;IF ABOUT TO OVERFLOW, STORE ON DISK
	IDPB	T1,T3		;SAVE THE LINEFEED IN THE CLOSE BUFFER
	AOS	CLSCNT		;BUMP COUNT FOR <LF>
CLSLN3:	SKIPLE	T4,ADDLSX	;GOT SOME SPACES TO CLOSE TOO?
	PUSHJ	P,CLLSPS	;YES - DO THEM

CLSLN4:	TRNN	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETERS?
	JRST	CLSL4A		;NO - JUST RE-POSITION AND LOOP
	MOVEI	T1,1
	MOVEM	T1,ADDLNS	;YES - SET BACK TO ONE LINE
	SETZM	ADDLSP		;  AND NO SPACES

CLSL4A:	SETZ	T1,		;END THE BUFFER WITH A NULL
	IDPB	T1,T3
	TRNE	F,COV		;HAS BUFFER OVERFLOWED?
	PUSHJ	P,CLSLST	;YES - WRITE OUT THE LAST PIECE
	MOVE	T1,PT		;MAKE SURE BUFFER ENDS WITH A CRLF
CLSLN5:	ILDB	T2,T1		;GET A CHARACTER
	CAMN	T1,EN		;REACHED END OF BUFFER?
	PUSHJ	P,ADDCR		;YES - PUT IN A CARRIAGE RETURN
	JUMPE	T2,CLSLN5	;NO - LOOP UNTIL END OR NON-NULL CHARACTER

	SOSG	SQZCNT		;TIME TO DO A SQUEEZE?
	PUSHJ	P,SQUEZW	;YES - REMOVE ALL NULL WORDS
	TLZE	F,PCM		;WAS THERE A MARK?
	JRST	DISALL		;YES - RE-DISPLAY THE SCREEN AND LOOP
	SKIPN	ADDLNX		;REALLY CLOSE ANY LINES?
	JRST	CLSLNL		;NO - JUST SPACES - RE-DO ONE LINE
	SKIPN	T3,DLN(TM)	;CAN TERMINAL DO ITS OWN CLOSE?
	JRST	CLSLNR		;NO - DISPLAY ALL FROM HERE DOWN
	MOVE	T4,LPP(TM)	;YES - GET NUMBER OF LINES PER PAGE
	SUB	T4,RW		;LESS CURRENT POSITION
	SUB	T4,ADDLNX	;LESS SIZE OF DELETE, GIVES LINES LEFT
	JUMPL	T4,DISDWN	;IF NONE (BIG DELETE), JUST RE-DISPLAY
	TLNE	F,FNC!FBL	;GOT FENCE OR FRAGGED BOTTOM LINE?
	PUSHJ	P,CBOTOM	;YES - ERASE IT
	MOVE	T4,RW		;MOVE TO START OF THE LINE THE CURSOR IS ON
	PUSHJ	P,POSLIN
	MOVE	T2,ADDLNX	;GET SIZE OF DELETE
	TLNE	F,FNC!FBL	;IS BOTTOM LINE O.K.?
	AOS	ROLLS		;NO - REWRITE ONE MORE LINE
	MOVE	T1,T3		;GET CODE TO CLOSE LINES
	PUSHJ	P,PUTSEQ	;CLOSE A LINE
	SOJG	T2,.-2		;LOOP THROUGH ALL LINES
	SKIPN	ADDLSX
	JUMPE	CM,.+3		;JUMP IF AT START OF A LINE
	MOVE	PT,LINPTR
	PUSHJ	P,DISONE	;ELSE DISPLAY SINGLE CLOSED-UP LINE
	MOVE	T4,LPP(TM)	;GET LINE NUMBER OF START OF REWRITE
	SUB	T4,ADDLNX
	TLNE	F,FBL		;IS BOTTOM LINE O.K.?
	SOJ	T4,		;NO - RE-DO IT, TOO
	MOVEM	T4,SAVEAC	;SET IT UP IN T4 AND SAVEAC
	PUSHJ	P,ROLFW1	;AND REWRITE FROM THERE DOWN
	JRST	LOOP

CLSLNL:	PUSHJ	P,DISLIN	;DISPLAY REST OF LINE CURSOR IS ON
	JRST	DISCUR		;RESTORE CURSOR AND LOOP

CLSLNR:	JUMPN	RW,DISDWN	;IF NOT HOME JUST DO DISPLAY
	JUMPN	CM,DISDWN
	SKIPN	ADDLSX		;DELETED ANY SPACES,
	SKIPN	RUP(TM)		;  OR NO ROLL UP SEQUENCE?
	JRST	DISDWN		;YES - DISPLAY ANYWAY
	MOVE	T4,ADDLNX	;GET NUMBER OF LINES DELETED
	CAML	T4,LPP(TM)	;LONGER THAN SCREEN SIZE?
	JRST	DISDWN		;YES - DISPLAY ANYWAY
	PUSHJ	P,ROLFW0	;NO - DISPLAY BY DOING A ROLL (AT LAST)
	JRST	LOOP		;DONE

;HERE IF END OF BUFFER REACHED DURING THE CLOSE

CLOSEN:	MOVE	PT,CHRPTR	;GET POINTER TO FIRST DELETED CHARACTER
	IBP	PT		;PLUS A CHARACTER
	MOVE	EN,PT		;SAVE AS NEW END OF BUFFER
	JUMPN	SL,.+2		;DID CLOSE START AT START OF A LINE?
	JUMPE	CM,.+2
	PUSHJ	P,ADDCR		;NO - PUT A <CRLF> AFTER THAT PARTIAL LINE
	TRNE	F,COV		;HAS BUFFER OVERFLOWED?
	PUSHJ	P,CLSLST	;YES - WRITE OUT THE LAST PIECE
	PUSHJ	P,POSCUR	;PUT CURSOR WHERE IT BELONGS
	SKIPN	CPG(TM)		;CAN TERMINAL CLEAR TO END OF SCREEN?
	JRST	DISALL		;NO - RE-DISPLAY THE ENTIRE SCREEN
	PUSHJ	P,FNCCLR	;YES - CLEAR AND PUT UP THE FENCE
	PUSHJ	P,POSCUR	;GET BACK TO PROPER POSITION
	JRST	LOOP		;AND GET ANOTHER COMMAND

;SUBROUTINE TO WRITE OUT THE LAST PIECE OF THE CLOSE BUFFER

CLSLST:	SETZ	T1,		;MAKE SURE LAST WORD OF BUFFER IS NULLED
	IDPB	T1,T3
	IDPB	T1,T3
	IDPB	T1,T3
	IDPB	T1,T3
	IDPB	T1,T3
	MOVE	T1,CLSCNT	;GET COUNT OF WORDS CLOSED
	IDIVI	T1,5
	AOJ	T1,
	SUBI	T1,PCBSIZ	;FIND SIZE OF LAST PIECE
	CAIL	T1,PCBSIZ	;SMALL ENOUGH?
	JRST	.-2		;NO - SUBTRACT SOME MORE
IFN TOPS10,<
	MOVNS	T1
	HRLM	T1,CLSCCL	;SET TO OUTPUT THAT MANY WORDS
>
	PUSHJ	P,CLSOV0	;YES - WRITE OUT THE LAST PIECE
IFN TOPS10,<
	MOVNI	T1,PCBSIZ	;RESTORE FULL BUFFER SIZE
	HRLM	T1,CLSCCL	;  TO CHANNEL COMMAND
>
	JRST	CLSOVE		;CLOSE THE DISK FILE AND RETURN

;HERE TO RESTORE INSERT-DELETE LINES NOMINALS (MAYBE), RE-SET CURSOR, AND LOOP

CLSLNE:	TRNN	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETERS?
	JRST	DISCUR		;NO - JUST RE-POSITION AND LOOP
	MOVEI	T1,1
	MOVEM	T1,ADDLNS	;YES - SET BACK TO ONE LINE
	SETZM	ADDLSP		;  AND NO SPACES
 	JRST	DISCUR		;RE-POSITION CURSOR AND LOOP

;SUBROUTINE FOR WHEN USER WANTS TO CLOSE SOME SPACES AFTER CLOSING LINES
;(WHICH HE'S INDICATED BY USING CURSOR MOVEMENT)

CLLSPS:	TLO	F,FLG		;SET TO NULL THE CHARACTERS AS THEY ARE FOUND
	MOVE	T2,CLSCNT	;GET NUMBER OF SPACES CLOSED
	PUSHJ	P,SPCBFZ	;NULL OUT (T4)S WORTH OF CHARACTERS
	TLZ	F,FLG		;CLEAR NULLING FLAG
	MOVE	T1,SPCCNT	;GET COUNT OF CHARACTERS
	ADDM	T1,CLSCNT	;ADD TO TOTAL COUNT
	POPJ	P,		;FINISH OFF

;HERE IF MARK WAS MADE - CLOSE FROM STARTING CHARACTER TO CURRENT POSITION
;note: does nothing about starting or ending in a tab

CLSMRK:	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	TLO	F,CHG		;SAY FILE IS CHANGED
	PUSHJ	P,MRKSET	;SET UP TO USE THE MARK (CLEAR T2, T4)
	SETZB	ADDLNX		;CLEAR LINES TO ADD (RE-COMPUTE BELOW)
	MOVE	T3,[POINT 7,CLSBUF]
CLSMK1:	CAMN	PT,MRKPTR	;AT END OF THE CLOSE?
	JRST	CLSMKE		;YES - FINISH OFF
	CAMN	T3,[010700,,CLSBUF+PCBSIZ-1]
	PUSHJ	P,CLSOVF	;WRITE TO DISK ON CLOSE BUFFER OVERFLOW
	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CLSMK1	;SKIP, IF NULL
	IDPB	T1,T3		;SAVE IT IN THE CLOSE BUFFER
	DPB	T4,PT		;NULL OUT THE CHARACTER IN THE FILE
	CAIN	T1,11		;TAB?
	OR	T2,[7,,0]	;YES - COUNT ITS LENGTH IN SPACES
	CAIE	T1,15		;END OF A LINE?
	AOBJP	T2,CLSMK1	;NO - COUNT CHARACTER (TWICE) AND LOOP

	MOVE	T1,PT		;MAYBE - GOT A LF AFTER THE CR?
	ILDB	T1,T1
	CAIE	T1,12
	AOBJP	T2,CLSMK1	;NO - COUNT CR AS JUST ANOTHER CHARACTER
	HRRO	T2,T2		;YES - CLEAR NUMBER OF SPACES (AFTER LF FOUND)
	AOS	ADDLNX		;BUMP NUMBER OF LINES
	AOJA	T2,CLSMK1	;AND CONTINUE

CLSMKE:	HRRZM	T2,CLSCNT	;SAVE COUNT OF CHARACTERS CLOSED
	HLRZM	T2,ADDLSX	;  AND SPACES TO ADD
	MOVE	T1,ADDLNX	;SAVE NUMBER OF LINES
	MOVEM	T1,ROLLS	;  FOR ROLLING AT END
	JRST	CLSLN4		;FINISH OFF

;SUBROUTINE TO SET UP FOR A MARKED PICK OR DELETE-LINES
;SIDE-EFFECT: CLEARS T2 AND T4

MRKSET:	MOVE	T1,MRKPTR	;GET THE STARTING DISPLAY POINTER
	CAMN	T1,DISPTR	;HAS DISPLAY POINTER CHANGED DURING MARKING?
	TLZ	F,PCM		;NO - CLEAR MARK FLAG (TO HELP DISPLAYING)
	MOVE	T2,CHRPTR	;GET POINTER TO ENDING POSITION
	MOVEM	T2,MRKPTR	;SAVE IT AS POINTER TO END OF REGION
	MOVE	PT,MRCPTR	;GET POINTER TO STARTING POSITION
	MOVE	T3,PT		;  SHIFT BYTE COUNT INTO LOW-ORDER BITS
	ROTC	T2,6		;  (NOW A SIMPLE COMPARE TELLS WHICH IS LARGER)
	MOVE	T0,T2		;PUT AC T2 IN A SAFE PLACE
	SETZB	T2,T4		;CLEAR COUNT OF CHARACTERS CLOSED
	CAMGE	T0,T3		;GOING FORWARDS?
	JRST	MRKST1		;NO - FINISH OFF DIFFERENTLY
	MOVEM	T1,DISPTR	;YES - USE STARTING DISPLAY POINTER
	DMOVE	RW,SVPMRK	;AND STARTING ROW AND COLUMN
	DMOVE	T0,MRLPTR	;SET UP STARTING LINE AND CURSOR POINTERS
	DMOVEM	T0,LINPTR
	POPJ	P,		;DONE

MRKST1:	EXCH	PT,MRKPTR	;BACKWARDS - SWAP START AND END POINTERS
	POPJ	P,		;DONE

;SUBROUTINE TO FIND (T4) REAL CHARACTERS (NOT NULLS) AT (PT), WHICH IS FRAGGED
;AND PUT THEM IN THE AREA POINTED TO BY T3
;IF FLG IS SET, NULLS THE CHARACTER IN THE FILE BUFFER; ELSE LEAVES IT ALONE
;STOPS WHEN COUNTED OUT. IF END OF LINE REACHED, PADS WITH SPACES
;RETURNS COUNT OF CHARACTERS MOVED IN SPCCNT

;NOTE: PICK OR CLOSE BUFFER can't OVERFLOW WHILE IN THIS ROUTINE, AS LONG AS
;BUFFER SIZE IS LARGER THAN ONE SCREENFUL (80*20/5 = 320 WORDS)
;THAT'S BECAUSE THIS IS REACHED FROM A CURSOR MOVE COMMAND, AND CURSOR MOVE
;CAN'T ENCOMPASS MORE THAN A SCREENFUL.
;WELL, ALMOST:	REAL LONG LINES can OVERFLOW. SO BEWARE OF, SAY, OBJECT FILES

SPCBFZ:	SETZM	SAVEAC		;CLEAR STARTING COLUMN NUMBER
	JUMPN	T2,.+2		;PICKED NOTHING SO FAR?
SPCBUF:	MOVEM	CM,SAVEAC	;RIGHT - SAVE COLUMN POSITION INSTEAD
	MOVEM	T4,WRTNUM	;SAVE NUMBER OF CHARS TO NULL
	SETZM	SPCCNT		;CLEAR COUNT OF CHARACTERS MOVED
	SETZB	T1,NUMCHR	;GET A NULL; CLEAR # SPACES TO ADD

SPCBF1:	CAMN	PT,EN		;AT END OF BUFFER?
	JRST	SPCBF4		;YES - PUT IN SOME SPACES AND FINISH UP
	ILDB	T2,PT		;NO - GET A CHARACTER
	JUMPE	T2,SPCBF1	;IGNORE IF NULL
	CAIN	T2,15		;IS IT A <CR>?
	PUSHJ	P,ISCRLF	;YES - GOT A CRLF?
	AOSA	SPCCNT		;NO - BUMP COUNT OF CHARACTERS
	JRST	SPCBF4		;YES - FINISH OFF AND RETURN
	TLNE	F,FLG		;ELSE WANT TO NULL IT OUT?
	DPB	T1,PT		;YES - ZAP
	CAIN	T2,11		;IS IT A TAB?
	JRST	SPCBTB		;YES - SEE HOW LONG THE TAB IS
	IDPB	T2,T3		;NO - SAVE CHARACTER IN THE DESIRED BUFFER
	SOJG	T4,SPCBF1	;AND COUNT IT - GOT ENOUGH?
SPCBEN:	SKIPE	NUMCHR		;GOT ANY SPACES TO ADD,
	TLZN	F,FLG		;REALLY WANT TO ADD THEM?
	POPJ	P,		;NO - JUST RETURN
	JRST	MAKSPC		;YES - ADD THEM AND RETURN

SPCBF4:	ADDM	T4,SPCCNT	;DONE - COUNT THE EXTRA SPACES
	MOVEI	T1," "		;PAD OUT WITH SPACES:
	IDPB	T1,T3		;SAVE SPACES UNTIL COUNTED OUT
	SOJG	T4,.-1
	POPJ	P,		;DONE FOR KEEPS

SPCBTB:	MOVE	T0,WRTNUM	;GET LENGTH OF DELETE
	ADD	T0,SAVEAC	;  PLUS STARTING CURSOR POSITION
	SUB	T0,T4		;  LESS NUMBER TO GO, GIVES PRESENT POSITION
	ANDI	T0,7		;FIND NEGATIVE SIZE OF TAB
	SUBI	T0,10
	ADD	T4,T0		;COUNT OFF THAT MANY SPACES FROM DELETE
	JUMPG	T4,[IDPB T2,T3	;IF STILL MORE TO GO, SAVE TAB
		    JRST SPCBF1];AND CONTINUE
	SOS	SPCCNT		;REMOVE TAB FROM COUNT OF CHARACTERS
	MOVN	T1,T4		;GET COUNT OF SPACES TO ADD TO FILE
	ADDM	T1,NUMCHR
	SUB	T4,T0		;GET COUNT OF SPACES TO ADD TO BUFFER
	MOVEI	T1," "		;AND SAVE OFF THOSE SPACES
	IDPB	T1,T3
	AOS	SPCCNT		;BUMP COUNT OF CHARACTERS
	SOJG	T4,.-2
	JRST	SPCBEN		;AND FINISH UP

;SUBROUTINE FOR OVERFLOW OF CLOSE BUFFER - SAVE ON DISK; SET COV FLAG

CLSOVF:	PUSH	P,T1		;SAVE LIVE CHARACTER
	SETZ	T1,		;STORE A NULL AT END OF CLOSE BUFFER
	IDPB	T1,T3
	TROE	F,COV		;SET CLOSE OVERFLOW FLAG - ALREADY SET?
	JRST	CLSOV1		;YES - FILE ALREADY OPEN
	PUSH	P,T2		;SAVE AN AC
	HRROI	T2,CLSFIL
IFN TOPS10,<
	PUSHJ	P,SETDEL	;DELETE OLD .TMP FILE
>
	PUSHJ	P,SETOUT	;SET UP THE DELETE BUFFER FILE
	MOVEM	T1,CLSJFN
	JRST	CLSOV2

CLSOV0:	PUSH	P,T1		;SAVE AN AC
CLSOV1:	PUSH	P,T2		;SAVE AN AC
IFN TOPS10,<
CLSOV2:	OUTPUT	5,CLSCCL	;WRITE OUT THE CLOSE BUFFER
>
IFE TOPS10,<
	MOVE	T1,CLSJFN
CLSOV2:	HRROI	T2,CLSBUF	;WRITE OUT THE CLOSE BUFFER
	SETZ	T3,
	SOUT
>
	MOVE	T3,[POINT 7,CLSBUF] ;START THE BUFFER AFRESH
	POP	P,T2		;RESTORE ACS
	POP	P,T1		;RESTORE ACS
	POPJ	P,		;CONTINUE

IFN TOPS10,<
CLSOVE:	CLOSE	5,
	RELEAS	5,		;FINISH OFF THE FILE
	POPJ	P,		;DONE
>
IFE TOPS10,<
CLSOVE:	MOVE	T1,CLSJFN	;GET FILE HANDLE
	JRST	SETTMP		;MAKE IT TEMPORARY, CLOSE IT, AND RETURN
>
;**********************************************************************
;HERE TO ADD SPACES TO THE BUFFER

OPENSP:	MOVE	T4,ADDSPC	;SET UP LAST TIME'S NOMINAL
	MOVEM	T4,PARG1	;AS DEFAULT FOR THIS TIME
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET SPACES TO ADD
	TRNE	F,CMV		;DOING CURSOR MOVEMENT?
	PUSHJ	P,SPSCUR	;YES - HANDLE THINGS A LITTLE DIFFERENTLY
	MOVEM	T4,ADDSPC	;SAVE NEW NOMINAL
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
OPSNPM:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	SKIPG	T1,ADDSPC	;SET UP LAST TIME'S NOMINAL
	JRST	OPNSPE		;DONE, IF NOTHING TO ADD
	TLOA	F,CHG!INS	;SAY FILE HAS BEEN MODIFIED
OPSNP1:	TLO	F,INS		;LET LINE BE EXTENDED IF NECESSARY
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	TLZ	F,INS!PCM
	MOVEM	T1,NUMCHR	;ADD THE RIGHT NUMBER OF SPACES
	CAIE	T3,11		;IS CHARACTER AT CURSOR A TAB?
	JRST	OPNSP1		;NO - CONTINUE
	MOVE	T1,TABSIZ	;YES - CONVERT THE TAB TO SPACES
	ADDM	T1,NUMCHR
	SETZ	T1,		;AND NULL OUT THE TAB
	DPB	T1,TABPTR
	SKIPN	TABSPC		;POINTING TO START OF TAB?
	TLO	F,XPC		;NO - CHARACTER POINTER IS BAD

OPNSP1:	PUSHJ	P,MAKSPC	;GO ADD THE SPACES
	MOVE	T4,ADDSPC	;GET NUMBER OF SPACES TO ADD
IFN FTIMD,<
	SKIPN	IMO(TM)		;DOES TERMINAL HAVE INSERT MODE?
>
	SKIPE	T3,ISP(TM)	;CAN TERMINAL OPEN SPACES ON ITS OWN?
	PUSHJ	P,OPNSPI	;YES - LET IT (SKIP RETURNS)
	PUSHJ	P,DISLIN	;NO - REWRITE REST OF LINE CURSOR IS ON
	SOSGE	ADDSLN		;WANT TO WORK WITH OTHER LINES?
	JRST	OPNSPE		;NO - GO FINISH UP
	TLO	F,XPC!XPL	;YES - RE-MAKE SOME POINTERS
	MOVE	T1,ADDSPC	;GET SIZE OF INSERT
	AOJA	RW,OPSNP1	;AND DO THE SAME WITH THE NEXT LINE

OPNSPE:	MOVEI	T1,1
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T1,ADDSPC	;YES - SET IT BACK TO 1
	JRST	DISCUR		;RE-POSITION THE CURSOR AND LOOP

;SUBROUTINES TO USE THE TERMINAL HARDWARE TO INSERT OR DELETE SPACES
;ENTER WITH T4/ NUMBER OF TIMES TO OUTPUT (T3)
;NORMAL RETURN: LINE HAS TABS, MUST BE RE-DISPLAYED
;SKIP	RETURN: LINE HAS BEEN HANDLED; NO FURTHER ACTION NECESSARY

CLSSPI:	MOVE	T2,CHRPTR	;SEE IF THERE ARE ANY TABS FROM HERE TO EOL
	MOVE	T0,CPL(TM)	;GET LENGTH OF REMAINDER OF LINE
	SUB	T0,ADDSPC
	SUB	T0,CM
CLSSI1:	ILDB	T1,T2
	JUMPE	T1,CLSSI1	;IGNORE IF NULL
	CAIN	T1,11		;TAB?
	POPJ	P,		;YES - GO RE-DISPLAY ENTIRE LINE
	CAIE	T1,15		;END OF LINE?
	SOJG	T0,CLSSI1	;NO - KEEP LOOKING
	JUMPLE	T0,CPOPJ	;NO TAB - IF LINE IS LONG GO REDISPLAY
	AOS	(P)		;SET UP FOR SKIP RETURN
	PUSHJ	P,POSCUR	;POINT TO THE RIGHT POSITION
	MOVE	T1,T3		;GET CODE TO DO THE CLOSE
	PUSHJ	P,PUTSEQ	;CLOSE ONE SPACE
	SOJG	T4,.-2		;LOOP THROUGH ALL SPACES
	JRST	PUTTYP		;OUTPUT THE BUFFER AND SKIP RETURN

OPNSPI:	MOVE	T2,CHRPTR	;SEE IF THERE ARE ANY TABS FROM HERE TO EOL
OPNSI1:	ILDB	T1,T2
	CAIN	T1,11		;TAB?
	POPJ	P,		;YES - GO RE-DISPLAY ENTIRE LINE
	CAIE	T1,15		;END OF LINE?
	JRST	OPNSI1		;NO - KEEP LOOKING
	AOS	(P)		;SET UP FOR SKIP RETURN
	PUSHJ	P,POSCUR	;POINT TO THE RIGHT POSITION
IFN FTIMD,<
	SKIPE	IMO(TM)		;DOES THE TERMINAL HAVE INSERT MODE?
	JRST	OPNSII		;YES - INSERT THE HOLE, THEN
>
	MOVE	T1,T3		;GET CODE TO DO THE OPEN
	PUSHJ	P,PUTSEQ	;OPEN ONE SPACE
	SOJG	T4,.-2		;LOOP THROUGH ALL SPACES
	JRST	PUTTYP		;OUTPUT THE BUFFER AND SKIP RETURN

IFN FTIMD,<
OPNSII:	PUSHJ	P,IMODON	;TURN ON INSERT MODE
	MOVEI	T1," "		;GET THE SPACE TO TYPE IN
	IDPB	T1,TY
	SOJG	T4,.-1		;OUTPUT ALL THE SPACES
	PUSHJ	P,IMODOF	;TURN OFF INSERT MODE
	JRST	PUTTYP		;OUTPUT THE BUFFER AND SKIP RETURN
>
;HERE TO DELETE THE PREVIOUS CHARACTER FROM THE BUFFER

DELCHR:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	JUMPE	CM,LOOP		;DO NOTHING IF AT START OF LINE
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	PUSHJ	P,MAKCPT	;RE-MAKE THE CURSOR POINTER
	MOVEM	CM,SAVEAC	;SAVE THE CURRENT COLUMN POSITION
	CAIN	T3,15		;IS THE CURSOR AT OR BEYOND END OF THE LINE?
	PUSHJ	P,ERSWDL	;YES - FIRST POSITION TO END OF LINE
	CAME	CM,SAVEAC	;WAS THE CURSOR BEYOND THE END OF THE LINE?
	JRST	LOOP		;YES - IT MOVED TO THE END; DONE
	TLO	F,CHG		;SAY THE FILE HAS BEEN MODIFIED
	TLZ	F,PCM		;CANCEL THE PICK-CLOSE MARK, IF ANY
	MOVE	PT,CHRPTR	;GET CHARACTER POINTER
	MOVEM	PT,SAVEAC	;STORE IT IN A SAFE PLACE
	JRST	DELCH2		;JUMP INTO THE LOOP

DELCH1:	ADD	PT,[70000,,0]	;BACK IT UP A NOTCH
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
DELCH2:	LDB	T1,PT		;GET THE PREVIOUS CHARACTER
	JUMPE	T1,DELCH1	;SKIP OVER IT IF NULL
	MOVEI	T4,1		;SET LENGTH OF DELETE TO 1
	MOVEM	T4,DELCNT	;SET SIZE OF DELETE BUFFER TO 1, TOO
	MOVE	T2,T1		;KEEP THE CHARACTER IN T2
	ROT	T1,-7		;LEFT JUSTIFY THE CHARACTER
	MOVEM	T1,DELBUF	;SAVE IT IN THE DELETE BUFFER
	CAIN	T3,11		;IS THE CHARACTER UNDER THE CURSOR A TAB?
	JRST	DELCHT		;YES - HANDLE SPECIALLY
	DPB	T1,PT		;NULL OUT THE LIVE CHARACTER
	CAIE	T2,11		;WAS A TAB DELETED?
	SOJA	CM,CLSNP3	;NO - CORRECT THE DISPLAY AND LOOP
	PUSHJ	P,CALCML	;YES - POSITION TO THE CHARACTER BEFORE THE TAB
	  JRST	CLSLNL
	JRST	CLSLNL		;RE-DISPLAY THE REST OF THE LINE; LOOP

;HERE WHEN THE CHARACTER UNDER THE CURSOR IS A TAB. FIND THE POSITION
;OF THE PREVIOUS CHARACTER. IF THE CURSOR IS NEXT TO IT, DELETE IT;
;IF THE CURSOR IS WITHIN THE TAB, DELETE THE TAB
;PT/ DPB POINTER TO PREVIOUS CHARACTER; SAVEAC/ DPB POINTER TO TAB

DELCHT:	MOVEM	CM,SAVEAC+1	;SAVE CURSOR POSITION
	PUSHJ	P,CALCML	;POSITION TO THE CHARACTER BEFORE THE TAB
	  TDZA	T4,T4
	SETZ	T4,		;GET A NULL
	CAMN	CM,SAVEAC+1	;IS THE CURSOR NEXT TO THE CHARACTER?
	JRST	DELCT1		;YES - DELETE THE CHARACTER
	IDPB	T4,SAVEAC	;NO - DELETE THE TAB
	MOVSI	T1,(BYTE (7) 11)
	MOVEM	T1,DELBUF	;NOTE THAT THE DELETED CHARACTER WAS THE TAB
	JRST	CLSLNL		;RE-DISPLAY THE REST OF THE LINE AND LOOP

DELCT1:	DPB	T4,PT		;DELETE THE CHARACTER
	SOJA	CM,CLSNP3	;FINISH UP THE DISPLAY AND LOOP

;HERE TO REMOVE CHARACTERS FROM THE BUFFER

CLOSSP:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	TLNN	F,ENT		;IS THERE A PARAMETER TYPED?
	JRST	CLSNPM		;NO - USE THE ONE ALREADY SET UP
	MOVE	T4,ADDSPC	;SET UP LAST TIME'S NOMINAL
	MOVEM	T4,PARG1
CLSSP1:	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET SPACES TO DELETE
	TRNE	F,CMV		;DOING CURSOR MOVEMENT?
	PUSHJ	P,SPSCUR	;YES - HANDLE THINGS A LITTLE DIFFERENTLY
	MOVEM	T4,ADDSPC	;SAVE NEW NOMINAL
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	TRZ	F,CMV		;CLEAR CURSOR MOVE FLAG (IF COMING FROM ERASWD)
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW

CLSNPM:	SKIPG	T1,ADDSPC	;GOT ANYTHING TO DELETE?
	JRST	CLOSP1		;NO - DONE
CLSNP0:	SOS	ISVCNT		;YES - DECREMENT INCREMENTAL SAVE COUNTER
	TLZ	F,PCM		;CANCEL THE PICK-CLOSE MARK, IF ANY
	MOVEM	T1,ADDSPS	;SET UP THE VALUE
	TLO	F,CHG		;SAY FILE IS MODIFIED
CLSNP1:	PUSHJ	P,MAKCPT	;RE-MAKE CHARACTER POINTER
	SETZM	NUMCHR		;ASSUME A TAB WON'T BE BROKEN
	CAIE	T3,11		;IS CHARACTER AT CURSOR A TAB?
	JRST	CLSNP2		;NO - CONTINUE
	MOVE	T1,TABSPC	;YES - ADD SPACES TO LEFT OF TAB, AFTER CLOSE
	MOVEM	T1,NUMCHR

CLSNP2:	MOVE	PT,CHRPTR
	MOVE	T4,ADDSPS	;GET NUMBER OF SPACES TO CLOSE
	PUSHJ	P,WRTNUL	;NULL OUT THAT MANY CHARACTERS
	MOVEM	T4,WRTNUM	;SAVE SIZE OF LEFTOVER, IF IT'S SHORT
	SKIPE	NUMCHR		;WANT TO ADD SPACES FOR A BROKEN TAB?
	PUSHJ	P,MAKSPC	;YES - DO IT
	MOVE	T4,ADDSPS	;GET NUMBER OF SPACES TO CLOSE
	SUB	T4,WRTNUM	;MINUS UNNEEDED OVERAGE
	SKIPE	WRTNUM		;DELETE PAST THE END OF THE LINE?
	JRST	CLSN2A		;YES - JUST CLEAR TO END OF LINE IF POSSIBLE
CLSNP3:	SKIPE	T3,DSP(TM)	;CAN TERMINAL CLOSE SPACES ON ITS OWN?
	PUSHJ	P,CLSSPI	;YES - LET IT (SKIP RETURNS)
	PUSHJ	P,CLOSP0	;NO - REWRITE THE LINE CURSOR IS ON
CLSNP4:	SOSGE	ADDSLN		;WANT TO DO IT WITH ANOTHER LINE?
	JRST	CLOSP1		;NO - JUST GET ANOTHER COMMAND
	TLO	F,XPC!XPL	;YES - RE-MAKE SOME POINTERS
	AOJA	RW,CLSNP1	;AND DO THE SAME WITH THE NEXT LINE

CLSN2A:	SKIPN	CLN(TM)		;CAN TERMINAL CLEAR TO END OF LINE?
	JRST	CLSNP3		;NO - DO IT SOME OTHER WAY
	PUSHJ	P,POSCUR	;YES - RE-POSITION THE CURSOR
	MOVE	T1,CLN(TM)	;CLEAR TO END OF LINE
	PUSHJ	P,PUTSEQ
	JRST	CLSNP4		;AND FINISH OFF

CLOSP0:	SKIPE	NUMCHR		;STARTED WITH A TAB?
	PUSHJ	P,MAKCK1	;YES - MAKE SURE THE CURSOR POINTER IS RIGHT
	JRST	DISLIN		;RE-WRITE REST OF LINE THE CURSOR IS ON; RETURN

CLOSP1:	SOSG	SQZCNT		;TIME TO DO A SQUEEZE?
	PUSHJ	P,SQUEZW	;YES - REMOVE ALL NULL WORDS
	JRST	OPNSPE		;FINISH UP AND GET ANOTHER COMMAND

;HERE FOR CURSOR MOVE OPENSP OR CLOSSP - COUNT LINES AND SPACES

SPSCUR:	MOVEM	T4,ADDSLN	;SAVE LINES TO WORK WITH
	SKIPN	T4,PARG2	;GET NUMBER OF SPACES - ANY?
	MOVE	T4,ADDSPC	;NO - USE CURRENT NOMINAL
	POPJ	P,

;**********************************************************************
;HERE TO TAKE LINES FROM THE BUFFER AND PUT THEM IN THE PICK BUFFER

PICK:	MOVE	T4,PICKLN	;SET UP LAST TIME'S NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET LINES TO PICK
	JUMPE	T1,[SETZM PICKLN    ;IF GOT A TOKEN, READ ZERO lINES
		    MOVEM T4,PICKSP ;AND GIVEN NUMBER OF SPACES
		    JRST  PICK0]    ;CONTINUE
	MOVEM	T4,PICKLN	;SAVE AS NEW NOMINAL
	TRNE	F,CMV		;CURSOR MOVEMENT?
	JRST	[MOVE  T1,PARG2    ;YES - GET SPACES TO PICK, TOO
		 MOVEM T1,PICKSP   ;IF NO LINES, COUNT SPACES FROM CURSOR
		 JUMPE T4,PICK0
		 ADD   T1,SAVPOS+1 ;IF SOME LINES, COUNT FROM LEFT MARGIN
		 ADD   T1,SL
		 MOVEM T1,PICKSP
		 JRST  PICK0]
	SETZM	PICKSP		;IF NO CURSOR MOVE, CLEAR EXTRA SPACES
PICK0:	PUSHJ	P,ERASPM	;ERASE PARAMETER
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW

PIKNPM:	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POINTER
	TLNE	F,PCM		;HAS A MARK BEEN MADE?
	JRST	PIKMRK		;YES - DO THINGS DIFFERENTLY
	MOVE	T1,T3		;SAVE CHARACTER AT CURSOR
	MOVE	PT,CHRPTR	;GET CURRENT CURSOR POSITION
	PUSHJ	P,PIKGPT	;SET UP THE POINTER TO THE PICK BUFFER
	SETZ	T2,		;CLEAR COUNT (IN CASE THERE AREN'T ANY LINES)
	SKIPG	T4,PICKLN	;GET NUMBER OF LINES TO PICK - ANY?
	JRST	PICK3		;NO - SEE IF WANT TO PICK SPACES

	CAIE	T1,11		;GOT A TAB AT THE CURSOR?
	JRST	PICK1-1		;NO - SKIP THIS
	MOVE	T2,PT		;GET CURSOR PTR AGAIN FOR SCRATCH
	ILDB	T1,T2		;GET CHARACTER CURSOR POINTS TO
	CAIE	T1,11		;FOUND THE TAB?
	JRST	.-2		;NO - KEEP LOOKING
	SKIPG	TABSPC		;YES - AT BEGINNING OF TAB?
	JRST	PICK1-1		;YES - DON'T TOUCH THE TAB, THEN
	MOVE	PT,T2		;WITHIN - POINT AFTER TAB
	MOVE	T2,TABSIZ	;GET TAB'S SIZE TO RIGHT OF CURSOR
	SUB	T2,TABSPC
	PUSH	P,T2		;SAVE COUNT FOR A WHILE
	MOVEI	T1," "		;PUT SOME SPACES IN THE PICK BUFFER
	IDPB	T1,T3
	SOJG	T2,.-1
	POP	P,T2		;RESTORE COUNT OF SPACES PUT IN
	JRST	PICK1

	SETZ	T2,		;CLEAR COUNT OF CHARACTERS PICKED
PICK1:	CAMN	EN,PT		;AT END OF USEABLE BUFFER?
	JRST	PIKPAD		;YES - PAD IN THE REMAINING <CRLF>S
	CAMN	T3,[010700,,PIKBUF+PCBSIZ-1]
	PUSHJ	P,PIKOVF	;WRITE TO DISK ON PICK BUFFER OVERFLOW
	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PICK1	;SKIP, IF NULL
	IDPB	T1,T3		;SAVE IT IN THE PICK BUFFER
	CAIE	T1,15		;CARRIAGE RETURN?
	AOJA	T2,PICK1	;NO - IGNORE IT

	CAMN	T3,[010700,,PIKBUF+PCBSIZ-1]
	PUSHJ	P,PIKOVF	;WRITE TO DISK ON PICK BUFFER OVERFLOW
	ILDB	T1,PT		;YES - PICK UP THE <LF>
	IDPB	T1,T3		;SAVE IT IN THE PICK BUFFER
	ADDI	T2,2		;COUNT IT
	CAIE	T1,12		;IS IT REALLY?
	JRST	PICK1		;NO - IT'S NOT THE END OF THE LINE
	SOJG	T4,PICK1	;YES - LOOP THROUGH DESIRED NUMBER OF LINES
PICK3:	ADDM	T2,PIKCNT	;SAVE COUNT OF CHARACTERS PICKED
	SKIPLE	T4,PICKSP	;DONE WITH LINES - GOT ANY SPACES?
	PUSHJ	P,PIKSPS	;YES - PICK THEM, TOO
PICK4:	SKIPE	APPFLG		;APPENDING?
	MOVEM	T3,APPFLG	;YES - SAVE THE LATEST POINTER
	SETZ	T1,		;DONE - END PICK BUFFER WITH A NULL
	IDPB	T1,T3
IFN TOPS10,<
	IDPB	T1,T3		;CLEAR OUT ENTIRE LAST WORD
	IDPB	T1,T3
	IDPB	T1,T3
	IDPB	T1,T3
>
	HRRZ	T3,T3		;GET BUFFER ENDING ADDRESS
	CAIL	T3,PIKBUF+PCBSIZ-400
	SETOM	INDFLG		;IF PICK IS LARGE SAY TAIL OF BUFFER FRAGGED
	TRNN	F,POV		;HAS BUFFER OVERFLOWED?
	JRST	PICK5		;NO - FINISH OFF
	SETOM	INDFLG		;YES - TAIL OF BUFFER IS FRAGGED
IFN TOPS10,<
	MOVNI	T1,-PIKBUF(T3)	;SET RH T1 = - [(T3) - PIKBUF]
	HRLM	T1,PIKCCL	;SET TO OUTPUT THAT MANY WORDS
>
	PUSHJ	P,PIKOV1	;WRITE OUT THE LAST PIECE
IFN TOPS10,<
	MOVNI	T1,PCBSIZ	;RESTORE FULL BUFFER SIZE
	HRLM	T1,PIKCCL	;  TO CHANNEL COMMAND
>
	PUSHJ	P,PIKOVE	;CLOSE THE DISK FILE
PICK5:	TRNN	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETERS?
	JRST	PICK6		;NO - SKIP THIS
	MOVEI	T1,1
	MOVEM	T1,PICKLN	;YES - SET BACK TO ONE LINE
	SETZM	PICKSP		;  AND NO SPACES
PICK6:	TLZE	F,PCM		;WAS THERE A MARK?
	PUSHJ	P,DISPLL	;YES - RE-DISPLAY THE SCREEN
	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR
	JRST	LOOP		;AND GET ANOTHER COMMAND

;SUBROUTINE TO SET UP T3/PICK POINTER. CLEARS THE CHARACTER COUNT IFF
;THE POINTER POINTS TO THE START OF THE BUFFER AND POV IS NOT SET
;ALSO, IF BUFFER HAS OVERFLOWED, RE-OPENS DISK FILE FOR APPENDING
;SAVES T1; USES T2

PIKGPT:	SKIPN	T3,APPFLG	;GET APPEND POINTER - ANY?
	SKIPA	T3,[POINT 7,PIKBUF] ;NO - POINT TO START OF BUFFER
	CAMN	T3,[POINT 7,PIKBUF] ;YES - POINTING TO START OF BUFFER?
	JRST	PIKGPS		;YES - CLEAR COUNT AND RETURN
	TRNN	F,POV		;NO - HAS PICK BUFFER OVERFLOWED?
	POPJ	P,		;NO - DONE
	HRROI	T2,PIKFIL	;YES - OPEN THE FILE FOR APPENDING
IFN TOPS10,<
	MOVEM	T1,SAVEAC	;SAVE AC T1
	PUSHJ	P,SETIN		;OPEN IT FOR INPUT
	HLRO	T3,T1		;SAVE NEGATIVE FILE SIZE
	PUSHJ	P,SETOU1	;OPEN FOR OUTPUT, TOO
	MOVN	T1,T3		;GET POSITIVE FILE SIZE
	LSHC	T1,-7		;MAKE IT A BLOCK NUMBER
	TLNN	T2,774000	;END EXACTLY ON A BLOCK BOUNDARY?
	AOJA	T1,PIKGPB	;YES - DON'T NEED TO READ ANYTHING
	AOJ	T1,		;NO - READ LAST BLOCK OF FILE
	USETI	5,(T1)
	INPUT	5,PKACCL	;READ IT
	USETO	5,(T1)		;PREPARE TO WRITE THE LAST BLOCK, TOO
	MOVN	T3,T3		;GET NUMBER OF FULL WORDS IN THE FILE
	ANDI	T3,177
	ADD	T3,[POINT 7,PIKBUF-1] ;MAKE IT A POINTER
	ILDB	T1,T3		;MAKE IT POINT AFTER THE DATA
	JUMPN	T1,.-1
	ADD	T3,[70000,,0]	;BACK UP BEFORE THE NULL
	JUMPGE	T3,.+2
	SUB	T3,[430000,,1]
	MOVE	T1,SAVEAC	;RESTORE AC T1
>
IFE TOPS10,<
	MOVEM	T1,PIKJFN	;SAVE T1
 	MOVE	T1,[GJ%SHT]	;OPEN THE PICK BUFFER FOR APPENDING
	GTJFN
	  HALTF
	MOVE	T2,[7B5+OF%APP]
	OPENF
	  HALTF
	EXCH	T1,PIKJFN	;RESTORE T1 AND SAVE JFN
	MOVE	T3,[POINT 7,PIKBUF] ;POINT TO START OF BUFFER
>
	POPJ	P,		;DONE

PIKGPS:	TRZ	F,POV		;SAY PICK BUFFER HASN'T OVERFLOWED (SO FAR)
	SETZM	PIKCNT		;CLEAR COUNT OF CHARACTERS PICKED
	POPJ	P,		;DONE

IFN TOPS10,<
PIKGPB:	MOVE	T3,[POINT 7,PIKBUF] ;POINT TO START OF BUFFER
	POPJ	P,		;DONE
>
;HERE IF PICK EXTENDS BEYOND FILE, TO PAD OUT WITH EXTRA <CR>S
;(IE, YOU ALWAYS GET THE NUMBER OF LINES YOU ASK FOR)

PIKPAD:	CAMN	T3,[010700,,PIKBUF+PCBSIZ-1]
	PUSHJ	P,PIKOVF	;WRITE TO DISK ON PICK BUFFER OVERFLOW
	MOVEI	T1,15		;THEN SAVE A CARRIAGE RETURN
	IDPB	T1,T3
	CAMN	T3,[010700,,PIKBUF+PCBSIZ-1]
	PUSHJ	P,PIKOVF	;WRITE TO DISK ON PICK BUFFER OVERFLOW
	MOVEI	T1,12		;THEN SAVE A LINEFEED
	IDPB	T1,T3
	ADDI	T2,2		;COUNT THE <CRLF>
	SOJG	T4,PIKPAD	;CONTINUE THROUGH ALL LEFTOVER LINES
	JRST	PICK3		;THEN FINISH OFF

;HERE TO PICK (T4) EXTRA SPACES AFTER THE LINES

PIKSPS:	TLZ	F,FLG		;DON'T NULL OUT THE PICKED CHARACTERS
	PUSHJ	P,SPCBFZ	;PICK (T4)S WORTH OF CHARACTERS AND RETURN
	MOVE	T1,SPCCNT	;GET COUNT OF CHARACTERS
	ADDM	T1,PIKCNT	;ADD TO TOTAL COUNT
	POPJ	P,		;DONE

;HERE IF MARK WAS MADE - PICK FROM STARTING CHARACTER TO (MRKPTR)
;note: does nothing about starting or ending in a tab

PIKMRK:	PUSHJ	P,MRKSET	;SET UP TO USE THE MARK (CLEAR T2, T4)
	PUSHJ	P,PIKGPT	;SET UP THE POINTER TO THE PICK BUFFER
	SETZ	T2,		;CLEAR COUNT OF CHARACTERS
PIKMK1:	CAMN	PT,MRKPTR	;AT END OF THE PICK?
	JRST	PIKMKE		;YES - FINISH OFF
	CAMN	T3,[010700,,PIKBUF+PCBSIZ-1]
	PUSHJ	P,PIKOVF	;WRITE TO DISK ON PICK BUFFER OVERFLOW
	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PIKMK1	;SKIP, IF NULL
	IDPB	T1,T3		;SAVE IT IN THE PICK BUFFER
	AOJA	T2,PIKMK1	;COUNT CHARACTER AND LOOP

PIKMKE:	ADDM	T2,PIKCNT	;SAVE COUNT OF CHARACTERS PICKED
	TLNN	F,PCM		;WANT TO RE-DISPLAY THE SCREEN?
	PUSHJ	P,MRKRES	;NO - REPAIR THE SCREEN AS IT IS
	JRST	PICK4		;GO FINISH OFF, EITHER WAY

;SUBROUTINE FOR OVERFLOW OF PICK BUFFER - SAVE ON DISK; SET POV FLAG
;USES T1, T2; RESETS T3

PIKOVF:	SETZ	T1,		;SAVE A NULL AT END OF PICK BUFFER
	IDPB	T1,T3
	TROE	F,POV		;SET PICK OVERFLOW FLAG - ALREADY SET?
	JRST	PIKOV1		;YES - FILE ALREADY OPEN
	PUSH	P,T2		;SAVE AN AC
	HRROI	T2,PIKFIL
IFN TOPS10,<
	PUSHJ	P,SETDEL	;DELETE OLD .TMP FILE
>
	PUSHJ	P,SETOUT	;SET UP THE PICK OUTPUT FILE
	MOVEM	T1,PIKJFN
	JRST	PIKOV2

PIKOV1:	PUSH	P,T2		;SAVE AN AC
IFN TOPS10,<
PIKOV2:	OUTPUT	5,PIKCCL	;WRITE OUT THE PICK BUFFER
>
IFE TOPS10,<
	MOVE	T1,PIKJFN
PIKOV2:	HRROI	T2,PIKBUF	;WRITE OUT THE PICK BUFFER
	SETZ	T3,
	SOUT
>
	MOVE	T3,[010700,,PIKBUF-1] ;START THE BUFFER AFRESH
	POP	P,T2		;RESTORE AC
	POPJ	P,		;CONTINUE

IFN TOPS10,<
PIKOVE:	CLOSE	5,
	RELEAS	5,		;FINISH OFF THE FILE
	POPJ	P,		;DONE
>
IFE TOPS10,<
PIKOVE:	MOVE	T1,PIKJFN	;GET FILE HANDLE
	JRST	SETTMP		;MAKE IT TEMPORARY, CLOSE IT, AND RETURN
>
;**********************************************************************
;HERE TO PUT THE CONTENTS OF THE PICK BUFFER INTO THE BUFFER
;HERE, SPECIFICALLY, TO DO AN IN-LINE PUT: PUT TEXT IN THE MIDDLE OF A LINE

PUT:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	SETZM	PIKJFN		;ASSUME NOT READING FROM DISK
	TLO	F,INS		;LET LINE BE EXTENDED IF NECESSARY
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION
	TLZ	F,INS!PCM
	CAIN	T3,11		;IS CHARACTER AT CURSOR A TAB?
	PUSHJ	P,RPLTAB	;YES - REPLACE IT WITH SPACES
	MOVE	T3,[010700,,PIKBUF-1]
	MOVEM	T3,PUTPTR	;ASSUME WILL READ FROM PUT BUFFER
	TLNN	F,ENT		;IS THERE A PARAMETER TYPED?
	JRST	PUTNPM		;NO - USE THE PICK BUFFER
	PUSHJ	P,PELS.1	;GET STRING TO PUT, IF ANY
	JUMPE	T1,PUTCLS	;IF ENTER-PUT TYPED GO USE THE CLOSE BFR
	TRZ	F,POV		;IF IMMEDIATE, BUFFER CAN'T OVERFLOW
	SETZM	APPFLG		;  AND APPENDING MUST BE TURNED OFF
	MOVEM	T1,PIKCNT	;SAVE SIZE OF STRING
	MOVEM	T1,NUMCHR	;SAVE AS NUMBER OF CHARACTERS TO ADD
	PUSHJ	P,ERASPM	;CLEAN THE SCREEN UP
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
	TLO	F,CHG!WRH	;SET TO READ FROM THE PICK BUFFER
	PUSHJ	P,MAKCPT	;RE-MAKE CURSOR POSITION, IF CURSOR MVMT USED
	SKIPN	T1,PIKCNT	;GET COUNT OF CHARACTERS PICKED - ANY?
	JRST	PUTERR		;NO - ERROR
	PUSHJ	P,MAKCHR	;YES - GO PUT THEM IN

;HERE FOR AN IN-LINE PUT (IE, NO <CRLF>S IN THE BUFFER)

PUT0:	TLZE	F,XPL		;IS LINE POINTER O.K.?
	PUSHJ	P,MAKLPT	;NO - RE-MAKE IT
	MOVE	T4,NUMCHR	;GET DISTANCE TO OPEN
IFN FTIMD,<
	SKIPN	IMO(TM)		;DOES THE TERMINAL HAVE INSERT MODE?
>
	SKIPE	T3,ISP(TM)	;CAN TERMINAL OPEN SPACES ON ITS OWN?
	PUSHJ	P,OPNSPI	;YES - OPEN UP THE LINE (SKIP RETURN)
	JRST	PUT0D		;NO - REWRITE THE LINE CURSOR IS ON
	PUSHJ	P,POSCUR	;GET BACK TO START OF NEWLY-OPENED SPACE
	AOS	T1,PUTPTR	;WRITE PICK OR CLOSE BUFFER THERE
	PUSHJ	P,PUTSTS
	CAME	RW,LPP.1	;PUTTING ON BOTTOM LINE?
	JRST	DISCUR		;NO - RE-DISPLAY THE CURSOR AND LOOP
	TLZE	F,FNC		;YES - IS FENCE UP?
	PUSHJ	P,CLRLNA	;YES - ERASE IT
	JRST	DISCUR		;THEN RE-DISPLAY THE CURSOR AND LOOP

PUT0D:	PUSHJ	P,DISLIN	;TERMINAL CAN'T HELP - RE-DO REST OF LINE
	CAMN	RW,LPP.1	;PUTTING ON BOTTOM LINE?
	TLZ	F,FNC		;YES - IF FENCE WAS UP, IT AIN'T NO MO
	JRST	DISCUR		;RE-POSITION CURSOR AND RETURN

;HERE TO PUT OLD CONTENTS OF PICK BUFFER

PUTNPM:	SKIPN	T1,PIKCNT	;GET COUNT OF CHARACTERS PICKED - ANY?
	JRST	PUTERR		;NO - ERROR
	MOVEM	T1,NUMCHR	;SAVE AS NUMBER OF CHARACTERS TO ADD
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	TLO	F,CHG!WRH	;SET TO READ FROM THE PICK BUFFER
	TRNN	F,POV		;WANT TO READ OFF DISK?
	JRST	PUTNP2		;NO - READ FROM BUFFER
	HRROI	T2,PIKFIL
	PUSHJ	P,SETIN		;YES - SET FILE UP
	MOVEM	T1,PUTJFN	;SAVE JFN FOR MAKSPC
PUTNP2:	SETZM	MAKLNS		;CLEAR NUMBER OF <CRLF>S IN BUFFER
	PUSHJ	P,MAKCHR	;PUT THE BUFFER
	SKIPN	T4,MAKLNS	;ARE THERE <CRLF>S IN THE PICK BUFFER?
	JRST	PUT0		;NO - JUST REWRITE ONE LINE
	TLO	F,XPB		;YES - BOTTOM POINTER IS BAD
	PUSHJ	P,OPENLD	;OPEN UP, SOMEHOW **NOTE: MAY NOT RETURN**
	PUSHJ	P,POSCUR	;POSITION TO START OF PUT
	MOVE	T4,MAKLNS	;GET NUMBER OF LINES TO DISPLAY
	JUMPN	CM,.+3		;JUMP IF NOT AT START OF A COLUMN
	LDB	T1,MAKPTR	;GET LAST CHARACTER PUT
	CAIE	T1,12		;END OF LINE?
	AOJ	T4,		;DO ONE MORE LINE IF START OR END W/IN LINE

	MOVE	T1,LPP(TM)	;FIND NUMBER OF LINES BELOW CURSOR
	SUB	T1,RW
	CAMG	T1,T4		;IS PUT LONGER THAN THAT?
	MOVE	T4,T1		;YES - DISPLAY ONLY WHAT WILL FIT

	MOVE	PT,CHRPTR	;DISPLAY FROM CURSOR POSITION
	PUSHJ	P,DISPLY
	JRST	DISCUR		;RE-POSITION CURSOR AND RETURN

;HERE TO PUT THE CONTENTS OF THE CLOSE BUFFER

PUTCLS:	MOVE	T1,[010700,,CLSBUF-1]
	MOVEM	T1,PUTPTR	;SET TO READ FROM CLOSE BUFFER
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	TLO	F,CHG!WRH	;SET TO READ FROM THE CLOSE BUFFER
	TRNN	F,COV		;WANT TO READ OFF DISK?
	JRST	PUTCS1		;NO - READ FROM BUFFER
	HRROI	T2,CLSFIL
	PUSHJ	P,SETIN		;YES - SET FILE UP
	MOVEM	T1,PUTJFN	;SAVE JFN FOR MAKSPC
PUTCS1:	SKIPG	T1,CLSCNT	;GET COUNT OF CHARS IN BUFFER - ANY?
	JRST	PUCERR		;NO - ERROR
	MOVEM	T1,NUMCHR	;YES - SAVE AS NUMBER OF CHARACTERS TO ADD
	JRST	PUTNP2		;GO PUT THEM IN

PUCERR:	MOVEI	T1,[ASCIZ /#######Close buffer is empty/]
	JRST	ERROR
PUTERR:	MOVEI	T1,[ASCIZ /########Put buffer is empty/]
	JRST	ERROR

;**********************************************************************
;HERE TO SLIDE THE VIEWING WINDOW TO THE LEFT

SLIDEL:	MOVE	T4,SLIDES	;SET UP LAST TIME'S SLIDE AS NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET LINES TO ROLL
	MOVEM	T4,SLIDES	;SAVE AS NEW NOMINAL
	PUSHJ	P,ERASPM
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
SLLNPM:	SKIPN	SLDFLG		;NEVER WANT TO SLIDE?
	JRST	LOOP		;RIGHT - DON'T
	JUMPE	SL,LOOP		;NOTHING TO DO IF AT LEFT MARGIN
	MOVE	T4,SLIDES	;GET DISTANCE TO SLIDE
	SUB	SL,T4		;SLIDE TO THE LEFT
	ADD	CM,T4		;KEEP CURSOR IN SAME POSITION IN TEXT
	JUMPL	SL,[ADD  CM,SL	;IF GONE TOO FAR, STOP AT LEFT EDGE
		    ADD  T4,SL
		    SETZ SL,	;YES - STOP AT THE LEFT EDGE
		    JRST .+1]
	CAMGE	CM,CPL.1	;HAS CURSOR GONE OFF THE RIGHT?
	JRST	SLLNP1		;NO - O.K.
	MOVE	CM,CPL.1	;YES - MOVE IT TO THE EDGE OF THE SCREEN
	TLO	F,XPC		;CHARACTER POINTER IS NOW BAD
SLLNP1:
IFN FTIMD,<
	CAIGE	T4,^D64		;SLIDING ALMOST A SCREENFUL?
	SKIPN	IMO(TM)		;DOES TERMINAL HAVE AN INSERT MODE?
>
	JRST	SLREND		;NO - GO FINISH UP

IFN FTIMD,<
;FOR EVERY LINE ON THE SCREEN, OPEN T4 SPACES AND WRITE INTO HOLE

	PUSH	P,RW		;AND CURRENT POSITION
	PUSH	P,CM
	MOVE	PT,LPP(TM)	;GET NUMBER OF LINES ON THE SCREEN
	MOVE	CM,CPL(TM)	;AND NUMBER OF CHARS THAT CAN STAY AROUND
	SUB	CM,T4
	SETZ	RW,
	PUSHJ	P,POSCUR	;POSITION THE CURSOR
	JRST	.+2

SLLIMD:	PUSHJ	P,CDOWN		;MOVE DOWN A LINE
	PUSHJ	P,CLRLNR	;CLEAR THE END OF THE LINE
	SOJG	PT,SLLIMD	;LOOP THROUGH ALL LINES
	POP	P,CM
	POP	P,RW

	PUSHJ	P,CHOME		;MOVE THE CURSOR HOME
	PUSHJ	P,IMODON	;TURN ON INSERT MODE
	MOVE	PT,DISPTR	;DISPLAY SLID-IN STUFF: GET DISPLAY POINTER
	EXCH	T4,CPL(TM)	;  AND NUMBER OF CHARACTERS TO DISPLAY PER LINE
	PUSH	P,T4		;SAVE THE REAL LINE SIZE
	PUSH	P,TM		;SAVE THE TERMINAL FLAGS, TOO
	TLZ	TM,WRP!TBS
	MOVE	T4,LPP(TM)	;GET SCREEN SIZE
	PUSHJ	P,DISPS0	;DO THE DISPLAY
	POP	P,TM
	POP	P,CPL(TM)	;RESTORE THE LINE SIZE
	PUSHJ	P,IMODOF	;TURN OFF INSERT MODE
	MOVEI	T1,10
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T1,SLIDES	;YES - SET IT BACK TO THE DEFAULT
	JRST	DISCUR		;RE-POSITION AND LOOP
>
;HERE TO SLIDE THE VIEWING WINDOW TO THE RIGHT

SLIDER:	MOVE	T4,SLIDES	;SET UP LAST TIME'S SLIDE AS NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET LINES TO ROLL
	TRNE	F,CMV		;CURSOR MOVEMENT?
	MOVE	T4,PARG2	;YES -	GET CHANGE IN COLUMNS
	MOVEM	T4,SLIDES	;SAVE AS NEW NOMINAL
	PUSHJ	P,ERASPM
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
SLRNPM:	SKIPN	SLDFLG		;NEVER WANT TO SLIDE?
	JRST	LOOP		;RIGHT - DON'T
	MOVE	T4,SLIDES	;GET DISTANCE TO SLIDE
	ADD	SL,T4		;SLIDE TO THE RIGHT
	SUB	CM,T4		;KEEP CURSOR IN SAME POSITION IN TEXT
	JUMPGE	CM,SLREND	;HAS CURSOR GONE OFF THE LEFT?
	MOVE	CM,LMARGN	;YES - GO TO THE LEFT MARGIN
	TLO	F,XPC		;CHARACTER POINTER IS NOW BAD
SLREND:	MOVEI	T1,10
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T1,SLIDES	;YES - SET IT BACK TO THE DEFAULT
	JRST	DISALL		;RE-DISPLAY SCREEN AND LOOP

;**********************************************************************
;HERE TO OPEN OR CLOSE THE EXECUTE BUFFER OR SET UP TO ITERATE IT A FEW TIMES

EXECUT:	TLZ	F,PCM		;CANCEL THE PICK-CLOSE MARK, IF ANY
	TRZE	F,CMV		;DID USER USE CURSOR MOVEMENT?
	JRST	[MOVE  T3,[POINT 7,PARBUF]
		 PUSHJ P,PELS.M	;YES - READ PARAMETER FROM THE FILE
		 JRST  .+3]	;CONTINUE
	SETZ	T1,		;END BUFFER WITH A NULL
	IDPB	T1,PARPTR
	HLRZ	T1,PARBUF	;GET FIRST CHARACTER OF PARAMETER
	LSH	T1,-^D11
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	CAIN	T1,"S"		;SET UP A BUFFER?
	JRST	XCTSET		;YES - DO IT
	CAIN	T1,"K"		;KILL A BUFFER?
	JRST	XCTKIL		;YES - DO IT
	CAIN	T1,"W"		;WRITE INTO A BUFFER?
	JRST	XCTWRT		;YES - DO IT
	CAIN	T1,"R"		;READ AND LIST A BUFFER IN SWITCH FORMAT?
	JRST	XCTRDL		;YES - DO IT
	CAIN	T1,"L"		;READ AND LIST A BUFFER IN WRITE FORMAT?
	JRST	XCTRDW		;YES - DO IT
	CAIN	T1,"N"		;LIST THE DEFINED BUFFER NAMES?
	JRST	XCTNML		;YES - DO IT
	CAIN	T1,"X"		;WRITE AND EXECUTE BUFFER?
	JRST	XCTXCT		;YES - DO IT
	CAIN	T1,"B"		;LINK BUFFER TO A KEYBOARD BUTTON?
	JRST	XCTBTN		;YES - DO IT
	CAIN	T1,"@"		;READ A FILE OF BUFFER SWITCHES?
	JRST	XCTBSW		;YES - DO IT

;HERE TO SET UP A NUMBER OF ITERATIONS

EXCUT0:	PUSHJ	P,PEEL.1	;READ PARAMETER, IF ANY
	JUMPE	T1,EXCOPN	;IF NO PARM, JUST OPEN EXECUTE BUFFER
	MOVE	T4,PARG1	;ELSE GET NUMBER OF ITERATIONS
	MOVE	T3,T4		;HERE, TOO
	EXCH	T4,XCTITR	;SAVE AS NEW NOMINAL
EXCUT1:	EXCH	T3,XCTNUM	;AND AS CURRENT NUMBER
	SKIPGE	T1,XCTACW	;GET BUFFER POINTER - IS THERE ONE?
	JRST	XCOERR		;NO - NO-ACTIVE-BUFFER ERROR
	MOVE	T1,XCTADR(T1)
	ILDB	T1,T1		;MAKE SURE THERE'S SOMETHING THERE
	JUMPE	T1,XCXERR	;IF NOTHING THERE, ERROR
	SKIPE	XSHFLG		;WANT TO DISPLAY THE EXECUTE?
	PUSHJ	P,ERASPM	;YES - ERASE PARAMETER
	TLNE	TM,JRC		;DOING A JOURNAL RESTORE?
	JRST	EXCU1A		;YES - THEN IT'S A TOP-LEVEL EXECUTE
	TRNE	F,XCT!XBN	;ALREADY EXECUTING?
	JRST	EXCSVX		;YES - SAVE CONTEXT (RETURN TO EXCU1C)
EXCU1A:	MOVE	T1,[PARAMS,,SAVPRM]
	BLT	T1,SAVPRM+SAVPML-1 ;SAVE ALL PARAMETERS
	HRRM	F,SAVFGS	;ALSO SAVE RH OF F
	HLLM	TM,SAVFGS	;  AND LH OF TM
	TRZ	F,XCT!XBN	;CLEAR JOURNAL-RESTORE FLAGS
	TLZ	TM,JRC
EXCU1B:	SKIPE	XSHFLG		;WANT TO DISPLAY THE EXECUTE?
	TROA	F,XBN		;YES - SET THE RIGHT FLAG
	TRO	F,XCT		;NO  - SET THE RIGHT FLAG
EXCU1C:	MOVE	T1,XCTACW	;GET BUFFER POINTER
	MOVE	T1,XCTADR(T1)
	MOVEM	T1,XCTACR	;SET BUFFER UP FOR READING
	MOVEM	T1,XCTPTR
	TRZE	F,XSV		;SAVING COMMANDS?
	PUSHJ	P,XCTWIP	;YES - WIPE OUT THE "ENTER NUMBER EXECUTE"
	JRST	XCTEND		;FINISH OFF

;SUBROUTINE TO WIPE OUT THE EXECUTE COMMAND ("ENTER SOMETHING EXECUTE")
;FROM THE BUFFER

XCTWIP:	MOVE	PT,XCTPTW	;GET POINTER TO END OF BUFFER
XCTWP1:	ADD	PT,[70000,,0]	;BACK IT UP A NOTCH
	JUMPGE	PT,.+2		;(USER TYPED "ENTER MUMBLE EXECUTE":
	SUB	PT,[430000,,1]	;  WANT TO REMOVE THAT FROM BUFFER)
	LDB	T1,PT		;GET CHARACTER
	CAIE	T1,33		;ENTER?
	JRST	XCTWP1		;NO - KEEP SKIPPING
XCTCLO:	SETZ	T1,		;YES - SAVE A NULL OVER THE ENTER
	DPB	T1,PT
	MOVEI	T1,1		;AND SET END-OF-BUFFER FLAG
	ORM	T1,(PT)
	HRRM	PT,XCFPTR	;SAVE NEW START-OF-FREE-SPACE POINTER
	POPJ	P,		;DONE

;HERE TO SAVE CURRENT BUFFER STATUS SO ANOTHER CAN BE EXECUTED

EXCSVX:	SKIPE	XCTPSV		;ALREADY DOWN A LEVEL?
	JRST	XSXERR		;YES - ONLY ONE STACK ALLOWED
	MOVE	T1,XCTPTR	;NO - SAVE ACTIVE BUFFER POINTER
	MOVEM	T1,XCTPSV
	MOVE	T1,XCTACR	;AND ACTIVE BUFFER STARTING POINTER
	MOVEM	T1,XCTASV
	MOVEM	T3,XCTNSV	;SAVE ACTIVE NUMBER OF ITERATIONS
	MOVEM	T4,XCTISV	;SAVE NOMINAL NUMBER OF ITERATIONS
	JRST	EXCU1C		;FINISH THE THE SET-UP

;HERE FOR JUST ENTER EXECUTE: OPEN BUFFER AND START SAVING COMMANDS

EXCOPN:	TRO	F,XSV		;SET FLAG TO SAVE COMMANDS
	SETZM	XCTITR		;CLEAR NUMBER OF ITERATIONS
	SETZM	XCTNUM
EXCOP1:	SKIPGE	T1,XCTACW	;IS THERE AN ACTIVE BUFFER?
	JRST	XCOERR		;NO - ERROR
	MOVE	T2,XCFPTR	;YES - GET POINTER TO START OF FREE SPACE
	MOVEM	T2,XCTPTW	;SAVE AS WRITE POINTER TO BUFFER DATA
	MOVEM	T2,XCTADR(T1)	;  AND AS STORED POINTER TO BUFFER DATA
XCTEND:	PUSHJ	P,ERASPM
	JRST	LOOP		;RE-POSITION CURSOR AND LOOP

;HERE TO SET UP AN EXECUTE BUFFER - IF GIVEN NAME IS NOT FOUND,
;CREATE BUFFER WITH THAT NAME

XCTSET:	TRZE	F,XSV		;WAS A BUFFER OPEN?
	PUSHJ	P,XCTWIP	;YES - CLOSE IT
	PUSHJ	P,XCTRED	;READ BUFFER NAME AND FIND IT
	JUMPGE	T1,XCTST1	;JUMP IF FOUND
	MOVEI	T1,XBFNUM-1	;ELSE CREATE IT - FIND OPEN SLOT
	SKIPE	XCTNAM(T1)
	SOJGE	T1,.-1		;NOT OPEN - TRY AGAIN
	JUMPL	T1,XCSERR	;JUMP IF NONE OPEN - ERROR
	MOVEM	T4,XCTNAM(T1)	;SAVE NAME IN THIS SLOT
XCTST1:	MOVEM	T1,XCTACW	;SAVE INDEX OF ACTIVE BUFFER
	TLZN	F,FLG		;WANT TO RETURN (TO SWHMNY)?
	JRST	XCTEND		;NO
	POPJ	P,		;YES

;HERE TO KILL OFF A GIVEN EXECUTE BUFFER

XCTKIL:	TRZE	F,XSV		;WAS A BUFFER OPEN?
	PUSHJ	P,XCTWIP	;YES - CLOSE IT
	PUSHJ	P,XCTRED	;READ AND FIND NAME OF BUFFER
	JUMPL	T1,XCKERR	;NOT FOUND - ERROR
	MOVE	PT,T1
	PUSHJ	P,XCTKLL	;ELSE ZERO OUT ITS INFORMATION
	CAMN	T2,XCTACW	;IS THIS THE ACTIVE ONE?
	SETOM	XCTACW		;YES - SAY THERE IS NO ACTIVE BUFFER
	JRST	XCTEND		;DONE

XCTKLL:	SETZM	XCTNAM(PT)	;ZERO OUT BUFFER NAME
	PUSHJ	P,XCTKLF	;DELETE THE BUFFER CONTENTS FROM FREE SPACE
XCTKLK:	SKIPN	XCTKEY(PT)	;IS THERE A KEY?
	POPJ	P,		;NO - DONE
	MOVE	T2,[POINT 7,XCTKEY(PT)]
	SETOM	SAVEAC+6	;RESTORE COMMAND IN TABLE
	PUSHJ	P,SUBTBX
	SETZM	XCTKEY(PT)	;CLEAN OUT OLD KEY
	POPJ	P,

;SUBROUTINE TO KILL THE CONTENTS OF AN EXECUTE BUFFER FROM FREE SPACE
;ENTER WITH PT/ BUFFER INDEX

XCTKLF:	SKIPN	T4,XCTADR(PT)	;GET EXECUTE BUFFER POINTER - ANY?
	POPJ	P,		;NO - NOTHING TO KILL
	AOJ	T4,		;YES - POINT TO FIRST WORD OF DATA
XCTKF1:	MOVE	T1,(T4)		;GET A BUFFER DATA WORD
	TRNN	T1,1		;IS IT THE LAST WORD?
	AOJA	T4,XCTKF1	;NO - LOOP UNTIL FOUND
	SETZB	T1,(T4)		;YES - TURN OFF THE END-OF-DATA FLAG
	EXCH	T1,XCTADR(PT)	;CLEAR AND GET POINTER TO START OF DATA
	CAMN	T4,XCFPTR	;DOES THIS DATA AREA BUTT AGAINST FREE SPACE?
	MOVEM	T1,XCFPTR	;YES - SAVE AS NEW START OF FREE SPACE
	POPJ	P,		;DONE

;HERE TO SAVE A STRING INTO THE ACTIVE BUFFER

XCTWRT:	TRZE	F,XSV		;WAS A BUFFER OPEN?
	PUSHJ	P,XCTWIP	;YES - CLOSE IT
	MOVE	PT,[POINT 7,PARBUF,6]
XCWRT0:	MOVEM	PT,SAVEAC	;SAVE THE POINTER TO THE NEW CONTENTS
	SKIPGE	PT,XCTACW	;GET POINTER TO OLD BUFFER CONTENTS - ANY?
	JRST	XCOERR		;NONE ACTIVE - ERROR
	PUSHJ	P,XCTKLF	;DELETE PREVIOUS CONTENTS FROM FREE SPACE
	MOVE	T4,XCFPTR	;GET POINTER TO START OF FREE SPACE
	MOVEM	T4,XCTADR(PT)	;SAVE AS TARGET POINTER
	MOVE	PT,SAVEAC	;GET POINTER TO NEW CONTENTS BACK
	SETZ	T0,		;CLEAR PARENTHETICAL COUNTER

XCWRT1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,XCWEND	;DONE IF NULL
	CAIGE	T1," "		;SOME CONTROL CHARACTER?
	JRST	XCWRT1		;YES - IGNORE IT
	CAIN	T1,"^"		;SOME COMMAND?
	JRST	XCWCMD		;YES - PURSUE IT
	CAIN	T1,"$"		;ENTER (OR ESCAPE)?
	MOVEI	T1,33		;YES - SET IT UP
	CAIN	T1,")"		;MAYBE THE END OF A CONDITIONAL?
	JUMPG	T0,XCWRPE	;IF SO, END THE BLOCK
XCWRT2:	PUSHJ	P,XCTWO1	;SAVE CHARACTER
	JRST	XCWRT1		;AND GET ANOTHER

XCWCMD:	ILDB	T1,PT		;GET 1ST LETTER OF COMMAND NAME
	CAIE	T1,"$"		;REALLY WANT A REAL DOLLAR SIGN,
	CAIN	T1,")"		;  OR CLOSE PAREN?
	JRST	XCWRT2		;YES - JUST SAVE IT
	CAIN	T1,"/"		;HOW ABOUT A REAL SLASH?
	JRST	XCWRT2		;YES - JUST SAVE IT
	CAIN	T1,"^"		;REALLY WANT AN UP-ARROW?
	JRST	[PUSHJ P,XCTWO1	;YES - JUST GO SAVE IT TWICE
		 JRST  XCWRT2]
	CAIG	T1,"9"		;NO - GOT A REPEAT COUNT?
	JRST	XCWRPT		;YES - SET COUNT UP
	MOVEI	T2,"^"		;NO - GET AN UP-ARROW
	PUSHJ	P,XCWGET+1	;PUT NEW CHARACTER IN WITH IT
	PUSHJ	P,XCWGET	;GET REST OF COMMAND NAME
	CAME	T2,["^RF"]	;GOT A ROLL FORWARD
	CAMN	T2,["^RB"]	;  OR BACKWARD?
	JRST	XCWRT3		;YES - NEED TO GET ANOTHER CHARACTER
	LSH	T2,^D15		;NO - LEFT-JUSTIFY COMMAND NAME
XCWRT4:	MOVEI	T1,CMDLEN-1	;LOOK FOR COMMAND AMONG NAMES
	CAME	T2,CMDNAM(T1)	;IS THIS IT?
	SOJGE	T1,.-1		;NO - KEEP LOOKING
	JUMPLE	T1,XCWCON	;IF NOT FOUND, SEE IF IT'S A CONDITIONAL
	CAIGE	T1," "		;GOT A HIGH-NUMBERED COMMAND?
	JRST	XCWRT2		;NO - O.K.
XCWRT5:	MOVEI	T2,"^"		;YES - PRECEDE IT WITH AN UP-ARROW
	PUSHJ	P,XCTWO2
	JRST	XCWRT2		;THEN SAVE COMMAND

XCWRT3:	PUSHJ	P,XCWGET	;GET REST OF COMMAND NAME
	LSH	T2,^D8		;LEFT-JUSTIFY COMMAND NAME
	JRST	XCWRT4		;GO FIND THE COMMAND

XCWGET:	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	LSH	T2,7		;SHIFT OVER ALREADY-GOTS
	OR	T2,T1		;PUT NEW CHARACTER IN WITH THEM
	POPJ	P,		;DONE

;CONDITIONAL FLAGS: COND; DO, FR, FC, IF, DW, NOT
;IF DO FLAG, THEN REST OF BYTE (5 BITS) IS HIGH ORDER OF COUNT
;IF FC, FR, OR F. THEN THREE LOW FLAGS ARE: EQU, GRTR, NOT
;ALSO, 100 IS END OF A DO BLOCK AND 101 IS END OF AN IF

XCWCON:	JUMPE	T1,[MOVEI T1,77	;IF RESET, SAVE "^",77
		    JRST  XCWRT5]
	MOVEI	T1,CMDCLN-1	;LOOK FOR CONSTRUCT AMONG THE NON-COMMANDS
XCWCN0:	MOVE	T3,CMDCON(T1)	;GET A NON-COMMAND
	TRZ	T3,77777	;KEEP ONLY 1ST 3 CHARACTERS
	CAME	T2,T3		;IS THIS IT?
	SOJGE	T1,XCWCN0	;NO - KEEP LOOKING
	JUMPL	T1,XCWERR	;ERROR IF NOT FOUND
	LDB	T2,[POINT 7,CMDCON(T1),35] ;ELSE GET TYPE FLAGS
	TRNN	T2,100		;GOT A CONDITIONAL?
	JRST	XCWCNX		;NO - CHECK FURTHER
	CAIN	T2,102		;GOT A DO WHILE?
	SKIPA	T1,[100]	;YES - STACK DO'S END CHARACTER
	MOVEI	T1,101		;ELSE STACK IF'S
	PUSH	P,T1		;STACK IT, ALREADY
	MOVEI	T1,"^"		;START CONDITIONAL BLOCK
	PUSHJ	P,XCTWO1
	TRNE	T2,30		;GOT IF-ROW, -COLUMN, OR -COUNTER?
	JRST	XCWCNF		;YES - GO READ CONDITION AND NUMBER
XCWCN1:	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIE	T1,"^"		;"NOT" OR CHARACTER CLASS?
	JRST	XCWCN2		;NO - FINISH OFF

;VALUES ARE: SPACE (5), NUMBER (3), ALPHA (LETTER) (1), UPPER CASE (6),
;ALPHA-NUMERIC (4), END OF LINE (2), CHARACTER == NOT SPACE
;ALSO, BLOCK OF CHARACTERS OR CONDITIONS TO BE OR'D STARTS WITH ^< (20)
; AND ENDS WITH > (21).

	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIN	T1,"("		;GOT A REAL OPEN PAREN?
	JRST	XCWCN2		;YES - TREAT IT LIKE THE CHARACTER IT IS
REPEAT 0,<
	CAIN	T1,"<"		;GOT THE START OF A CONDITIONAL BLOCK?
	JRST	XCWCBS		;YES - SET TO CALL THIS STUFF MANY TIMES
	CAIN	T1,">"		;GOT THE END OF A CONDITIONAL BLOCK?
	JRST	XCWCBE		;YES - NOTE THAT THE BLOCK IS OVER
>
	CAIGE	T1,"A"		;GOT SOME REAL LETTER?
	JRST	XCWERR		;NO - IT'S AN ERROR FROM THE START
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	CAIN	T1,"X"		;GOT A "NOT" FLAG?
	JRST	[TRO  T2,1	;YES - SET THE FLAG
		 JRST XCWCN1]	;GO GET THE CHARACTER OR CLASS
	CAIN	T1,"L"		;CHECK CLASS: LETTER?
	MOVEI	T1,1		;YES - GET VALUE
	CAIN	T1,"N"		;NUMERIC?
	MOVEI	T1,3		;YES - GET VALUE
	CAIN	T1,"E"		;END OF LINE?
	MOVEI	T1,2		;YES - GET VALUE
	CAIN	T1,"A"		;ALPHA-NUMERIC?
	MOVEI	T1,4		;YES - GET VALUE
	CAIN	T1,"U"		;UPPER CASE?
	MOVEI	T1,6		;YES - GET VALUE
	CAIN	T1,"C"		;ANY CHARACTER?
	TROA	T2,1		;YES - SET "NOT" AND SPACE VALUE
	CAIN	T1,"S"		;SPACE CHARACTER?
	MOVEI	T1,5		;YES - SET VALUE
	CAILE	T1,6		;GOT A LEGAL VALUE?
	JRST	XCWERR		;NO - MISTAKE

	PUSHJ	P,XCTWO2	;SAVE FLAGS
	MOVEI	T2,"^"		;SAVE CLASS FLAG
XCWCN2:	PUSHJ	P,XCTWO2
	PUSHJ	P,XCTWO1	;SAVE CLASS TO LOOK FOR
	ILDB	T1,PT		;GET CHARACTER AFTER CONDITIONAL
	JRST	XCWRPX		;SKIP "(", IF ANY, AND LOOP

XCWCNX:	MOVEI	T1,"^"		;SAVE AN UP-ARROW
	PUSHJ	P,XCTWO1
	PUSHJ	P,XCTWO2	;THEN SAVE COMMAND
	CAIN	T2,16		;IS IT OUTPUT?
	JRST	XCWCXO		;YES - READ AND SET UP THE STRING
	CAIE	T2,15		;IS IT INITIALIZE?
	CAIN	T2,21		;  OR DO-ON-SEARCH-FAILURE?
	JRST	XCWCX1		;YES - GO STACK
	CAIE	T2,10		;IS IT ITERATE-COUNTER?
	JRST	XCWRT1		;NO - LOOP
XCWCX1:	PUSH	P,[100]		;YES - STACK THE END-REPEAT CHARACTER
	ILDB	T1,PT		;GET NEXT CHARACTER
	JRST	XCWRPX		;SKIP "(", IF ANY, AND LOOP

;HERE FOR THE OUTPUT CONSTRUCT - SAVE CHARACTERS UNTIL A ")"

XCWCXO:	ILDB	T1,PT		;GET THE "(" AFTER THE "^OU"
	CAIE	T1,"("		;IS IT REALLY AN OPEN PAREN?
	JRST	XCWERR		;NO - ERROR
XCWXO1:	ILDB	T1,PT		;GET A CHARACTER TO OUTPUT
	JUMPE	T1,XCWERR	;ERROR IF END OF BUFFER REACHED
	CAIN	T1,")"		;END OF STRING?
	JRST	XCWXOE		;YES - FINISH OFF
	CAIN	T1,"$"		;WANT AN ESCAPE?
	MOVEI	T1,33		;YES - GET ONE
	CAIN	T1,"^"		;WANT A CONTROL CHARACTER?
	PUSHJ	P,XCWXOC	;YES - CONVERT THE NEXT CHARACTER
	PUSHJ	P,XCTWO1	;SAVE THE CHARACTER
	JRST	XCWXO1		;AND GET ANOTHER

XCWXOC:	ILDB	T1,PT		;GET THE CONTROL CHARACTER
	CAIE	T1,"$"		;WANT A REAL DOLLAR SIGN,
	CAIN	T1,")"		;  OR CLOSE PAREN?
	POPJ	P,		;YES - GO SAVE IT
	ANDI	T1,37		;NO - MAKE IT A CONTROL CHARACTER
	POPJ	P,		;RETURN TO SAVE IT

XCWXOE:	MOVEI	T1,177		;END THE STRING
	PUSHJ	P,XCTWO1
	JRST	XCWRT1		;AND GET MORE INPUT

;HERE FOR IF-ROW, -COLUMN, OR -COUNTER

XCWCNF:	ILDB	T1,PT		;GET CONDITION OF THE IF (G, L, E, N)
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	CAIN	T1,"G"		;GREATER?
	TRO	T2,2		;YES - SET FLAG
	CAIN	T1,"L"		;LESS?
	TRO	T2,3		;YES - SET FLAGS
	CAIN	T1,"E"		;EQUAL?
	TRO	T2,4		;YES - SET FLAG
	CAIN	T1,"N"		;NOT EQUAL?
	TRO	T2,5		;YES - SET FLAGS
	TRNN	T2,7		;ARE ANY FLAGS AT ALL SET?
	JRST	XCWERR		;NO - ERROR
	ILDB	T1,PT		;YES - GET FIRST DIGIT OF ROW OR COLUMN
	JRST	XCWRP0		;READ AND SAVE NUMBER OF ROW OR COLUMN

XCWRPT:	PUSH	P,[100]		;STACK THE END-REPEAT CHARACTER
	MOVEI	T2,"^"		;ANNOUNCE START OF COUNT
	PUSHJ	P,XCTWO2
	MOVEI	T2,140		;GET FLAGS TO INDICATE A "DO"
XCWRP0:	HRREI	T3,-60(T1)	;CONVERT CHARACTER TO A DIGIT
	JUMPL	T3,XCWERR	;ERROR IF NOT NUMERIC
XCWRP1:	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIG	T1,"9"		;NUMERIC?
	CAIGE	T1,"0"
	JRST	XCWRP2		;NO - END OF COUNT
	SUBI	T1,"0"		;MAYBE - CONVERT TO A DIGIT
	IMULI	T3,^D10		;SHIFT OVER THE OLD STUFF
	ADD	T3,T1		;PUT NEW DIGIT IN
	JRST	XCWRP1		;AND GET ANOTHER ONE

XCWRP2:	TRNN	T2,40		;GOT DO, OR FR/FC/F.?
	JRST	XCWRP3		;FR/FC/F. - PUT COUNT IN ONE BYTE
	ROT	T3,-7		;GET HIGH-ORDER COUNT BITS
	OR	T2,T3		;SET THEM IN FLAG WORD
	ROT	T3,7		;GET LOW BITS BACK
XCWRP3:	PUSHJ	P,XCTWO2	;SAVE FLAGS AND HIGH BITS
	PUSHJ	P,XCTWO3	;SAVE REST OF REPEAT COUNT
XCWRPX:	CAIN	T1,"("		;GOT START OF THE REPEAT BLOCK?
	AOJA	T0,XCWRT1	;YES - IGNORE IT
	AOJA	T0,XCWRT1+1	;ELSE PROCESS CHARACTER, WHATEVER IT IS

XCWRPE:	MOVEI	T1,"^"		;MARK THE END OF THE REPEAT SECTION
	PUSHJ	P,XCTWO1
	POP	P,T1		;GET FLAVOR OF REPEAT
	PUSHJ	P,XCTWO1	;STORE IT
	SOJA	T0,XCWRT1	;GET NEXT CHARACTER

XCWEND:	SETZ	T1,		;END BUFFER WITH A NULL
	IDPB	T1,T4
	MOVEI	T2,1		;AND SET END-OF-DATA FLAG IN LAST WORD
	ORM	T2,(T4)
	HRLI	T4,010700	;MAKE FREE POINTER BE START OF NEXT WORD
	MOVEM	T4,XCFPTR	;SAVE IT
	EXCH	T1,XCTLVL	;CLEAR OVERFLOW FLAG
	JUMPL	T1,XCVERR	;ERROR IF IT OVERFLOWED
	JUMPG	T0,XCWEN1	;ERROR IF SOME CONDITIONAL NOT CLOSED
	TLZN	F,FLG		;WANT TO RETURN (TO SWHMNY)?
	JRST	XCTEND		;NO
	POPJ	P,		;YES

XCWEN1:	POP	P,T1		;POP SAVED CONDITIONALS OFF STACK
	SOJG	T0,XCWEN1	;THEN GIVE ERROR MESSAGE
	MOVEI	T1,[ASCIZ /###Conditional block not closed/]
	JRST	ERROR
XCWERR:	MOVEI	T1,[ASCIZ /#########Bad command name/]
	JRST	ERROR

XCTWO3:	IDPB	T3,T4		;OUTPUT CHARACTER IN T3
	JRST	XCTWOU
XCTWO2:	IDPB	T2,T4		;I MEAN IN T2
	JRST	XCTWOU
XCTWO1:	IDPB	T1,T4		;I MEAN IN T1
XCTWOU:	CAME	T4,XCTOVF	;IS BUFFER ABOUT TO OVERFLOW?
	POPJ	P,		;NO - O.K.
	MOVEI	T1,1		;LIGHT END-OF-DATA BIT
	ORM	T1,(T4)
	PUSHJ	P,XCGARB	;DO A GARBAGE COLLECT
	MOVEI	T1,1		;CLEAR THE END-OF-DATA BIT
	ANDCAM	T1,(T4)
	CAME	T4,XCTOVF	;WAS ANYTHING RECOVERED?
	POPJ	P,		;YES - DONE
	MOVE	T4,XCTACW	;NO - RESET CURRENT WRITE POINTER
	MOVE	T4,XCTADR(T4)
	SETOM	XCTLVL		;NOTE THAT BUFFER OVERFLOWED
	POPJ	P,		;READ REST OF BUFFER

;SUBROUTINE TO GARBAGE COLLECT THE EXECUTE FREE SPACE (XCTFRE)
;RETURNS POINTER TO LOWEST FREE ADDRESS IN T4
;USES T0-T3

XCGARB:	MOVEI	T4,XCTFRE-1	;POINT TO START OF FREE SPACE
XCGAR1:	MOVEI	T0,-1		;LOOK FOR SMALLEST POINTER - START BIG
	MOVEI	T3,XBFNUM-1	;LOOK THROUGH ALL BUFFER POINTERS
XCGAR2:	SKIPE	T1,XCTADR(T3)	;IS THIS POINTER ACTIVE?
	CAILE	T4,(T1)		;YES - IS ADDRESS GREATER THAN START OF F.S.?
	JRST	XCGAR3		;NOT ACTIVE OR TOO SMALL - GET ANOTHER
	CAIG	T0,(T1)		;IS ADDRESS LESS THAN LOWEST SO FAR?
	JRST	XCGAR3		;NO - SKIP IT
	HRR	T0,T1		;YES - SAVE NEW ONE INSTEAD
	MOVE	T2,T3		;SAVE INDEX, TOO
XCGAR3:	SOJGE	T3,XCGAR2	;LOOP THROUGH ALL POINTERS
	CAIN	T0,-1		;IS THERE A LOWEST POINTER?
	JRST	XCGARD		;NO - FINISH OFF

	MOVE	T3,T0		;PUT ADDRESS IN AN INDEXABLE AC
	HRRM	T4,XCTADR(T2)	;SAVE NEW POINTER TO BUFFER DATA
XCGAR4:	MOVE	T1,1(T3)	;GET A WORD
	MOVEM	T1,1(T4)	;SAVE IT
	TRNE	T1,1		;END OF THE DATA?
	JRST	XCGAR5		;YES - FINISH
	AOJ	T3,		;NO - BUMP POINTERS
	AOJA	T4,XCGAR4	;  AND LOOP

XCGAR5:	CAME	T3,T4		;DONE MOVING - WAS IT REALLY A MOVE?
	SETZM	T1,1(T3)	;YES - CLEAR FLAG IN OLD LAST WORD
	AOJA	T4,XCGAR1	;DO ANOTHER PASS TO FIND NEXT DATA TO MOVE

XCGARD:	HRLI	T4,010700	;MAKE F.S. ADDRESS INTO A POINTER
	POPJ	P,		;RETURN

;HERE TO WRITE THE ACTIVE BUFFER
;AND THEN EXECUTE IT THE GIVEN NUMBER OF TIMES

XCTXCT:	TRZE	F,XSV		;WAS A BUFFER OPEN?
	PUSHJ	P,XCTWIP	;YES - CLOSE IT
	MOVE	PT,[POINT 7,PARBUF,6] ;POINT TO 2ND CHARACTER OF PARAMETER
	MOVE	T4,[POINT 7,PARBUF]   ;AND TO ITS START
XCTXC1:	ILDB	T1,PT		;SHIFT EXECUTE COUNT LEFT A NOTCH
	CAIL	T1,"0"		;IS THIS A DIGIT?
	CAILE	T1,"9"
	JRST	XCTXC2		;NO - GOT IT ALL
	IDPB	T1,T4		;YES - SAVE IT AND GET MORE
	JRST	XCTXC1

XCTXC2:	CAIE	T1,":"		;DOES THE NUMBER END WITH A COLON?
	PUSHJ	P,XCBKPT	;NO - BACK UP OVER THE LATEST CHARACTER
	SETZ	T1,		;END COUNT WITH A NULL
	IDPB	T1,T4
	TLO	F,FLG		;SET TO GET A RETURN FROM XCTWRT
	PUSHJ	P,XCWRT0	;WRITE INTO THE BUFFER
	JRST	EXCUT0		;SET UP AND EXECUTE THE NEW BUFFER

;SUBROUTINE TO BACK UP THE POINTER IN AC PT A NOTCH
;NOT USED MUCH. WHY SPEND TWO EXTRA INSTRUCTIONS?

XCBKPT:	ADD	PT,[70000,,0]
	JUMPGE	PT,CPOPJ
	SUB	PT,[430000,,1]
	POPJ	P,

;HERE TO OUTPUT THE CONTENTS OF THE ACTIVE BUFFER IN WRITE FORMAT

XCTRDW:	MOVE	T1,[260700,,PARBUF]
	CAMN	T1,PARPTR	;HAS A NAME BEEN GIVEN?
	JRST	XCRDWC		;NO - READ THE ACTIVE BUFFER
	TLO	F,FLG		;YES - SET UP THAT BUFFER FIRST
	PUSHJ	P,XCTSET
XCRDWC:	TRZE	F,XSV		;SAVING COMMANDS?
	PUSHJ	P,XCTWIP	;YES - STOP, AND WIPE OUT THIS ONE
	SKIPGE	PT,XCTACW	;POINT TO ACTIVE EXECUTE BUFFER - ANY?
	JRST	XCOERR		;NO - ERROR
	MOVE	PT,XCTADR(PT)	;YES - GET POINTER
	MOVE	TY,[POINT 7,PARBUF] ;WRITE TO PARAMETER BUFFER
	MOVEI	T1,"W"		;START IT OFF
	IDPB	T1,TY
	JRST	XCRDL0		;GO OUTPUT THE BUFFER'S CONTENTS

;HERE TO OUTPUT NAME AND CONTENTS OF ACTIVE BUFFER IN SWITCH FORMAT

XCTRDL:	MOVE	T1,[260700,,PARBUF]
	CAMN	T1,PARPTR	;HAS A NAME BEEN GIVEN?
	JRST	XCRDLC		;NO - READ THE ACTIVE BUFFER
	TLO	F,FLG		;YES - SET UP THAT BUFFER FIRST
	PUSHJ	P,XCTSET
XCRDLC:	TRZE	F,XSV		;SAVING COMMANDS?
	PUSHJ	P,XCTWIP	;YES - STOP, AND WIPE OUT THIS ONE
	SKIPGE	T2,XCTACW	;GET NAME OF ACTIVE EXECUTE BUFFER - ANY?
	JRST	XCOERR		;NO - ERROR
	MOVE	TY,[POINT 7,PARBUF] ;WRITE TO PARAMETER BUFFER
	MOVE	T1,[ASCII ?/X?]	;START IT OFF
	PUSHJ	P,PUTSQ1
	MOVE	PT,XCTADR(T2)	;GET POINTER TO BUFFER
	MOVE	T1,XCTNAM(T2)
	TRZ	T1,1		;CLEAR FLAG BIT IN NAME
	JUMPE	T1,.+2		;IS NAME NULL
	PUSHJ	P,PUTSQ1	;NO - OUTPUT IT
	SKIPE	T1,XCTKEY(T2)	;GOT A KEY SEQUENCE, TOO?
	PUSHJ	P,XCTRDK	;YES - OUTPUT IT
	MOVEI	T1,":"		;SEPARATE NAME AND CONTENTS
	IDPB	T1,TY

XCRDL0:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,XCREND	;IF NULL FINISH OFF
	CAIN	T1,"^"		;SPECIAL FLAG?
	JRST	XCRSPC		;YES - HANDLE SEPARATELY
	CAIGE	T1," "		;CONTROL CHARACTER?
	JRST	XCRCTL		;YES - HANDLE SEPARATELY
	CAIN	T1,"$"		;WANT A REAL DOLLAR SIGN?
	JRST	[MOVEI T0,"^"	;YES - DISPLAY IT AS UP-ARROW DOLLAR SIGN
		 IDPB  T0,TY
		 JRST  .+1]
XCRDL1:	IDPB	T1,TY		;YES - OUTPUT IT
XCRDL2:	HRRZ	T1,TY		;IS THERE ROOM IN THE BUFFER FOR THE CHARACTER?
	CAIL	T1,PARBUF+PARBLN
	JRST	XCRENF		;NO - FINISH OFF NOW
	JRST	XCRDL0		;AND GET ANOTHER

XCRSPC:	HRRZ	T1,TY		;IS THERE LIKELY TO BE ROOM IN THE BUFFER?
	CAIL	T1,PARBUF+PARBLN-1
	JRST	XCRENF		;NO - FINISH OFF NOW
	ILDB	T1,PT		;GET CHARACTER AFTER SPECIAL FLAG
	CAIN	T1,"^"		;WANT A REAL UP-ARROW?
	JRST	[IDPB T1,TY	;YES - OUTPUT TWO ARROWS TO SHOW IT'S REAL
		 JRST XCRDL1]
	CAIN	T1,77		;RESET COMMAND?
	JRST	[SETZ T1,	;YES - GET THE RIGHT CODE
		 JRST XCRCTL]
	TRNE	T1,100		;GOT SOME KIND OF CONDITIONAL?
	JRST	XCRRPT		;YES - HANDLE SEPARATELY
	CAIGE	T1,40		;GOT AN EXIT OR CONTINUE, OR OTHER?
	JRST	XCRCON		;YES - GET STRING FROM CONDITIONAL TABLE
XCRCTL:	MOVE	T1,CMDNAM(T1)	;GET COMMAND NAME
XCRCT1:	PUSHJ	P,PUTSQ1	;OUTPUT IT
	JRST	XCRDL2		;BACK TO THE FLOW

XCRCON:	MOVE	T1,CMDCON(T1)	;GET STRING FROM THE CONDITIONAL TABLE
	TRZ	T1,177		;CLEAR OUT FLAGS
	CAME	T1,[ASCIZ /^OU(/] ;GOT AN OUTPUT COMMAND?
	JRST	XCRCT1		;NO - PROCESS IT NORMALLY
	PUSHJ	P,PUTSQ1	;YES - OUTPUT IT
	MOVEI	T2,"^"		;GET AN UP-ARROW FOR SAVING
XCRCN1:	ILDB	T1,PT		;GET A CHARACTER OF THE OUTPUT STRING
	CAIN	T1,177		;END OF STRING?
	JRST	XCRCNE		;YES - FINISH OFF
	CAIE	T1,"$"		;GOT A REAL DOLLAR SIGN,
	CAIN	T1,")"		;  OR CLOSE PAREN?
	IDPB	T2,TY		;YES - PRECEDE WITH AN UP-ARROW
	CAIGE	T1,40		;CONTROL CHARACTER?
	PUSHJ	P,XCRCNC	;YES - OUTPUT SPECIALLY
	IDPB	T1,TY		;OUTPUT THE CHARACTER
	JRST	XCRCN1		;AND GET MORE

XCRCNC:	CAIN	T1,33		;ESCAPE?
	JRST	[MOVEI T1,"$"	;YES - OUTPUT AS A DOLLAR SIGN
		 POPJ  P,]
	IDPB	T2,TY		;NO - PRECEDE WITH AN UP-ARROW
	ADDI	T1,100
	POPJ	P,		;THEN OUTPUT THE CONTROL CHARACTER AND FINISH

XCRCNE:	MOVEI	T1,")"		;END STRING WITH A CLOSE PAREN
	IDPB	T1,TY
	JRST	XCRDL0		;AND GET MORE OF THE BUFFER

;HERE IF SOME KIND OF CONDITIONAL IS FOUND

XCRRPT:	TRNN	T1,76		;ENDING A REPEAT BLOCK?
	JRST	XCRRPE		;YES - DO SO
	TRNE	T1,40		;GOT AN ITERATED DO?
	JRST	XCRRPD		;YES - HANDLE SPECIALLY
	TRNE	T1,30		;GOT AN IF-ROW, -COLUMN, OR -COUNTER?
	JRST	XCRRPF		;YES - HANDLE SPECIALLY
	TRNE	T1,4		;GOT AN IF-CHARACTER?
	SKIPA	T2,CMDCON+3	;YES - GET ITS SEQUENCE
	MOVE	T2,CMDCON+4	;NO - GET SEQUENCE FOR DO-WHILE
	TRZ	T2,177		;CLEAR OUT FLAGS
	EXCH	T1,T2		;GET READY TO OUTPUT THE SEQUENCE
	TRNE	T2,1		;WANT A "NOT" FLAG?
	ORI	T1,57260	;YES - SET "^X" IN SEQUENCE (REALLY)
	PUSHJ	P,PUTSQ1	;OUTPUT CONDITIONAL (AND MAYBE THE NOT)
	ILDB	T1,PT		;GET CHARACTER TO CONDITION ON
	CAIN	T1,"("		;IS IT A REAL OPEN PAREN?
	JRST	[MOVEI T0,"^"	;YES - LEAD IT OFF WITH AN UP-ARROW
		 IDPB  T0,TY
		 JRST  .+1]
	IDPB	T1,TY		;OUTPUT CONDITION CHARACTER
	CAIN	T1,"^"		;WANT A CLASS OF CHARACTERS?
	JRST	[ILDB T1,PT	;YES - GET CLASS
		 LDB  T1,[POINT 7,XCTCLS-1(T1),27]
		 IDPB T1,TY	;OUTPUT IT
		 JRST .+1]	;AND CONTINUE
XCRRPX:	MOVEI	T1,"("		;START OFF THE REPEAT BLOCK
	IDPB	T1,TY
	JRST	XCRDL0		;AND BACK TO FLOW

XCRRPF:	TRNE	T1,10		;GOT AN IF-COLUMN?
	SKIPA	T2,CMDCON+1	;YES - GET ITS SEQUENCE
	MOVE	T2,CMDCON	;NO - GET SEQUENCE FOR IF-ROW
	CAIL	T1,130		;OR IS IT REALLY AN IF-COUNTER?
	MOVE	T2,CMDCON+2	;YES - GET THE REAL SEQUENCE
	TRZ	T2,177		;CLEAR OUT FLAGS
	ANDI	T1,7		;ISOLATE CONDITION TYPE
	OR	T2,XCTREL-2(T1)	;SET UP THE RIGHT CONDITION
	MOVE	T1,T2
	PUSHJ	P,PUTSQ1	;OUTPUT THE CONDITIONAL
	ILDB	T1,PT		;GET ROW OR COLUMN NUMBER
	JRST	XCRPD1		;OUTPUT IT AND FINISH OFF

XCRRPD:	MOVEI	T2,"^"		;FLAG NUMBER AS A COUNT
	IDPB	T2,TY
	ILDB	T2,PT		;GET REPEAT COUNT
	DPB	T1,[POINT 5,T2,28]
	MOVE	T1,T2		;PUT IN HIGH-ORDER BITS
XCRPD1:	PUSHJ	P,PUTNUM	;OUTPUT IT
	JRST	XCRRPX		;SAVE CHARACTER AND FLOW

XCRRPE:	MOVEI	T1,")"		;END THE REPEAT BLOCK
	JRST	XCRDL1		;SAVE CHARACTER AND FLOW

XCRENF:	TYPCHI	207		;BEEP TO SHOW ENTIRE BUFFER DIDN'T FIT
XCREND:	SETZ	T1,		;END WITH A NULL
	IDPB	T1,TY
	MOVEM	TY,PARPTR	;SAVE TYPE POINTER AS PARAMETER POINTER
	MOVE	TY,TYPPTR	;POINT BACK TO TYPE BUFFER
	JRST	RECALL		;PRETEND THIS WAS THE LAST PARAM TYPED

XCTRDK:	MOVEI	T0,","		;SUB. TO OUTPUT KEY SEQUENCE
	IDPB	T0,TY		;OUTPUT THE SEPARATOR
XCTRK1:	SETZ	T0,		;SHIFT IN A CHARACTER
	LSHC	T0,7
	CAIE	T0,177		;GOT A RUBOUT,
	TRNN	T0,140		;  OR CONTROL CHARACTER?
	JRST	[MOVEI T2,"^"	;YES - SIMULATE AS UP-ARROW CHARACTER
		 IDPB  T2,TY	;(RUBOUT IF UP-ARROW "?")
		 CAIE  T0,177
		 TROA  T0,100
		 MOVEI T0,"?"
		 JRST  .+1]
	IDPB	T0,TY		;OUTPUT THE CHARACTER
	JUMPN	T1,XCTRK1	;LOOP THROUGH THEM ALL
	POPJ	P,		;THEN DONE

;HERE TO OUTPUT LIST OF DEFINED NAMES

XCTNML:	PUSHJ	P,SWHBOT	;SET UP THE BOTTOM LINE
	MOVEI	T2,XBFNUM-1	;LOOK FOR NAME OF BUFFER
XCNAM1:	SKIPN	T1,XCTNAM(T2)	;GET A NAME - ANY?
XCNAM2:	SOJGE	T2,.-1
	JUMPL	T2,SWHNPE	;WHEN DONE, FINISH OFF LIKE THE SWITCH INFO
	TRZ	T1,1		;ELSE CLEAR FLAG BIT IN NAME
	JUMPN	T1,.+2		;IS THIS THE NULL BUFFER?
	MOVE	T1,[ASCII /<NUL>/] ;YES - SET UP NULL NAME
	PUSHJ	P,PUTSQ1	;OUTPUT NAME
	MOVE	T1,[ASCII / /]	;SEPARATE NAME FROM NEXT NAME
	PUSHJ	P,PUTSQ1
	JRST	XCNAM2		;GET NEXT NAME

;SUBROUTINE TO READ THE BUFFER NAME AND FIND IT AMONG XCTNAM
;RETURNS NAME IN T4; INDEX IN T1. T1/-1 IF NOT FOUND

XCTRED:	MOVE	T2,[POINT 7,T4] ;GET POINTERS TO SOURCE, TARGET OF NAME
	MOVE	PT,[POINT 7,PARBUF,6]
	MOVEI	T4,1		;CLEAR TARGET - NAME WILL HAVE LOW BIT ON
	MOVEI	T3,5		;READ AT MOST 5 CHARACTERS
XCTRD1:	PUSHJ	P,REDCHR	;GET A CHARACTER
	JUMPE	T1,XCTRD2	;DONE IF NULL
	IDPB	T1,T2		;STORE IT IN TARGET
	SOJG	T3,XCTRD1	;GET ANOTHER CHARACTER
XCTRD2:	MOVEI	T1,XBFNUM-1	;NOW LOOK FOR NAME
	CAME	T4,XCTNAM(T1)	;IS THIS IT?
	SOJGE	T1,.-1		;NO - LOOP
	POPJ	P,		;YES (OR NOT FOUND) - RETURN

;HERE TO LINK CURRENT EXECUTE BUFFER TO THE PUSH OF A BUTTON

XCTBTN:	TRZE	F,XSV		;WAS A BUFFER OPEN?
	PUSHJ	P,XCTWIP	;YES - CLOSE IT
	MOVEI	T1,[ASCIZ /Push any command button, then "G": /]
	PUSHJ	P,PUTBTM	;OUTPUT THE MESSAGE ON BOTTOM LINE
	PUSHJ	P,PROTOF	;UNPROTECT
	PUSHJ	P,PUTTYP	;OUTPUT ALL THIS NOW

	MOVEI	DO,1001		;NOTE THAT IT'S BUTTON TIME
	MOVE	PT,XCTACW	;POINT TO ACTIVE EXECUTE BUFFER
	PUSHJ	P,XCTKLK	;CLEAN OUT OLD KEY, IF ANY
	MOVEI	T2,200000(PT)	;SET EXECUTE BIT AND SAVE FOR SUBTBX
	MOVEM	T2,SAVEAC+6
	MOVEI	PT,XCTKEY(PT)	;MAKE AN ABSOLUTE-ADDRESS POINTER
	HRLI	PT,440700
	MOVEM	PT,SAVEAC+5	;SAVE IT ALSO FOR LATER
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKOALL	;ECHO OFF; BREAK ON EVERYTHING
>>
XCTBT1:	GETCHR			;READ A CHARACTER FROM THE TERMINAL IN T1
	CAIE	T1,"G"		;END OF COMMAND?
	CAIN	T1,"g"
	JRST	XCTBT3		;YES - FINISH OFF
	TLNE	PT,760000	;NO - ALREADY GOT 5 CHARACTERS?
	IDPB	T1,PT		;NO - SAVE CHARACTER
	JRST	XCTBT1		;AND GET SOME MORE

XCTBT3:
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKONPT	;ECHO ON; BREAK ON NON-PRINTING CHARACTERS
>>
	MOVE	T2,SAVEAC+5	;GET POINTER TO EXECUTE COMMAND SEQUENCE
	SKIPE	(T2)		;GOT A SEQUENCE?
	PUSHJ	P,SUBTBX	;YES - IF IT'S LEGAL CHANGE INPUT TABLE
	JRST	XCTEND		;DONE

;HERE TO READ A FILE OF EXECUTE BUFFER SWITCHES
;CURRENT BUFFERS ARE REPLACED BY THESE

;XCTBW0:	SKIPA	PT,T2
XCTBSW:	TRZE	F,XSV		;WAS A BUFFER OPEN?
	PUSHJ	P,XCTWIP	;YES - CLOSE IT
	MOVE	PT,[POINT 7,PARBUF,6]
	MOVE	T3,[POINT 7,SAVEAC+4]
IFN TOPS10,<
	MOVEI	T4,'XCT'	;GET DEFAULT EXTENSION
>
IFE TOPS10,<
	MOVE	T4,[ASCII /XCT/]
>
	PUSHJ	P,PARSFX	;PARSE THE SPECS INTO SCRATCH AREA
	HRROI	T2,SAVEAC+4	;FIND THE EXECUTE FILE
	PUSHJ	P,SETINP
	JUMPE	T1,XCIERR	;ERROR IF FILE NOT FOUND
XCTSB0:	PUSHJ	P,PIKFRG	;MAKE SURE PICK BUFFER IS NOT FRAGGED
IFN TOPS10,<
	MOVEI	T1,-400		;SET TO READ 400 WORDS
	HRLM	T1,SEDCCL
	INPUT	5,SEDCCL	;READ FILE INTO PICK BUFFER
	RELEAS	5,
>
IFE TOPS10,<
	MOVE	T2,[POINT 7,PIKBUF+PCBSIZ-400]
	SETZ	T3,		;READ THE FILE
	SIN
	CLOSF			;CLOSE IT
	  HALTF
>
	MOVEI	PT,XBFNUM-1	;ZERO ALL EXISTING INFORMATION
	PUSHJ	P,XCTKLL
	SOJGE	PT,.-1
	MOVE	T2,[010700,,XCTFRE-1]
	MOVEM	T2,XCFPTR	;ALL BUFFER SPACE IS NOW FREE
	MOVE	PT,[POINT 7,PIKBUF+PCBSIZ-400]
XCTSB1:	ILDB	T1,PT		;GET 1ST CHARACTER OF FILE
	JUMPE	T1,XWFERR	;END - ERROR - WRONG FORMAT
	CAIE	T1,"/"		;IS IT A SWITCH?
	JRST	XCTSB1		;NO - LOOP UNTIL START OF SWITCHES
XCTSB2:	PUSHJ	P,SWHMNY	;GO PARSE THE SWITCHES
	ILDB	T1,PT		;GET CHARACTER OF NEXT LINE
	CAIN	T1,"/"		;ANOTHER SWITCH?
	JRST	XCTSB2		;YES - SET IT UP, TOO
	TLZN	F,FLG		;NO - CALLED BY SWHMNX?
	JRST	XCTEND		;NO - FINISH OFF
	POPJ	P,		;YES - RETURN TO IT

;EXECUTE, NO PARAMETER: IF BUFFER IS OPEN, JUST CLOSE IT
;IF ALREADY CLOSED, SET TO DO SAME NUMBER OF ITERATIONS AS LAST TIME

EXCNPM:	TRZN	F,XSV		;SAVING COMMANDS?
	JRST	EXCNP1		;NO - SET UP FOR ITERATING
	MOVE	PT,XCTPTW	;YES - GET POINTER TO END OF BUFFER
	PUSHJ	P,XCTCLO	;CLOSE OFF THE BUFFER
	JRST	LOOP		;AND GET A NEW COMMAND

EXCNP1:	MOVE	T3,XCTITR	;GET NUMBER OF ITERATIONS
	SKIPLE	T4,T3		;ANY?
	JRST	EXCUT1		;YES - GO SET IT UP
	MOVEI	T1,[ASCIZ /####Enter number of iterations/]
	JRST	ERROR

;GET A COMMAND FROM THE EXECUTE BUFFER, FROM LOOP

XCTGET:
IFN FTJOUR,<
	TLNE	TM,JRC		;IS THIS A JOURNAL RESTORE?
	JRST	LOPJRN		;YES - GET THE CHARACTER FROM THE JOURNAL
>
	ILDB	T1,XCTPTR	;GET A COMMAND FROM READ BUFFER
	CAIN	T1,"^"		;SPECIAL CHARACTER FLAG?
	JRST	XCTGT1		;YES - HANDLE SPECIALLY
	JUMPN	T1,XCTGTE	;IF GOT A REAL CHARACTER, USE IT
XCTGT0:	MOVE	T1,XCTACR	;ELSE POINT BACK TO START OF BUFFER
	MOVEM	T1,XCTPTR
	SOSG	T2,XCTNUM	;ELSE WANT TO DO ANOTHER ITERATION?
	JRST	XCTDUN		;NO - FINISH OFF OR POP A LEVEL
	PUSHJ	P,XCTWIS	;YES - MAY WANT TO WHISTLE
	JRST	XCTGET		;GO GET FIRST COMMAND

XCTWIS:	TRNN	F,XBN		;DISPLAYING THE EXECUTE,
	TRNE	T2,7		;  OR DON'T WANT TO WHISTLE?
	JRST	XCTSTP		;EITHER - DON'T WHISTLE
	TYPCHI	207		;NEITHER - WHISTLE
XCTSTP:	GOTINP			;SKIP IF USER TYPED SOMETHING
	  POPJ	P,		;NO - RETURN
	GETCHR			;READ A CHARACTER INTO T1
	CAIN	T1,177		;IS IT A RUBOUT?
	JRST	RUBEXC		;YES - ABORT THE EXECUTE
	POPJ	P,

XCTGTE:	CAIGE	T1," "		;SOME CONTROL CHARACTER?
	JRST	LOOP2		;YES - HANDLE IT
XCTGE1:
IFE TOPS10,<
IFN FTECHO,<
	TDNE	F,[CCH!ENT,,XCT] ;NO - ENTERING, EXECUTING, OR GOT ECC?
	JRST	ALPNUM		;YES - JUMP WITHOUT ECHOING
	TLNN	TM,XCI		;NO - INITIALIZING FOR AN EXECUTE?
	TYPCHA			;NO - ECHO THE REAL CHARACTER
>>
	JRST	ALPNUM		;NO - JUST PUT IT IN FILE OR BUFFER

XCTGT1:	ILDB	T1,XCTPTR	;GET CHARACTER AFTER THE UP-ARROW
	CAIN	T1,"^"		;WANT A REAL UP-ARROW?
	JRST	XCTGE1		;YES - TREAT IT LIKE A NORMAL CHARACTER
	CAIN	T1,77		;GOT A RESET COMMAND?
	JRST	[SETZ T1,	;YES - GET THE REAL CODE AND DISPATCH
		 JRST LOOP2]
	CAIGE	T1,40		;GOT AN EXIT OR CONTINUE, OR SOMETHING?
	JRST	XCTGCT		;YES - GO HANDLE IT
	TRNN	T1,100		;GOT THE START OR END OF A REPEAT?
	JRST	LOOP2		;NO - PROCESS THE COMMAND
	TRNN	T1,76		;END OF A REPEAT?
	JRST	XCTGRX		;YES - GO HANDLE IT

;HERE IF SOME KIND OF CONDITIONAL

	TRNE	T1,40		;GOT AN ITERATED DO?
	JRST	XCGITR		;YES
	TRNE	T1,30		;GOT AN IF-ROW, -COLUMN OR -COUNTER?
	JRST	XCGTRC		;YES
	PUSHJ	P,MAKCPT	;NO - RE-MAKE CHARACTER POINTER
	ILDB	T2,XCTPTR	;GET CHARACTER OR CLASS TO CHECK FOR
	CAIN	T2,"^"		;GOT A CLASS?
	TRO	T1,200000	;YES - SET CLASS FLAG
	PUSHJ	P,XCTCHK	;SEE IF CONDITION IS TRUE
	TRNE	T1,4		;GOT AN IF-CHARACTER?
	JRST	XCGTIF		;YES

;HERE FOR DO-WHILE

	JUMPN	T0,XCTSKB	;IF FALSE SKIP THE BLOCK
	HRL	T2,T1		;ELSE SET UP FLAGS,,CHAR
	TLO	T2,400000	;SET DO-WHILE FLAG
	JRST	XCGIT1		;SAVE STUFF AND DO THE BLOCK

;HERE FOR ITERATED DO

XCGITR:	ILDB	T2,XCTPTR	;GET LOW BITS OF REPEAT COUNT
	DPB	T1,[POINT 5,T2,28] ;PUT HIGH-ORDER BITS IN, TOO
XCGIT1:	JUMPE	T2,XCTSKB	;IF ZERO ITERATIONS, JUST SKIP THE BLOCK
	AOS	T1,XCTLVL	;DROP DOWN A LEVEL OF NESTING
	CAIN	T1,1		;NOW AT LEVEL ONE?
	JRST	.+3		;YES - DON'T SAVE
	PUSH	P,XCTRPR	;SAVE PTR TO START OF BLOCK
	PUSH	P,XCTRPT	;SAVE PREVIOUS REPEAT COUNT
	MOVEM	T2,XCTRPT	;SAVE COUNT AND FLAGS
	MOVE	T1,XCTPTR	;SAVE POINTER TO START OF BLOCK
	MOVEM	T1,XCTRPR
	JRST	XCTGET		;PICK UP THE FIRST ITERATION

;HERE FOR IF-ROW, IF-COLUMN, IF-COUNTER, AND IF-CHARACTER (XCGTIF)

XCGTRC:	TRNN	T1,10		;GOT AN IF-COLUMN?
	SKIPA	T3,RW		;NO - GET ROW FOR COMPARISON
	MOVE	T3,CM		;YES - GET COLUMN FOR COMPARISON
	ILDB	T2,XCTPTR	;GET VALUE TO COMPARE WITH
	CAIL	T1,130		;IS IT REALLY AN IF-COUNTER?
	SKIPA	T3,XCTCTR	;YES - GET THE COUNTER (DON'T DEC VALUE)
	SOJ	T2,		;IT'S ONE TOO HIGH, SINCE RW & CM ZERO-BASED
	TRNE	T1,4		;WANT EQUALITY?
	JRST	[CAME T3,T2	;YES - ARE THEY EQUAL?
		 JRST XCGRCF	;NO - SET UP FALSE
		 JRST XCGRCT]	;YES - SET UP TRUE
	CAMN	T3,T2		;DON'T WANT EQUALITY - ARE THEY EQUAL?
	JRST	XCTSKB		;YES - IT MUST BE FALSE
	CAML	T3,T2		;NO - IS PARAMETER GREATER THAN VALUE?
XCGRCT:	TDZA	T0,T0		;YES - SET UP TRUE
XCGRCF:	SETO	T0,		;NO - SET UP FALSE
	TRNE	T1,1		;WANT TO NEGATE THE RESULT?
	SETCM	T0,T0		;YES

XCGTIF:	JUMPE	T0,XCTGET	;IF TRUE, KEEP GOING
XCTSKB:	PUSHJ	P,XCTSKP	;ELSE SKIP OVER THE BLOCK
	JUMPE	T1,XCTGT0	;JUMP IF END OF BUFFER
	JRST	XCTGET		;AND GET WHAT COMES AFTERWARDS

;HERE TO SKIP TO END OF A BLOCK AND GET WHAT FOLLOWS

XCTSKP:	SETZ	T0,		;CLEAR COUNT OF BLOCKS PASSED OVER
XCTSK1:	ILDB	T1,XCTPTR	;SKIP OVER NEGATIVE "IF" BLOCK
	JUMPE	T1,CPOPJ	;DONE IF END OF BUFFER
	CAIE	T1,"^"		;START OR END OF A BLOCK?
	JRST	XCTSK1		;NO - KEEP SKIPPING
	ILDB	T1,XCTPTR	;YES - GET FOLLOWING CHARACTER
	TRNE	T1,76		;END OF A BLOCK?
	JRST	XCTSK2		;NO - MAYBE DROP A LITTLE DEEPER
	SOJGE	T0,XCTSK1	;YES - LOOP OF NOT THE RIGHT END
	POPJ	P,		;ELSE DONE

XCTSK2:	TRNE	T1,100		;IS THIS A COMMAND,
	CAIN	T1,"^"		;  OR WANT A REAL UP-ARROW?
	JRST	XCTSK1		;EITHER - SKIP OVER IT
	AOJA	T0,XCTSK1	;ELSE DROP A LEVEL AND KEEP SKIPPING

;HERE FOR AN EXIT OR CONTINUE CONSTRUCT

XCTGCT:	CAILE	T1,7		;GOT AN EXIT OR CONTINUE?
	JRST	@XCTJMP-10(T1)	;NO - DISPATCH TO HANDLE IT
	CAIN	T1,7		;WANT TO END THIS ITERATION (^XX)?
	JRST	XCTGTX		;YES - POP STACK AND DO SO
	MOVE	T2,T1		;NO - SAVE TYPE OF CONSTRUCT
	ILDB	T0,XCTPTR	;GET THE ")" THAT FOLLOWS THE COMMAND
	PUSHJ	P,XCTSKP	;SKIP TO END OF THE BLOCK
	JUMPE	T1,XCTGT0	;JUMP IF END OF BUFFER
	CAIE	T1,100		;IS THIS AN IF CONSTRUCT?
	JRST	XCTGET		;YES - GO EXECUTE FROM HERE
	CAIE	T2,6		;NO - WANT TO EXIT THE BLOCK (^XB)?
	JRST	XCTGXP		;YES - DO SO
				;ELSE FALL TO CONTINUE THE BLOCK

;HERE IF END OF A BLOCK - IGNORE IF ^A (IF); LOOP OR EXIT IF ^@ (^DO)

XCTGRX:	CAIE	T1,100		;END OF DO BLOCK?
	JRST	XCTGET		;NO - IGNORE IT
	TLZE	TM,XCI		;STOP INITIALIZING?
	JRST	XCTGXI		;YES - JUST DE-BUMP LEVEL
	PUSHJ	P,XCTSTP	;SEE IF USER WANTS TO STOP
	SKIPGE	XCTRPT		;GOT A DO-WHILE?
	JRST	XCTGXW		;YES - CHECK CHARACTER AT CURSOR
	SOSG	XCTRPT		;NO - DO-ITR - DE-BUMP COUNTER - DONE?
	JRST	XCTGXP		;YES - POP BACK A LEVEL
XCTGXR:	MOVE	T1,XCTRPR	;NO - GET POINTER TO START OF BLOCK
	MOVEM	T1,XCTPTR	;SAVE IT AS REAL POINTER
	JRST	XCTGET		;AND TAKE COMMANDS FROM THERE

XCTGXW:	PUSHJ	P,MAKCPT	;RE-MAKE CHARACTER POINTER
	HLRZ	T1,XCTRPT	;GET FLAGS
	HRRZ	T2,XCTRPT	;GET CHARACTER OR CLASS TO CHECK FOR
	TRNE	T1,200000	;GOT A CLASS?
	JRST	[SETZ  T0,	;YES - GO CHECK THE CONDITION
		 PUSHJ P,XCTCHC+1
		 JRST  .+2]
	PUSHJ	P,XCTCHK	;NO - CHECK THE CONDITION
	JUMPE	T0,XCTGXR	;IF TRUE JUST DO THE BLOCK, ELSE POP LEVEL

XCTGXP:	SKIPE	XCTLVL		;SKIP IF STACK IS CLEAR
	SOSG	XCTLVL		;AT BOTTOM LEVEL?
	JRST	XCTGET		;YES - JUST KEEP GOING
	POP	P,XCTRPT	;ELSE GET SAVED COUNT (OR COMPARATOR)
	POP	P,XCTRPR	;AND INITIAL REPEAT POINTER
	JRST	XCTGET		;AND TAKE COMMANDS FROM THERE

XCTGTX:	SKIPE	XCTLVL		;SKIP IF STACK IS CLEAR
	SOSG	XCTLVL		;POP EVERYTHING OFF THE STACK - ANY LEFT?
	JRST	XCTGT0		;NO - DO ANOTHER ITERATION
	POP	P,XCTRPT	;YES - POP IT OFF ALREADY
	POP	P,XCTRPR
	JRST	XCTGTX+1	;AND TRY AGAIN

XCTGXI:	SETZM	XCTLVL		;END OF XCT INIT - CLEAR LEVEL
	MOVE	T1,XCTPTR	;GET POINTER TO CURRENT POSITION
	EXCH	T1,XCTACR	;SAVE AS STARTING POINTER
	MOVEM	T1,XCTINI	;SAVE REAL STARTING POINTER, TOO
	JRST	XCTGET		;READ MORE OF BUFFER

;DISPATCH FOR ROUTINES TO HANDLE SPECIAL EXECUTE CONSTRUCTS

XCTJMP:	XCTG10			;(10) ITERATE-COUNTER
	XCTG11			;(11) CLEAR-COUNTER
	XCTG12			;(12) BUMP-COUNTER
	XCTG13			;(13) DE-BUMP-COUNTER
	XCTG14			;(14) USE-COUNTER
	XCTG15			;(15) INITIALIZE
	XCTG16			;(16) OUTPUT
	XCTG17			;(17) SAVE-COUNTER
	XCTG20			;(20) NO-DISPLAY
	XCTG21			;(21) DO-ON-SEARCH-ERROR

XCTG21:	PUSHJ	P,XCTSKP	;NOT A SEARCH ERROR, SO JUST SKIP THE BLOCK
	JRST	XCTGET		;DONE

XCTG20:	TRZE	F,XBN		;TURN OFF BUTTON FLAG - ON?
	TRO	F,XCT		;YES - TURN ON NORMAL EXECUTE FLAG
	JRST	XCTGET		;DONE

XCTG17:	TLNN	F,ENT		;IS THERE A PARAMETER?
	JRST	XCG17A		;NO - USE OLD NOMINAL
	MOVE	T4,XCTSNM	;GET LAST TIME'S NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	TRNE	F,CMV		;CURSOR MOVEMENT?
	SKIPA	T4,PARG2	;YES -	GET CHANGE IN COLUMNS
	MOVE	T4,PARG1
	MOVEM	T4,XCTSNM	;SAVE AS NEW NOMINAL
	PUSHJ	P,ERASPM	;FIX UP THE SCREEN
XCG17A:	MOVE	T4,XCTSNM	;GET COUNTER SETTING
	MOVEM	T4,XCTCTR	;SAVE AS COUNTER VALUE
	JRST	XCTGET		;DONE

XCTG16:	ILDB	T1,XCTPTR	;GET A CHARACTER TO OUTPUT
	CAIN	T1,177		;END OF STRING?
	JRST	XCG16A		;YES - OUTPUT IT AND FINISH OFF
	IDPB	T1,TY		;NO - SAVE THE CHARACTER
	JRST	XCTG16		;AND GET ANOTHER

XCG16A:	PUSHJ	P,PUTTYP	;OUTPUT THE STRING
	JRST	XCTGET		;AND READ MORE OF THE BUFFER

XCTG15:	TLO	TM,XCI		;INITIALIZE - SET FLAG
	AOS	XCTLVL		;DROP DOWN A LEVEL
	JRST	XCTGET		;READ MORE OF BUFFER

XCTG14:	SKIPGE	T1,XCTCTR	;GET COUNTER - IS IT NEGATIVE?
	SETZ	T1,		;YES - SET TO ZERO
	EXCH	TY,PARPTR	;SAVE OUTPUT POINTER AND GET PARAMETER POINTER
	PUSHJ	P,PUTNUM	;OUTPUT NUMBER TO PARAMETER BUFFER
	EXCH	TY,PARPTR	;SWAP PARAMETER AND OUTPUT POINTERS BACK
	JRST	XCTGET		;READ MORE OF BUFFER

XCTG13:	SOSA	XCTCTR		;DE-BUMP COUNTER
XCTG12:	AOS	XCTCTR		;I MEAN BUMP IT
	JRST	XCTGET		;GET A NEW COMMAND

XCTG11:	SETZM	XCTCTR		;CLEAR THE COUNTER
	JRST	XCTGET

XCTG10:	SKIPGE	T2,XCTCTR	;GET COUNTER - NEGATIVE?
	SETZ	T2,		;YES - USE 0
	JRST	XCGIT1		;USE IT WITH AN ITERATED DO

REPEAT 0,<
;SUBROUTINE TO .OR. A NUMBER OF CHARACTERS OR CONDITIONS FOR ^DW OR ^IF

XCTCKI:	SETZM	SAVEAC+1	;CLEAR THE OVERALL CONDITION FLAG

XCTCI1:	ILDB	T2,XCTPTR	;GET A CHARACTER OR CLASS TO CHECK FOR
	PUSHJ	P,XCTCHK	;CHECK IT OUT
	JUMPG	T0,XCTCI2	;DONE IF END OF BLOCK
	ORM	T0,SAVEAC+1	;OR THIS CONDITION WITH THE OTHERS
	JRST	XCTCI1		;AND CHECK THE NEXT CONDITION

XCTCI2:	MOVE	T0,SAVEAC+1	;GET THE CONDITION FLAG
	POPJ	P,		;DONE

;HERE FOR THE START OR END OF A LIST OF CONDITIONALS

XCTCIE:	CAIN	T2,20		;START OF A LIST OF CONDITIONS?
	JRST	XCTCHI		;YES
	MOVEI	T0,1		;RETURN A POSITIVE VALUE
	POPJ	P,		;DONE
>
;SUBROUTINE TO CHECK TO SEE IF CHARACTER IN T3 MATCHES CHAR OR CLASS IN T2

XCTCHK:	CAIN	T2,"^"		;WANT A CLASS?
	JRST	XCTCHC		;YES - HANDLE SEPARATELY
	CAMN	T3,T2		;NO - GOT THE RIGHT CHARACTER?
XCTCHT:	TDZA	T0,T0		;YES - FLAG AS TRUE
XCTCHF:	SETO	T0,		;NO - FLAG AS FALSE
	TRNE	T1,1		;GOT .NOT. FLAG?
	SETCM	T0,T0		;YES - RETURN THE OPPOSITE RESULT
	POPJ	P,		;DONE

XCTCHP:	MOVE	T1,SAVEAC	;RESTORE SAVED T1
	POPJ	P,		;DONE

XCTCHC:	ILDB	T2,XCTPTR	;GET CLASS TO CHECK FOR
REPEAT 0,<
	CAIL	T2,20		;START OR END OF A CONDITION LIST?
	JRST	XCTCIE		;YES
>
	CAIN	T2,2		;END OF LINE?
	JRST	XCTCHE		;YES
	CAIN	T2,3		;NUMBER?
	JRST	XCTCHN		;YES
	CAIN	T2,5		;SPACE?
	JRST	XCTCHS		;YES

	CAIGE	T3,"A"		;CHECK FOR UPPER, LETTER OR ALPHA-NUM
	JRST	XCTCHM		;NOT LETTER - MAY BE NUMBER
	CAIG	T3,"Z"		;LETTER?
	JRST	XCTCHT		;YES - RETURN TRUE
	CAIN	T2,6		;LOOKING FOR UPPER CASE?
	JRST	XCTCHF		;YES - RETURN FALSE
	CAIL	T3,"a"		;NO - IS IT LOWER CASE?
	CAILE	T3,"z"
	JRST	XCTCHF		;NO - RETURN FALSE
	JRST	XCTCHT		;ELSE TRUE

XCTCHM:	CAIE	T2,4		;NOT ALPHA - WANT ALPHA-NUM?
	JRST	XCTCHF		;NO - RETURN FALSE
XCTCHN:	CAIL	T3,"0"		;CHECK FOR NUMBER - IS IT?
	CAILE	T3,"9"
	JRST	XCTCHF		;NO - RETURN FALSE
	JRST	XCTCHT		;ELSE RETURN TRUE

XCTCHS:	TRNN	T1,1		;CHECKING FOR A CHARACTER?
	JRST	XCCHSS		;NO - CHECK FOR SPACE
	CAIN	T3,15		;YES - END OF LINE?
	JRST	XCTCHT		;YES - RETURN TRUE (NEGATED)
	CAIE	T3," "		;NO - SPACE OR TAB?
	CAIN	T3,11
	JRST	XCTCHT		;YES - RETURN TRUE (NEGATED)
	JRST	XCTCHF		;ELSE RETURN FALSE

XCCHSS:	CAIN	T3," "		;SPACE?
	JRST	XCCHE0		;YES - MAKE SURE IT'S NOT TRAILING
	CAIE	T3,11		;TAB?
	JRST	XCTCHF		;NO - RETURN FALSE

XCCHE0:	MOVEM	T1,SAVEAC	;SAVE T1
	PUSH	P,[XCTCHP]	;SAVE RESTORE-T1 ADDRESS
	TRO	T1,1		;LOOK FOR NON-END OF LINE
XCTCHE:	MOVE	T4,CHRPTR	;GET CURSOR POINTER
	CAIN	T3,15		;AT END OF LINE?
	JRST	XCTCHT		;YES - RETURN TRUE
	CAIN	T3," "		;NO - GOT A (MAYBE TRAILING) SPACE?
	JRST	XCCHE1		;YES - SKIP IT
	CAIE	T3,11		;HOW ABOUT A (MAYBE TRAILING) TAB?
	JRST	XCTCHF		;NO - RETURN FALSE
XCCHE1:	ILDB	T3,T4		;YES - GET NEXT CHARACTER
	JUMPE	T3,.-1		;IGNORE NULLS
	JRST	XCTCHE+1	;GO CHECK THE REAL CHARACTER

;HERE AT END OF EXECUTE BUFFER - FINISH OFF OR POP UP A LEVEL

XCTDUN:	SKIPN	T1,XCTPSV	;GOT A SAVED POINTER?
	JRST	XCTDN1		;NO - REALLY DONE
	SETZ	T1,		;YES - GET READY TO ZERO THINGS
	EXCH	T1,XCTPSV	;GET AND ZERO SAVED POINTER
	MOVEM	T1,XCTPTR	;MAKE IT ACTIVE AGAIN
	MOVE	T1,XCTASV	;GET SAVED STARTING POINTER
	MOVEM	T1,XCTACR	;SET IT UP
	MOVE	T1,XCTISV	;GET NOMINAL SAVED ITERATIONS
	MOVEM	T1,XCTITR	;SET THEM UP, TOO
	MOVE	T1,XCTNSV	;GET SAVED ITERATIONS
	MOVEM	T1,XCTNUM	;SET THEM UP, TOO
	JRST	XCTGET		;AND CONTINUE WITH THEM

XCTDN1:	TRNE	F,XBN		;DID USER PUSH A SPECIAL BUTTON?
	TLO	F,FLG		;YES - REMEMBER IT
	EXCH	T1,XCTASV	;GET AND ZERO SAVED STARTING POINTER
	JUMPE	T1,XCTDN2	;IS THERE ONE?
	MOVEI	T2,XBFNUM-1	;YES - FIND ITS INDEX
	CAME	T1,XCTADR(T2)	;IS THIS IT?
	SOJGE	T2,.-1		;NO - TRY NEXT ONE
	MOVEM	T2,XCTACW	;SAVE INDEX AS THE ACTUAL ACTIVE BUFFER
XCTDN2:	MOVE	TY,TYPPTR
	MOVS	T1,[PARAMS,,SAVPRM]
	BLT	T1,PARAMS+SAVPML-1 ;RESTORE ALL PARAMETERS
	HRRZ	T1,SAVFGS	;RESTORE PREVIOUS F SWITCH FLAGS
	TRZ	F,SWFLGS
	ANDI	T1,SWFLGS
	OR	F,T1
	HLLZ	T1,SAVFGS	;RESTORE PREVIOUS TM SWITCH FLAGS
	TLZ	TM,BEP!LSD!JRC
	AND	T1,[BEP!LSD!JRC,,0]
	OR	TM,T1
	SKIPE	T1,XCTINI	;IS THERE AN INITIAL POINTER?
	MOVEM	T1,XCTACR	;YES - SET IT UP AS STARTING POINTER
	SETZM	XCTINI		;CLEAR INITIAL POINTER
	TLZ	F,ENT		;DON'T ALLOW THE USER TO LEAVE ENTER IN EFFECT
	TLZE	F,FLG		;DID USER PUSH A SPECIAL BUTTON?
	JRST	LOOP		;YES - SCREEN IS ALREADY O.K.
	JRST	DISALL		;NO - RE-DISPLAY SCREEN AND LOOP

;EXECUTE ERROR MESSAGES

XSXERR:	MOVEI	T1,[ASCIZ /####Execute stacked too deeply/]
	SETZM	XCTPSV
	JRST	ERROR
XSCERR:	SKIPA	T1,[[ASCIZ /Counter must have a numeric parameter/]]
XWFERR:	MOVEI	T1,[ASCIZ /####Bad format for execute file/]
	JRST	ERROR

XCIERR:
IFN TOPS10,<
	MOVSI	T1,'TED'	;TRY FOR FILE ON THE TEXT EDITOR DEVICE
	MOVEM	T1,GENBLK+1
	PUSHJ	P,SETINP	;SEE IF IT'S THERE
	JUMPN	T1,XCTSB0	;IF THERE, USE IT
>
	MOVEI	T1,[ASCIZ /#######Execute file not found/]
	JRST	ERROR
XCXERR:	MOVEI	T1,[ASCIZ /######Current buffer is empty/]
	JRST	ERROR
XCOERR:	MOVEI	T1,[ASCIZ /########No buffer is active/]
	JRST	ERROR
XCSERR:	MOVEI	T1,[ASCIZ /#No free buffers - kill something/]
	JRST	ERROR
XCEERR:	MOVEI	T1,[ASCIZ /####Start or end of file reached/]
	SKIPA	TY,TYPPTR
XCKERR:	MOVEI	T1,[ASCIZ /####Can't kill - name not found/]
	JRST	ERROR
XCTERR:	MOVE	PT,XCTPTW	;GET POINTER TO BUFFER CONTENTS
	PUSHJ	P,XCTCLO	;CLOSE OFF THE BUFFER
	TRZ	F,XSV		;STOP SAVING
	MOVEI	T1,[ASCIZ /Execute buffer is about to overflow/]
	JRST	ERROR
XCVERR:	MOVE	T1,XCTACW	;CLEAR OVERFLOWED BUFFER
	MOVE	T1,XCTADR(T1)
	SETZM	@1(T1)
	MOVEI	T1,[ASCIZ /#####Execute buffer overflowed/]
	JRST	ERROR

;**********************************************************************
;HERE TO SET UP A NEW FILE FOR EDITING

SETFIL:	HRRZM	P,SAVEAC+11	;SET READ-WRITE FLAG POSITIVE (IE, NONE)
	MOVEM	F,SAVEAC	;SAVE THE FLAGS FOR LATER
	TRZE	F,RDO		;ASSUME WILL WRITE FILE - CAN WRITE NOW?
	TLZA	F,CHG		;NO - FORGET ANY CHANGES THAT WERE MADE; SKIP
SETFLS:	MOVEM	F,SAVEAC	;SAVE THE FLAGS FOR LATER
	MOVE	T2,PARPTR	;END PARAMETER WITH A NULL
	SETZ	T1,		;GET A NULL
	IDPB	T1,T2
	MOVE	PT,[POINT 7,PARBUF]
	ILDB	T1,PT		;GET FIRST CHARACTER OF FILESPECS
	CAIE	T1,"/"		;GOT JUST A STRING OF SWITCHES?
	JRST	SETFL0		;NO - CONTINUE
	PUSHJ	P,RESTPM	;YES - CLEAR ENTER MODE
	PUSHJ	P,SWHMNY	;SET UP THE SWITCHES
	SKIPN	AGNFLG		;WANT TO SET TO THE SAME FILE AGAIN?
	JRST	SETNPM		;NO - GO SET UP THE ALTERNATE FILE

	SETZM	AGNFLG		;YES - CLEAR THE AGAIN FLAG
	MOVE	T3,[POINT 7,FILSPC]
	MOVE	T4,[POINT 7,PARBUF]
SETAG0:	ILDB	T1,T3		;MOVE CURRENT FILESPECS TO PARM BUFFER
	IDPB	T1,T4		;AS IF THE USER TYPED THEM IN
	JUMPN	T1,SETAG0
	MOVEM	T4,PARPTR	;SAVE POINTER TO END OF PARAMETER

SETFL0:	MOVE	T1,[OLDSPC,,SVASPC] ;COPY OLD SPECS TO SAVE AREA
	BLT	T1,SVASPC+SPCSIZ+3  ;  (COPY THE SAVED POINTERS, TOO)
	MOVE	T1,[FILSPC,,OLDSPC] ;AND CURRENT SPECS TO OLD AREA
	BLT	T1,OLDSPC+SPCSIZ-1
IFE TOPS10,<
	DMOVE	T1,EXTPTR	;SAVE EXTENSION AND ITS POINTER
	DMOVEM	T1,SAVEXP
>
	SKIPA	T1,SAVEAC	;SAVE THE ORIGINAL CURRENT FLAGS
SETFLC:	MOVE	T1,F		;SAVE THE CURRENT FLAGS
	MOVEM	T1,SAVEFG
	MOVE	T1,DISPTR	;SAVE CURRENT DISPLAY POINTER
	MOVEM	T1,SAVEDP
	MOVEM	SL,SAVESL	;SAVE SLIDE
	MOVE	T3,[POINT 7,FILSPC]
	PUSHJ	P,PELS.F	;PICK UP USER'S FILESPEC, IF ANY
	MOVEM	RW,SAVERW	;SAVE POSITION AGAIN IN CASE OF CUR MVMT
	HRLM	CM,SAVERW
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	SETZM	WINDIS		;IF WINDOWING BE SURE TO DISPLAY THE FILE
	SETZM	MFLPTR		;FORGET INDIRECT STUFF IF USER GIVES A FILE
	TRZE	F,IND		;WANT TO LOOK AT FILES INDIRECTLY?
	JRST	SETIND		;YES - HANDLE SEPARATELY
	PUSHJ	P,PNTSTT	;SET UP POINTERS TO START OF FILE
	PUSHJ	P,PARSEF	;PARSE FILESPEC AND (MAYBE) SWITCHES
	TLZ	F,PCM!FLG!FNC	;CLEAR MARK AND PARSE FLAGS

IFN TOPS10,<
SETFL1:	TLZ	F,FLG		;CLEAR FLAG FROM PARSEF
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,FILPTH]
	PATH.	T1,
	  JRST	SETERR
>
	OPEN	2,FILBLK	;OPEN FILE FOR EDITING
	  JRST	SETERR
	LOOKUP	2,FILFIL	;SET UP FILE FOR READING
	  JRST	SETERR

	SETOM	INJFN		;SAY FILE HAS BEEN SET UP
	MOVE	T1,FILFIL+5	;GET SIZE OF FILE (IN WORDS)
	CAILE	T1,MAXSIZ*200	;IS FILE TOO BIG?
	JRST	SSZERR		;YES - ERROR
	MOVEM	T1,FILSIZ	;NO - SAVE FILE SIZE
	HRRZ	T2,DISPTR	;GET DISPLAY POINTER ADDRESS
	SUBI	T2,BUFFER
	CAMGE	T1,T2		;IS IT POINTING BEYOND THE BUFFER?
	JRST	[MOVE  T2,[010700,,BUFFER-1]
		 MOVEM T2,DISPTR ;YES - POINT TO START OF BUFFER
		 JRST  .+1]
;	LSH	T1,-7		;GET SIZE IN BLOCKS
;	MOVEM	T1,FILBSZ	;SAVE IT, TOO
IFE FTSFD,<
	MOVE	T1,FILFIL+16	;GET ACTUAL DEVICE NAME
	MOVEM	T1,FILBLK+1	;SAVE IN OPEN BLOCK, AND GET WHAT'S THERE
>
	HLLZS	FILFIL+3	;CLEAN UP FILESPEC BLOCK
	SETZ	T1,
	EXCH	T1,FILFIL+4
	MOVEM	T1,SAVEAC+10
IFN FTSFD,<
	SETZM	FILFIL+5
	MOVEI	T2,2		;SEE WHAT THE PDP-10 THINKS THE PATH IS
	MOVEM	T2,FILPTH
	MOVE	T1,[SFDLVL+4,,FILPTH]
	PATH.	T1,
	  JRST	SETERR		;(THIS SHOULD NEVER HAPPEN)
	MOVN	T2,T2		;SAVE SET-PATH ARGUMENT
	EXCH	T2,FILPTH	;  AND GET THE DEVICE NAME
	MOVEM	T2,FILBLK+1	;SAVE DEVICE IN OPEN BLOCK
	SETZM	FILPTH+1	;CLEAN UP THE PATH BLOCK
	SETZM	FILFIL+1	;  AND THE LOOKUP BLOCK
	MOVE	T1,FILPTH+2	;GET THE PPN
>
IFE FTSFD,<
	MOVE	T1,[FILFIL+4,,FILFIL+5]
	BLT	T1,FILFIL+LUKLEN ;ZERO REST OF FILE BLOCK
	MOVE	T1,FILFIL+1
>
	MOVEM	T1,FILPPN	;SAVE THE REAL FILE PPN

	JUMPLE	DO,SETF10	;UNPARSE NOT NEEDED IF NO PARAMETER WAS GIVEN
	PUSHJ	P,UNPARS	;NOW UNPARSE THE FILESPECS
	SKIPE	RSCANF		;GOT A FILE FROM RESCAN?
	JRST	SETF10		;YES - DON'T SAVE PREVIOUS FILE
	TLNN	DO,200000	;WORKING ON AN INDIRECT FILE,
	SKIPN	OLDSPC		;  OR IS THERE A PREVIOUS FILE?
	JRST	SETF10		;EITHER - DON'T SAVE OLD FILE
	PUSHJ	P,SAMFIL	;AND SEE FILE IS SAME AS PREVIOUS ONE
	TLNE	F,SMF		;ARE FILES THE SAME?
	JRST	[RELEAS 2,
		 JRST   SETWIN] ;YES - JUST SET THE THE NEW POSITION
	MOVEI	T4,OLDSPC	;NO - PREPARE TO SAVE FILE
	MOVEI	PT,OLDBLK
	MOVE	T1,SAVEDP
	MOVEM	T1,DISPTR
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,OLDPTH]
	PATH.	T1,		;SET THE PATH TO THE OLD FILE
	  JRST	SETERR
>
	PUSHJ	P,SAVFIL	;SAVE THE OLD FILE
	MOVE	T1,[010700,,BUFFER-1]
	EXCH	T1,DISPTR
	MOVEM	T1,SAVEDP

SETF10:	SETZM	RSCANF		;CLEAR FILE-FROM-RESCAN FLAG
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,FILPTH]
	PATH.	T1,		;PATH BACK TO THE NEW FILE
	  JRST	SETERR
>
	LDB	T1,[POINT 9,SAVEAC+10,8] ;GET PROTECTION CODE
	HRRM	T1,REDACC	;SAVE IN ACCESS CHECKING BLOCKS
	HRRM	T1,WRTACC
	MOVE	T2,USRPPN	;GET RUNNER'S PPN
	SKIPN	T1,FILPPN	;GET PPN OF FILE - ANY?
	MOVE	T1,T2		;NO - USE RUNNER'S PPN
	DMOVEM	T1,REDACC+1	;SAVE PPNS IN ACCESS BLOCKS
	DMOVEM	T1,WRTACC+1
	MOVEI	T1,REDACC	;SEE IF THE FILE CAN BE READ
	CHKACC	T1,
	  JFCL			;(NOT IMPLEMENTED)
	JUMPL	T1,SETERD	;NO READ ACCESS - ERROR
	MOVEI	T1,WRTACC	;SEE IF FILE CAN BE WRITTEN
	CHKACC	T1,
	  JFCL
	JUMPGE	T1,.+2		;CAN FILE BE WRITTEN?
	TRO	F,RDO		;NO - READ ONLY

	MOVEI	T1,BUFFER-1	;SHRINK CORE TO GET RID OF OLD FILE
	CORE	T1,
	  HALT
	MOVE	T1,FILSIZ	;EXPAND CORE TO ACCOMMODATE NEW FILE
	ADDI	T1,BUFFER
	CAMGE	T1,.JBREL	;IS IT WITHIN PRESENT CORE?
	JRST	[SETZM BUFFER	;YES - CLEAR OUT ALL OF CORE
		 MOVE  T2,[BUFFER,,BUFFER+1]
		 MOVE  T3,.JBREL
		 BLT   T2,(T3)
		 JRST  .+1]
	ADDI	T1,2000
	CORE	T1,
	  JRST	SSZERR		;ERROR - FILE TOO BIG
	MOVN	T1,FILSIZ
	HRLM	T1,FILCCL	;READ ENTIRE FILE IN
	JUMPE	T1,.+2		;UNLESS IT'S A ZERO-LENGTH FILE
	INPUT	2,FILCCL
	RELEAS	2,		;GET RID OF CHANNEL
	MOVE	T1,FILSIZ
>
IFE TOPS10,<
SETFL1:	MOVE	T1,[GJ%OLD+GJ%SHT]
	HRROI	T2,FILSPC	;GET A JFN FOR THIS FILE
	GTJFN
	  JRST	SETERR
	JUMPLE	DO,SETF11	;UNPARSE NOT NEEDED IF NO PARAMETER WAS GIVEN
	HRRZM	T1,NEWJFN	;SAVE FILE'S JFN IN A SCRATCH AREA FOR NOW
	PUSHJ	P,UNPARS	;READ THE SPECS BACK FROM THE MONITOR

	SKIPE	RSCANF		;GOT A FILE FROM RESCAN?
	JRST	SETF10		;YES - DON'T SAVE PREVIOUS FILE
	TLNN	DO,200000	;WORKING ON AN INDIRECT FILE,
	SKIPN	OLDSPC		;  OR IS THERE A PREVIOUS FILE?
	JRST	SETF10		;EITHER - DON'T SAVE OLD FILE
	PUSHJ	P,SAMFIL	;SEE FILE IS SAME AS PREVIOUS ONE
	TLNE	F,SMF		;ARE FILES THE SAME?
	JRST	[MOVE  T1,NEWJFN ;YES - JUST SET THE THE NEW POSITION
		 CLOSF
		  JRST SETWIN
		 JRST  SETWIN]
	MOVEI	T4,OLDSPC	;NO - PREPARE TO SAVE FILE
	MOVE	T1,SAVEDP
	MOVEM	T1,DISPTR
	PUSHJ	P,SAVFIL	;SAVE THE OLD FILE
	MOVE	T1,[010700,,BUFFER-1]
	EXCH	T1,DISPTR
	MOVEM	T1,SAVEDP

SETF10:	SETZM	RSCANF		;CLEAR FILE-FROM-RESCAN FLAG
	MOVE	T1,NEWJFN	;MAKE THE NEW FILE'S JFN OFFICIAL
SETF11:	MOVEM	T1,INJFN	;  (AND GET JFN IN T1)
	MOVEI	T2,OF%THW+OF%RD
	OPENF
	  JRST	SETERC
SETF12:	SETO	T1,		;UN-MAP THE PREVIOUS FILE
	MOVE	T2,[400000,,BUFBLK]
	MOVE	T3,[PM%CNT]
	HRR	T3,FILBSZ
	PMAP

	MOVE	T1,INJFN	;GET THE NEW FILE'S JFN
	MOVE	T2,[1,,.FBBYV]	;FIND BYTE SIZE OF THE FILE
	MOVEI	T3,T4		;  IN T4
	GTFDB
	HLRZ	T4,T4
	ANDI	T4,7700		;CLEAR OUT ALL FIELDS BUT BYTE SIZE
	MOVEI	PT,1		;ASSUME BYTE SIZE IS 7
	CAIN	T4,4400		;IS IT REALLY 36?
	MOVEI	PT,5		;YES - MAKE ADJUSTMENT

	SIZEF			;FIND THE SIZE OF THE FILE
	  JRST	SETERC
	IMUL	T2,PT		;CONVERT BYTE COUNT INTO CHARACTER COUNT
	MOVEM	T2,FILSIZ	;AND SAVE IT
	MOVEM	T3,FILBSZ	;AND BLOCK COUNT

	CAIL	T3,777-BUFBLK	;IS FILE TOO BIG?
	JRST	SSZERR		;YES - TOUGH LUCK
	HRLZ	T1,INJFN	;NO - READ IN THE ENTIRE FILE
	MOVE	T2,[400000,,BUFBLK]
	MOVE	T4,T3		;SAVE NUMBER OF PAGES IN FILE
	ADD	T3,[PM%CNT+PM%RD+PM%CPY]
	PMAP

	SETO	T1,		;SNIFF ALL PAGES SO THEY'LL BE LOCALLY COPIED
	MOVEI	T2,BUFFER
SETF1A:	ANDM	T1,(T2)		;WRITE INTO A PAGE
	ADDI	T2,1000		;GO TO NEXT PAGE
	SOJG	T4,SETF1A	;LOOP THROUGH ALL PAGES
	MOVE	T1,INJFN	;DONE WITH THE INPUT FILE - GET RID OF IT
	HRLI	T1,(CO%NRJ)	;BUT KEEP THE JFN FOR THE BACKUP FILE
	CLOSF			;CLOSE THE FILE
	  JFCL
	MOVE	T1,FILSIZ	;GET BYTE SIZE
	IDIVI	T1,5		;CONVERT TO WORDS
>
	MOVE	EN,[010700,,BUFFER]
	ADD	EN,T1		;SET UP POINTER TO END OF FILE
	TRO	F,GFL		;NOTE THAT A FILE HAS BEEN SET UP
	TLZ	F,FLG!PCM	;CLEAR EXTENSION AND MARK FLAGS
	SKIPN	DISPTR		;WANT TO USE PRE-SET POINTERS?
	PUSHJ	P,PRESET	;YES - SET THEM UP
	SETZM	EEEPTR		;CLEAR FREE-EXTENSION POINTER
IFN FTJOUR,<
	TLNE	TM,JRW		;WANT TO WRITE A JOURNAL?
	PUSHJ	P,JRNSTT	;YES - START IT UP
>
	SKIPN	(EN)		;GOT A WORD ENTIRELY OF NULLS?
	SOJA	EN,.-1		;YES - BACK UP OVER IT
	CAMN	EN,[010700,,BUFFER-1] ;IF THERE'S NOTHING IN THE BUFFER,
	AOJA	EN,SETCR2	      ;PUT IN A FREE CARRIAGE RETURN
	MOVE	T1,EN		;GET POINTER TO END OF FILE
	AOJA	EN,SETCR0	;MAKE SURE FILE ENDS WITH A CRLF

SETCR:	ADD	T1,[70000,,0]	;BACK UP END POINTER A NOTCH
	JUMPGE	T1,.+2
	SUB	T1,[430000,,1]
SETCR0:	LDB	T2,T1		;GET CHARACTER
	JUMPE	T2,SETCR	;SKIP IF NULL
	CAIE	T2,12		;ELSE GOT A LINEFEED?
	JRST	SETCR2		;NO - GO ADD A CRLF
	ADD	T1,[70000,,0]	;YES - SEE IF IT'S PRECEDED BY A <CR>
	JUMPGE	T1,.+2		;BACK UP A NOTCH
	SUB	T1,[430000,,1]
	LDB	T2,T1		;GET CHARACTER
	CAIN	T2,15		;GOT A <CR>
	JRST	SETRDO		;YES - O.K.
				;NO - FALL TO ADD A CRLF
SETCR2:	MOVE	T1,[BYTE (7) 15,12] ;GET A <CRLF>
	MOVEM	T1,1(EN)	;SAVE AS LAST WORD OF FILE
	AOJA	EN,SETRDO	;NOW GO CHECK FOR LINE NUMBERS

;NOW CHECK READ-WRITE STATUS. IF THE FILE ACCESS DOES NOT PERMIT WRITING,
;IT'S READ-ONLY. ELSE USE THE SWITCH THE USER GAVE IN THE SET-FILE COMMAND.
;ELSE IT'S WRITEABLE.

;IF THE FILE IS WRITEABLE, SEE IF LOW ORDER BITS ARE ON IN FILE WORDS: IF
;SO, FILE HAS LINE NUMBERS OR IS NOT TEXT. IF THE USER WANTS TO STRIP LINE
;NUMBERS, DO SO AND CONTINUE. ELSE SET READ-ONLY FLAG AND WARN THE USER.

;(GOSH, YOU WONDER HOW ANY FILE ENDS UP WRITEABLE)

SETRDO:
IFE TOPS10,<
	TLNE	DO,100000	;IS THIS THE END OF A SAVE (COMMAND OR INC'L)?
	JRST	SETWIN		;YES - IT CAN'T BE READ-ONLY
>
	TRNE	F,RDO		;IS FILE ALREADY READ-ONLY?
	JRST	SETRD5		;YES - NO FURTHER CHECKING IS NECESSARY
	SKIPG	T1,SAVEAC+11	;DID USER GIVE A READ OR WRITE SWITCH?
	JRST	SETRD3		;YES - LET IT OVERRIDE ANYTHING ELSE
	JRST	SETRD4		;NO - SKIP THIS

SETRD3:	JUMPL	T1,SETRD5	;IF USER GAVE READ, SET READ-ONLY
SETRD4:	MOVE	T2,BUFFER	;GET FIRST WORD OF BUFFER
	TRNN	T2,1		;IS THE LINE NUMBER FLAG ON?
	JRST	SETWIN		;NO - GO CHECK FOR A WINDOW
	SKIPE	STRFLG		;YES - WANT TO STRIP LINE NUMBERS?
	JRST	SETSTP		;YES - DO SO (RETURN TO SETRD6)
	SKIPA	T1,[[ASCIZ /######Line numbers - read only/]]
SETRD5:	MOVEI	T1,[ASCIZ /######File cannot be modified/]
	TRO	F,RDO		;MARK FILE AS READ ONLY
SETRD6:	PUSHJ	P,ERRDSP	;DISPLAY THE MESSAGE

;NOW SEE IF WINDOWING IS IN EFFECT. IF SO, CHANGE WINDOWS (MAYBE).

SETWIN:	TLNE	TM,WDW		;WANT WINDOWING,
	SKIPE	CRRFLG		;  AND WANT TO REPLACE THE ALTERNATE FILE?
	JRST	SETCUR		;NOT BOTH - JUST DISPLAY THE FILE
	SKIPE	HOMPOS		;BOTH - IN TOP WINDOW?
	JRST	[SETZ  T3,	;NO - MOVE TO TOP
		 EXCH  T3,HOMPOS
		 MOVEI T1,"^"	;GET UPWARD-POINTING SEPARATOR
		 SETZM CPG(TM)	;MAKE CLEAR-TO-EOP NOT WORK
		 SETZM ILN(TM)	;AND INSERT-LINES
		 SETZM DLN(TM)	;AND DELETE-LINES
		 SOJA  T3,SETWN1]
	MOVE	T3,LPP(TM)	;YES - GET CURRENT SCREEN LENGTH
	MOVEM	T3,HOMPOS	;SAVE AS ROW POSITION OF HOME
	SETO	T3,		;PUT SEPARATOR ON LINE ABOVE HOME
	DMOVE	T1,SAVILN	;RESTORE INSERT- AND DELETE-LINE SEQUENCES
	MOVEM	T1,ILN(TM)
	MOVEM	T2,DLN(TM)
	MOVE	T1,SAVCPG	;RESTORE CLEAR-TO-EOP SEQUENCE
	MOVEM	T1,CPG(TM)
	MOVEI	T1,"v"		;GET DOWNWARD-POINTING SEPARATOR
SETWN1:	PUSHJ	P,WINSEP
	SKIPE	WINDIS		;IS THERE A DISPLAY IN BOTH WINDOWS?
	SETOM	DSPFLG		;YES - DON'T DISPLAY NOW
	SETOM	WINDIS		;EITHER WAY, DON'T DISPLAY NEXT TIME
SETCUR:	MOVS	T1,[OLDSPC,,SVASPC]
	SKIPE	CRRFLG		;WANT TO REPLACE THE CURRENT (NOT OLD) FILE?
	BLT	T1,OLDSPC+SPCSIZ+2 ;YES - COPY THE OLD STUFF BACK
	SETZM	CRRFLG		;CLEAR USE CURRENT FILE FLAG
	SETZM	CHGSPC		;NOTE THAT FILESPECS AREN'T CHANGED (YET)
	SKIPE	OUTFLG		;NEED TO FINISH UP AN /OUT: SWITCH?
	PUSHJ	P,OUTSET	;YES - CHANGE THE FILESPECS TO THOSE IN NEWFIL
	TRZ	F,200		;MAKE SURE CREATE-FILE FLAG IS OFF
	LDB	T1,DISPTR	;IS THE DISPLAY PTR AT THE START OF LINE?
	MOVEI	T4,1
	CAIE	T1,12
	PUSHJ	P,ADVDPT	;NO - MOVE TO THE START OF THE NEXT LINE
IFE TOPS10,<
	TLNE	DO,100000	;IS THIS THE END OF A SAVE (COMMAND OR INC'L)?
	JRST	SETREP		;YES - DON'T RE-DISPLAY IT
>
	SKIPN	CHGSPC		;HAVE FILESPECS CHANGED,
	TLNE	F,SMF		;  OR ARE THE TWO FILES THE SAME?
	JRST	NEWFIL+1	;EITHER - START EDITING THE SAME FILE
	JRST	NEWFIL		;NEITHER - SET UP NEW FILE

IFE TOPS10,<
;HERE WHEN A SAVE (INCREMENTAL OR THE SAVE COMMAND) WAS DONE. INCSAV WENT
;TO SET-FILE TO GET THE FILE BACK. THIS CODE REPAIRS THE SCREEN WITHOUT
;RE-DISPLAYING IT AND MAKES SURE THE FILE IS STILL MARKED "CHANGED".

SETREP:	TLO	F,CHG		;NOTE THAT THE FILE HAS BEEN CHANGED
	TRZ	F,RDO		;AND IT'S NOT READ-ONLY
	PUSHJ	P,FIXBLN	;REPAIR THE BOTTOM LINE OF THE SCREEN
	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR
	JRST	LOOP		;AND GO GET A NEW COMMAND
>
SSZERR:
IFE TOPS10,<
	MOVE	T1,INJFN	;CLOSE THE NEWLY-GTJFN-ED FILE
	CLOSF
	  JFCL
>
	MOVEI	T1,[ASCIZ /#####File is too large to edit/]
	JRST	STFERR

;HERE TO STRIP THE LINE NUMBERS FROM THE FILE (IF /STRIP SET)
;THE TAB AFTER THE LINE NUMBER HAS TO BE STRIPPED TOO

SETSTP:	MOVEI	PT,BUFFER	;POINT TO START OF BUFFER
	SETZ	T2,		;GET A ZERO TO SAVE
	MOVE	T3,[003777,,-1]	;AND THE ANTI-TAB MASK
SETST1:	MOVE	T1,(PT)		;GET A WORD FROM THE BUFFER
	TRNN	T1,1		;IS THE LINE NUMBER BIT ON?
	JRST	SETST2		;NO - LEAVE IT ALONE
	MOVEM	T2,(PT)		;YES - ZERO THE WORD IN THE BUFFER
	ANDM	T3,1(PT)	;ZERO THE FOLLOWING TAB, TOO
SETST2:	CAIG	PT,(EN)		;AT END OF BUFFER?
	AOJA	PT,SETST1	;NO - LOOP
	MOVEI	T1,[ASCIZ /#######Stripping line numbers/]
	JRST	SETRD6		;YES - DONE

;HERE IF NO PARAMETER WAS TYPED - SET UP PREVIOUS FILE, AND SAVE PRESENT
;ONE AS NEW PREVIOUS ONE

SETNPM:	SKIPN	OLDSPC		;ARE THERE OLD FILE SPECS?
	JRST	SETERX		;NO - ERROR
	TLO	DO,400000	;MAKE SETNPM LOOK DIFFERENT FROM SETFIL
IFN TOPS10,<
	MOVEI	PT,FILBLK	;POINT TO NAME OF CURRENT FILE
>
	SETZM	CRRFLG		;MAKE SURE USE-CURRENT-FILE FLAG IS CLEAR
	MOVEI	T4,FILSPC	;POINT TO SPECS (BOTH FOR SAVFIL)
	TLNE	F,SMF		;ARE FILE AND ALTERNATE FILE THE SAME?
	JRST	SETNP0		;YES - DON'T SAVE
	SKIPE	FILSPC		;IS THERE AN ACTIVE FILE?
	PUSHJ	P,SAVFIL	;YES - SAVE IT NOW
SETNP0:	SKIPE	PT,MFLPTR	;GOT MORE FILES IN nnnSED.TMP?
	PUSHJ	P,SETMFL	;YES - SET NEXT ONE UP AS ALTERNATE
	MOVEI	T1,SPCSIZ-1
SETNP1:	MOVE	T2,FILSPC(T1)
	EXCH	T2,OLDSPC(T1)
	MOVEM	T2,FILSPC(T1)
	SOJGE	T1,SETNP1
IFE TOPS10,<
	DMOVE	T1,SAVEXP	;GET SAVED EXTENSION AND ITS POINTER
	EXCH	T1,EXTPTR	;SWAP WITH THE CURRENT ONES
	EXCH	T2,EXTTBL
	DMOVEM	T1,SAVEXP
>
	HRL	RW,CM		;SWAP ROW AND COLUMN POSITIONS
	EXCH	RW,SAVERW
	HLRZ	CM,RW
	HRRZ	RW,RW
	MOVE	T1,DISPTR	;SWAP DISPLAY POINTER
	EXCH	T1,SAVEDP
	MOVEM	T1,DISPTR
	EXCH	SL,SAVESL	;SET UP SLIDE
	MOVE	T1,SAVEFG	;GET THE ALTERNATE FILE'S FLAGS
	MOVEM	F,SAVEFG	;SAVE CURRENT FILE'S FLAGS
	TRZ	F,RDO		;USE CURRENT FLAGS, BUT ALTERNATE'S READ-ONLY
	ANDI	T1,RDO
	OR	F,T1
	TRNN	F,RDO		;IS THE ALTERNATE FILE READ-ONLY?
	TDZA	T1,T1		;NO - SAY IT'S WRITEABLE
	SETO	T1,		;YES - MARK AS READ-ONLY
	MOVEM	T1,SAVEAC+11	;SAVE THE READ-WRITE FLAG
	SKIPN	DISPTR		;NEED TO PARSE SPECS (FROM .TMP)?
	PUSHJ	P,PARSFN	;YES - DO SO
IFN TOPS10,<
IFE FTSFD,<
	MOVE	T1,FILFIL+1	;SET UP THIS FILE'S PPN
	MOVEM	T1,FILPPN
>>
IFE TOPS10,<
	SETOM	SAVEAC+12	;FLAG FILES AS NOT SAME, IF THEY'RE NOT SAME
>
	TLO	F,XPC!XPL!XPB	;NO POINTERS ARE VALID
	TLZ	F,FNC!FLG	;CLEAR FLAG FROM PARSEF AND FENCE
	TLNN	F,SMF		;ARE FILE AND ALTERNATE FILE THE SAME?
	JRST	SETFL1		;NO - GO SET UP THAT FILE
	SKIPN	DISPTR		;NEED TO SET UP PRE-SET POINTERS?
	PUSHJ	P,PRESET	;YES - DO SO
	JRST	SETWIN		;DON'T LOOK FILE UP; JUST USE IT

;HERE TO CREATE FILE. WRITE FIRST LINE IN IT, CLOSE IT,
;AND PRETEND IT WAS THERE ALL THE TIME
;RETURNS +1 ON FAILURE, +2 ON SUCCESS

IFN TOPS10,<
SETCRE:	MOVE	T1,FILBLK+1	;MAKE SURE DEVICE IS RIGHT
	MOVEM	T1,GENBLK+1
	OPEN	5,GENBLK	;OPEN A DUMP MODE OUTPUT FILE ON CHANNEL 5
	  POPJ	P,		;OOPS - CAN'T
	MOVSI	T1,'DSK'	;RESTORE GENBLK'S GENERALITY
	MOVEM	T1,GENBLK+1
	ENTER	5,FILFIL
	  POPJ	P,
	HLLZS	FILFIL+3
	SETZM	FILFIL+4
	SETZM	FILFIL+5
IFN FTSFD,<
	SETZM	FILFIL+1
>
IFE FTSFD,<
	MOVE	T1,FILPPN	;PUT USER'S PPN BACK IN
	MOVEM	T1,FILFIL+1
>
	OUTPUT	5,NEWCCL	;OUTPUT CHEERY MESSAGE
	RELEAS	5,		;CLOSE THE FILE
>
IFE TOPS10,<
SETCRE:	HRROI	T2,FILSPC	;SET UP NEW FILE FOR OUTPUT
	PUSHJ	P,SETOUT
	JUMPE	T1,CPOPJ	;GIVE ERROR RETURN IF FILE CAN'T BE CREATED
	MOVE	T2,[POINT 7,NEWMSG]
	SETZ	T3,
	SOUT			;WRITE STARTING MESSAGE TO NEW FILE
	MOVEI	T2,15		;END IT ALL WITH A <CR>
	BOUT
	MOVEI	T2,12
	BOUT
	CLOSF			;COMPLETE THE FILE
	  POPJ	P,		;OOPS - GIVE ERROR RETURN
>
	SETZM	SAVEAC+11	;SUCCESS - FORCE THE FILE TO BE WRITEABLE
	TRZ	F,RDO		;DITTO
	AOS	(P)		;RETURN SUCCESS
	POPJ	P,		;RETURN TO LOOK UP THE FILE FOR EDITING

;HERE ON A FILE-NOT-FOUND ERROR. MAY WANT TO LOOK FOR OTHER FILES

IFE TOPS10,<
SETERC:	MOVE	T1,INJFN	;TRY TO OPEN THE FILE FROZEN
	MOVEI	T2,OF%RD+OF%WR
	OPENF
	  TROA	F,RDO		;NOPE - TRY TO GET THE FILE READ-ONLY
	JRST	SETF12		;YES - CONTINUE
	MOVE	T1,INJFN	;TRY TO OPEN THE FILE THAWED, READ-ONLY
	MOVEI	T2,OF%THW+OF%RD+OF%DUD
	OPENF
	  SKIPA	T1,INJFN	;NOPE - TRY FROZEN, READ-ONLY
	JRST	SETF12		;YES - CONTINUE
	MOVEI	T2,OF%RD
	OPENF
	  SKIPA	T1,INJFN	;NOPE - CLOSE THE NEWLY-GTJFN-ED FILE
	JRST	SETF12		;SUCCESS - CONTINUE SETTING UP THE FILE
	CLOSF			;CLOSE, AND FALL INTO ERROR CODE
	  JFCL
	TRZ	F,RDO		;CLEAR READ-ONLY FLAG
>
SETERR:	TRZN	F,CRE		;REALLY WANT TO CREATE?
	JRST	SETER0		;NO - IT'S A REAL ERROR
	PUSHJ	P,SETCRE	;YES - CREATE THE FILE
	  JRST	SETER3		;CREATE FAILED - ERROR
	JRST	SETFL1		;O.K. - NOW LOOK IT UP

SETER0:	SKIPE	EEEPTR		;WORKING ON A LIST OF EXT'S?
	JRST	SETER1		;YES - KEEP WORKING
IFN TOPS10,<
	SKIPE	FILFIL+3	;IS THERE A CURRENT EXTENSION?
	JRST	SETER2		;YES - IT'S A REAL ERROR
	TLO	F,FLG		;NO - TRY SOME USUAL EXTENSIONS
	MOVE	PT,[POINT 18,EXTTBL]
	HLLZ	T1,OLDFIL+3	;GET EXTENSION OF PREVIOUS FILE
	HLLM	T1,EXTTBL	;SAVE AS FIRST EXTENSION TO TRY
	JUMPN	T1,.+2		;DID PREVIOUS FILE HAVE AN EXTENSION?
	IBP	PT		;NO - SKIP OVER IT
	MOVEM	PT,EEEPTR	;SAVE EXTENSION POINTER
	HLRZ	T1,FILBLK+1	;GET DEVICE NAME
	CAIE	T1,'DSK'	;IS IT DISK?
	JRST	SETR1A		;NO - TRY USING DEVICE AS EXT, TOO

SETER1:	ILDB	T1,EEEPTR	;SET UP ANOTHER EXTENSION
	JUMPE	T1,SETER2	;UNLESS NONE LEFT, THEN ERROR
SETR1A:	HRLZM	T1,FILFIL+3
	JRST	SETFL1
>
IFE TOPS10,<
	SKIPN	T2,EXTPTR	;IS THERE A CURRENT EXTENSION?
	JRST	SETER2		;YES - IT'S A REAL ERROR
	SETOM	EEEPTR
	MOVEI	PT,EXTTBL
	SKIPN	T1,(PT)		;NO - IS FIRST EXT NULL?
	AOJA	PT,SETER1+1	;YES - SKIP IT
	JRST	SETER1+3	;NO - WORK WITH IT

SETER1:	MOVE	T2,EXTPTR	;GET POINTER TO WHERE TO STORE EXT
	SKIPN	T1,(PT)		;SET UP ANOTHER EXTENSION - ANY?
	JRST	SETER2		;NO - ERROR (AT LAST)
	MOVEI	T0,"."		;YES - PUT IN THE DOT
	DPB	T0,T2
	LSHC	T0,7		;GET AN EXTENSION CHARACTER
	IDPB	T0,T2		;SAVE IT
	JUMPN	T1,.-2		;LOOP THROUGH ALL CHARS
	IDPB	T1,T2		;SAVE A NULL AT THE END
	AOJA	PT,SETFL1	;TRY TO FIND THAT FILE
>
SETER3:	SKIPA	T1,[[ASCIZ /######Unable to create file/]]
SETER2:	MOVEI	T1,[ASCIZ /##########File not found/]
	SETZM	EEEPTR
	JRST	STFERR		;GO DISPLAY THE ERROR
SETERX:	MOVEI	T1,[ASCIZ /#########No alternate file/]
	JRST	ERROR
IFN TOPS10,<
SETERD:	MOVEI	T1,[ASCIZ /#####Access to file not allowed/]
	JRST	STFERR
>
;SUBROUTINE TO READ NEXT LINE OF STAT.TMP FILE INTO (T4 - FRAGGED)
;ENTER ALSO WITH PT/MFLPTR

SETMFE:	MOVE	T4,[POINT 7,OLDSPC] ;HERE AFTER SETERR - READ INTO ALT SPECS
	SETZM	SAVEDP		;CLEAR SAVED DISPLAY POINTER
	JRST	SETMF0		;CONTINUE

SETMFL:	SKIPE	MFLPT0		;GET HERE FROM SETMFB?
	JRST	SETMFC		;NO - CONTINUE
	MOVE	T1,SAVEAC	;YES - SET UP REAL MFLPT0
	MOVEM	T1,MFLPT0
	POPJ	P,		;AND DO NOTHING MORE

SETMFC:	SETZM	DISPTR		;CLEAR DISPLAY PTR SO SPECS WILL BE PARSED
	TLC	DO,600000	;CLEAR NPM AND SET INDIRECT FLAGS
	MOVE	T4,[POINT 7,FILSPC] ;POINT TO FILSPC BLOCK
SETMF0:	EXCH	PT,MFLPT0	;SAVE POINTER TO ALTERNATE SPECS
	MOVEM	PT,MFLPT1	;AND CURRENT SPECS
	MOVE	PT,MFLPT0	;GET CURRENT POINTER BACK
	PUSHJ	P,SETINF	;READ IN INDIRECT FILE
	TRZ	F,GFL		;CURRENT FILE IS NO LONGER AROUND
	PUSHJ	P,TMPGET	;READ NEW SPECS INTO CURRENT FILE AREA
	CAIGE	T1,"!"		;IS THERE AT LEAST A COMMENT ON THE NEXT LINE?
	SETZM	MFLPTR		;NO - FORGET THE POINTER
	POPJ	P,

;SUBROUTINE TO READ IN THE INDIRECT FILESPEC FILE

SETINF:	SETZ	T2,		;CLEAR T2 FOR TMPGET
	SKIPN	INDFLG		;IS FILE ALREADY HERE?
	POPJ	P,		;YES - NOTHING TO DO
	PUSHJ	P,SETIDI	;GO FIND THE TEMPORARY FILE
IFN TOPS10,<
	INPUT	5,SEDCCL	;READ STATUS INTO PICK BUFFER
	RELEAS	5,
>
IFE TOPS10,<
	MOVE	T2,[POINT 7,PIKBUF+PCBSIZ-400]
	SETZ	T3,		;READ THE FILE INTO THE PICK BUFFER
	SIN
	CLOSF			;CLOSE THE FILE
	  HALTF
>
	SETZM	INDFLG		;NOTE THAT FILE IS HERE
	POPJ	P,		;DONE

;HERE ON ENTER SET-FILE, TO SET TO THE PREVIOUS ONE ON THE LIST
;CONTROL GOT HERE FROM PEEL.F, WHICH WAS CALLED BY SETFIL
;CONTROL PASSES TO SETNPM, NOT BACK TO SETFIL. VERY UNSTRUCTURED.

SETMFB:	MOVEI	T1,SETNPM	;FAKE RETURN TO SETNPM
	MOVEM	T1,(P)
	MOVE	PT,MFLPT1	;GET POINTER TO CURRENT FILE
	CAMN	PT,[POINT 7,PIKBUF+PCBSIZ-400]
	POPJ	P,		;IF AT START, JUST TOGGLE
	MOVEM	PT,SAVEAC	;SAVE TO PUT IN MFLPT0 LATER
	SETZ	T1,		;CLEAR ALTERNATE PTR AS A FLAG
	EXCH	T1,MFLPT0
	MOVEM	T1,SAVEAC+1
	PUSHJ	P,SETINF	;SET UP THE INDIRECT FILE
STMFB1:	ADD	PT,[70000,,0]	;BACK UP ONE CHARACTER
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T1,PT		;GET THE CHARACTER
	JUMPE	T1,.+3		;END OF LINE IF NULL
	CAIE	T1,12		;END OF PREVIOUS LINE?
	JRST	STMFB1		;NO - KEEP LOOPING
	MOVEM	PT,MFLPT1	;SAVE POINTER TO (MAYBE) CURRENT FILE
	ILDB	T1,PT		;GET THE FIRST CHARACTER OF THE LINE
	MOVE	PT,MFLPT1	;GET THE REAL POINTER BACK
	CAIE	T1,";"		;IS THE LINE A COMMENT?
	CAIN	T1,"!"
	JRST	STMFB1		;YES - BACK UP ONE MORE LINE

	MOVE	T4,[POINT 7,OLDSPC] ;NO - POINT TO OLD FILESPEC BLOCK
	SETZM	SAVEDP		;CLEAR DISPLAY PTR SO SPECS WILL BE PARSED
	PUSHJ	P,TMPGET	;READ NEW SPECS INTO ALTERNATE FILE AREA
	MOVE	T1,SAVEAC+1	;GET REAL POINTER TO NEXT FILE
	MOVEM	T1,MFLPTR	;SAVE IT
	POPJ	P,		;RETURN TO SET UP THE FILE

;HERE ON "@FILSPC" TO USE GIVEN FILE AS A LIST OF FILES TO EDIT

SETIND:	MOVE	T1,SEDFIL	;SAVE ORIGINAL .TMP FILE NAME
	SKIPN	SAVSED		;UNLESS IT'S SAVED ALREADY
	MOVEM	T1,SAVSED
	MOVE	PT,[POINT 7,FILSPC]
	MOVE	T3,[POINT 7,SEDFIL]
IFN TOPS10,<
	MOVEI	T4,'DIR'	;GET DEFAULT EXTENSION
>
IFE TOPS10,<
	MOVE	T4,[ASCII /DIR/]
>
	PUSHJ	P,PARSFX	;PARSE THESE FILE SPECS
	MOVEI	T4,OLDSPC	;PREPARE TO SAVE FILE
IFN TOPS10,<
	MOVEI	PT,OLDBLK
>
	TRNN	F,GFL		;HAS A FILE BEEN SET UP?
	JRST	.+3		;NO - DON'T SAVE
	SKIPE	OLDSPC		;IS THERE AN ACTIVE FILE?
	PUSHJ	P,SAVFIL	;YES - SAVE IT
	PUSHJ	P,SETIDI	;LOOK UP INDIRECT FILE
	PUSHJ	P,REDTM0	;TREAT @FILE JUST LIKE nnnSED.TMP
	TLZ	F,SMF		;FILES CAN'T BE THE SAME
	TLO	DO,200000	;NOTE THAT AN INDIRECT FILE IS BEING SET UP
	JRST	INDIRE

SETIDI:	HRROI	T2,SEDFIL
	PUSHJ	P,SETINP	;FIND THE FILE
	JUMPN	T1,PIKFRG	;IF O.K., CHECK PICK BUFFER AND RETURN
	MOVEI	T1,[ASCIZ /######Indirect file not found/]
	JRST	STFERR		;TREAT LIKE A NORMAL BAD FILE

;**********************************************************************
;HERE TO ENTER A PARAMETER TO A COMMAND

ENTERA:	TLOE	F,ENT		;SAY ENTER TYPED - WAS IT ALREADY?
	JRST	ENTHLP		;YES - MAYBE GIVE SOME HELP
	MOVE	T1,[POINT 7,PARBUF] ;POINT TO START OF PARAMETER BUFFER
	MOVEM	T1,PARPTR
	DMOVEM	RW,SAVPOS	;SAVE POSITION, IN CASE OF CURSOR MOVE
	PUSHJ	P,MRKCUR	;MARK THE CURRENT CURSOR POSITION
	TLO	F,FBL		;NOTE THAT BOTTOM LINE IS FRAGGED
ENTERM:	PUSHJ	P,ENTRMK	;NO - MAKE THE MARK ON THE BOTTOM LINE
	PUSHJ	P,PUTTYP	;DISPLAY IT NOW
	JRST	LOOP		;AND GO GET A NEW COMMAND

ENTER0:	DMOVEM	RW,SAVPOS	;SAVE POSITION, IN CASE OF CURSOR MOVE
	PUSHJ	P,MRKCUR	;MARK THE CURRENT CURSOR POSITION
	TLO	F,FBL		;NOTE THAT BOTTOM LINE IS FRAGGED
ENTRMK:	TRNE	F,XCT!XBN	;EXECUTING?
	POPJ	P,		;YES - DO NOTHING
	PUSHJ	P,CBOTOM	;MOVE TO BOTTOM OF SCREEN
ENTMK1:	PUSHJ	P,PROTON	;TURN HIGHLIGHTING ON
	MOVEI	T1,">"		;PUT UP ENTER MARK
	IDPB	T1,TY
	JRST	PROTOF		;TURN OFF HIGHLIGHTING AND RETURN

;SUBROUTINE TO MARK CURRENT CURSOR POSITION
;NOTE: EXPECTS CALLER TO CALL PUTTYP TO OUTPUT ALL THIS

MRKCUR:	PUSHJ	P,MAKCPT	;MAKE MARK AT CURSOR POSITION - MAKE POINTER
	MOVE	T2,CHRPTR	;GET CURSOR POINTER
	MOVEM	T2,SAVCPT	;SAVE FOR AFTER ENTER
	TRNE	F,XCT!XBN	;EXECUTING?
	POPJ	P,		;YES - DONE NOW
	CAIGE	T3," "		;POINTING TO A CONTROL CHARACTER?
	JRST	[CAIE  T3,15	;YES - GOT A <CR>,
		 CAIN  T3,11	;  OR A TAB?
		 MOVEI T3," "	;YES - USE A SPACE INSTEAD
		 JRST  .+1]
	MOVEM	T3,CHRCUR	;SAVE CHARACTER FOR LATER
	TLNE	TM,MRK		;WANT TO PUT UP A SPECIAL MARK?
	JRST	[MOVE T1,MAR(TM) ;YES - GET THE MARK
		 IDPB T1,TY	;SAVE IT
		 POPJ P,]	;AND DISPLAY IT
	CAIGE	T3," "		;GOT A CONTROL CHARACTER?
	POPJ	P,		;YES - IT'S ALREADY REVERSED
	PUSHJ	P,PROTON	;TURN PROTECTION ON
	IDPB	T3,TY
	JRST	PROTOF		;TURN OFF PROTECTION AND RETURN

;HERE ON ENTER ENTER. IF A PARAMETER WAS TYPED, SAVE A 177 CHARACTER
;ELSE PREPARE TO GIVE HELP (UNLESS NO HELP [NHP] FLAG IS SET)

ENTHLP:	MOVE	T1,[POINT 7,PARBUF]
	TRNN	F,NHP!CMV	;REALLY DON'T WANT HELP, DOING CURSOR MOVEMENT,
	CAME	T1,PARPTR	;  OR HAS PART OF A PARAMETER BEEN TYPED?
	JRST	ENTHLD		;EITHER - SAVE A DELIMITER CHARACTER
HELPR0:	MOVEI	DO,1000		;NEITHER - NOTE THAT HELP IS BEING GIVEN
ENTHL0:	PUSHJ	P,PROTON	;SAY HELP IS ON THE WAY
	MOVEI	T1,[ASCIZ /Type any command to get help for it /]
	PUSHJ	P,PUTSTG
ENTH0A:	MOVEI	T1,[ASCIZ /(or G to get out): /]
	PUSHJ	P,PUTSTG
	PUSHJ	P,PROTOF
	PUSHJ	P,PUTTYP	;TYPE OUT THE MESSAGE
	TLO	F,FBL		;BOTTOM LINE IS FRAGGED
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKOALL	;ECHO ON; BREAK ON EVERYTHING
>>
	GETCHR			;READ A CHARACTER FROM THE TERMINAL IN T1
	CAIE	T1,"G"		;GOT A "G"?
	CAIN	T1,"g"
	JRST	ENTHLE		;YES - END OF HELP
	CAIL	T1," "		;SOME CONTROL CHARACTER?
	JRST	HLPERR		;NO - CAN'T GIVE HELP

ENTHL2:	ADD	T1,ITB(TM)	;GET OFFSET IN TERMINAL TABLE
	SKIPL	T1,(T1)		;IS IT A NORMAL COMMAND?
	JRST	.+3		;YES - CONTINUE
	PUSHJ	P,SUBTAB	;NO - READ MORE CHARACTERS
	  JRST	HLPERR		;ILLEGAL - TRY AGAIN
	TLNE	TM,LSD		;ARE LINEFEED AND CURSOR-DOWN ALIKE?
	JRST	[CAIN  T1,12	;YES - GOT A LINEFEED?
		 MOVEI T1,34	;YES - IT'S REALLY A CURSOR-DOWN
		 JRST  .+1]
ENTHL3:	TRNE	T1,200000	;IS THE COMMAND AN EXECUTE BUFFER POINTER?
	PUSHJ	P,HLPXCT	;YES - FIND WHICH COMMAND IT IS, IF IT IS
	TLZ	F,ENT		;SAY NO LONGER ENTERING A PARAMETER
IFE NEWTAB,<
	CAIN	T1,"K"-100	;CONVERT OLD TABLE'S COMMANDS
	JRST	[MOVEI T1,"V"-100
		 JRST  ENTHLO]
	CAIN	T1,"L"-100
	MOVEI	T1,"K"-100
	CAIN	T1,"U"-100
	MOVEI	T1,"L"-100
	CAIN	T1,"N"-100
	MOVEI	T1,"U"-100
	CAIN	T1,"V"-100
	MOVEI	T1,"N"-100
ENTHLO:
>
	MOVE	PT,T1		;SAVE INDEX OF COMMAND TO HELP WITH
IFN TOPS10,<
	MOVSI	T2,'HLP'	;LOOK FOR THE HELP FILE ON THE HELP DEVICE
	MOVEM	T2,GENBLK+1
>
IFE TOPS10,<
	CAIN	T1,15		;GOT A CARRIAGE RETURN?
	PBIN			;YES - BURN THE LINEFEED THAT FOLLOWS IT
>
	HRROI	T2,HLPFIL
	PUSHJ	P,SETINP	;SET UP HELP FILE
	JUMPE	T1,NHPERR	;IF NOT THERE, SCREAM
	PUSHJ	P,PIKFRG	;SAVE PICK BUFFER IF IT'S ABOUT TO BE FRAGGED
IFN TOPS10,<
	USETI	5,1(PT)		;READ BLOCK THAT COMMAND IS IN
	INPUT	5,HLPCCL	;READ IT INTO THE END OF THE PICK BUFFER
	RELEAS	5,		;GET RID OF FILE
	PUSHJ	P,CLRALL	;GO HOME AND CLEAR SCREEN
	PUSHJ	P,PUTTYP	;(NOW)
IFE FTNIHO,<
	OUTSTR	PIKBUF+PCBSIZ-200 ;OUTPUT THE HELP
>
IFN FTNIHO,<
	MOVE	T0,[POINT 7,PIKBUF+PCBSIZ-200]
	PUSHJ	P,PUTTYH	;OUTPUT HELP THE HARD WAY
>
>
IFE TOPS10,<
	PUSH	P,T1		;SAVE JFN
	MOVE	T1,PT		;CONVERT COMMAND TO PAGE AND POSITION
	SETZ	T2,
	LSHC	T1,-2
	ROT	T2,2
	MOVE	PT,T2		;SAVE POSITION IN PAGE
	LSH	PT,7

	HRL	T1,(P)		;READ IN THE RIGHT FILE BLOCK
	MOVE	T2,[400000,,777]
	MOVE	T3,[PM%CNT+PM%RD+1]
	PMAP
	PUSHJ	P,CLRALL	;GO HOME AND CLEAR SCREEN
	PUSHJ	P,PUTTYP	;(NOW)
	MOVEI	T1,777000	;OUTPUT THE HELP
	ADD	T1,PT
	PSOUT
	SETO	T1,		;UN-MAP THE BLOCK
	MOVE	T2,[400000,,777]
	MOVE	T3,[PM%CNT+1]
	PMAP

	POP	P,T1		;GET JFN AGAIN
	CLOSF			;CLOSE THE FILE
	  HALTF
>
	PUSHJ	P,CBOTOM
	JRST	ENTHL0		;LOOP TO GET NEW OPTION

ENTHLE:
IFE TOPS10,<
IFN FTECHO,<
	PUSHJ	P,EKONPT	;ECHO OFF; BREAK ON NON-PRINTING CHARACTERS
>>
	TLNN	F,ENT		;HAS HELP BEEN GIVEN?
	JRST	DISALL		;NO - REDISPLAY THE ENTIRE SCREEN
	PUSHJ	P,ERASPM	;YES - JUST FIX BOTTOM LINE
	JRST	DISCUR		;RE-POSITION CURSOR, AND LOOP

HLPERR:	CAIN	T1,177		;RUBOUT?
	JRST	[SETO T1,	;YES - GIVE HELP AFTER ALL
		 JRST ENTHL2]
	MOVEI	T1,[ASCIZ /Illegal command. Try again /]
HLPER1:	PUSHJ	P,PUTBTM	;OUTPUT MESSAGE
	JRST	ENTH0A		;AND TRY AGAIN

;HERE IF THE COMMAND IS REALLY AN EXECUTE BUFFER - GIVE HELP IF IT'S ONE
;COMMAND LONG, ELSE ERROR

HLPXCT:	ANDI	T1,77		;KEEP ONLY GOOD INDEX BITS
	MOVE	T2,XCTADR(T1)	;GET POINTER TO THIS BUFFER
	ILDB	T1,T2		;GET FIRST CHARACTER FROM BUFFER
	JUMPE	T1,HLXERR	;ERROR IF NULL
	CAIN	T1,"^"		;SPECIAL CHARACTER FLAG?
	JRST	[ILDB T1,T2	;GET COMMAND FROM EXECUTE BUFFER
		 CAIG T1,37	;IS IT A REAL COMMAND?
		 JRST HLXERR	;NO (AN EXECUTE CONSTRUCT) - CAN'T HELP
		 JRST .+1]
	ILDB	T0,T2		;GET NEXT COMMAND
	JUMPE	T0,CPOPJ	;IF THERE'S ONLY ONE COMMAND GO USE IT
HLXERR:	MOVEI	T1,[ASCIZ /Can't help with an execute buffer. Try again /]
	JRST	HLPER1		;OUTPUT THE MESSAGE AND ASK FOR MORE HELP

NHPERR:	MOVEI	T1,[ASCIZ /########No help file. Sorry./]
	JRST	ERROR

;HERE TO SAVE A DELIMITER CHARACTER (177) IN THE PARAMETER BUFFER
;(USER TYPED ENTER WITHIN A PARAMETER)
;DELIMITER IS IGNORED WHILE PARSING UNLESS THE COMMAND IS SUBSTITUTE

ENTHLD:	CAME	T1,PARPTR	;HAS ANYTHING BEEN TYPED,
	TRNE	F,CMV		;  OR DOING CURSOR MOVEMENT?
	JRST	LOOP		;YES - NOTHING TO DO
	MOVEI	T2,177		;GET THE DELIMITER CHARACTER
	LDB	T1,PARPTR	;GET LATEST PARAMETER CHARACTER TYPED
	CAIN	T1,177		;IS IT A DELIMITER?
	JRST	LOOP		;YES - DON'T ALLOW IT TWICE IN A ROW
	IDPB	T2,PARPTR	;NO - SAVE THE DELIMITER
	PUSHJ	P,ENTMK1	;PUT IN ANOTHER MARK
	PUSHJ	P,PUTTYP	;TYPE IT OUT AND GET A NEW COMMAND
	JRST	LOOP

;SUBROUTINE TO SEE IF PICK BUFFER WILL BE FRAGGED, AND SAVE IT IF SO
;PRESERVES T1
;@@ well, for now it just invalidates the buffer

PIKFRG:	TRNN	F,POV		;IS PICK BUFFER SAFELY ON DISK,
	SKIPN	T2,PIKCNT	;  OR IS IT NOT LOADED?
	POPJ	P,		;NOT LOADED OR ON DISK - O.K.
	CAIL	T2,(5*(PCBSIZ-400)) ;WILL TAIL OF BUFFER GET FRAGGED?
	SETZM	PIKCNT		;YES - PRETEND PICK BUFFER IS EMPTY
	POPJ	P,		;DONE

;**********************************************************************
;HERE TO ROLL FORWARD A GIVEN NUMBER OF PAGES (THE EASY WAY)

ROLFWP:	MOVE	T4,ROLPGS	;SET UP LAST TIME'S ROLL AS NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET LINES TO ROLL
	MOVEM	T4,ROLPGS	;SAVE AS NEW NOMINAL
	PUSHJ	P,RESTPM	;ERASE PARAMETER FIRST
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
RFPNPM:	MOVE	T4,ROLPGS	;SET UP LAST TIME'S ROLL AS NOMINAL
	IMUL	T4,LPP(TM)	;GET NUMBER OF LINES TO ROLL
	TLNE	TM,WDW		;IN A WINDOW?
	SUB	T4,ROLPGS	;YES - DO ONE LINE FEWER
	MOVEM	T4,ROLLS	;SAVE AS PARM TO ROLFW
	PUSHJ	P,ROLFW		;GO DO THE ROLL
RFPEND:	MOVEI	T1,1
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T1,ROLPGS	;YES - SET IT BACK TO ONE
	JRST	LOOP		;THEN GET ANOTHER COMMAND

;HERE TO ROLL BACKWARD A GIVEN NUMBER OF PAGES (ALSO THE EASY WAY)

ROLBKP:	MOVE	T4,ROLPGS	;SET UP LAST TIME'S ROLL AS NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET LINES TO ROLL
	MOVEM	T4,ROLPGS	;SAVE AS NEW NOMINAL
	PUSHJ	P,RESTPM	;ERASE PARAMETER FIRST
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
RBKNPM:	MOVE	T4,ROLPGS	;SET UP LAST TIME'S ROLL AS NOMINAL
	IMUL	T4,LPP(TM)	;GET NUMBER OF LINES TO ROLL
	TLNE	TM,WDW		;IN A WINDOW?
	SUB	T4,ROLPGS	;YES - DO ONE LINE FEWER
	MOVEM	T4,ROLLS	;SAVE AS PARM TO ROLBK
	PUSHJ	P,ROLBK		;GO DO THE WORK
	JRST	RFPEND		;THEN FINISH UP AND GET ANOTHER COMMAND

;HERE TO ROLL FORWARD A GIVEN NUMBER OF LINES

ROLFWL:	MOVE	T4,ROLLIN	;SET UP LAST TIME'S ROLL AS NOMINAL
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	JUMPE	T1,[TLO  F,SCN	;SET FLAG IF WANT SCAN MODE
		    JRST RFLNP0]
	MOVE	T4,PARG1	;GET LINES TO ROLL
	MOVEM	T4,ROLLIN	;SAVE AS NEW NOMINAL
RFLNP0:	PUSHJ	P,ERASPM	;ERASE PARAMETER FIRST
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
RFLNPM:	MOVE	T4,ROLLIN	;SET UP LAST TIME'S ROLL AS NOMINAL
	MOVEM	T4,ROLLS	;SAVE ALSO AS PARM TO ROLFW
	PUSHJ	P,ROLFW		;GO DO THE ACTUAL ROLLING
	TLNN	F,SCN		;SCANNING?
	JRST	RFLEND		;NO - GO FINISH UP
	SNOOZE	^D1200		;YES - SLEEP A BIT
	TLNN	F,FNC		;IS FENCE ON SCREEN?
	JRST	RFLNPM		;NO - CONTINUE (UNTIL USER TYPES SOMETHING)
	TLZ	F,SCN		;YES - TIME TO STOP SCANNING
	MOVEI	RW,^D15		;PUT CURSOR NEAR CENTER OF SCREEN
	MOVEI	CM,^D40
	JRST	RFLNPM		;AND DO THE LAST ONE

RFLEND:	MOVE	T1,LINROL
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T1,ROLLIN	;YES - SET IT BACK TO 1/3 THE SCREEN
	JRST	LOOP		;AND GO GET ANOTHER COMMAND

;SUBROUTINE TO DO THE ACTUAL ROLLING FORWARD (CALLED BY ROLFWL, ROLFWP)

ROLFW:	JUMPLE	T4,POSCUR
	TLO	F,XPB		;SAY BOTTOM POINTER IS INVALID
	PUSHJ	P,ADVDPT	;MOVE DISPLAY POINTER FORWARD
	MOVE	T4,ROLLS	;GET LINES TO ROLL AGAIN
	SUB	RW,T4		;ADJUST CURSOR POSITION - IF OFF SCREEN
	JUMPL	RW,[TLO   F,XPL!XPC ;LINE AND CHARACTER POINTERS ARE INVALID
		    SETZB RW,CM	    ;PUT CURSOR AT UPPER LEFT
		    JRST  .+1]
	TLZE	F,FLG		;HIT END OF FILE?
	JRST	ROLFW2		;YES - GO REWRITE THE SCREEN
	MOVE	T1,T4		;GET FRAGGABLE LINES TO ROLL
	TLNN	F,FNC!FBL	;IS BOTTOM LINE ON SCREEN BAD?
	TLNE	TM,NEL		;..
	AOJ	T1,		;YES - FUDGE THE COUNT ONE HIGHER
	SKIPE	RUP(TM)		;NO ROLL UP SEQUENCE,
	CAML	T1,LPP(TM)	;  OR WANT TO ROLL MORE THAN A SCREENFUL?
	JRST	ROLFW3		;YES - GO REWRITE THE SCREEN

ROLFW0:	PUSHJ	P,CMVBTM	;MOVE TO BOTTOM LINE
	TLNN	TM,NEL		;IS BOTTOM LINE FRAGGED SOMEHOW?
	TLNE	F,FNC!FBL
	PUSHJ	P,CLRLNA	;YES - ERASE IT
	PUSHJ	P,ROLLUP	;DO A ROLL
	SOJG	T4,.-1		;LOOP THROUGH PROPER NUMBER OF LINES

	MOVE	T4,LPP(TM)	;POSITION TO START OF LINES TO REWRITE
	SUB	T4,ROLLS
	MOVEM	T4,SAVEAC	;SAVE POSITION COUNT
ROLFW1:	MOVE	PT,DISPTR
	TLNN	F,FNC!FBL	;IS BOTTOM LINE ON SCREEN BAD?
	TLNE	TM,NEL		;..
	SOJ	T4,		;YES - WRITE FROM ONE HIGHER
	PUSHJ	P,ADVLPT	;ELSE GET POINTER TO START OF NEW STUFF
	JUMPL	T4,[PUSHJ P,FNCPUT ;IF BEYOND FILE OUTPUT THE FENCE
		    JRST  POSCUR]  ;POSITION CURSOR AND RETURN
	MOVE	T4,SAVEAC	;RESTORE POSITION COUNT
	TLNN	F,FNC!FBL	;IS BOTTOM LINE ON SCREEN BAD?
	TLNE	TM,NEL		;..
	SOJL	T4,ROLFW3	;YES - WRITE FROM ONE HIGHER - REDISPLAY IF NEG
	PUSHJ	P,POSLIN	;POSITION CURSOR AT THE LINE
	MOVE	T4,ROLLS	;DISPLAY THE MISSING LINES
	TLZE	F,FNC!FBL	;IS BOTTOM LINE ON SCREEN BAD?
	AOJ	T4,		;YES - WRITE ONE MORE LINE
	PUSHJ	P,DISPLY	;REWRITE BOTTOM OF THE SCREEN
	TRNE	F,IMD		;IN INSERT MODE?
	PUSHJ	P,INSMSG	;YES - PUT MESSAGE UP
	JRST	POSCUR		;RE-POSITION THE CURSOR AND RETURN

ROLFW2:	ADD	RW,T4		;DE-ADJUST CURSOR POSITION (AT EOF)
ROLFW3:	PUSHJ	P,DISPLL	;RE-DISPLAY SCREEN
	JRST	POSCUR		;POSITION CURSOR AND RETURN

;HERE TO ROLL BACKWARD A GIVEN NUMBER OF LINES

ROLBKL:	MOVE	T4,ROLLIN	;SET UP LAST TIME'S ROLL AS NOMINAL
	TLNN	F,ENT		;IS THERE A PARAMETER TYPED?
	JRST	RBLNPM		;NO - USE THE ONE ALREADY SET UP
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	JUMPE	T1,[TLO  F,SCN	;SET FLAG IF WANT SCAN MODE
		    MOVE T4,ROLLIN ;GET SIZE OF SCAN
		    JRST RBLNP0]
	MOVE	T4,PARG1	;GET LINES TO ROLL
	MOVEM	T4,ROLLIN	;SAVE AS NEW NOMINAL
RBLNP0:	PUSHJ	P,RESTPM	;ERASE PARAMETER
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
RBLNPM:	MOVEM	T4,ROLLS	;SAVE ALSO AS PARM TO ROLBK
	PUSH	P,F		;SAVE FENCE FLAG FOR LATER
	PUSHJ	P,ROLBK		;DO THE ACTUAL WORK
	POP	P,T1		;GET OLD FLAGS BACK
	TLNE	T1,FNC		;DID FENCE USED TO BE ON SCREEN?
	PUSHJ	P,RBLFNC	;YES - SEE IF IT NEEDS TO BE UP NOW
	TLNN	F,SCN		;SCANNING?
	JRST	RFLEND		;NO - GO FINISH UP
	SNOOZE	^D1200		;NO - WAIT A BIT
	MOVE	T4,ROLLIN	;GET SIZE OF ROLL AGAIN
	JRST	RBLNPM		;AND CONTINUE (UNTIL USER TYPES SOMETHING)

RBLFNC:	PUSHJ	P,MAKBPT	;YES - RE-MAKE PTR TO BOTTOM OF SCREEN
	TLZ	F,XPB		;MARK THAT IT'S GOOD
	JUMPN	PT,CPOPJ	;IF NOT BEYOND END OF FILE, O.K.
	PUSHJ	P,FNCPUT
	JRST	POSCUR		;POSITION CURSOR AND RETURN

;SUBROUTINE TO ROLL BACKWARDS (CALLED BY ROLBKL AND ROLBKP)
;IT CAN'T JUST BE A FLOW, SINCE ONE GOES TO LOOP AND THE OTHER DEBRK'S

ROLBK:	JUMPLE	T4,POSCUR	;DONE IF NO ROLL
	TLO	F,XPB		;SAY BOTTOM POINTER IS INVALID
	PUSHJ	P,BAKDPT	;MOVE DISPLAY POINTER BACKWARD (T4) LINES
	JUMPE	T4,ROLBK1	;HIT START OF FILE?
	TLZE	F,SCN		;YES - SCANNING?
	JRST	[MOVEI RW,^D5	;YES - PUT CURSOR NEAR CENTER OF SCREEN
		 MOVEI CM,^D40
		 JRST  .+1]	;AND CONTINUE
	TRNE	F,XCT		;EXECUTING?
	JRST	XCEERR		;YES - GIVE SPECIAL MESSAGE
ROLBK1:	MOVNS	T4		;SUBTRACT FROM LINES ROLLED
	ADDB	T4,ROLLS	;  (BOTH IN ROLLIN AND IN T4)
	MOVN	T1,T4
	JUMPE	T4,POSCUR	;IF ALREADY AT START OF BUFFER, QUIT
	ADD	RW,T4		;ADJUST CURSOR POSITION
	CAMGE	RW,LPP(TM)	;WILL CURSOR BE OFF THE SCREEN?
	JRST	.+3		;NO - O.K.
	SETZB	RW,CM		;YES - PUT IT AT UPPER LEFT
	TLZ	F,FBL		;BOTTOM LINE IS ALL RIGHT
	TLO	F,XPL!XPC	;LINE AND CHARACTER POINTERS ARE INVALID
	SKIPE	RLD(TM)		;NO ROLL DOWN SEQUENCE,
	CAML	T4,LPP(TM)	;  OR WANT TO ROLL MORE THAN A SCREENFUL?
	JRST	ROLBK2		;EITHER - JUST REWRITE THE SCREEN

	PUSHJ	P,CHOME		;HOME THE CURSOR
	PUSHJ	P,ROLLDN	;ROLL AND CLEAR A LINE
	SOJG	T4,.-1		;DO THE PHYSICAL ROLL OF THE SCREEN

	MOVE	PT,DISPTR	;POINT TO DESIRED POSITION IN BUFFER
	MOVE	T4,ROLLS	;GET NUMBER OF LINES TO REWRITE
	PUSHJ	P,DISPLY	;REWRITE THEM
	TLZ	F,XPB		;SAY BOTTOM POINTER IS VALID
	PUSHJ	P,MAKBPT	;RE-MAKE POINTER TO BOTTOM OF SCREEN
	JUMPE	PT,POSCUR	;IF FENCE IS UP, LEAVE IT UP
	TLZ	F,FNC		;ELSE TAKE IT DOWN
	TRNE	F,IMD		;IN INSERT MODE?
	PUSHJ	P,INSMSG	;YES - OUTPUT INSERT MESSAGE
	JRST	POSCUR		;RE-POSITION THE CURSOR AND RETURN

ROLBK2:	PUSHJ	P,RESTPM	;ERASE PARAMETER
	JRST	ROLFW3		;RE-DO THE SCREEN, RE-POSITION, AND RETURN

;**********************************************************************
;HERE ON RESET (ALIAS RUBOUT) RESETS ENTER MODE, OR RE-WRITES SCREEN

XRESET:	PUSHJ	P,ERSPM2	;RESTORE SAVED POSITION
	MOVE	T2,PARPTR	;DID USER TYPE JUST ENTER RESET?
	CAME	T2,[POINT 7,PARBUF]
	CAMN	T2,[010700,,PARBUF-1]
	JRST	RESET1		;YES - LEAVE BUFFER ALONE
	SETZ	T1,		;NO - END PARAMETER BUFFER WITH A NULL
	IDPB	T1,PARPTR
	LDB	T1,[POINT 7,PARBUF,6] ;GET 1ST CHARACTER OF PARAMETER
	CAIN	T1,136		;UP-ARROW?
	JRST	DISRES		;YES - GO RE-DISPLAY ENTIRE SCREEN

RESET2:	PUSHJ	P,ERASPM	;ERASE THE PARAMETER
RESNPM:	TLZE	F,FBL		;IS THE BOTTOM LINE FRAGGED?
	PUSHJ	P,FIXBLN	;YES - REPAIR IT
	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR
	MOVEI	T1,77		;GET EXECUTE CODE FOR RESET
	TRNE	F,XSV		;SAVING IN AN EXECUTE BUFFER?
	DPB	T1,XCTPTW	;YES - OVERWRITE REAL CODE WITH EXECUTE CODE
	JRST	LOOP		;GET ANOTHER COMMAND

RESET1:	TRNE	F,CMV		;CURSOR MOVE?
	JRST	RESET2		;YES - THEN IT'S NOT A TOKEN
	TLZE	F,XPL		;ELSE RE-DO CURRENT LINE
	PUSHJ	P,MAKLPT	;RE-MAKE LINE POINTER, IF NEEDED
	PUSHJ	P,DISONL
	JRST	RESET2		;CONTINUE

;**********************************************************************
;HERE FOR THE COMMAND TO SET A NUMBER OF SWITCHES

SWITCH:	MOVE	T1,PARPTR	;DID USER TYPE JUST ENTER SWITCH?
	CAME	T1,[POINT 7,PARBUF]
	CAMN	T1,[010700,,PARBUF-1]
	JRST	SWHSTS		;YES - GIVE HIM SOME STATUS INFORMATION
	PUSHJ	P,ERASPM	;ELSE ERASE PARAMETER
	SETZ	T1,		;END PARAMETER WITH A NULL
	IDPB	T1,PARPTR
	MOVE	PT,[POINT 7,PARBUF]
	MOVE	T3,PT
	ILDB	T1,T3		;GET FIRST CHARACTER
	CAIN	T1,"/"		;SUPERFLUOUS SLASH?
	MOVE	PT,T3		;YES - SKIP IT
	PUSHJ	P,SWHMNY	;HANDLE THE SWITCH(S) IN THE PARAMETER BUFFER
	JRST	DISCUR		;RE-POSITION CURSOR AND GET NEW COMMAND

;HERE ON SWITCH WITH NO PARAMETER: GIVE FILE STATUS

SWHNPM:	PUSHJ	P,SWHBOT	;SET UP THE BOTTOM LINE
	MOVEI	T1,[ASCIZ /FILE: /]
	PUSHJ	P,PUTSTG
	MOVEI	T1,FILSPC
	PUSHJ	P,PUTSTF

	PUSHJ	P,MAKCPT	;MAKE A GOOD CHARACTER POINTER
	MOVE	T2,RW		;SAVE REAL ROW POINTER
	MOVE	PT,[010700,,BUFFER-1]
	PUSHJ	P,FINDRW	;COUNT PAGES AND LINES FROM START OF BUFFER
	EXCH	T2,RW
	EXCH	T2,SAVEAC

	SKIPN	PAGFLG		;WANT BOTH PAGES AND LINES?
	JRST	SWHNP1		;NO - JUST LINES
	MOVEI	T1,[ASCIZ / PAGE: /]
	PUSHJ	P,PUTSTG
	MOVEI	T1,1(T3)	;GET PAGE NUMBER
	PUSHJ	P,PUTNUM	;OUTPUT PAGE
	MOVEI	T1,"-"
	IDPB	T1,TY
	AOS	T1,SAVEAC	;GET LINE NUMBER
	PUSHJ	P,PUTNUM	;OUTPUT IT
	JRST	SWHNP2		;SKIP LINES-ONLY STUFF

SWHNP1:	MOVEI	T1,[ASCIZ / LINE: /]
	PUSHJ	P,PUTSTG
	MOVEI	T1,1(T2)	;GET LINE NUMBER
	PUSHJ	P,PUTNUM	;OUTPUT IT

SWHNP2:	MOVEI	T1,"("
	IDPB	T1,TY
	HRRZ	T1,LINPTR	;GET OFFET OF PAGE INTO BUFFER
	SUBI	T1,BUFFER-1
	IMULI	T1,^D100	;TIMES 100
	HRRZ	T2,EN		;DIVIDED BY SIZE OF FILE
	SUBI	T2,BUFFER
	IDIV	T1,T2
	PUSHJ	P,PUTNUM	;OUTPUT PERCENT THROUGH FILE

	MOVEI	T1,[ASCIZ /%) POS: /]
	PUSHJ	P,PUTSTG
	MOVEI	T1,1(CM)	;OUTPUT COLUMN + SLIDE + 1
	ADD	T1,SL
	PUSHJ	P,PUTNUM
	SKIPN	OLDSPC		;GOT AN ALTERNATE FILE?
	JRST	SWHNPE		;NO - DON'T TALK ABOUT IT
	MOVEI	T1,[ASCIZ / ALT: /]
	PUSHJ	P,PUTSTG
	MOVEI	T1,OLDSPC
	PUSHJ	P,PUTSTF
SWHNPE:	MOVEI	T1," "
	IDPB	T1,TY
	SETZ	T1,
	MOVE	T2,CPL.1	;GET TERMINAL WIDTH - 1
	SUBI	T2,3		;(IN CASE THE TTY COUNTS THE PROT'N CHARS)
IFN TOPS10,<
	IDIVI	T2,5		;FIND NUMBER OF WORDS + REMAINDER
	ADD	T2,[POINT 7,TYPBUF,6] ;ADJUST PTR TO THE RIGHT WIDTH
	HRL	T2,PTRTBL+1(T3)
>
IFE TOPS10,<
IFN FTECHO,<
	ADJBP	T2,[POINT 8,TYPBUF,7]
>
IFE FTECHO,<
	ADJBP	T2,[POINT 7,TYPBUF,6]
>>
	DPB	T1,T2		;MAKE MESSAGE END AT WIDTH - 1
	PUSHJ	P,PUTTYP	;OUTPUT THE TEXT
	PUSHJ	P,PROTOF	;TURN PROTECTION OFF
	TLO	F,FBL		;SAY BOTTOM LINE HAS BEEN FRAGGED
	JRST	DISCUR		;RE-POSITION CURSOR AND RETURN

;SUBROUTINE TO SET UP THE BOTTOM OF THE SCREEN FOR THE SWITCH COMMAND ETC.

SWHBOT:	PUSHJ	P,RESTPM	;CLEAN UP THE PARAMETER ENTRY
	PUSHJ	P,CBOTOM	;PUT MESSAGE ON BOTTOM LINE
	PUSHJ	P,PROTON	;PROTECTED
	JRST	PUTTYP		;OUTPUT POSITIONING NOW AND RETURN

;HERE ON TOKEN SWITCH (ENTER, BUT NO PARAMETER): GIVE NOMINAL SETTINGS

SWHSTS:	PUSHJ	P,SWHBOT	;SET UP THE BOTTOM LINE
	MOVEI	T1,[ASCIZ / RL:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,ROLLIN	;OUTPUT NUMBER OF LINES TO ROLL
	PUSHJ	P,PUTNUM
	MOVEI	T1,[ASCIZ / RP:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,ROLPGS	;OUTPUT NUMBER OF PAGES TO ROLL
	PUSHJ	P,PUTNUM
	MOVEI	T1,[ASCIZ / PC:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,GOPERC	;OUTPUT PERCENT-GOTO NOMINAL
	PUSHJ	P,PUTNUM
	MOVEI	T1,[ASCIZ / SL:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,SLIDES	;OUTPUT SIZE OF SLIDE
	PUSHJ	P,PUTNUM
	MOVEI	T1,[ASCIZ / IL:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,ADDLNS	;OUTPUT NUMBER OF LINES TO INSERT/DELETE
	PUSHJ	P,PUTNUM
	SKIPN	T1,ADDLSP	;GOT SPACES TO GO WITH THOSE LINES?
	JRST	SWHST1		;NO - SKIP OUTPUT
	MOVEI	T1,","
	IDPB	T1,TY
	MOVE	T1,ADDLSP	;AND SPACES TO GO WITH THOSE LINES
	PUSHJ	P,PUTNUM
SWHST1:	MOVEI	T1,[ASCIZ / IS:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,ADDSPC	;OUTPUT NUMBER OF SPACES TO INSERT/DELETE
	PUSHJ	P,PUTNUM
	MOVEI	T1,[ASCIZ / PK:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,PICKLN	;OUTPUT NUMBER OF LINES TO PICK
	PUSHJ	P,PUTNUM
	SKIPN	T1,PICKSP	;GOT SPACES TO GO WITH THOSE LINES?
	JRST	SWHST2		;NO - SKIP OUTPUT
	MOVEI	T1,","
	IDPB	T1,TY
	MOVE	T1,PICKSP	;AND SPACES TO PICK, TOO
	PUSHJ	P,PUTNUM

SWHST2:	MOVEI	T1,[ASCIZ / CS:/]
	PUSHJ	P,PUTSTG
	SKIPN	T1,CASLNS	;CHANGING THE CASE OF ANY LINES?
	JRST	SWHS2A		;NO - SKIP OUTPUT
	PUSHJ	P,PUTNUM	;YES - OUTPUT THEM AND A COMMA
	MOVEI	T1,","
	IDPB	T1,TY
SWHS2A:	MOVE	T1,CASSPS	;OUTPUT NUMBER OF CHARS TO CHANGE CASE OF
	PUSHJ	P,PUTNUM

	MOVEI	T1,[ASCIZ / SU:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,SUBCNT	;OUTPUT NUMBER OF SUBSTITUTES TO DO
	PUSHJ	P,PUTNUM

	SKIPG	ISVNUM		;GOT AN INCREMENTAL SAVE?
	JRST	SWHST3		;NO
	MOVEI	T1,[ASCIZ / ISV:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,ISVNUM
	PUSHJ	P,PUTNUM
SWHST3:	SKIPG	SAVNUM		;GOT AN INCREMENTAL TYPEIN SAVE?
	JRST	SWHST4		;NO
	MOVEI	T1,[ASCIZ / SV:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,SAVNUM
	PUSHJ	P,PUTNUM
SWHST4:	SKIPG	LMARGN		;GOT A CHANGED LEFT MARGIN?
	JRST	SWHST5		;NO
	MOVEI	T1,[ASCIZ / LM:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,LMARGN
	PUSHJ	P,PUTNPO
SWHST5:	MOVE	T1,RMARGN	;GOT A RIGHT MARGIN WITHIN THE SCREEN?
	CAML	T1,CPL.1
	JRST	SWHST6		;NO
	MOVEI	T1,[ASCIZ / RM:/]
	PUSHJ	P,PUTSTG
	MOVE	T1,RMARGN
	PUSHJ	P,PUTNPO
SWHST6:	MOVEI	T1,[ASCIZ / TB:/]
	PUSHJ	P,PUTSTG	;OUTPUT SIZE OF TAB
	TRNE	F,WTB		;GOT WORD-WISE TABS?
	JRST	SWHS6W		;YES - CALL THEM SIZE "W" (RETURN TO SWHST7)
	TLNE	TM,STB		;GOT SETTABLE TABS?
	JRST	SWHS6S		;YES - CALL THEM SIZE "S" (RETURN TO SWHST7)
	MOVE	T1,TABLEN	;NO - OUTPUT SIZE OF TAB
	PUSHJ	P,PUTNUM
SWHST7:	SKIPN	SRCKEY		;GOT A SEARCH KEY?
	JRST	SWHST8		;NO
	MOVEI	T1,[ASCIZ / KEY:/]
	PUSHJ	P,PUTSTG
	MOVEI	T1,SRCKEY
	PUSHJ	P,PUTSTC
SWHST8:	SKIPN	SUBSTG		;GOT A SUBSTITUTE STRING?
	JRST	SWHNPE		;NO
	MOVEI	T1,[ASCIZ / RPL:/]
	PUSHJ	P,PUTSTG
	MOVEI	T1,SUBSTG
	PUSHJ	P,PUTSTC
	JRST	SWHNPE		;FINISH OFF

SWHS6W:	SKIPA	T1,["W"]	;CALL WORD-WISE TABS SIZE "W"
SWHS6S:	MOVEI	T1,"S"		;CALL SETTABLE TABS SIZE "S"
	IDPB	T1,TY
	JRST	SWHST7

;**********************************************************************
;HERE TO DO A RECALL COMMAND -
;GIVES BACK PREVIOUS PARAMETER FOR EDITING AND REUSE
;ALSO  ENTER F RECALL FORCES BACK THE FILESPECS
;AND   ENTER A RECALL THE ALTERNATE FILESPECS
;AND   ENTER S RECALL THE SEARCH KEY
;AND   ENTER O RECALL THE OLD (PREVIOUS) SEARCH KEY
;AND   ENTER R RECALL THE SUBSTITUTE (REPLACE) STRING

RECARG:	SETZ	T1,		;END PARAMETER BUFFER WITH A NULL
	IDPB	T1,PARPTR
	MOVE	PT,[POINT 7,PARBUF]
	PUSHJ	P,SWHLUR	;READ PARAMETER CHARACTER
	CAIGE	T1,"A"		;ALPHABETIC?
	JRST	RECAR1		;NO - JUST DO A NORMAL RECALL
	CAIN	T1,"F"		;WANT TO SET UP FILESPECS?
	JRST	RECFIL		;YES - GO DO IT
	CAIN	T1,"A"		;WANT TO SET UP ALTERNATE FILESPECS?
	JRST	RECAFL		;YES - GO DO IT
	CAIN	T1,"R"		;WANT TO SET UP SUBSTITUTE STRING?
	JRST	RECSCR		;YES - GO DO IT
	CAIN	T1,"O"		;WANT TO SET UP OLD SEARCH KEY?
	JRST	RECSCO		;YES - GO DO IT
	CAIE	T1,"S"		;WANT TO SET UP THE SEARCH KEY?
	JRST	RECAR1		;NO - JUST DO A NORMAL RECALL

	SKIPA	T1,[SRCKEY,,PARBUF] ;TRANSFER SEARCH KEY ...
RECSCO:	MOVE	T1,[SROKEY,,PARBUF] ;TRANSFER OLD SEARCH KEY ...
RECSC1:	BLT	T1,PARBUF+7	;  TO PARAMETER BUFFER
	JRST	RECAR1		;CONTINUE TO RECALL THE KEY

RECSCR:	MOVE	T1,[SUBSTG,,PARBUF] ;TRANSFER SUBSTITUTE STRING
	JRST	RECSC1

IFN TOPS10,<
RECAFL:	SKIPA	PT,[POINT 7,OLDSPC] ;POINT TO ASCII ALTERNATE FILE SPECS
RECFIL:	MOVE	PT,[POINT 7,FILSPC] ;POINT TO ASCII FILE SPECS
	MOVE	T4,[POINT 7,PARBUF] ;AND PARAMETER BUFFER
	ILDB	T1,PT		;IF FILESPECS ARE NULL SAY SO
	JUMPE	T1,RECFL2
	ILDB	T1,PT		;SKIP OVER THE DEVICE
	CAIE	T1,":"
	JRST	.-2
RECFL1:	ILDB	T1,PT		;THEN COPY NAME AND EXT (BUT NOT PPN)
	IDPB	T1,T4
	CAIE	T1,"["		;IF PPN, FLOW TO SAVE NULLS
	JRST	RECFL1
>
IFE TOPS10,<
RECFIL:	MOVE	T1,[FILSPC,,PARBUF] ;TRANSFER FILESPECS TO PARAMETER BUFFER
	BLT	T1,PARBUF+13	;AND FALL INTO NORMAL RECALL CODE
	JRST	RECAR1

RECAFL:	MOVE	PT,[POINT 7,OLDSPC] ;POINT TO ASCII ALTERNATE FILE SPECS
	MOVE	T4,[POINT 7,PARBUF] ;AND PARAMETER BUFFER
RECAF1:	ILDB	T1,PT		;COPY UNTIL NULL OR SWITCHES
	IDPB	T1,T4
	JUMPE	T1,RECFL2
	CAIE	T1,"/"
	JRST	RECAF1
>
	SETZ	T1,		;END WITH TWO NULLS
	DPB	T1,T4
RECFL2:	IDPB	T1,T4

RECAR1:	PUSHJ	P,ENTRMK	;MARK THE BOTTOM OF THE SCREEN
	JRST	RECAL0		;CONTINUE TO RECALL THE KEY

RECALL:	TLO	F,ENT		;PRETEND ENTER WAS TYPED
	PUSHJ	P,ENTER0	;SET UP LIKE AN ENTER
RECAL0:	MOVE	T1,[POINT 7,PARBUF]
	ILDB	T2,T1		;RE-MAKE THE PARAMETER POINTER
	JUMPN	T2,.-1		;  TO POINT TO THE FIRST NULL
	MOVEM	T1,PARPTR
RECAL1:	MOVE	T1,PARPTR	;GET RID OF NULL AT END OF PARAMETER BUFFER
	ADD	T1,[70000,,0]	;FUDGE A DECREMENT OF THE PARM POINTER
	JUMPGE	T1,.+2
	SUB	T1,[430000,,1]
	MOVEM	T1,PARPTR
	TRNE	F,XCT!XBN	;EXECUTING?
	JRST	LOOP		;YES - DONE NOW
	MOVEI	T1,PARBUF	;NO - OUTPUT CURRENT PARAMETER
	PUSHJ	P,PUTSTS
	PUSHJ	P,PUTTYP	;TYPE IT ALL OUT NOW
	JRST	LOOP		;LET USER EDIT IT

;**********************************************************************
;HERE TO INSERT A REAL TAB IN THE FILE - SAME AS IF USER TYPED E-C-C I

REALTB:	MOVEI	T1,11		;GET A TAB
	SETO	DO,		;NOTE THAT A COMMAND IS ACTIVE
	JRST	ALPNU1		;TREAT IT LIKE E-C-C I

;**********************************************************************
;HERE TO MARK POSITION FOR PICK OR CLOSE-LINES. THE NEXT SUCH COMMAND
;WILL TAKE TEXT FROM THE MARK TO THE CURSOR POSITION.

MARK:	PUSHJ	P,MAKCPT	;GET A CORRECT CURSOR POINTER
	DMOVE	T1,LINPTR	;SAVE LINE AND CURSOR POINTER FOR LATER
	DMOVEM	T1,MRLPTR
	MOVE	T1,DISPTR	;SAVE CURRENT DISPLAY POINTER
	MOVEM	T1,MRKPTR
	TLO	F,PCM		;SET MARK FLAG
	DMOVEM	RW,SVPMRK	;SAVE STARTING POSITION
	PUSHJ	P,MRKCUR	;MARK THE CURSOR POSITION
	MOVEM	T3,SVPMRK+2	;SAVE THE CHARACTER MARKED
	PUSHJ	P,POSCUR	;RE-POSITION AND OUTPUT
	JRST	LOOP		;THAT'S ALL

;HERE ON ENTER MARK, WHICH CANCELS THE MARK

MRKARG:	TLZN	F,PCM		;CANCEL THE MARK - GOT ONE?
	JRST	TBCLRX		;NO - REPAIR SCREEN AND GO HOME
	DMOVE	T1,MRLPTR	;RESTORE CURSOR AND LINE POINTERS
	DMOVEM	T1,LINPTR
	MOVE	T1,MRKPTR	;RESTORE THE OLD DISPLAY POINTER
	EXCH	T1,DISPTR
	CAMN	T1,DISPTR	;HAS DISPLAY POINTER CHANGED?
	JRST	MRKAG0		;NO - REPAIR THE SCREEN AS IT IS
	DMOVE	RW,SVPMRK	;YES - RESTORE SAVED ROW AND COLUMN
	TLZ	F,ENT!XPL!XPC	;CANCEL THE ENTER; SAY CUR, LINE PTRS ARE GOOD
	TLO	F,XPB		;BUT BOTTOM POINTER IS NOT
	JRST	DISALL		;RE-DISPLAY THE SCREEN AND LOOP

MRKAG0:	PUSHJ	P,ERASPM	;FIX UP THE SCREEN
	DMOVE	RW,SVPMRK	;RESTORE SAVED ROW AND COLUMN
	PUSHJ	P,MRKAG1	;DE-BLIP THE MARK
	JRST	LOOP		;RE-POSITION AND LOOP

MRKAG1:	MOVE	T1,SVPMRK+2	;GET CHARACTER MARKED
	MOVEM	T1,CHRCUR
	JRST	RESTPM+2	;DE-BLIP THE MARK AND RETURN

MRKRES:	EXCH	RW,SVPMRK	;DE-BLIP THE MARK AT THE STARTING POINT
	EXCH	CM,SVPMRK+1
	PUSHJ	P,MRKAG1
	DMOVE	RW,SVPMRK	;GET THE REAL POSITION BACK
	POPJ	P,		;DONE

;**********************************************************************
;HERE TO CHANGE THE CASE OF STUFF AT THE CURSOR. IF THE SWITCH
;/RAISE IS ON THE LETTER WILL BECOME UPPER; IF /NORAISE, LOWER

CHGCAS:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	MOVE	T4,CASSPS	;GET LAST TIME'S NOMINAL
	TLNN	F,ENT		;IS THERE A PARAMETER TYPED?
	JRST	CASNPM		;NO - USE THE ONE ALREADY SET UP
	MOVEM	T4,PARG1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET COUNT OF CHARACTERS
	TRNE	F,CMV		;CURSOR MOVEMENT?
	JRST	[MOVEM T4,CASLNS   ;YES - SAVE LINES TO WORK WITH
		 MOVE  T4,PARG2    ;GET REAL SPACES TO WORK WITH
		 SKIPN CASLNS	   ;GOT ANY LINES?
		 JRST  CASNP0	   ;NO - USE SPACES AS IS
		 ADD   T4,SAVPOS+1 ;YES - COUNT THEM FROM LEFT MARGIN
		 ADD   T4,SL
		 JRST  CASNP0]
	SETZM	CASLNS		;IF NO CURSOR MOVE, CLEAR EXTRA LINES
CASNP0:	MOVEM	T4,CASSPS	;SAVE SPACE COUNT AS NEW NOMINAL
	PUSHJ	P,ERASPM	;RESET ENTER MODE
	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR
	TLNE	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	JRST	LOOP		;YES - DONE NOW
CASNPM:	SKIPE	T1,CASLNS	;GET LINES TO WORK WITH
	MOVEI	T4,^D1000	;SET TO DO ENTIRE LINE
	JUMPLE	T4,DISCUR	;DONE IF GOT ZERO SPACES
	MOVEM	T1,CASLIN	;ELSE SAVE LINES IN A FRAGGABLE PLACE
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	MOVEM	T4,SAVEAC	;SAVE SPACE COUNT
	PUSHJ	P,MAKCPT	;GET A GOOD CHARACTER POINTER
	MOVE	T4,SAVEAC	;GET SPACE COUNT BACK
	TLO	F,CHG		;SAY FILE HAS BEEN CHANGED
	SKIPN	INVFLG		;WANT TO INVERT THE CASE?
	JRST	CASINV		;YES - GO DO IT
	SKIPE	UPCFLG		;NO - WANT LOWER CASE?
	JRST	CASUC0		;NO - MAKE IT UPPER CASE

;HERE TO CHANGE LOWER CASE TO UPPER

	MOVEI	PT,CASLC2	;YES - SET UP LC RETURN ADDRESS
CASLC1:	ILDB	T1,CHRPTR	;GET THE NEXT CHARACTER FROM THE FILE
	JUMPE	T1,CASENB	;IF NULL CHECK FOR END OF BUFFER
	CAIL	T1,"a"		;IS CHARACTER LOWER CASE?
	CAILE	T1,"z"
	JRST	CASSKP		;NO - JUST SKIP OVER IT
	HRRZI	T1,-40(T1)	;YES - CONVERT TO UPPER
	PUSHJ	P,CASSAV	;STORE AND OUTPUT THE CHANGED CHARACTER
CASLC2:	SOJG	T4,CASLC1	;HANDLE THE NEXT CHARACTER
	TLZ	F,LFF		;CLEAR RETURN-FROM-CURSOR-MOVE FLAG
CASEND:	TRNN	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	JRST	DISCUR		;NO - POSITION CURSOR; DONE
	MOVEI	T1,1
	MOVEM	T1,CASSPS	;YES - SET IT BACK TO ONE CHARACTER
	SETZM	CASLNS		;  AND NO LINES
	JRST	DISCUR		;POSITION CURSOR; DONE

;HERE TO CHANGE UPPER CASE TO LOWER

CASUC0:	MOVEI	PT,CASUC2	;GET UPPER CASE RETURN ADDRESS
CASUC1:	ILDB	T1,CHRPTR	;GET NEXT CHARACTER FROM THE FILE
	JUMPE	T1,CASENB	;IF NULL CHECK FOR END OF BUFFER
	CAIL	T1,"A"		;IS CHARACTER UPPER CASE?
	CAILE	T1,"Z"
	JRST	CASSKP		;NO - JUST SKIP OVER IT
	MOVEI	T1,40(T1)	;YES - CONVERT TO LOWER
	PUSHJ	P,CASSAV	;SAVE AND OUTPUT THE CHARACTER
CASUC2:	SOJG	T4,CASUC1	;HANDLE THE NEXT CHARACTER
CASUC3:	TLZ	F,LFF		;CLEAR RETURN-FROM-CURSOR-MOVE FLAG
	JRST	CASEND		;DONE; GO FINISH UP

;HERE TO INVERT THE CASE: UPPER GOES TO LOWER AND VICE VERSA

CASINV:	MOVEI	PT,CASIV2	;GET INVERT CASE RETURN ADDRESS
CASIV1:	ILDB	T1,CHRPTR	;GET NEXT CHARACTER FROM THE FILE
	JUMPE	T1,CASENB	;IF NULL CHECK FOR END OF BUFFER
	CAIGE	T1,"A"		;IS CHARACTER UPPER CASE?
	JRST	CASSKP		;NO - JUST SKIP OVER IT
	CAILE	T1,"Z"
	JRST	CASIVL		;NO - CHECK FOR LOWER CASE
	MOVEI	T1,40(T1)	;YES - CONVERT TO LOWER
CASIL1:	PUSHJ	P,CASSAV	;SAVE AND OUTPUT THE CHARACTER
CASIV2:	SOJG	T4,CASIV1	;HANDLE THE NEXT CHARACTER
CASIV3:	TLZ	F,LFF		;CLEAR RETURN-FROM-CURSOR-MOVE FLAG
	JRST	CASEND		;DONE; GO FINISH UP

CASIVL:	CAIL	T1,"a"		;IS CHARACTER LOWER CASE?
	CAILE	T1,"z"
	JRST	CASSKP		;NO - JUST SKIP OVER IT
	HRRZI	T1,-40(T1)	;YES - CONVERT TO UPPER
	JRST	CASIL1		;AND CONTINUE

CASENB:	CAMN	EN,CHRPTR	;FOUND A NULL - AT END OF BUFFER?
	JRST	CASIV3		;YES - QUIT NOW
	AOJA	T4,@PT		;NO - LOOP

CASSAV:	DPB	T1,CHRPTR	;SAVE IT OVER THE OTHER ONE
	JUMPL	CM,CASSV1	;DONE IF OFF THE LEFT OF THE SCREEN
	TRNN	F,XCT		;EXECUTING,
	CAML	CM,CPL.1	;  OR OFF THE RIGHT SIDE?
	JRST	CASSV1		;YES - NO ECHO
	MOVEM	T1,SAVEAC	;NO - SAVE CHARACTER TO ECHO
	TLZE	F,LFF		;ALREADY POSITIONED?
	PUSHJ	P,POSCUR	;NO - POSITION, ALREADY
	MOVE	T1,SAVEAC	;GET CHARACTER BACK
	TYPCHA			;AND OUTPUT IT
CASSV1:	AOJA	CM,CPOPJ	;ADJUST COLUMN POSITION AND RETURN

CASSKP:	CAIN	T1,15		;END OF LINE?
	JRST	CASSKC		;MAYBE - CHECK IT OUT
	JUMPL	CM,CASSK2	;NO DISPLAY IF OFF THE LEFT OF THE SCREEN
	CAML	CM,CPL.1	;OFF THE RIGHT SIDE?
	AOJA	CM,@PT		;YES - NO DISPLAY EITHER
	CAIN	T1,11		;TAB?
	JRST	CASSKT		;YES - FIX COLUMN POSITION AND CHARACTER COUNT
CASSK1:	TLO	F,LFF		;FLAG THAT CURSOR HAS MOVED
CASSK2:	AOJA	CM,@PT		;AND CONTINUE

CASSKT:	ADD	T4,CM		;GOT A TAB - SUBTRACT ITS LENGTH FROM THE COUNT
	TRO	CM,7		;MOVE OVER TO TAB BOUNDARY
	SUB	T4,CM		;COMPLETE THE SUBTRACTION
	JRST	CASSK1		;BACK TO THE FLOW

CASSKC:	MOVE	T2,CHRPTR	;GET CHARACTER AFTER THE CARRIAGE RETURN
	ILDB	T1,T2
	CAIE	T1,12		;IS IT A LINEFEED?
	JRST	CASSK1		;NO - JUST SKIP OVER THE CR
	MOVEM	T2,CHRPTR	;YES - DON'T COUNT IT AS A CHARACTER
	MOVN	CM,SL		;MOVE TO THE NEXT LINE
	AOJ	RW,
	CAML	RW,LPP(TM)	;WORKING ON BOTTOM LINE?
	PUSHJ	P,CASROL	;YES - ROLL DOWN A LINE
	TLO	F,XPL!XPC!LFF	;LINE AND CHARACTER POINTERS ARE INVALID

	SOSGE	T1,CASLIN	;GOT MORE LINES TO DO?
	JRST	CASUC3		;NO - DONE
	MOVEI	T4,^D1000	;SET TO DO ONE MORE LINE
	JUMPN   T1,@PT		;JUMP IS THIS IS NOT THE LAST LINE
	SKIPE	T4,CASSPS	;ELSE GET NUMBER OF SPACES IN LAST LINE - ANY?
	AOJA	T4,@PT		;YES - GO DO LAST LINE
	JRST	CASUC3		;NO - DONE

CASROL:	MOVEI	T4,1		;ROLL UP ONE LINE
	MOVEM	T4,ROLLS
	PUSH	P,PT
	PUSHJ	P,ROLFW		;GO DO THE ACTUAL ROLLING
	POP	P,PT
	POPJ	P,

;**********************************************************************
;HERE TO SET UP OR CANCEL WINDOWING

WINCLR:	PUSHJ	P,RESTPM	;RESET PARAMETER
	PUSHJ	P,WNCLST	;CLEAR WINDOWING
	PUSHJ	P,DISPLL	;RE-DISPLAY THE SCREEN
	JRST	DISCUR		;POSITION THE CURSOR AND LOOP

WNCLST:	TLZ	TM,WDW		;GET OUT OF WINDOWING
	SETZM	HOMPOS		;PUT HOME BACK HOME
	DMOVE	T1,SAVRUP	;RESTORE SAVED ROLL UP AND DOWN
	DMOVEM	T1,RUP(TM)
	DMOVE	T1,SAVILN	;RESTORE SAVED INSERT AND DELETE LINE
	MOVEM	T1,ILN(TM)
	MOVEM	T2,DLN(TM)
	MOVE	T1,SAVCPG	;RESTORE CLEAR-TO-EOP, TOO
	MOVEM	T1,CPG(TM)
	MOVE	T3,SAVLPP	;SET UP FULL SCREEN LENGTH
	JRST	SWHLPP		;ALSO SET UP AS LINES PER PAGE, AND RETURN

WINSET:	TLOE	TM,WDW		;ALREADY IN A WINDOW?
	JRST	WINCLR+1	;YES - CANCEL WINDOWING
	MOVE	T3,LPP(TM)	;GET THE SCREEN LENGTH
	MOVEM	T3,SAVLPP	;SAVE IT FOR AFTER WINDOWING
	LSH	T3,-1		;DIVIDE IN TWO, ONE FOR EACH WINDOW
	CAML	RW,T3		;IS CURSOR BELOW WINDOW?
	SETZB	RW,CM		;YES - MOVE IT HOME
	TLO	F,XPL!XPC	;CURSOR AND LINE POINTERS ARE BAD (only above)
	SETZB	T1,T2		;CLEAR AND GET
	EXCH	T1,RUP(TM)	;  ROLL UP AND ROLL DOWN SEQUENCES
	EXCH	T2,RLD(TM)	;  (SO ROLLS WON'T BE DONE)
	DMOVEM	T1,SAVRUP	;SAVE THEM
	SETZB	T1,T2		;SAME WITH INSERT AND DELETE LINE SEQUENCES
	EXCH	T1,ILN(TM)	;  (IN THE UPPER WINDOW ONLY)
	EXCH	T2,DLN(TM)
	DMOVEM	T1,SAVILN	;SAVE THEM
	PUSHJ	P,SWHLPP	;ALSO SET UP AS LINES PER PAGE
	MOVEI	T1,"^"		;GET UPWARD-POINTING SEPARATOR
	PUSHJ	P,WINSEP	;PUT WINDOW SEPARATOR UP
	SKIPE	CPG(TM)		;IS THERE A CLEAR-TO-EOP SEQUENCE?
	PUSHJ	P,CLEARP	;YES - DO IT
	SETZB	T1,WINDIS	;CLEAR AND SAVE
	EXCH	T1,CPG(TM)	;  SEQUENCE FOR CLEAR-TO-EOP
	MOVEM	T1,SAVCPG
	JRST	DISCUR		;RE-POSITION THE CURSOR; DONE

;SUBROUTINE TO OUTPUT WINDOW SEPARATOR ON LINE (T3)
;ENTER WITH SEPARATOR CHARACTER IN T1

WINSEP:	PUSH	P,T1		;SAVE SEPARATOR CHARACTER
	EXCH	RW,T3		;MOVE TO THE START OF LINE (T3)
	SETZ	T2,
	EXCH	T2,CM
	PUSHJ	P,POSCUR
	MOVE	CM,T2		;RESTORE THE REAL ROW AND COLUMN
	MOVE	RW,T3
	MOVE	T2,CPL.1
	SUBI	T2,5
	PUSHJ	P,PROTON	;OUTPUT A PROTECTED SEPARATOR
	POP	P,T1
	IDPB	T1,TY
	SOJG	T2,.-1
	PUSHJ	P,PROTOF
	JRST	PUTTYP		;OUTPUT AND RETURN

;**********************************************************************
;HERE TO DELETE THE FIRST CHARACTER FROM THE PARAMETER BUFFER

DELFIR:	SETZ	T1,		;END PARAMETER BUFFER WITH A NULL
	MOVE	T2,PARPTR
	IDPB	T1,T2
	CAMN	T2,[POINT 7,PARBUF,6]
	JRST	LOOP		;NOTHING TO DO IF NOTHING IN BUFFER
	MOVE	PT,[POINT 7,PARBUF] ;ELSE POINT TO START OF THE BUFFER
	MOVE	T4,PT		;POINT TO FIRST AND SECOND CHARACTERS
	IBP	PT
DELFR1:	ILDB	T1,PT		;GET A CHARACTER
	IDPB	T1,T4		;SAVE IT IN THE PREVIOUS POSITION
	JUMPN	T1,DELFR1	;LOOP UNTIL NULL
	PUSHJ	P,ENTRMK	;MAKE THE MARK ON THE BOTTOM LINE
	JRST	RECAL1		;GO TO RECALL CODE TO FINISH UP

;**********************************************************************
;UP-TAB: MOVE THE CURSOR UP 6 LINES

UPTARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT

UPTAB:	TLO	F,XPL!XPC	;LINE POINTER IS NO LONGER GOOD
	SUBI	RW,6		;MOVE UP SIX LINES
	JUMPGE	RW,DISCUR	;WRAP AROUND THE TOP TONIGHT?
	ADD	RW,LPP(TM)	;YES - WRAP 'TIL THE BROAD DAYLIGHT
	JRST	DISCUR		;REPOSITION CURSOR; DONE

;DOWN-TAB: MOVE THE CURSOR DOWN 6 LINES

DNTARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT

DNTAB:	TLO	F,XPL!XPC	;LINE POINTER IS NO LONGER GOOD
	ADDI	RW,6		;MOVE DOWN SIX LINES
	CAMLE	RW,LPP.1	;WRAP AROUND THE BOTTOM?
	SUB	RW,LPP(TM)	;YES - COME BACK DOWN THE TOP
	JRST	DISCUR		;REPOSITION CURSOR; DONE

;MOVE TO START OF THE CURRENT LINE

BLIARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
BLINE:	MOVE	CM,LMARGN	;GO TO THE LEFT MARGIN
	TLO	F,XPC		;CHARACTER POINTER IS BAD
;	SKIPN	XXXFLG		;WANT TO MOVE TO THE START OF THE TEXT?
	JRST	DISCUR		;NO - DISPLAY THE CURSOR AND LOOP
	PUSHJ	P,MAKCPT	;YES - GET A GOOD CURSOR POINTER
	CAIE	T3," "		;GOT A SPACE OR TAB?
	CAIN	T3,11
	JRST	WTAB		;YES - WORD-WISE TAB OVER TO THE TEXT
	JRST	DISCUR		;NO - ALREADY AT THE START OF TEXT

;MOVE TO THE END OF THE CURRENT LINE

ELIARG:	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
ELINE:	TLO	F,XPC!XPL	;CHARACTER AND LINE POINTERS ARE BAD
	SETZ	CM,		;MOVE TO THE BEGINNING OF THE NEXT LINE
	AOJA	RW,WBTAB	;GO DO A WORDWISE BACKTAB FROM THERE

;**********************************************************************
;ERASE THE PREVIOUS WORD

ERASWD:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	SOS	ISVCNT		;DECREMENT INCREMENTAL SAVE COUNTER
	TLO	F,XPC		;FORCE RE-MAKE OF CHARACTER POINTER
	PUSHJ	P,MAKCPT	;RE-MAKE IT
	CAIN	T3,15		;IS THE CURSOR AT OR BEYOND END OF THE LINE?
	PUSHJ	P,ERSWDL	;YES - POSITION TO END OF LINE
	MOVE	PT,CHRPTR	;GET CHARACTER POINTER
	JUMPE	CM,ERAWDE	;IF AT LEFT MARGIN MOVE TO END OF LINE
ERAWD0:	DMOVEM	RW,SAVPOS	;SAVE CURRENT POSITION
	TLO	F,CHG!XPC	;SAY CHARACTER POINTER BAD; FILE MODIFIED
	TLZ	F,PCM!FLG	;CANCEL THE PICK-CLOSE MARK, IF ANY
	IBP	PT		;MAKE THE BYTE POINTER RIGHT FOR DECREMENTING

ERAWD1:	PUSHJ	P,ERAGET	;GET NEXT-MOST-RECENT CHARACTER
	CAIN	T1,12		;LINEFEED?
	JRST	[PUSHJ P,ERAGET	   ;YES - GET (MAYBE) THE CARRIAGE RETURN
		 CAIE  T1,15	   ;IS IT?
		 SOJA  CM,ERAWD2+1 ;NO - TREAT JUST LIKE A NORMAL CHARACTER
		 JRST  ERAWDB]	   ;YES - END OF THE ERASE
	CAIN	T1,11		;TAB?
	TLOA	F,FLG		;YES - SET FLAG, COUNT IT AND LOOP
	CAIN	T1," "		;SPACE?
	SOJA	CM,ERAWD1	;YES - MOVE OVER IT
IFN TOPS10,<
	CAIGE	T1,"0"		;NUMERIC?
	JRST	.+3		;NO - KEEP CHECKING
	CAIG	T1,"9"
	SOJA	CM,ERAWD2	;YES - PHASE TWO
	CAIL	T1,"A"		;ALPHABETIC?
	CAILE	T1,"Z"
	SOJA	CM,ERAWDX	;NO - STOP ON THE SPECIAL CHARACTER
>
	SOJ	CM,
ERAWD2:	PUSHJ	P,ERAGET	;GET NEXT-MOST-RECENT CHARACTER
	CAIGE	T1,"0"		;NUMERIC?
	JRST	.+3		;NO - KEEP CHECKING
	CAIG	T1,"9"
	SOJA	CM,ERAWD2	;YES - MOVE OVER IT
	CAIGE	T1,"A"		;ALPHABETIC?
	JRST	ERAWDX		;NO - STOP HERE
	CAIG	T1,"Z"
	SOJA	CM,ERAWD2	;YES - MOVE OVER IT

ERAWDX:	JUMPGE	CM,.+2		;BACK TO THE START OF THE LINE?
	SETZ	CM,
	TLZE	F,FLG		;WERE ANY TABS FOUND?
	PUSHJ	P,ERAWDT	;YES - CM MUST BE MADE RIGHT
ERAWX1:	TRO	F,CMV		;PRETEND ALL THIS WAS CURSOR MOVEMENT
	MOVEI	DO,$DELSP	;AND THAT DELETE-SPACES WAS TYPED
	EXCH	RW,SAVPOS	;SWAP CURRENT AND STARTING POSITIONS
	EXCH	CM,SAVPOS+1
	PUSHJ	P,PEEL.1	;READ NEW PARM, IF ANY
	MOVE	T4,PARG1	;GET SPACES TO DELETE
	PUSHJ	P,SPSCUR	;YES - HANDLE THINGS A LITTLE DIFFERENTLY
	TRZ	F,CMV		;CLEAR CURSOR MOVE FLAG (IF COMING FROM ERASWD)
	SKIPN	T1,T4		;PUT SPACES TO DELETE IN THE RIGHT AC - ANY?
	JRST	DISCUR		;NO - DONE
	JRST	CLSNP0		;GO DO THE CLOSE-SPACES

ERAWDB:	SETZ	CM,		;MOVE TO THE BEGINNING OF THE LINE
	TLZ	F,FLG		;DON'T CARE IF A TAB WAS FOUND
	JRST	ERAWX1		;GO FINISH OFF

ERAWDT:	MOVE	T4,CHRPTR	;GET OLD CHARACTER POINTER
	MOVEM	PT,CHRPTR	;SAVE POINTER TO ENDING CHARACTER
	TLO	F,XPC!XPL
	PUSHJ	P,CALCML	;FIND WHERE CM REALLY IS
	  JFCL
	MOVEM	T4,CHRPTR	;RESTORE OLD POINTER
	POPJ	P,		;DONE

;HERE IF STARTING AT OR BEYOND THE END OF A LINE
;POSITION TO THE END OF THE LINE, THEN ERASE THE WORD
;(CALLED ALSO BY DELCHR)

ERSWDL:	PUSHJ	P,CALCML	;CALCULATE PROPER VALUE OF CM
	  JRST	POSCUR		;DON'T CARE IF THERE'S A SLIDE
	JRST	POSCUR		;POSITION THE CURSOR AND RETURN

;HERE IF STARTING AT START OF LINE - DELETE LAST WORD OF PREVIOUS LINE

ERAWDE:	SOJL	RW,ERAWE2	;MOVE UP A ROW - JUMP IF AT TOP
	PUSHJ	P,ERAGET	;BACK THE CHARACTER POINTER UP
	PUSHJ	P,ERAGET
	MOVEM	PT,CHRPTR
	PUSHJ	P,MAKLPT	;GET THE POINTER TO THAT ROW (IN LINPTR AND PT)
	PUSHJ	P,CALCCM	;FIND CHARACTER POSITION
	  JRST	ERAWD0
	JRST	ERAWD0

ERAWE2:	SETZB	RW,CM		;IF USER STARTED AT HOME
	JRST	DISCUR		;LEAVE HIM THERE

;SUBROUTINE TO GET THE NEXT-LATEST FILE CHARACTER

ERAGET:	ADD	PT,[70000,,0]	;GET NEXT-MOST-RECENT CHARACTER
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T1,PT
	JUMPE	T1,ERAGET	;SKIP IF NULL
	CAIL	T1,"a"		;LOWER CASE (MAYBE)?
	SUBI	T1,40		;YES - CONVERT TO (MAYBE) UPPER
	POPJ	P,		;DONE

;SAVE THE FILE

SAVEIT:	PUSHJ	P,INCSAV	;SAVE THE FILE
	JRST	LOOP		;THAT'S ALL

;**********************************************************************
;GIVE HELP

HELPER:	PUSHJ	P,CBOTOM	;MOVE TO BOTTOM OF SCREEN
	PUSHJ	P,PROTON	;TURN PROTECTION ON
	TLON	F,ENT		;PRETEND ENTER WAS TYPED - WAS IT?
	SETZM	CHRCUR		;NO - THERE'S NO CHARACTER TO DE-BLIP
	JRST	HELPR0		;JUMP INTO ENTER-ENTER CODE (NEAR ENTHLP)

;**********************************************************************
;RECOVER COMMAND - PUT THE CONTENTS OF THE DELETE BUFFER BACK IN THE FILE

RECOVR:	PUSHJ	P,ERASPM	;CLEAN UP ENTER MODE
	TLO	F,INS!CHG	;LET LINE BE EXTENDED IF NECESSARY
	PUSHJ	P,MAKCPT	;MAKE SURE THE CURSOR POINTER IS RIGHT
	TLZ	F,INS!PCM
	SKIPN	T4,DELCNT	;GET SIZE OF THE DELETE BUFFER - ANY?
	JRST	DISCUR		;NO - NOTHING TO DO
	CAIN	T4,1		;WANT TO PUT IN ONE CHARACTER?
	JRST	RECOV1		;YES - HANDLE SPECIALLY
	MOVEM	T4,NUMCHR	;SAVE NUMBER OF CHARACTERS TO ADD
	MOVE	T1,[010700,,DELBUF-1]
	MOVEM	T1,PUTPTR	;SET TO READ FROM DELETE BUFFER
	TLO	F,WRH		;SET USE-BUFFER FLAG FOR MAKCHR
	JRST	PUTNP2		;GO PUT THEM IN

;HERE TO RECOVER ONE CHARACTER - SIMULATE INSERT-MODE TYPE-IN

RECOV1:	LDB	T1,[350700,,DELBUF] ;GET THE CHARACTER TO INSERT
	JRST	ALPIMD		;INSERT THE CHARACTER; DONE

;**********************************************************************
;HERE FOR THE SUBSTITUTE COMMAND - SEARCH FOR THE SEARCH KEY, REPLACE IT
;WITH THE SUBSTITUTE STRING; LOOP THE GIVEN NUMBER OF TIMES

SUBSTI:	TRZE	F,CMV		;DID USER USE CURSOR MOVEMENT?
	JRST	SUMERR		;YES - ILLEGAL
	SETZB	T1,SUBNUM	;END BUFFER WITH A NULL
	IDPB	T1,PARPTR
	MOVE	T4,[POINT 7,PARBUF] ;GET POINTER TO PARAMETER BUFFER
SUBST0:	SETZB	T1,T3		;CLEAR THINGS FOR PEEL ROUTINES
	ILDB	T2,T4		;GET FIRST CHARACTER OF PARAMETER
	CAIL	T2,"a"		;LOWER CASE?
	SUBI	T2,40		;YES - CONVERT TO UPPER
	CAIN	T2,"S"		;SET UP THE SEARCH KEY?
	JRST	SUBSRC		;YES - DO IT
	CAIN	T2,"R"		;SET UP THE SUBSTITUTE STRING?
	JRST	SUBSUB		;YES - DO IT

;HERE TO SET UP A NUMBER OF ITERATIONS

	PUSHJ	P,PEEL1+1	;READ (HOPEFULLY) A NUMBER
	JUMPE	T1,SUMERR	;ERROR IF TOKEN
	SKIPG	T1,PARG1	;ELSE GET NUMBER OF ITERATIONS - ANY?
	JRST	SUNERR		;NO - ERROR
	MOVEM	T1,SUBCNT	;YES - SAVE AS NEW NOMINAL
	MOVEM	T1,SUBNUM	;AND NOTE THAT IT'S NEW
	CAIE	T2,177		;END WITH A DELIMITER?
	JRST	SUBDUN		;NO - FINISH UP
	JRST	SUBST0		;YES - FIND WHAT'S NEXT

;HERE TO SET UP THE SUBSTITUTE KEY AS THE SEARCH KEY (SUBSRC)
; OR THE SUBSTITUTE STRING (SUBSUB)
;ENTER WITH T4/ POINTER TO START OF KEY IN PARBUF

SUBSRC:	MOVE	T2,[SRCKEY,,SROKEY]
	BLT	T2,SROKEY+7	;SAVE CURRENT KEY AS PREVIOUS ONE
	MOVE	T3,[POINT 7,SRCKEY]
	PUSHJ	P,PELST2	;GET SEARCH KEY
	MOVEM	T1,SRCKLN	;SAVE ITS LENGTH
	CAIE	T2,177		;END WITH A DELIMITER?
	JRST	SUBDUN		;NO - FINISH UP
	JRST	SUBST0		;YES - FIND WHAT'S NEXT

SUBSUB:	MOVE	T3,[POINT 7,SUBSTG]
	PUSHJ	P,PELST2	;GET SUBSTITUTE STRING
	MOVEM	T1,SUBSLN	;SAVE ITS LENGTH
	CAIN	T2,177		;END WITH A DELIMITER?
	JRST	SUBST0		;YES - FIND WHAT'S NEXT (ELSE FALL TO FINISH)

;HERE TO FINISH WITH PARAMETERS - DO COMMAND ONLY IF ITERATIONS WERE GIVEN

SUBDUN:	PUSHJ	P,ERASPM	;ERASE THE PARAMETER FROM THE SCREEN
	TLNN	TM,XCI		;INITIALIZING FOR AN EXECUTE?
	SKIPN	SUBNUM		;NO - WAS A NUMBER OF ITERATIONS GIVEN?
	JRST	LOOP		;NO INIT, NO NUMBER - DONE

;HERE TO DO THE SUBSTITUTE FROM THE PARAMETERS SET UP ABOVE

SUBNPM:	TRNE	F,RDO		;IS FILE READ-ONLY?
	JRST	RDOERR		;YES - COMMAND IS ILLEGAL
	SKIPG	T1,SUBCNT	;WANT TO DO ANY SUBSTITUTES?
	JRST	SUNERR		;NO - ERROR (SHOULDN'T HAPPEN)
	MOVEM	T1,SUBNUM	;YES - SAVE DECREMENTABLE NUMBER TO DO
	MOVEI	T2,1
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T2,SUBCNT	;YES - SET IT BACK TO ONE
	SETZM	SAVEAC+1	;CLEAR BOTTOM-LINE MESSAGE FLAG
	TLZ	F,PCM		;CANCEL THE PICK-CLOSE MARK, IF ANY
	TLO	F,CHG		;SAY FILE HAS CHANGED
	MOVEM	F,SAVEAC+10	;SAVE OLD SETTING OF XCT FLAG

SUBNP0:	PUSHJ	P,SRFNPM	;SEARCH FOR THE KEY
	MOVE	T4,SRCKLN	;NULL IT OUT
	SETZ	T2,
	MOVE	PT,CHRPTR
SUBNP1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,SUBNP1	;IGNORE IF NULL
	DPB	T2,PT		;ELSE NULL IT OUT
	SOJG	T4,SUBNP1	;LOOP THROUGH ALL CHARACTERS

	SKIPN	T4,SUBSLN	;GET SIZE OF THE SUBSTITUTE STRING - ANY?
	JRST	SUBNP2		;NO - NOTHING TO DO
	MOVEM	T4,NUMCHR	;SAVE NUMBER OF CHARACTERS TO ADD
	MOVE	T1,[010700,,SUBSTG-1]
	MOVEM	T1,PUTPTR	;SET TO READ FROM SUBSTITUTE BUFFER
	TLO	F,WRH		;SET USE-BUFFER FLAG FOR MAKCHR
	PUSHJ	P,MAKCHR	;PUT THE STUFF IN
SUBNP2:	TLO	F,XPC		;MARK CURSOR POINTER AS INVALID
	SKIPE	SAVEAC+1	;WAS DISPLAY POINTER MOVED DURING LAST SEARCH?
	TROA	F,XCT		;YES - PRETEND EXECUTING TO TURN OFF DISPLAY
	PUSHJ	P,DISLIN	;NO - DISPLAY THE CHANGE THAT WAS MADE

	MOVE	T1,CM		;SAVE OLD CURSOR POSITION
	ADD	CM,SUBSLN	;MOVE CURSOR TO LAST CHARACTER OF SUB. STRING
	SOSLE	SUBNUM		;GOT MORE TO DO?
	SOJA	CM,SUBNP0	;YES - LOOP

	EXCH	T1,SAVEAC+10	;NO - GET SAVED FLAGS AND SAVE OLD POSITION
	TRNN	T1,XCT		;WAS AN EXECUTE IN PROGRESS?
	TRZ	F,XCT		;NO - CLEAR EXECUTE FLAG
	SKIPE	SAVEAC+1	;MOVE OFF THE SCREEN?
	SOJA	CM,DISALL	;YES - REWRITE THE SCREEN AND RETURN
	SOJA	CM,DISCUR	;NO - MAKE CURSOR POSITION RIGHT AND LOOP

SUNERR:	SKIPA	T1,[[ASCIZ /######Can't do 0 iterations/]]
SUMERR:	MOVEI	T1,[ASCIZ /#####Cursor movement is illegal/]
	JRST	ERROR

IFE TOPS10,<
;**********************************************************************
;PUSH: RUN THE SYSTEM EXEC ON AN INFERIOR FORK. WHEN IT POPS, CONTINUE.

PSHARG:	PUSHJ	P,RESTPM	;CLEAN UP (AND IGNORE) THE PARAMETER
PUSHER: TLNE	TM,WDW		;WINDOWING?
	JRST	PUSHWI		;YES - SET THE SCREEN UP SPECIALLY
	PUSHJ	P,CLRALL	;CLEAR THE SCREEN
PUSHR0:	PUSHJ	P,PUTTYP	;NOW
	MOVEI	T1,.PRIIN
	MOVE	T2,FMDSAV	;GET BACK THE ORIGINAL FMOD WORD
	SFMOD
	STPAR
	MOVEI	T1,-5		;RE-ENABLE MONITOR INTERRUPTS
	SETO	T2,
	STIW
	MOVEI	T1,-1		;RESTORE THE CCOC WORDS
	DMOVE	T2,SAVCOC
	SFCOC
	SKIPE	T1,EXCHDL	;DOES THE FORK ALREADY EXIST?
	JRST	PUSHR2		;YES - JUST CONTINUE IT
	HRROI	T2,[ASCIZ /SYSTEM:EXEC.EXE/]
	PUSHJ	P,RUNFRK	;RUN THE EXEC AND RETURN WHEN IT EXITS
	MOVEM	T1,EXCHDL	;SAVE THE FORK HANDLE FOR NEXT TIME

PUSHR1:
IFN FTECHO,<
	HRRZM	P,EKOFLG	;MAKE SURE THE ECHO AND BREAK SETS
	HRRZM	P,BRKFLG	;  GET RE-SET
>
	PUSHJ	P,INITTY	;WHEN DONE, RE-INIT THE TERMINAL
	PUSHJ	P,@RTE(TM)	;CALL USER'S ENTRY ROUTINE
	PUSHJ	P,INITT1
	PUSHJ	P,INITTF
	JRST	DISALL		;THEN RE-DISPLAY THE SCREEN; DONE

PUSHR2:	MOVEI	T2,1		;REENTER THE EXEC
	SFRKV
	WFORK			;WAIT FOR THE FORK TO COMPLETE
	JRST	PUSHR1		;THEN RE-JOIN THE FLOW

;HERE IF WINDOWING - LEAVE THE TOP WINDOW ALONE AND CLEAR THE BOTTOM ONE

PUSHWI:	SKIPE	HOMPOS		;WINDOWING - IN BOTTOM WINDOW NOW?
	TDZA	T4,T4		;YES - POSITION HOME
	MOVE	T4,LPP(TM)	;NO - POSITION TO START OF LOWER WINDOW
	PUSHJ	P,POSLIN
	SKIPE	HOMPOS		;IN BOTTOM WINDOW NOW?
	SKIPA	T1,CPG(TM)	;YES - GET CLEAR-EOP SEQUENCE
	SKIPN	T1,SAVCPG	;NO - GET BOTTOM'S CLEAR-EOP SEQUENCE
	JUMPE	T1,PSHWI1	;IF NO CLEAR-EOP SEQUENCE, GO SIMULATE
	PUSHJ	P,PUTSEQ	;CLEAR THE BOTTOM HALF OF THE SCREEN
	JRST	PUSHR0		;RE-JOIN THE FLOW

PSHWI1:	SKIPA	T4,LPP(TM)	;OUTPUT A BUNCH OF CLEAR-LINES
	PUSHJ	P,CDOWN
	PUSHJ	P,CLRLNA
	SOJG	T4,.-2
	SKIPE	HOMPOS		;WINDOWING - IN BOTTOM WINDOW NOW?
	TDZA	T4,T4		;YES - POSITION HOME
	MOVE	T4,LPP(TM)	;NO - POSITION TO START OF LOWER WINDOW
	PUSHJ	P,POSLIN
	JRST	PUSHR0		;RE-JOIN THE FLOW

;SUBROUTINE TO CREATE A FORK AND RUN THE PROGRAM WHOSE ASCII NAME IS
;POINTED TO BY AC T2. RETURNS WHEN PROGRAM EXITS, WITH FORK HANDLE IN T1

RUNFRK:	MOVE	T1,[GJ%OLD+GJ%SHT]
	GTJFN
	  HALTF
	HRRZ	T4,T1		;SAVE JFN FOR LATER
	MOVSI	T1,200000	;CREATE AN INFERIOR FORK
	CFORK
	  HALTF
	HRL	T1,T1		;PUT PROCESS HANDLE IN LH
	HRR	T1,T4		;AND FILE'S JFN IN RH (NO SPECIAL FLAGS)
	GET			;READ IN THE PROGRAM
	HLRZ	T1,T1		;PUT PROCESS HANDLE IN RH (AGAIN)
	SETZ	T2,		;START THE FORK RUNNING
	SFRKV
	WFORK			;WAIT FOR THE FORK TO COMPLETE
	POPJ	P,		;AND RETURN
>
;%% APPEND SED2.MAC AFTER THIS
;%% SED2.MAC STARTS HERE

;**********************************************************************
;			UTILITY SUBROUTINES
;**********************************************************************
;THE ROUTINES BELOW DEAL WITH DISPLAYING PART OF THE BUFFER ON THE SCREEN
;JRST    DISDWN - FROM CURSOR POSITION TO END OF SCREEN
;JRST    DISALL - ENTIRE SCREEN
;PUSHJ P,DISPLL - ENTIRE SCREEN
;JRST    DISCUR - REPOSITION CURSOR
;PUSHJ P,DISLIN - POSITION, REMAINDER OF LINE
;PUSHJ P,DISONL - POSITION, ENTIRE LINE
;PUSHJ P,DISONE - ENTIRE LINE

;HERE TO DISPLAY FROM THE LINE THE CURSOR IS ON TO THE BOTTOM,
;POSITION THE CURSOR WHERE IT BELONGS, AND GO GET A NEW COMMAND

DISDWN:	TRNE	F,XCT		;DOING AN EXECUTE?
	JRST	DISCUR		;YES - NO DISPLAY
	SKIPN	CPG(TM)		;IS THERE A SEQUENCE FOR CLEAR-TO-EOP?
	JRST	DISDWC		;NO - SEE IF CLEAR-TO-EOL'S WILL WORK
	MOVE	T4,RW		;YES - MOVE CURSOR TO START OF LINE
	PUSHJ	P,POSLIN
	PUSHJ	P,CLEARP	;CLEAR TO END OF PAGE
DISDW1:	MOVE	PT,LINPTR
	MOVE	T4,LPP(TM)	;FIND NUMBER OF LINES TO DISPLAY
	SUB	T4,RW
	TLNE	TM,WDW		;WINDOWING?
	PUSHJ	P,DISWDW	;YES - (MAYBE) ADJUST COUNT
	TLZ	F,FNC!FBL	;FENCE WILL BE RE-DRAWN; BOTTOM LINE O.K.
	PUSHJ	P,DISPLY	;RE-DISPLAY ALL LINES AFTER CURSOR POSITION
	TRNE	F,IMD		;IN INSERT MODE?
	PUSHJ	P,INSMSG	;YES - PUT UP INSERT MESSAGE
	JRST	DISCUR		;POSITION CURSOR AND LOOP

;HERE IF THERE'S NO CLEAR-TO-END-OF-SCREEN - USE C-EOL'S IF POSSIBLE

DISDWC:	SKIPN	CLN(TM)		;CAN THE TERMINAL CLEAR A LINE?
	JRST	DISALL		;NO - GO DISPLAY THE ENTIRE PAGE
	MOVE	T4,LPP(TM)	;YES - CLEAR EACH LINE SEPARATELY
	SUB	T4,RW		;FIND NUMBER OF LINES TO DISPLAY
	TLNE	TM,WDW		;WINDOWING?
	PUSHJ	P,DISWDW	;YES - (MAYBE) ADJUST COUNT
	MOVE	T3,T4
	MOVE	T4,RW
DISDCL:	PUSHJ	P,POSLIN	;MOVE TO THE START OF ANOTHER LINE
	PUSHJ	P,CLRLNA	;CLEAR IT OUT
	AOJ	T4,		;MOVE TO NEXT LINE
	SOJG	T3,DISDCL	;LOOP THROUGH ALL LINES
	MOVE	T4,RW		;MOVE CURSOR TO START OF THE FIRST LINE
	PUSHJ	P,POSLIN
	JRST	DISDW1		;RE-JOIN THE FLOW

;DISRES: ENTRY POINT FOR THE RE-DISPLAY SCREEN OPTION OF THE RESET COMMAND

DISRES:	PUSHJ	P,RESTPM	;RESET ENTER MODE
	MOVEI	T1,77		;GET EXECUTE CODE FOR RESET
	TRNE	F,XSV		;SAVING IN AN EXECUTE BUFFER?
	DPB	T1,XCTPTW	;YES - OVERWRITE REAL CODE WITH EXECUTE CODE
DISALL:	PUSHJ	P,DISPLL	;(ENTER HERE TO DISPLAY ALL AND LOOP)
DISCUR:	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR AND RETURN
	JRST	LOOP		;AND GET ANOTHER COMMAND

;SUBROUTINE TO DISPLAY A SCREENFUL OF DATA, STARTING FROM DISPTR
;T1-T4 AND PT ARE FRAGGED

DISPLL:	TRNE	F,XCT		;DOING AN EXECUTE?
	POPJ	P,		;YES - NO DISPLAY
	PUSHJ	P,CLRALL	;GO HOME AND CLEAR THE SCREEN
	MOVE	PT,DISPTR	;GET POINTER TO START OF DISPLAY
	MOVE	T4,LPP(TM)	;SET TO DISPLAY THE ENTIRE SCREEN
	TLNE	TM,WDW		;WINDOWING?
	PUSHJ	P,DISWDW	;YES - (MAYBE) ADJUST COUNT
	PUSHJ	P,DISPS0	;DO THE DISPLAY
	MOVE	T1,DISPPT	;GET POINTER TO LAST LINE
	MOVEM	T1,BOTPTR	;SAVE AS BOTTOM POINTER
	TLNN	F,FNC		;IS THE FENCE ON THE SCREEN?
	TLZA	F,XPB		;NO - MARK BOTTOM POINTER AS GOOD
	TLO	F,XPB		;YES - BOTTOM POINTER IS BAD
	TLZ	F,FBL		;BUT BOTTOM LINE ITSELF IS O.K.
	TRNE	F,IMD		;IN INSERT MODE?
	JRST	INSMSG		;YES - PUT INSERT MESSAGE UP
	POPJ	P,		;NO - DONE

;SUBROUTINE IF WINDOWING - IF TOP WINDOW DISPLAY ONE FEWER LINE

DISWDW:	SKIPN	HOMPOS		;IN THE TOP WINDOW?
	SOJ	T4,		;YES - DISPLAY ONE FEWER LINE
	POPJ	P,

;SUBROUTINE TO DISPLAY ONE LINE, FROM CURSOR POSITION TO END
;CURSOR DOES NOT HAVE TO BE POSITIONED; CHRPTR MUST BE RIGHT

DISLIN:	TRNE	F,XCT		;DOING AN EXECUTE?
	POPJ	P,		;YES - NO DISPLAY
	PUSHJ	P,POSCUR	;MOVE CURSOR TO ITS RIGHTFUL POSITION
	SKIPN	CLN(TM)		;CAN TERMINAL CLEAR TO END OF LINE?
	JRST	[MOVEM TM,SAVEAC+4
		 TLZ   TM,TBS	;NO - MAKE TABS COME OUT AS SPACES
		 JRST  .+2]	;AND CLEAR LINE LATER
	PUSHJ	P,CLRLNR	;YES - LET IT DO SO
	MOVE	PT,CHRPTR	;SET TO WRITE ONE LINE WHERE CURSOR IS
	MOVEI	T4,1		;SAY ONE LINE WILL BE DISPLAYED

	MOVN	T2,CPL(TM)	;GET IOWD FOR CHARACTER COUNT:
	ADD	T2,CM		;  COUNT: CHARS REMAINING IN LINE
        TLNN	TM,WRP		;  WILL LINES WRAP AROUND?
	JRST	.+3		;  NO - NO EXTRA CHARACTER
	CAMGE	RW,LPP.1	;  YES - ON LAST LINE?
	SOJ	T2,		;  NO - DO ONE MORE CHARACTER
	HRLI	T2,-1(T2)
	HRR	T2,SL		;  OFFSET: SLIDE + CHARS NOT REMAINING
	ADD	T2,CM
	PUSHJ	P,DISPL0	;DISPLAY FROM CURSOR TO END OF LINE

DISCLR:	SKIPE	CLN(TM)		;COULD TERMINAL CLEAR TO END OF LINE?
	POPJ	P,		;YES - DONE
	MOVE	TM,SAVEAC+4	;NO - RESTORE CORRECT TBS FLAG
	HLRE	T0,T2		;GET ENDING POSITION IN LINE
	JUMPE	T0,CPOPJ	;NOTHING TO CLEAR IF LINE IS FULL
	ADD	T0,CPL(TM)
	SUBI	T0,2
	JRST	CLRLNR+1	;CLEAR REMAINDER OF LINE AND RETURN

;HERE TO DISPLAY ONE ENTIRE LINE POINTED TO BY (PT)
;IF CURSOR IS ALREADY POSITIONED ENTER AT DISONE

DISONL:	TRNE	F,XCT		;DOING AN EXECUTE?
	POPJ	P,		;YES - NO DISPLAY
	MOVE	T4,RW
	PUSHJ	P,POSLIN	;MOVE CURSOR TO START OF LINE
	MOVE	PT,LINPTR

DISONE:	SKIPN	CLN(TM)		;CAN TERMINAL CLEAR TO END OF LINE?
	JRST	[MOVEM TM,SAVEAC+4
		 TLZ   TM,TBS	;NO - MAKE TABS COME OUT AS SPACES
		 JRST  .+2]	;AND CLEAR LINE LATER
	PUSHJ	P,CLRLNA	;YES - LET IT CLEAR THE WHOLE LINE
	MOVEI	T4,1		;DISPLAY ONE ENTIRE LINE
	PUSHJ	P,DISPLY	;DISPLAY THE LINE
	JRST	DISCLR		;CLEAR REST OF LINE AND RETURN

;SUBROUTINE TO DISPLAY (T4) LINES STARTING AT WHERE PT POINTS IN BUFFER
;CURSOR IS ASSUMED TO BE AT THE RIGHT POSITION
;T1-T4 AND PT ARE FRAGGED

DISPLY:	TRNE	F,XCT		;DOING AN EXECUTE?
	POPJ	P,		;YES - NO DISPLAY
	TLZA	F,LFF
DISPS0:	TLZ	F,FNC!LFF
	PUSHJ	P,DISSLD	;SKIP OVER, IF THERE'S A SLIDE
DISPL0:	MOVEI	T3,TYPBUF+TYPSIZ+1 ;SET UP END-OF-TYPE-BUFFER ADDRESS

;NOW COPY LINE INTO DISPLAY BUFFER

DISPL1:	CAMN	PT,EN		;AT END OF BUFFER?
	JRST	DISPEN		;YES - DISPLAY THE REST, THEN DONE
	ILDB	T1,PT		;GET A CHARACTER FROM THE FILE BUFFER
	JUMPE	T1,DISPL1	;IGNORE A NULL
	AOBJP	T2,DISSKP	;JUMP IF LINE HAS FILLED SCREEN
	TLZE	F,LFF		;LOOKING FOR A LINEFEED?
	JRST	DISPLF		;YES - SEE IF THIS IS ONE
DISPL2:	CAIN	T1,177		;GOT A RUBOUT CHARACTER?
	JRST	DISRUB		;YES - DISPLAY AS HIGHLIGHTED "?"
	CAIGE	T1," "		;SOME KIND OF CONTROL CHARACTER?
	JRST	DISCTL		;YES - HANDLE IT SEPARATELY
DISPL3:	IDPB	T1,TY		;STORE CHARACTER IN TYPE BUFFER

DISPL4:	CAIL	T3,(TY)		;IS BUFFER FILLED?
	JRST	DISPL1		;NO - LOOP
	PUSHJ	P,PUTTYP	;FINISH BUFFER AND OUTPUT IT
	JRST	DISPL1		;AND GET MORE OUTPUT

;HERE IF A FULL LINE OF CHARACTERS HAS BEEN FOUND; IGNORE REST OF LINE

DISSKP:	CAIN	T1,12		;IS LAST CHARACTER A <LF>?
	JRST	[TLZ  F,LFF	;YES - CLEAR LINEFEED FLAG
		 JRST DISPLF]	;AND END LINE
	CAIE	T1,15		;USE THIS CHAR IF IT'S A <CR>
DISKP1:	ILDB	T1,PT		;IGNORE REST OF LINE
	CAIE	T1,15		;END OF LINE?
	JRST	DISKP1		;NO - IGNORE ANOTHER CHARACTER
	ILDB	T1,PT		;FOUND <CR> - GET <LF>
	CAIE	T1,12		;IS IT REALLY?
	JRST	DISKP1+1	;OF COURSE NOT - KEEP IGNORING
	TLNN	TM,WRP		;NEED A CARRIAGE RETURN AT END OF LONG LINE?
	JRST	DISPF1		;YES - FINISH LINE WITH CR
	SOJG	T4,DISPF2	;NO - WORKING ON LAST LINE?

;need to know if this is last line on screen or just last of display

	SETZ	T1,		;YES - OVERWRITE LAST CHAR WITH A NULL
	DPB	T1,TY
	JRST	PUTTYP		;FINISH THE DISPLAY AND RETURN

;HERE IF CHARACTER IS A RUBOUT - DISPLAY AS PROTECTED "?"

DISRUB:	MOVEI	T1,"?"-100	;GET THE QUESTION MARK
	PUSHJ	P,DISREV	;OUTPUT IT PROTECTED
	JRST	DISPL4		;AND CONTINUE

;HERE IF CHARACTER IS A CONTROL CHARACTER
;IF NOT <CR>, <LF>, OR <TB>, DISPLAY AS REVERSED-ASCII CHARACTER

DISCTL:	CAIN	T1,15		;JUST A <CR>?
	JRST	[TLO  F,LFF	;MAYBE - SET FLAG TO LOOK FOR <LF>
		 JRST DISPL4]	;AND CHECK NO FURTHER
	CAIN	T1,11		;TAB?
	JRST	DISTAB		;YES - TREAT SPECIALLY
	PUSHJ	P,DISREV	;ELSE OUTPUT REVERSED CHARACTER
	JRST	DISPL4

;HERE TO HANDLE A TAB - DE-BUMP POSITION BY SIZE OF TAB
;IF SLIDE IS A MULTIPLE OF 8, WORK WITH TAB; ELSE CONVERT TO SPACES

DISTAB:	TRNN	SL,7		;IS SLIDE A MULTIPLE OF 8?
	TLNN	TM,TBS		;  OR GOT HARDWARE TABS?
	JRST	DISTBX		;NEITHER - SIMULATE WITH SPACES
	TRNE	F,DTB		;WANT TO DISPLAY TABS?
	JRST	DISTBA		;YES - GO DO IT
DISTB0:	TRNE	T2,7		;MOVE OVER TO TAB BOUNDARY
	AOBJN	T2,.-1
	JRST	DISPL3		;SAVE TAB IN DISPLAY BUFFER

DISTBA:
DISTBB:	PUSHJ	P,PROTON	;TURN PROTECTION ON
	MOVEI	T1,"."		;OUTPUT PROTECTED DOTS OVER THE LENGTH OF TAB
DSTBA1:	IDPB	T1,TY		;OUTPUT PROTECTED "I"S
	TRNE	T2,7		;AT TAB BOUNDARY?
	AOBJN	T2,DSTBA1	;NO - KEEP GOING
	PUSHJ	P,PROTOF	;YES - TURN PROTECTION OFF
	JRST	DISPL4		;YES - CONTINUE

REPEAT 0,<
DISTBA:	PUSHJ	P,DISREV	;OUTPUT A REVERSED "I"
	TRNN	T2,7		;IS TAB REALLY ONLY ONE SPACE LONG?
	JRST	DISPL4		;YES - DON'T OUTPUT THE TAB
	MOVEI	T1,11		;ELSE - GET THE TAB BACK AGAIN
	JRST	DISTB0		;AND OUTPUT IT
>
DISTBX:	TRNE	F,DTB		;WANT TO DISPLAY TABS?
	JRST	DISTBB
DISTX1:	MOVEI	T1," "		;SIMULATE TAB: GET A SPACE
	IDPB	T1,TY
	TRNE	T2,7		;SAVE UNTIL AT TAB BOUNDARY
	AOBJN	T2,.-2
	JRST	DISPL4

REPEAT 0,<
DISTBB:	PUSHJ	P,DISREV	;OUTPUT A REVERSED "I"
	TRNN	T2,7		;AT TAB BOUNDARY?
	JRST	DISPL4		;YES - CONTINUE
	AOBJN	T2,DISTX1	;NO - OUTPUT SOME SPACES, TOO
	JRST	DISTX1
>
;SUBROUTINE TO OUTPUT THE CHARACTER IN T1 AS HIGHLIGHTED ASCII

DISREV:	PUSH	P,T1		;OUTPUT REVERSED CHARACTER
	PUSHJ	P,PROTON
	POP	P,T1		;RESTORE REVERSABLE CHARACTER
	ADDI	T1,"A"-1	;MAKE IT A CHARACTER
	IDPB	T1,TY
	PUSHJ	P,PROTOF
	CAIGE	T3,(TY)		;IS BUFFER FILLED?
	JRST	PUTTYP		;YES - FINISH BUFFER AND OUTPUT IT
	POPJ	P,		;NO - JUST RETURN

;HERE IF EOF REACHED BEFORE E.O. SCREEN. OUTPUT FENCE; DONE

	POP	P,		;(HERE FROM DISSLD)
DISPEN:	PUSHJ	P,PUTTYP	;FINISH BUFFER AND OUTPUT IT
	JRST	FNCPUT		;DISPLAY FENCE AND RETURN

;HERE IF EXPECTING A <LF> AFTER A <CR>. IF GOT ONE, COUNT AN END OF LINE

DISPLF:	CAIE	T1,12		;IS THIS CHARACTER A <LF>?
	JRST	DISPCR		;NO - REVERSE THE <CR> AND CONTINUE
DISPF1:	SOJLE	T4,[TLNE F,SCN	 ;SCANNING?
		    JRST DISTST	 ;YES - SEE IF USER WANTS TO STOP
		    JRST PUTTYP] ;NO - OUTPUT THE LAST BUFFER AND RETURN
IFN FTNIH,<
	MOVEI	T1," "		;END THE LINE WITH A SPACE
	TLNE	TM,WRP		;UNLESS DOING A SLIDE
	IDPB	T1,TY
>
	MOVEI	T1,15		;SAVE THE OLD <CR>
	IDPB	T1,TY
	PUSHJ	P,CDOWN		;MOVE TO NEXT LINE DOWN

DISPF2:	PUSHJ	P,DISTST	;SEE IF THE USER WANTS TO INTERRUPT
	CAMN	PT,EN		;AT END OF BUFFER?
	JRST	DISPEN		;YES - FINISH THE DISPLAY
	MOVEM	PT,DISPPT	;SAVE POINTER TO THE START OF THIS LINE
	PUSHJ	P,DISSLD	;SKIP OVER, IF THERE'S A SLIDE
	JRST	DISPL4		;AND CONTINUE

;HERE IF CHARACTER FOLLOWING <CR> IS NOT <LF> - MAKE <CR> REVERSED CTRL-M

DISPCR:	PUSH	P,T1		;SAVE CURRENT CHARACTER
	MOVEI	T1,15		;SET TO OUTPUT A REVERSED <CR>
	PUSHJ	P,DISREV
	POP	P,T1		;RESTORE CURRENT CHARACTER
	JRST	DISPL2

;HERE IF USER TYPED A CHARACTER DURING THE DISPLAY - STOP IT IF
;ENTER OR COMMAND, ELSE DRIVE ON
;TOPS20 NOTE: SIBE (GOTINP) FRAGS T2

DISTST:
IFN TOPS10,<
	SNOOZE	30		;SLEEP FOR AN INSTANT
	MOVE	T1,[XWD 2,[EXP 2,-1]]
	TRMOP.	T1,		;SKIP IF OUTPUT IS COMPLETE - IS IT?
	  JRST	.+2
	JRST	DISTST		;NO - KEEP WAITING
>
	GOTINP			;SKIP IF USER TYPED SOMETHING
	  POPJ	P,		;NO - CONTINUE
	TLOE	F,CWT		;SAY CHARACTER HAS BEEN READ - HAS ONE?
	POPJ	P,		;YES - JUST HAVE TO FORGET THIS ONE, THEN
	GETCHR			;READ A CHARACTER FROM THE TERMINAL IN T1
	TLZE	F,SCN		;SCANNING?
	JRST	[TLZ   F,CWT	;YES - NO WAITING COMMAND
		 MOVEI RW,^D12	;PUT CURSOR NEAR CENTER OF SCREEN
		 MOVEI CM,^D40
		 TLO   F,XPL!XPC ;LINE AND CHARACTER POINTERS ARE NO GOOD
		 POPJ  P,]	;AND QUIT
	MOVEM	T1,TYPCHR	;SAVE CHARACTER FOR LATER
	CAIL	T1,40		;CONTROL CHARACTER?
	POPJ	P,		;NO - JUST CONTINUE WITH THE DISPLAY
	MOVE	TY,TYPPTR	;IF SOMETHING WAS READY TO OUTPUT, FORGET IT
	MOVE	P,[IOWD STKSIZ,STACK] ;YES - CLEAN UP THE STACK
IFE TOPS10,<
IFN FTECHO,<
	MOVE	T1,TTYJFN	;CLEAR THE OUTPUT BUFFER
>
IFE FTECHO,<
	MOVEI	T1,.PRIOU
>
	CFOBF
>
	JRST	LOOP		;GET ANOTHER COMMAND

;SUBROUTINE TO SKIP OVER A SLIDE'S WORTH OF SPACES

DISSLD:	JUMPE	SL,DISSLE	;IF NO SLIDE, JUST SET UP SIZE
	MOVN	T2,SL		;ELSE SKIP THAT MANY REAL CHARACTERS
	HRLZ	T2,T2		;  GET AN IOWD FOR SLIDE SKIPPING
DISSL1:	ILDB	T1,PT		;GET A CHARACTER FROM THE FILE BUFFER
	CAMN	PT,EN		;AT END OF BUFFER?
	JRST	DISPEN-1	;YES - DISPLAY THE REST, THEN DONE
	JUMPE	T1,DISSL1	;IGNORE A NULL
	CAIN	T1,15		;IF <CR>, SEE IF END OF LINE
	JRST	[MOVE  T1,PT	;GET FRAGGABLE POINTER
		 ILDB  T1,T1	;GET LINEFEED
		 CAIE  T1,12	;IS IT REALLY?
		 JRST  DISSL2	;NO - SKIP THE <CR>
		 IBP   PT	;YES - SKIP <CRLF>
		 POP   P,	;KILL CALL TO DISSLD
		 MOVEI T3,TYPBUF+TYPSIZ+1 ;SET UP END-OF-TYPE-BUFFER ADDRESS
		 JRST  DISPLF]	;AND END THE LINE
	CAIN	T1,11		;TAB?
	JRST	DISSLT		;YES - COUNT IT
DISSL2:	AOBJN	T2,DISSL1	;GO UNTIL SKIPPED OUT
DISSLE:	MOVN	T2,CPL(TM)	;GET IOWD FOR CHARACTER COUNT
	HRLI	T2,-1(T2)
	HRR	T2,SL
	POPJ	P,		;THEN RETURN

DISSLT:	HRRZ	T1,T2		;HERE IF TAB - FIND ITS SIZE
	ANDI	T1,7
	SUBI	T1,10
	AOBJP	T2,DISLFP	;COUNT A SPACE; JUMP IF END OF SLIDE
	AOJL	T1,.-1		;LOOP THROUGH TAB
	JRST	DISSL1		;GET ANOTHER CHARACTER

DISLFP:	AOJE	T1,DISSLE	;IF EXACTLY COUNTED OUT, PUT NOTHING IN
	HRLZ	T1,T1		;GET IOWD FOR SPACES ADDED
	MOVEI	T2," "		;SLIDE ENDS IN MIDDLE OF TAB - PUT IN SPACES
	IDPB	T2,TY		;STORE CHARACTER IN TYPE BUFFER
	AOBJN	T1,.-1		;PUT IN ALL EXTRA SPACES
	HRLZ	T2,T1		;SET UP LENGTH OF REMAINDER OF LINE
	HRLZ	T0,CPL(TM)
	ADD	T0,[1,,0]
	SUB	T2,T0
	POPJ	P,		;THEN DONE

;************************************************************************
;SUBROUTINE TO INITIALIZE CURSOR MOVEMENT PARAMETERS
;PUT CURSOR BACK INTO TEXT AND MARK STARTING POSITION

MARKUP:	TRNE	F,XCT!XBN	;DOING AN EXECUTE?
	POPJ	P,		;YES - NO DISPLAY, THEN
	PUSH	P,T1		;SAVE CHARACTER TYPED BY USER
	MOVE	T1,[POINT 7,PARBUF]
	CAME	T1,PARPTR	;POINTING TO START OF PARAMETER BUFFER?
	JRST	[POP  P,T1	;NO - DON'T WANT TO ALLOW CURSOR MOVE
		 POP  P,
		 TRZ  F,CMV
		 JRST LOOP]
	PUSHJ	P,CMVBTM	;GO TO START OF BOTTOM LINE
	PUSHJ	P,PROTON
	MOVEI	T1,[BYTE (7) 076," ","*","*","*"
		    ASCIZ / Parm defined by cursor movement ***/]
	PUSHJ	P,PUTSTG
	PUSHJ	P,PROTOF
	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR
	POP	P,T1		;RESTORE USER'S CHARACTER
	POPJ	P,

;************************************************************************
;SUBROUTINE TO SQUEEZE ENTIRE NULL WORDS OUT OF THE BUFFER
;CALLED DURING EDITING, TO TAKE CARE OF MASSIVE DELETIONS

SQUEZW:	MOVEI	T0,SQZVAL	;RESET NUMBER OF COMMANDS TO LET GO BY
	MOVEM	T0,SQZCNT
	TRNE	F,RDO		;IS FILE READ-ONLY?
	POPJ	P,		;YES - DO NOTHING
	PUSH	P,T1		;SAVE CURRENT COMMAND
IFE TOPS10,<
	PUSH	P,EN		;SAVE OLD END OF FILE
>
	SKIPN	(EN)		;IS END PTR POINTING TO A NULL WORD
	SOJA	EN,.-1		;YES - BACK UP OVER IT
	HRLI	EN,010700	;NO - POINT TO LAST BYTE OF NON-0 WORD
	LDB	T1,EN		;GET THAT BYTE
	JUMPE	T1,.+2		;IF NULL, O.K.
	IBP	EN		;ELSE SKIP TO NEXT BYTE (WHICH IS ZERO)

	MOVEI	T3,BUFFER	;GET TWO BUFFER POINTERS
	MOVE	T4,T3
	HRRZ	T2,DISPTR	;SET UP ADDRESS FROM DISPLAY PTR
	CAIN	T2,BUFFER-1
	HRR	T2,EN		;YES - SET UP END POINTER INSTEAD

SQUEW1:	CAMN	T3,T2		;REACHED DISPLAY OR END POINTER?
	JRST	SQUEW2		;YES - DO SOMETHING
	SKIPN	T1,(T3)		;GET A WORD - NULL?
	AOJA	T3,SQUEW1	;YES - SKIP OVER IT
	AOJ	T3,		;NO - SAVE IT OFF
	MOVEM	T1,(T4)
	AOJA	T4,SQUEW1	;AND GET ANOTHER ONE

SQUEW2:	CAIE	T2,(EN)		;FOUND DISPLAY POINTER?
	JRST	[HRRM T4,DISPTR ;YES - SAVE ITS NEW ADDRESS
		 HRR  T2,EN
		 JRST SQUEW1]	;AND CONTINUE
	MOVE	T1,(EN)		;NO - SAVE LAST WORD OF BUFFER
	MOVEM	T1,(T4)
	HRR	EN,T4		;POINT TO SQUEEZED-OUT END OF BUFFER
IFN TOPS10,<
	MOVEI	T1,2(EN)	;CLEAR FROM END OF FILE TO TOP OF CORE
	HRLI	T1,-1(T1)
	MOVE	T2,.JBREL
	SETZM	1(EN)
	BLT	T1,(T2)
>
IFE TOPS10,<
	MOVEI	T1,2(EN)	;CLEAR FROM END OF FILE TO OLD END OF FILE
	HRLI	T1,-1(T1)
	POP	P,T2
	SETZM	1(EN)
	BLT	T1,(T2)
>
	TLO	F,XPB!XPL!XPC	;POINTERS ARE NO LONGER VALID
	POP	P,T1		;RESTORE CURRENT COMMAND
	POPJ	P,		;DONE

;************************************************************************
;SUBROUTINE CALLED ON EXIT TO REMOVE ALL NULLS
;AND TRAILING SPACES AND TABS FROM THE FILE

TRAILL:	MOVE	T4,[POINT 7,BUFFER]
	MOVE	PT,T4		;SET UP SOURCE AND TARGET POINTERS
	MOVE	T3,DISPTR	;GET DISPLAY POINTER
	SETZ	T2,		;CLEAR POINTER TO TRAILING SPACES
	ILDB	T1,EN		;MAKE SURE LAST CHARACTER IS A NULL
	JUMPE	T1,TRAIL1	;IF SO, O.K.
	DPB	T2,EN		;ELSE MAKE IT ONE

TRAIL1:	CAMN	T4,T3		;REACHED DISPTR?
	MOVEM	PT,DISPTR	;YES - SAVE ADJUSTED POINTER
	ILDB	T1,T4		;GET A CHARACTER
	CAIG	T1," "		;IS IT A CONTROL CHAR OR A SPACE?
	JRST	TRAILX		;YES - CHECK DEEPER
TRAIL2:	SETZ	T2,		;FORGET TRAILING SPACE POINTER
TRAIL3:	IDPB	T1,PT		;SAVE CHARACTER
	JRST	TRAIL1		;AND GET ANOTHER

TRAILX:	JUMPE	T1,[CAME T4,EN	;IF NULL, AT END OF BUFFER?
		    JRST TRAIL1 ;NO - IGNORE THE NULL
		    MOVE EN,PT	;YES - SAVE ADJUSTED END POINTER
		    IDPB T1,EN	;MAKE SURE IT ENDS ON A NULL
		    IDPB T1,EN
		    POPJ P,]
	CAIE	T1," "		;IS IT A SPACE?
	CAIN	T1,11		;IS IT A TAB?
	JRST	TRAILS		;YES - MARK CURRENT POSITION
	JUMPE	T2,TRAIL3	;IF NO TRAILING SPACES, PROCEED
	CAIE	T1,15		;ELSE IS CHARACTER A CR?
	JRST	TRAIL2		;NO - SAVE THE CHARACTER

	MOVE	T0,T4		;YES - GET CHARACTER AFTER CR
	ILDB	T0,T0
	CAIN	T0,12		;IS IT A LINEFEED?
	MOVE	PT,T2		;YES - BACK UP OVER THE TRAILING STUFF
	JRST	TRAIL2		;AND GO SAVE THE CRLF

TRAILS:	JUMPN	T2,TRAIL3	;IS POINTER ALREADY SAVED?
	MOVE	T2,PT		;NO - SAVE IT
	JRST	TRAIL3		;AND LOOP

;************************************************************************
;SUBROUTINE TO SAVE THE CURRENT FILE
;TOPS10: ENTER WITH ADDRESS OF FILBLK OR OLDBLK SET UP IN AC PT
;BOTH:	 ENTER WITH ADDRESS OF FILSPC OR OLDSPC SET UP IN AC T4

SAVFIL:
IFE TOPS10,<
	TRZ	F,GFL		;SAY FILE IS NO LONGER AROUND
>
	TRNN	F,RDO		;IS FILE READ-ONLY?
	TLZN	F,CHG		;NO - HAS IT BEEN MODIFIED?
	JRST	SAVFNO		;READ-ONLY OR NOT MODIFIED - DON'T SAVE FILE
	PUSHJ	P,SAVMGS	;YES - OUTPUT FILE-MODIFIED MESSAGE
IFN TOPS10,<
	MOVEM	PT,SAVEAC+1	;SAVE POINTER TO TOPS10 FILE DATA
	SKIPE	TAGFLG		;WANT TO PUT A TAG LINE AT START OF FILE?
	PUSHJ	P,SAVTAG	;YES - DO SO
	PUSHJ	P,TRAILL	;CHOP OUT TRAILING SPACES AND NULLS
	MOVE	PT,SAVEAC+1	;RESTORE TOPS10 POINTER
SAVFLC:
>
IFE TOPS10,<
	SETZ	T1,		;MAKE SURE ENDING CHARACTERS ARE NULLS
	MOVE	T2,EN
	DPB	T1,T2
	IDPB	T1,T2
	PUSHJ	P,SVFSET	;GET THE OUTPUT JFN
	SKIPE	TAGFLG		;WANT TO PUT A TAG LINE AT START OF FILE?
	PUSHJ	P,SAVTAG	;YES - DO SO
	PUSHJ	P,TRAILL	;CHOP OUT TRAILING SPACES AND NULLS
>
SAVFL1:	SETZ	T1,		;MAKE SURE THE REST OF LAST WORD IS NULL
	MOVE	T2,EN
	IDPB	T1,T2
	IDPB	T1,T2
	IDPB	T1,T2
	IDPB	T1,T2
	IDPB	T1,T2
	SETZM	(T2)
	MOVEI	T1,1(T2)	;THEN NULL OUT FROM END OF FILE
	HRL	T1,T2		;(TO END OF CORE OR END OF PAGE)
IFN TOPS10,<
	MOVE	EN,T2
	HRRZ	T2,.JBREL	;TO END OF CORE
	BLT	T1,(T2)
	OPEN	3,(PT)		;SET UP CHANNEL FOR THE EXISTING FILE
	  HALT
	DMOVE	T0,5(PT)	;GET FILE NAME AND EXTENSION
	SETZ	T2,
	MOVE	T3,4(PT)	;GET FILE PPN
	SKIPN	CHGSPC		;ARE SPECS UNCHANGED,
	SKIPN	BAKFLG		;AND IS A BACKUP FILE WANTED?
	JRST	SAVFLB		;NOT BOTH - NO BACKUP
	MOVSI	T1,'BAK'	;YES - SET UP A BACKUP FLAVORED FILE
	DMOVEM	T0,BAKFIL	;SAVE BACKUP NAME AND EXT
	MOVEM	T3,BAKFIL+3	;SAVE BACKUP PPN
	OPEN	5,(PT)		;ELIMINATE CURRENT BACKUP FILE (IF ANY)
	  HALT
	LOOKUP	5,BAKFIL
	  CAIA			;(DON'T DO IT IF IT'S NOT THERE)
	RENAME	5,DELFIL
	  JFCL
	RELEAS	5,
	DMOVEM	T0,BAKFIL	;GET A CLEAN LOOKUP BLOCK
	DMOVEM	T2,BAKFIL+2
	LOOKUP	3,3(PT)		;RENAME THE OLD FILE TO *.BAK
	  JRST	SAVFLA+1	;IF NONE, DON'T WORRY ABOUT IT
	LDB	T1,[POINT 9,7(PT),8] ;ELSE GET THE FILE PROTECTION
	CAIGE	T1,300		;IS IT BETWEEN 200 AND 277?
	CAIGE	T1,200
	  JRST	SAVFLA		;NO - NO NEED TO LOWER THE PROTECTION
	DMOVE	T0,5(PT)	;YES - GET THE ORIGINAL FILENAME
	HLLZ	T1,T1		;ZERO THE UNWANTED PART
	DMOVEM	T0,PRTFIL	;AND SAVE IT
	DMOVEM	T2,PRTFIL+2	;SET UP THE REST OF THE BLOCK
	LDB	T1,[POINT 9,7(PT),8] ;GET THE PROTECTION
	XORI	T1,300		;MAKE IT IN THE 100'S
	DPB	T1,[POINT 9,PRTFIL+2,8]	;AND SAVE IT
	RENAME	3,PRTFIL	;LOWER THE PROTECTION
	  JFCL			;IGNORE THE ERROR
SAVFLA:	RENAME	3,BAKFIL
	  JFCL
	CLOSE	3,
	HLL	T1,6(PT)	;GET REAL FILE'S EXTENSION
	HLLZ	T2,7(PT)	;  AND ITS PROTECTION
	TLZ	T2,000777
	DMOVEM	T0,5(PT)	;SET UP EXT AND PROTECTION IN FILE BLOCK
	MOVEM	T2,7(PT)	;SAVE FILE PROTECTION
	MOVEM	T3,4(PT)	;  AND PPN

SAVFLB:
IFE FTSFD,<
	SETZM	3+11(PT)	;ALLOW FILE NOT TO BE CONTIGUOUS IF NECESSARY
>
	ENTER	3,3(PT)		;FIND THE FILE AGAIN (FOR OUTPUT)
	  JRST	SVEERR		;ERROR - OVER QUOTA OR DISK FULL
	DMOVEM	T0,5(PT)	;CLEAN UP FILE BLOCK
	MOVEM	T2,7(PT)
	MOVEM	T3,4(PT)
	MOVE	T1,EN
	SUBI	T1,BUFFER
	MOVN	T1,T1
	HRLM	T1,FILCCL	;SET UP FILE SIZE IN COMMAND
	OUTPUT	3,FILCCL	;OUTPUT THE ENTIRE FILE
	RELEAS	3,		;CLOSE THE FILE UP
>
IFE TOPS10,<
	HRRZ	T2,EN		;CLEAR TO END OF PAGE
	TRO	T2,777
	BLT	T1,(T2)
	MOVE	T1,OUTJFN	;GET THE OUTPUT JFN
	MOVEI	T2,OF%THW+OF%WR
	OPENF
	  ERJMP	SVEERR		;IF CAN'T, JUST FINISH OFF

SAVFLB:	LDB	T1,EN		;BACK UP END PTR TO LAST REAL CHARACTER
	JUMPN	T1,SAVFB1	;DONE IF NON-NULL
	ADD	EN,[70000,,0]	;BACK UP THE BUFFER POINTER
	JUMPGE	EN,.+2
	SUB	EN,[430000,,1]
	JRST	SAVFLB		;AND TRY THE PREVIOUS CHARACTER

SAVFB1:	HRRZI	T1,1(EN)	;FIND FINAL FILE SIZE
	SUBI	T1,BUFFER
	MOVE	T3,T1		;FIND IT IN BYTES
	ADDI	T3,777		;ROUND TO NEXT HIGHER PAGE
	LSH	T3,-11
	MOVEM	T3,FILBSZ

	SOJ	T1,		;FIND IT IN CHARACTERS
	IMULI	T1,5
	HLRZ	T0,EN		;GET POINTER PART OF POINTER
	SETZ	T2,		;FIND NUMBER OF CHARACTERS IN FINAL WORD
	CAME	T0,PTRTBL(T2)
	AOJA	T2,.-1
	ADD	T1,T2
	MOVEM	T1,FILSIZ

	MOVE	T1,[400000,,BUFBLK]
	HRLZ	T2,OUTJFN	;WRITE ALL OF BUFFER INTO FILE
	MOVE	T3,[PM%CNT+PM%WR]
	ADD	T3,FILBSZ
	PMAP

	SKIPN	CHGSPC		;ARE SPECS UNCHANGED,
	SKIPN	BAKFLG		;AND IS A BACKUP FILE WANTED?
	JRST	NOBAK		;NOT BOTH - NO BACKUP
	HRROI	T1,BAKSPC	;YES - GET BACKUP SPECS
	MOVE	T2,INJFN	;  WITH INPUT FILE NAME
	MOVE	T3,[221000,,1]
	SETZ	T4,
	JFNS
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	HRROI	T2,[ASCII /.BAK/] ;CHANGE EXTENSION TO .BAK
	MOVNI	T3,5
	SOUT			;MOVE THE STRING
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	MOVSI	T1,(GJ%FOU+GJ%SHT) ;OPEN THE BACKUP FILE
	HRROI	T2,BAKSPC
	GTJFN
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	MOVE	T2,T1
	MOVE	T3,T1
	MOVE	T1,INJFN	;SET TO RENAME THE ORIGINAL FILE
	RNAMF
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	SKIPA	T1,T3		;SET TO RELEASE THE BACKUP JFN
NOBAK:	MOVE	T1,INJFN	;(OR RELEASE THE INPUT JFN)
	RLJFN
	  JFCL
	HRLI	T1,(CO%NRJ)	;CLOSE FILE; DON'T RELEASE JFN
	HRR	T1,OUTJFN
	CLOSF
	  JRST	SVEERR
	HRLI	T1,.FBSIZ	;CHANGE FILE SIZE IN DESCRIPTOR BLOCK
	OR	T1,[CF%NUD]
	SETO	T2,
	MOVE	T3,FILSIZ
	CHFDB
	HRLI	T1,.FBBYV	;TELL FILE ITS BYTE SIZE IS NOW 7
	MOVE	T2,[FB%BSZ]
	MOVSI	T3,700
	CHFDB
	MOVE	T1,OUTJFN	;NOW RELEASE THE JFN
	RLJFN
	  JRST	SVEERR
>
	POPJ	P,

IFE TOPS10,<
SAVFLC:	PUSHJ	P,SVFSET	;GET THE OUTPUT JFN
	JRST	SAVFL1		;JUMP INTO THE FLOW

SVFSET:	MOVE	T1,EXTTBL	;IS .TMP THE EXTENSION OF THIS FILE?
	CAMN	T1,[ASCII /TMP/]
	SKIPA	T1,[GJ%SHT]	;YES - DON'T BUMP VERSION NUMBER (ELSE DO)
	MOVE	T1,[GJ%FOU+GJ%SHT]
	HRRO	T2,T4		;GET A JFN FOR THE OUTPUT FILE
	GTJFN
	  ERJMP	SVEERR		;OOPS - FILE IS READ-ONLY - JUST FINISH OFF
	MOVEM	T1,OUTJFN	;SAVE THE OUTPUT JFN
	POPJ	P,		;DONE
>
SAVFNO:
IFE TOPS10,<
	MOVE	T1,INJFN	;RELEASE THE INPUT JFN
	RLJFN
	  JFCL
>
	PUSHJ	P,SAVMGN	;TELL USER THAT FILE IS NOT CHANGED
	SNOOZE	^D0700		;SLEEP A BIT
	POPJ	P,

IFE TOPS10,<
NBKERR:	MOVEI	T1,[ASCIZ /
Error - no backup file generated /]
	PUSHJ	P,PUTSTG	;OUTPUT THE ERROR MESSAGE
	PUSHJ	P,PUTTYP
	JRST	NOBAK		;GO FINISH OFF
>
SVEERR:	TLO	F,CHG		;REMEMBER THAT FILE WAS CHANGED
	IBP	EN		;POINT BEYOND THE LAST CHARACTER OF THE FILE
	MOVEI	T1,[ASCIZ /Can't save - quota exceeded or disk full/]
	PUSHJ	P,ERRDSP	;OUTPUT THE MESSAGE
IFN TOPS10,<				;is this necessary?
	PUSHJ	P,INITTY	;RE-INIT THE TERMINAL
>
	PUSHJ	P,DISPLL	;RE-DISPLAY THE SCREEN
	MOVE	P,[IOWD STKSIZ,STACK]
	JRST	DISCUR		;WAIT FOR FURTHER INSTRUCTIONS

;SUBROUTINE TO PUT A TAG LINE AT THE START OF THE FILE BEFORE IT'S SAVED.
;THE TAG LOOKS LIKE: ";<CHALL>SED.MAC.1, 11-Mar-82 09:25:27, Edit by CHALL"

SAVTAG:	MOVEM	TY,SAVEAC	;SAVE THE TYPE-OUT BUFFER POINTER
	MOVEI	T1,^D100	;INSERT 100 NULLS
	MOVEM	T1,NUMCHR
	MOVE	TY,[010700,,BUFFER-1]
	MOVEM	TY,CHRPTR	;AT THE START OF THE FILE
	HRRZ	T1,DISPTR	;TELL MAKNUL TO ADJUST THE DISPLAY POINTER
	MOVEM	T1,ADJWRD
	TLO	F,XPB!XPL!XPC	;POINTERS ARE NO LONGER VALID
	PUSHJ	P,MAKNUL	;AND POINT TO START OF FILE
	SETZ	T1,		;CLEAR AND GET ADJUSTED DISPLAY ADDRESS
	EXCH	T1,ADJWRD
	MOVE	T2,DISPTR	;AT THE START OF THE FILE?
	CAMN	T2,[010700,,BUFFER-1]
	AOJA	RW,.+2		;YES - LEAVE DISPTR ALONE; MOVE ONE ROW DOWN
	HRRM	T1,DISPTR	;SAVE IT WITH THE DISPLAY POINTER
	MOVEI	T1,";"		;START WITH THE COMMENT CHARACTER
	IDPB	T1,TY
IFN TOPS10,<
	MOVEI	T1,FILSPC	;OUTPUT THE CURRENT FILESPECS
	PUSHJ	P,PUTSTG
	MOVEI	T3,","		;DELIMIT WITH COMMA, SPACE
	IDPB	T3,TY
	MOVEI	T3," "
	IDPB	T3,TY

	MOVS	T4,[60,,11]	;SET UP INDEX FOR DATES IN CONFIG TABLE
	PUSHJ	P,SAVTAD	;READ DAY
	PUSHJ	P,SVTATN 	;OUTPUT IT AS TWO DIGITS
	PUSHJ	P,SAVTAD 	;READ MONTH
	MOVE	T1,MONTAB-1(T1)	;GET ITS NAME
	PUSHJ	P,PUTSQ1 	;OUTPUT IT
	PUSHJ	P,SAVTAD 	;READ YEAR
	PUSHJ	P,PUTNUM 	;OUTPUT IT
	IDPB	T3,TY		;SEPARATE DATE FROM TIME WITH A SPACE

	MOVS	T4,[61,,11]	;SET UP INDEX FOR TIMES IN CONFIG TABLE
	MOVEI	T3,":"		;GET A COLON FOR DELIMITING
	PUSHJ	P,SAVTAT 	;READ AND OUTPUT THE HOUR
	IDPB	T3,TY		;DELIMIT WITH A COLON
	PUSHJ	P,SAVTAT 	;READ AND OUTPUT THE MINUTE
	IDPB	T3,TY		;DELIMIT WITH A COLON
	PUSHJ	P,SAVTAT 	;READ AND OUTPUT THE SECOND
>
IFE TOPS10,<
	MOVE	T1,TY		;SET UP POINTER FOR JSYS'S
	MOVE	T2,OUTJFN	;GET THE JFN OF THE OUTPUT FILE
	MOVE	T3,[2B2+1B5+1B8+1B11+1B14+1B35]
	JFNS			;OUTPUT THE COMPLETE FILESPEC
	MOVEI	T2,","		;DELIMIT WITH COMMA, SPACE
	IDPB	T2,T1
	MOVEI	T2," "
	IDPB	T2,T1
	SETO	T2,		;OUTPUT THE CURRENT DATE AND TIME
	SETZ	T3,
	ODTIM
	MOVE	TY,T1		;UPDATE THE CHARACTER POINTER
>
	MOVEI	T1,[ASCIZ /, Edit by /]
	PUSHJ	P,PUTSTG
IFN TOPS10,<
	MOVE	PT,TY
	PJOB	T4,		;GET JOB NUMBER
	HRL	T2,T4
	HRRI	T2,31		;READ FIRST PART OF USER NAME
	GETTAB	T2,
	  SETZ	T2,		;(IT BETTER WORK)
	PUSHJ	P,PUTSIX	;OUTPUT THE SIXBIT FIRST PART
	HRL	T2,T4
	HRRI	T2,32		;READ SECOND PART OF USER NAME
	GETTAB	T2,
	  SETZ	T2,
	PUSHJ	P,PUTSIX	;OUTPUT THE SIXBIT SECOND PART
	MOVEI	T2,15		;END WITH A CRLF
	IDPB	T2,PT
	MOVEI	T2,12
	IDPB	T2,PT
>
IFE TOPS10,<
	GJINF			;GET LOGGED-IN DIRECTORY NUMBER
	MOVE	T2,T1		;PUT IN THE RIGHT PLACE FOR DIRST
	MOVE	T1,TY
	DIRST			;WRITE USER NAME
	 JRST	SAVTGN		;UNKNOWN - SAY SO AND RETURN
	MOVEI	T2,15		;END WITH A CRLF
	IDPB	T2,T1
	MOVEI	T2,12
	IDPB	T2,T1
>
	MOVE	TY,SAVEAC	;GET THE READ TYPE-OUT BUFFER POINTER BACK
	POPJ	P,		;DONE

IFE TOPS10,<
SAVTGN:	MOVEI	T1,[ASCIZ /Unknown user
/]
	PUSHJ	P,PUTSTG	;DIRST FAILED - SAY SOMETHING USEFUL
	MOVE	TY,SAVEAC	;GET THE READ TYPE-OUT BUFFER POINTER BACK
	POPJ	P,		;DONE
>
IFN TOPS10,<
SAVTAD:	MOVS	T1,T4		;READ THE NEXT DATE TABLE ENTRY
	GETTAB	T1,
	  HALT			;(IT BETTER WORK)
	SOJA	T4,CPOPJ

SAVTAT:	MOVS	T1,T4		;READ THE NEXT TIME TABLE ENTRY
	AOJ	T4,
	GETTAB	T1,
	  HALT			;(IT BETTER WORK)
SVTATN:	IDIVI	T1,^D10		;SEPARATE INTO TWO DIGITS
	ADDI	T1,"0"		;MAKE THEM BOTH ASCII
	ADDI	T2,"0"
	IDPB	T1,TY		;SAVE THEM
	IDPB	T2,TY
	POPJ	P,

MONTAB:	ASCII	/-Jan-/		;TABLE OF NAMES OF MONTHS
	ASCII	/-Feb-/
	ASCII	/-Mar-/
	ASCII	/-Apr-/
	ASCII	/-May-/
	ASCII	/-Jun-/
	ASCII	/-Jul-/
	ASCII	/-Aug-/
	ASCII	/-Sep-/
	ASCII	/-Oct-/
	ASCII	/-Nov-/
	ASCII	/-Dec-/
>
;ROUTINES TO OUTPUT FILE SAVE MESSAGES
;ENTER WITH T4/ ADDR OF OLDSPC OR FILSPC (WHICHEVER IS CURRENT FILE)

SAVMGN:	TLNE	TM,WDW		;IN A WINDOW?
	POPJ	P,		;YES - NO MESSAGE
	PUSHJ	P,CLRALL	;TELL USER THAT FILE IS NOT CHANGED
	MOVEI	T1,[ASCIZ /NOT MODIFIED: /]
	PUSHJ	P,PUTSTG
	MOVE	T1,T4		;OUTPUT FILESPECS
	PUSHJ	P,PUTSTG
	JRST	SAVMG1

SAVMGS:	TLNE	TM,WDW		;IN A WINDOW?
	POPJ	P,		;YES - NO MESSAGE
	PUSHJ	P,CLRALL
	MOVEI	T1,[ASCIZ /SAVING FILE: /]
	PUSHJ	P,PUTSTG
	MOVE	T1,T4		;OUTPUT FILESPECS
	PUSHJ	P,PUTSTG
	SKIPN	CHGSPC		;ARE SPECS UNCHANGED,
	SKIPN	BAKFLG		;AND IS A BACKUP FILE WANTED?
	SKIPA	T1,[[ASCIZ / (NO BACKUP)/]]
	MOVEI	T1,[ASCIZ / (WITH BACKUP)/]
	PUSHJ	P,PUTSTG

SAVMG1:	MOVEI	T1,15		;END WITH A CARRIAGE RETURN
	IDPB	T1,TY
	MOVEI	T1,12
	IDPB	T1,TY
	JRST	PUTTYP

;************************************************************************
;SUBROUTINE TO LOOK UP THE FILE POINTED TO BY T2, FOR OUTPUT
;TOPS10 CALL: MOVEI T2,FILFIL;	       PUSHJ P,SETOUT
;TOPS20 CALL: HRROI T2,[ASCIZ /FILE/]; PUSHJ P,SETOUT

IFN TOPS10,<
SETOUT:	MOVE	T1,USRPPN	;SET UP USER'S PPN
	MOVEM	T1,3(T2)
	OPEN	5,GENBLK	;OPEN A DUMP MODE OUTPUT FILE
	  HALT			;ON CHANNEL 5
SETOU1:	ENTER	5,(T2)
	  HALT
	HLLZS	1(T2)
	SETZM	2(T2)
	SETO	T1,
	POPJ	P,
>
IFE TOPS10,<
SETOUT:	MOVE	T1,[GJ%SHT]	;IT COULDN'T BE MORE STRAIGHTFORWARD
	GTJFN
	  JRST	SETOU1
	MOVE	T2,[7B5+OF%WR]
	OPENF
SETOU1:	  SETZ	T1,		;ON FAILURE RETURN T1/ 0
	POPJ	P,
>
;SUBROUTINE TO LOOK UP THE FILE POINTED TO BY T2, FOR INPUT
;TOPS10 CALL: MOVEI T2,FILFIL;	       PUSHJ P,SETIN
;TOPS20 CALL: HRROI T2,[ASCIZ /FILE/]; PUSHJ P,SETIN
;RETURNS -FILE SIZE OR HANDLE IN T1 IF LOOKUP SUCCESSFUL, ELSE 0

;SETINP USES THE PPN IN THE BLOCK; SETIN USES THE USER'S PPN

IFN TOPS10,<
SETINP:	MOVE	T0,3(T2)	;GET THE PPN FROM THE BLOCK
	JRST	.+2
SETIN:	MOVE	T0,USRPPN	;SET UP USER'S PPN
	SETZB	T1,3(T2)	;TRY PATHED DIR. FIRST; ASSUME FILE'S NOT THERE
	OPEN	5,GENBLK	;OPEN A DUMP MODE INPUT FILE
	  POPJ	P,		;ON CHANNEL 5
	LOOKUP	5,(T2)
	  JRST	SETIN1		;NO SUCH FILE - TRY LOGIN DIRECTORY
SETIN2:	MOVSI	T1,'DSK'	;REPAIR THE OPEN BLOCK
	MOVEM	T1,GENBLK+1	;  IN CASE IT WAS CHANGED
	HLLZS	1(T2)
	SETZM	2(T2)
	MOVE	T1,3(T2)	;GET THE NEGATIVE FILE SIZE
	MOVEM	T0,3(T2)	;PUT THE PPN BACK IN
	POPJ	P,

SETIN1:	HLLZS	1(T2)		;CLEAN UP LOOKUP BLOCK
	SETZM	2(T2)
	MOVEM	T0,3(T2)	;LOOK IN LOGIN DIRECTORY
	LOOKUP	5,(T2)
	  POPJ	P,		;NO SUCH FILE - RETURN ZERO
	JRST	SETIN2		;GOT IT - BACK TO FLOW
>
IFE TOPS10,<
SETINP:
SETIN:	MOVE	T0,T2		;SAVE FILESPEC POINTER
	MOVSI	T1,(GJ%OLD+GJ%SHT)
	GTJFN
	  SKIPA	T1,[INIJFN]	;NOT FOUND - TRY USER'S PS:
	JRST	SETIN1		;GOT IT - GO OPEN AND READ
	MOVE	T2,T0		;GET FILESPEC POINTER BACK
	SKIPE	USRNAM		;(DON'T DO IT IF NO USER NAME)
	GTJFN
	  JRST	SETIN2		;NO SED.INIT - RETURN FAILURE
SETIN1:	HRRZ	T1,T1		;CLEAR FLAGS OUT OF LH OF T1
	MOVE	T2,[7B5+OF%RD]
	OPENF			;OPEN THE FILE
SETIN2:	  SETZ	T1,		;FAILED - FLAG AS SUCH
	POPJ	P,		;RETURN SUCCESS OR FAILURE
>
IFN TOPS10,<
;SUBROUTINE TO DELETE A FILE. SPECS IN T2

SETDEL:	MOVE	T1,USRPPN	;SET UP USER'S PPN
	MOVEM	T1,3(T2)
	OPEN	5,GENBLK	;OPEN A DUMP MODE INPUT FILE
	  HALT			;ON CHANNEL 5
	LOOKUP	5,(T2)
	  CAIA			;NO FILE - DON'T DELETE IT
	RENAME	5,DELFIL	;DELETE IT
	  JFCL
	RELEAS	5,		;GET RID OF IT
	POPJ	P,
>
IFE TOPS10,<
;SUBROUTINE TO MAKE A TOPS20 FILE TEMPORARY. ENTER WITH JFN IN T1

SETTMP:	HRLI	T1,1		;LIGHT TEMP BIT IN
	MOVSI	T2,(FB%TMP)	;  2ND WORD OF FILE DATA BLOCK
	MOVSI	T3,(FB%TMP)
	CHFDB
	CLOSF			;THEN CLOSE THE FILE
	  POPJ	P,
	POPJ	P,
>
;************************************************************************
;ROUTINES TO UNDO THE DAMAGE CAUSED BY ENTER MODE, WHICH CAN BE:
;  1. REVERSED-SPACE AT CURSOR POSITION (COVER WITH CHARACTER FROM BUFFER)
;  2. ENTER LINE AT BOTTOM OF SCREEN (RE-WRITE WITH LINE FROM BUFFER)
;  3. ENTER FLAG (RESET IT)
;  4. CURSOR IS ILL-POSITIONED (RE-POSITION IT)

;THE ENTER FLAG MUST ALWAYS BE CLEARED. THE OTHER THINGS MAY NOT NEED TO
;BE UNDONE, DEPENDING ON HOW MUCH OF THE SCREEN HAS BEEN OVERWRITTEN.
;THUS THE ABOVE ARE HANDLED BY DIFFERENT SUBROUTINES, SO NO MORE WORK NEEDS
;TO BE DONE THAN NECESSARY.

;THE LINE AT THE BOTTOM MUST BE RE-DONE QUICKLY IF IT NEEDS TO BE DONE AT ALL
;THE TEXT MARK SHOULD ALSO BE DONE QUICKLY, SO CHRPTR MAY NOT NEED RE-MAKING
;CURSOR POSITIONING SHOULD BE THE LAST THING DONE BY THE COMMAND ROUTINE

;SUBROUTINE TO RESET ENTER MODE (NOTE: CAN'T FRAG T4)

RESTPM:	TLZN	F,ENT		;WAS ENTER TYPED?
	POPJ	P,		;NO - NOTHING TO DO
	TRNE	F,XCT!XBN	;EXECUTING?
	JRST	ERSPM2		;YES - DON'T OUTPUT ANYTHING
	PUSH	P,T4		;ELSE SAVE OLD T4
	JRST	ERSPM1		;AND DE-BLIP THE BLIP

;SUBROUTINE TO WRITE LAST LINE OF SCREEN OVER ENTERED PARAMETER

ERASPM:	TLZN	F,ENT		;WAS ENTER TYPED?
	POPJ	P,		;NO - NOTHING TO DO
	TRNE	F,XCT!XBN	;EXECUTING?
	JRST	ERSPM2		;YES - DON'T OUTPUT ANYTHING
ERSPM0:	PUSH	P,T4		;SAVE OLD T4
	TLNE	TM,NEL		;IS BOTTOM LINE SCRATCH?
	JRST	ERSPM1		;YES - DON'T BOTHER TO ERASE IT
	TRNE	F,IMD		;IN INSERT MODE?
	JRST	[TLNE  TM,BEP	;YES - JUST WANT TO BEEP?
		 JRST  .+1	;YES - FIX UP BOTTOM LINE, THEN
		 PUSHJ P,INSMSG ;NO - RESTORE INSERT MESSAGE
		 JRST  ERSPM1]
	PUSHJ	P,FIXBLN	;RE-DO THE BOTTOM LINE
ERSPM1:	SKIPN	T1,CHRCUR	;GOT A BLIP TO DE-BLIP?
	JRST	ERSPM2-1	;NO - DON'T DE-BLIP IT, ALREADY
	CAIGE	T1," "		;IS CHARACTER A CONTROL CHARACTER?
	JRST	[TLNN  TM,MRK	;YES - GOT A MARK THERE?
		 JRST  ERSPM2-1	;NO - DON'T DE-BLIP IT
		 ADDI  T1,100	;YES - MAKE CHARACTER A REAL CHARACTER
		 MOVEM T1,CHRCUR
		 JRST  .+1]	;AND DRIVE ON
	PUSHJ	P,POSCUR	;ELSE POSITION THE CURSOR
IFN FTNIH,<
	PUSHJ	P,PROTOF	;UNPROTECT THE CHARACTER
>
IFE FTNIH,<
	MOVE	T1,CHRCUR
	IDPB	T1,TY		;PUT THE PROPER CHARACTER BACK THERE
	PUSHJ	P,CLEFT		;AND POSITION OVER THE CHARACTER
>
	POP	P,T4		;RESTORE THE T4 THAT WAS ENTERED WITH
ERSPM2:	TRZN	F,CMV		;CLEAR CURSOR MOVEMENT FLAG - ON?
	POPJ	P,		;NO - RETURN
	CAME	RW,SAVPOS	;YES - WAS ROW CHANGED?
	TLO	F,XPL!XPC	;YES - POINTERS ARE NO GOOD
	MOVE	RW,SAVPOS	;RESTORE SAVED POSITION
	CAME	CM,SAVPOS+2	;WAS COLUMN CHANGED?
	TLO	F,XPC		;YES - CURSOR POINTER IS NO GOOD
	MOVE	CM,SAVPOS+1
	JRST	PUTTYP		;OUTPUT THE POSITIONING AND RETURN

;SUBROUTINE TO FIX UP THE BOTTOM LINE OF THE SCREEN

FIXBLN:	TLZ	F,FBL		;YES - SAY BOTTOM WON'T BE FRAGGED AFTER ALL
	PUSHJ	P,CBOTOM	;MOVE TO BOTTOM OF SCREEN
	TLZE	F,XPB		;IS POINTER TO LAST LINE VALID?
	PUSHJ	P,MAKBPT	;NO - MAKE IT
	SKIPN	PT,BOTPTR	;IS THERE REALLY A BOTTOM LINE?
	JRST	FNCPUT		;NO - PUT UP THE FENCE AND RETURN
	JRST	DISONE		;ELSE RE-DO THE BOTTOM LINE AND RETURN

;**********************************************************************
;SUBROUTINES TO POSITION THE CURSOR
;THESE JUST CALL THE ACTUAL POSITIONING ROUTINES IN THE TERMINAL-DEPENDENT
;CODE, OUTPUT IDLES AS DESIRED, AND TYPE OUT THE TYPE BUFFER

POSLIN:	ADD	T4,HOMPOS	;MAKE POSITION RELATIVE TO HOME
	PUSHJ	P,@PSL(TM)	;POSITION TO THE RIGHT LINE
	SUB	T4,HOMPOS	;RESTORE PROPER POSITION
	JRST	POSEND		;GO FINISH OFF

POSCUR:	ADD	RW,HOMPOS	;MAKE POSITION RELATIVE TO HOME
	PUSHJ	P,@PSC(TM)	;POSITION TO THE RIGHT CHARACTER
	SUB	RW,HOMPOS	;RESTORE PROPER POSITION
POSEND:	TLNN	TM,NLP		;FOLLOW WITH SOME NULLS?
	JRST	PUTTYP		;NO - OUTPUT THE POSITIONING AND QUIT
	MOVE	T1,NUL(TM)	;YES - GET NULL CHARACTER
	HLRZ	T2,T1		;AND NUMBER OF NULLS TO OUTPUT
	IDPB	T1,TY		;OUTPUT A NULL
	SOJG	T2,.-1		;OUTPUT ALL THE NULLS, IN FACT
	JRST	PUTTYP		;THEN SEND IT ALL AND RETURN

;************************************************************************
;SUBROUTINES TO MANIPULATE POINTERS

;SUBROUTINE TO BACK UP THE DISPLAY POINTER BY (T4) LINES
;STOPS, NATURALLY, IF IT HITS THE START OF BUFFER. IN THAT CASE, T4 HAS
;NUMBER OF LINES NOT BACKED UP, SO SUBTRACT T4 FROM THE DISTANCE YOU
;THINK YOU WENT TO GET THE ACTUAL DISTANCE

BAKDPT:	MOVE	PT,DISPTR	;GET POINTER TO START OF SCREEN
	CAMN	PT,[010700,,BUFFER-1] ;AT START OF BUFFER?
	POPJ	P,		      ;YES - NOTHING TO DO AT ALL
BAKDP1:	ADD	PT,[70000,,0]	;FUDGE A DECREMENT OF THE BUFFER POINTER
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T2,PT		;GET A CHARACTER
BAKDP2:	CAIE	T2,12		;LINEFEED?
	JRST	BAKDP1		;NO - IGNORE IT

	CAMN	PT,[010700,,BUFFER-1] ;AT START OF BUFFER?
	JRST	[MOVEM PT,DISPTR      ;YES - POINT TO START OF BUFFER
		 SOJA  T4,CPOPJ]      ;ADJUST COUNT AND RETURN
	ADD	PT,[70000,,0]	;FUDGE A DECREMENT OF THE BUFFER POINTER
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T2,PT		;YES - PICK UP THE <CR>
	CAIE	T2,15		;IS IT REALLY?
	JRST	BAKDP2		;NO - IT'S NOT THE END OF THE LINE
	SOJG	T4,BAKDP1	;YES - LOOP THROUGH DESIRED NUMBER OF ROWS
	IBP	PT		;SKIP OVER THAT LAST LINEFEED
	MOVEM	PT,DISPTR	;SAVE SET-UP DISPLAY POINTER
	POPJ	P,		;DONE

;SUBROUTINE TO ADVANCE DISPLAY POINTER BY (T4) LINES
;IF END OF FILE FOUND, SETS DISPTR TO LINROL LINES BEFORE END OF FILE

ADVDPT:	MOVE	PT,DISPTR	;GET DISPLAY POINTER
	PUSHJ	P,ADVLPT	;ADVANCE IT
	MOVEM	PT,DISPTR	;SAVE IT AGAIN
	JUMPGE	T4,CPOPJ	;IF NOT HIT END JUST RETURN
	TRNE	F,XCT		;EXECUTING?
	JRST	XCEERR		;YES - SAY FINISHED PREMATURELY
	ADD	T4,ROLLS	;ELSE FIND DISTANCE OF REAL ROLL
	SUB	T4,LINROL
	SOJ	T4,
	MOVEM	T4,ROLLS	;SAVE REAL ROLL
	MOVE	T4,LINROL	;BACK UP LINROL LINES
	TLO	F,FLG		;SET FLAG FOR RE-DISPLAY
	JRST	BAKDPT		;AND RETURN WITH THAT

;SUBROUTINE TO MAKE A POINTER TO THE CHARACTER WHERE THE CURSOR IS
;CANNOT USE T1, SINCE THERE MAY BE A LIVE CHARACTER THERE
;RETURNS CHARACTER POINTED TO BY CHRPTR, IN T3
;IF THAT CHARACTER IS A TAB, RETURNS PTR TO IT IN TABPTR

MAKCPT:	TLZN	F,XPC		;IS CHARACTER POINTER ALREADY GOOD?
	JRST	MAKCOK		;YES - CHECK FOR TAB (MAY COME BACK TO .+1)
MAKCK1:	TLZE	F,XPL		;IS LINE POINTER GOOD?
	PUSHJ	P,MAKLPT	;NO - MAKE IT FIRST

MAKCP0:	MOVE	T3,LINPTR	;GET LINE POINTER
	MOVEM	T3,CHRPTR	;SAVE AS STARTING CHARACTER POINTER
	MOVE	T2,CM		;GET COLUMN TO MOVE TO
	ADD	T2,SL		;  (INCLUDING SLIDE OFFSET)
	JUMPE	T2,MAKCP3	;IF ZERO, JUST CHECK FOR A TAB
MAKCP1:	CAMN	EN,CHRPTR	;AT END OF USEABLE BUFFER?
	JRST	MAKCR0		;YES - ADD A FEW SPACES buggy if here
	ILDB	T3,CHRPTR	;GET A CHARACTER
	JUMPE	T3,MAKCP1	;IGNORE IF NULL
	CAIN	T3,15		;CARRIAGE RETURN?
	JRST	MAKCCR		;YES - NEED TO EXTEND LINE
MAKCP2:	CAIN	T3,11		;TAB?
	JRST	MAKCTB		;YES - NEED TO USE THE RIGHT NUMBER OF SPACES
	SOJG	T2,MAKCP1	;LOOP THROUGH DESIRED NUMBER OF COLUMNS
MAKCP3:	MOVE	T2,CHRPTR	;DONE - SEE WHAT CHARACTER IS POINTED TO
	CAMN	T2,EN		;AT END OF BUFFER?
	JRST	[MOVEI T2,15	;YES - NEED A FINAL <CR>
		 IDPB  T2,EN
		 MOVEI T2,12
		 IDPB  T2,EN
		 POPJ  P,]
	ILDB	T3,T2
	JUMPE	T3,MAKCP3+1	;SKIP, IF NULL
	CAIE	T3,11		;IF IT'S A TAB, SET UP COUNTS AND RETURN
	POPJ	P,		;ELSE JUST RETURN
	MOVEM	T2,TABPTR	;SAVE POINTER TO TAB
	MOVE	T2,CM		;FIND NEGATIVE HOW LONG THIS TAB SHOULD BE
	ADD	T2,SL
	ANDI	T2,7
	SUBI	T2,10
	SETZM	TABSPC		;WANT NO SPACES TO LEFT OF TAB
	MOVNM	T2,TABSIZ	;SAVE LENGTH OF TAB
	POPJ	P,		;NOW RETURN

;HERE WHEN TAB FOUND. JUMP THE CORRECT NUMBER OF SPACES
;IF DESIRED POSITION IS WITHIN THE TAB, POINT TO START OF TAB

MAKCTB:	MOVE	T3,CM		;FIND NEGATIVE HOW LONG THIS TAB SHOULD BE
	ADD	T3,SL
	SUB	T3,T2
	ANDI	T3,7
	SUBI	T3,10
	DPB	T2,[POINT 3,TABSPC,35]
	MOVNM	T3,TABSIZ
	ADD	T2,T3		;MOVE OVER THAT MANY POSITIONS
	MOVEI	T3,11		;GET THE TAB BACK
	JUMPG	T2,MAKCP1	;O.K. IF STILL MORE TO GO
	JUMPE	T2,MAKCP3	;OR JUMP IF COUNTED OUT EXACTLY
	MOVE	T2,CHRPTR	;BACK POINTER UP BEFORE THE TAB
	MOVEM	T2,TABPTR
	ADD	T2,[70000,,0]
	JUMPGE	T2,.+2
	SUB	T2,[430000,,1]
	MOVEM	T2,CHRPTR
	POPJ	P,		;AND THEN DONE

;HERE IS CHARACTER POINTER IS O.K. - RECALCULATE IF IT POINTS TO A TAB

MAKCOK:	MOVE	T2,CHRPTR	;DONE - SEE WHAT CHARACTER IS POINTED TO
	CAMN	T2,EN		;AT END OF BUFFER?
	JRST	[MOVEI T2,15	;YES - NEED A FINAL <CR>
		 IDPB  T2,EN
		 MOVEI T2,12
		 IDPB  T2,EN
		 JRST  MAKCK1]
	ILDB	T3,T2
	JUMPE	T3,MAKCOK+1	;SKIP, IF NULL
	CAIN	T3,15		;GET A <CR>?
	JRST	[TLNN  F,INS	;YES - WANT TO INSERT IF CURSOR OUT OF RANGE?
		 POPJ  P,	;NO - RETURN FROM MAKCPT
		 JRST  MAKCK1]	;YES - RE-CALC CURSOR POINTER
	CAIE	T3,11		;TAB?
	POPJ	P,		;NO - RETURN FROM MAKCPT
	JRST	MAKCK1		;ELSE RE-DO CHARACTER POINTER

;HERE IF END OF LINE FOUND, BUT NOT ENOUGH CHARACTERS
;IF FLAG INS IS SET, ADD SPACES TO THE LINE, THEN POINT BEYOND THEM
;ELSE JUST POINT TO THE <CR>

MAKCCR:	MOVE	T0,CHRPTR	;GET THE CHARACTER AFTER THE CARRIAGE RETURN
	ILDB	T0,T0
	CAIE	T0,12		;IS IT A LINEFEED?
	JRST	MAKCP2		;NO - TREAT LONE CR LINE ANY OTHER CHARACTER

MAKCR0:	TLNN	F,INS		;WANT TO EXTEND THE LINE?
	JRST	MAKCC1		;NO - JUST RETURN POINTING TO <CR>
	PUSH	P,T1		;SAVE CHARACTER TO BE EVENTUALLY ADDED
	MOVSI	T1,70000	;MOVE POINTER BEHIND THE <CR>
	ADD	T1,CHRPTR
	JUMPGE	T1,.+2
	SUB	T1,[430000,,1]
	MOVEM	T1,CHRPTR	;SAVE IT AGAIN
	SKIPE	INSTBS		;WANT TO TRY TO INSERT TABS?
	JRST	MAKCR2		;NO - SKIP THE TAB STUFF
	MOVE	T1,CM		;YES - SEE IF ANY TABS CAN BE ADDED
	TRZ	T1,7
	MOVN	T1,T1
	ADD	T1,CM
	CAML	T1,T2		;CAN THEY?
	JRST	MAKCR2		;NO - JUST ADD SPACES
	JUMPE	T1,MAKCT0	;NO SPACES IF END ON A TAB BOUNDARY
	PUSH	P,T2		;ELSE ADD EXTRA SPACES FIRST
	MOVEM	T1,NUMCHR	;ADD (T2) SPACES (AND SOME NULLS) TO THE FILE
	PUSHJ	P,MAKSPC	;PUNCH A HOLE IN THE FILE
	POP	P,T2		;GET TOTAL SPACES BACK
MAKCT0:	MOVE	T1,CM		;FIND POSITION OF LAST REAL CHARACTER
	SUB	T1,T2
	TRNE	T1,7		;WAS IT AT A TAB STOP?
	ADDI	T2,7		;NO - ADD ONE MORE TAB
	LSH	T2,-3		;FIND NUMBER OF TABS TO ADD
	MOVEM	T2,NUMCHR	;SAVE IT
	MOVEI	T1,11		;SET TO ADD TABS
	MOVEM	T1,CHARAC
	PUSHJ	P,MAKCHR	;ADD 'EM
	POP	P,T1		;CLEAN UP
	JRST	MAKCP0		;MAKE CURSOR POINTER RIGHT; DONE

MAKCR2:	MOVEM	T2,NUMCHR	;ADD (T2) SPACES (AND SOME NULLS) TO THE FILE
	PUSHJ	P,MAKSPC	;PUNCH A HOLE IN THE FILE
	POP	P,T1
	JRST	MAKCP0		;MAKE CURSOR POINTER RIGHT

MAKCC1:	MOVSI	T2,70000	;BACK THE CHARACTER POINTER ONE NOTCH
	ADD	T2,CHRPTR
	JUMPGE	T2,.+2
	SUB	T2,[430000,,1]
	MOVEM	T2,CHRPTR
	POPJ	P,

;SUBROUTINE TO MAKE A POINTER TO THE START OF THE LINE THE CURSOR IS ON
;CANNOT USE T1, SINCE THERE MAY BE A LIVE CHARACTER THERE

MAKLPT:	MOVE	PT,DISPTR	;GET POINTER TO START OF SCREEN
	MOVEM	PT,LINPTR	;SAVE IT AS INITIAL LINE POINTER
	SKIPN	T4,RW		;GET ROW TO MOVE TO - ZERO?
	POPJ	P,		;YES - DONE
	PUSHJ	P,ADVLPT	;NO - ADVANCE THE POINTER
	JUMPL	T4,MAKLP2	;ADD LINES IF AT END OF FILE
	MOVEM	PT,LINPTR	;SAVE THE CORRECT LINE POINTER
	MOVE	T3,PT		;GET FRAGGABLE POINTER
MAKLP0:	CAMN	T3,EN		;AT END OF BUFFER?
	JRST	ADDCR		;YES - NEED TO ADD A <CRLF> AT END
	ILDB	T2,T3		;NO - FIND A NON-NULL CHARACTER
	JUMPE	T2,MAKLP0
	POPJ	P,		;GOT ONE - O.K.

;HERE IF END OF BUFFER FOUND, BUT NOT ENOUGH <CR>S
;IF THE INS FLAG IS SET, ADD THE DESIRED <CR>S TO BUFFER, PLUS SOME NULLS
;THEN POINT BEYOND THE <CR>S
;IF INS NOT SET, POINT TO LAST <CR>

MAKLP2:	TLNN	F,INS		;WANT TO INSERT STUFF?
	JRST	MAKLP3		;NO - JUST POINT TO LAST <CR>
	MOVEI	T3,15		;NO - SAVE OFF <CRLF>S
	MOVEI	T2,12
	IDPB	T3,EN
	IDPB	T2,EN
	AOJL	T4,.-2		;UNTIL GOT ENOUGH
	MOVEM	EN,LINPTR	;SAVE AS POINTER TO DESIRED LINE
	IDPB	T3,EN		;AND A FINAL <CR>
	IDPB	T2,EN
	SETZ	T3,
	IDPB	T3,EN
	POPJ	P,

MAKLP3:	ADD	PT,[70000,,0]	;BACK THE LINE POINTER ONE NOTCH
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	LDB	T0,PT		;LOOK FOR A <CR>
	CAIE	T0,15		;IS IT?
	JRST	MAKLP3		;NO - LOOP
	ADD	PT,[70000,,0]	;BACK UP BEFORE THE <CR>
	JUMPGE	PT,.+2
	SUB	PT,[430000,,1]
	MOVEM	PT,LINPTR	;SAVE LINE POINTER
	TLO	F,XPL!XPC	;BUT SAY IT'S INVALID
	POPJ	P,		;AND RETURN

ADDCR:	MOVEI	T2,15		;END BUFFER WITH A <CRLF>
	IDPB	T2,EN		;  AND A NULL
	MOVEI	T2,12
	IDPB	T2,EN
	SETZ	T2,
	IDPB	T2,EN
	POPJ	P,

;SUBROUTINE TO SET UP THE POINTER TO THE LAST LINE ON THE SCREEN
;WORKS WITH LINPTR IF IT'S VALID (BEING CLOSER); ELSE USES DISPTR
;RETURNS BOTTOM POINTER BOTH IN PT AND BOTPTR

;RETURNS 0 IF LAST LINE IS BEYOND END OF BUFFER, HENCE NOTHING TO DISPLAY
;  (ALSO, IF ZERO, FENCE SHOULD BE ON SCREEN)

MAKBPT:	MOVE	T4,LPP.1	;GET DISTANCE OF BOTTOM LINE FROM TOP LINE
	TLNE	F,XPL		;IS LINE POINTER VALID?
	JRST	MAKBP0		;NO - USE DISPLAY POINTER
	MOVE	PT,LINPTR	;YES - USE IT
	SUB	T4,RW		;AND WORK A FEW LINES LESS
	JUMPN	T4,MAKBP1	;ALREADY AT BOTTOM LINE. WADDAYA KNOW.
	JRST	MAKBP2

MAKBP0:	MOVE	PT,DISPTR	;GET THE DISPLAY POINTER
MAKBP1:	PUSHJ	P,ADVLPT	;ADVANCE THE POINTER
	JUMPGE	T4,.+2		;BEYOND END OF FILE?
	SETZ	PT,		;YES - NO POINTER, THEN
MAKBP2:	MOVEM	PT,BOTPTR	;SAVE POINTER (OR NON-POINTER)
	POPJ	P,

;SUBROUTINE TO ADVANCE THE POINTER IN PT (T4) LINES
;T4 IS RETURNED WITH NEGATIVE NUMBER OF LINES NOT FOUND (0 IF ALL FOUND)

ADVLPT:	CAMN	EN,PT		;AT END OF USEABLE BUFFER?
	JRST	[MOVN T4,T4	;NO - RETURN NEGATIVE # LINES NOT FOUND
		 POPJ P,]	;AND RETURN
	ILDB	T2,PT		;GET A CHARACTER
ADVLP1:	CAIE	T2,15		;CARRIAGE RETURN?
	JRST	ADVLPT		;NO - IGNORE IT

	ILDB	T2,PT		;YES - PICK UP THE <LF>
	CAIE	T2,12		;IS IT REALLY?
	JRST	ADVLP1		;NO - IT'S NOT THE END OF THE LINE
	SOJG	T4,ADVLPT	;YES - LOOP THROUGH DESIRED NUMBER OF ROWS
	POPJ	P,		;DONE

;************************************************************************
;SUBROUTINE TO OVERWRITE (T4) REAL CHARACTERS (NOT NULLS) WITH NULLS
;AT (PT), WHICH IS FRAGGED
;STOPS WHEN COUNTED OUT, OR AT END OF LINE
;SAVES CHARACTERS NULLED OUT IN DELBUF (UP TO 5*32 CHARACTERS)

WRTNUL:	MOVEM	T4,WRTNUM	;SAVE NUMBER OF CHARS TO NULL
	MOVNI	T1,5*40		;INIT NUMBER OF CHARACTERS IN DELETE BUFFER
	MOVEM	T1,DELCNT
	SETZ	T1,		;GET A NULL
	MOVE	T3,[POINT 7,DELBUF] ;POINT TO START OF DELETE BUFFER
	ILDB	T2,PT		;GET FIRST CHARACTER
	JUMPE	T2,[CAME PT,EN	;IF NULL, REACHED END OF BUFFER?
		    JRST .-1	;NO - JUST IGNORE THE NULL
		    JRST WRTNLE] ;YES - RETURN NOW
	CAIE	T2,11		;IS IT A TAB?
	JRST	WRTNL2		;NO - CONTINUE
	AOSG	DELCNT		;YES - COUNT IT - COUNTED OUT?
	IDPB	T2,T3		;NO - SAVE THE TAB IN THE DELETE BUFFER
	MOVE	T2,TABSPC	;FIND -NUMBER OF SPACES RIGHT OF CURSOR
	SUB	T2,TABSIZ
	ADD	T4,T2		;COUNT OFF THAT MANY SPACES FROM DELETE
	DPB	T1,PT		;NULL OUT THE TAB
	JUMPLE	T4,WRTNT1	;JUMP IF DONE (START AND END IN THE SAME TAB)
	SKIPE	NUMCHR		;START WITHIN THE TAB?
	PUSHJ	P,WRTNLS	;YES - CHANGE THE TAB IN THE BUFFER TO SPACES

WRTNL1:	ILDB	T2,PT		;GET A CHARACTER
	CAMN	PT,EN		;AT END OF BUFFER?
	JRST	WRTNLE		;YES - GO HOME EARLY
	JUMPE	T2,WRTNL1	;IGNORE IF NULL
	CAIN	T2,11		;IS IT A TAB?
	JRST	WRTNTB		;YES - SEE HOW LONG THE TAB IS
WRTNL2:	CAIN	T2,15		;IS IT A <CR>?
	JRST	WRTNLC		;YES - DONE, IF FOLLOWED BY <LF>
WRTNL3:	AOSG	DELCNT		;ELSE COUNT IT - COUNTED OUT?
	IDPB	T2,T3		;NO - SAVE THE DELETED CHARACTER
	DPB	T1,PT		;OVERWRITE IT WITH A NULL
	SOJG	T4,WRTNL1	;AND COUNT IT - LOOP IF NOT DONE
WRTNLE:	IDPB	T1,T3		;END DELETE BUFFER WITH A NULL
	MOVEI	T1,5*40		;ADJUST COUNT OF CHARACTERS DELETED
	MOVEI	T2,5*40
	ADDB	T1,DELCNT
	CAIL	T1,5*40		;DID BUFFER OVERFLOW?
	MOVEM	T2,DELCNT	;YES - SET TO THE MAXIMUM
	POPJ	P,		;NO - DONE

WRTNLC:	MOVE	T0,PT		;GET SCRATCH BUFFER POINTER
	ILDB	T2,T0		;GET NEXT CHARACTER
	CAIE	T2,12		;<LF>?
	JRST	WRTNL3		;NO - <CR>'S JUST ANOTHER CHARACTER
	JRST	WRTNLE		;YES - GO FINISH OFF

WRTNTB:	AOSG	DELCNT		;ELSE COUNT IT - COUNTED OUT?
	IDPB	T2,T3		;NO - SAVE THE TAB
	MOVE	T2,CM		;GET STARTING COLUMN POSITION
	ADD	T2,WRTNUM	;PLUS LENGTH OF DELETE
	SUB	T2,T4		;LESS NUMBER TO GO, GIVES PRESENT POSITION
	ANDI	T2,7		;FIND NEGATIVE SIZE OF TAB
	SUBI	T2,10
	ADD	T4,T2		;COUNT OFF THAT MANY SPACES FROM DELETE
	DPB	T1,PT		;NULL OUT THE TAB
	JUMPG	T4,WRTNL1	;CONTINUE, IF STILL MORE TO GO
WRTNT1:	JUMPE	T4,WRTNLE	;LEAVE TAB IF ENDED AT THE END OF IT
	MOVN	T4,T4		;ELSE ADD SOME SPACES FOR THIS TAB, TOO
	ADDM	T4,NUMCHR
	ADD	T2,T4		;FIND NUMBER OF SPACES THIS TAB REPRESENTS
	PUSHJ	P,WRTNLS	;CHANGE THE TAB IN THE BUFFER TO SPACES
	SETZ	T4,		;SAY NOTHING WAS LEFT OVER
	JRST	WRTNLE		;AND GO FINISH UP

WRTNLS:	MOVEI	T0," "		;REPLACE TAB WITH -(T2) SPACES
	DPB	T0,T3		;COVER TAB WITH A SPACE
	AOJE	T2,CPOPJ	;DONE IF ONLY ONE SPACE WANTED
	AOSG	DELCNT		;ELSE COUNT EACH SPACE - COUNTED OUT?
	IDPB	T0,T3		;NO - SAVE THE SPACE
	AOJG	T2,.-2
	POPJ	P,		;DONE

;************************************************************************
;SUBROUTINE TO CALCULATE RW AND LINPTR, GIVEN CHRPTR AND DISPTR

CALCRW:	MOVE	PT,DISPTR	;START FROM START OF SCREEN
	MOVEM	PT,LINPTR	;SAVE (TENTATIVE) LINE POINTER
	SETZ	RW,		;CLEAR ROW NUMBER
CALRW1:	CAMN	PT,CHRPTR	;AT DESIRED POSITION?
	POPJ	P,		;YES - DONE
	ILDB	T1,PT		;NO - GET CHARACTER
CALRW2:	CAIE	T1,15		;<CR>?
	JRST	CALRW1		;NO - SKIP IT
	CAMN	PT,CHRPTR	;YES - AT DESIRED POSITION?
	POPJ	P,		;YES - DONE
	ILDB	T1,PT		;NO - GET NEXT CHARACTER
	CAIE	T1,12		;<LF>?
	JRST	CALRW2		;NO - SKIP IT
	MOVEM	PT,LINPTR	;SAVE (TENTATIVE) LINE POINTER
	AOJA	RW,CALRW1	;YES - COUNT LINE AND LOOP

;SUBROUTINE TO CALCULATE THE NUMBER OF LINES AND PAGES, AND TOTAL LINES
;SINCE THE START OF THE FILE

FINDRW:	SETZB	T3,SAVEAC	;CLEAR PAGE NUMBER AND TOTAL LINES
	JRST	.+2		;SKIP SUMMING THE FIRST TIME
FNDRW0:	ADDM	RW,SAVEAC	;ADD UP TOTAL LINES PASSED OVER
	SETZ	RW,		;CLEAR ROW NUMBER
FNDRW1:	CAMN	PT,CHRPTR	;AT DESIRED POSITION?
	JRST	[ADDM RW,SAVEAC	;YES - ADD IN LINES FROM LAST PAGE
		 POPJ P,]	;DONE
	ILDB	T1,PT		;NO - GET CHARACTER
FNDRW2:	CAIN	T1,14		;FORMFEED?
	AOJA	T3,FNDRW0	;YES - BUMP PAGES AND ZERO LINES
	CAIE	T1,15		;<CR>?
	JRST	FNDRW1		;NO - SKIP IT
	ILDB	T1,PT		;YES - GET NEXT CHARACTER
	CAIE	T1,12		;<LF>?
	JRST	FNDRW2		;NO - SKIP IT
	AOJA	RW,FNDRW1	;YES - COUNT LINE AND LOOP

;SUBROUTINE TO CALCULATE CM, GIVEN CHRPTR, AND LINPTR IN PT
;(ALTERNATE ENTRY: CALCML - PUTS LINPTR INTO PT)
;IF CM IS BEYOND SCREEN LIMITS, DOES A SLIDE TO PUT IT WITHIN LIMITS
;NORMAL RETURN IF SLIDE, ELSE SKIP RETURN

CALCML:	MOVE	PT,LINPTR	;GET POINTER TO START OF LINE
CALCCM:	SETZ	CM,		;CLEAR COLUMN NUMBER
CALCM1:	CAMN	PT,CHRPTR	;AT CHARACTER POSITION?
	JRST	CALCCD		;YES - DONE
	ILDB	T1,PT		;NO - GET CHARACTER
	JUMPE	T1,CALCM1	;IGNORE IF NULL
	CAIN	T1,11		;TAB?
	TRO	CM,7		;YES - COUNT IT
	AOJA	CM,CALCM1	;COUNT CHARACTER AND LOOP

CALCCD:	SUB	CM,SL		;ACCOUNT FOR THE SLIDE
	CAMGE	CM,CPL(TM)	;OFF THE RIGHT SIDE?
	JRST	CALCD1		;NO - CHECK LEFT
	MOVE	T1,CM		;YES - SLIDE A BIT TO SHOW THE MATCH
	MOVE	T2,CPL(TM)
	IDIVI	T2,3
	LSH	T2,1
	SUB	T1,T2
	ADD	SL,T1
	SUB	CM,T1
	POPJ	P,		;GIVE NON-SKIP RETURN

CALCD1:	JUMPGE	CM,CPOPJ1	;OFF THE LEFT SIDE (IF NO, SKIP RETURN)?
	ADD	SL,CM		;YES - MOVE LEFT SO KEY IS ON SCREEN
	SETZ	CM,
	POPJ	P,		;GIVE NON-SKIP RETURN

;************************************************************************
;SWITCH HANDLING SUBROUTINES. THERE BE:
;SWHMNY - HANDLES A STRING OF SWITCHES. PT POINTS TO START OF FIRST ONE
;SWHONE - HANDLES A SINGLE SWITCH IN PARBUF

;MANY SWITCHES: FIND CHARACTER AFTER NEXT SWITCH; SAVE IT; REPLACE IT
;		WITH A NULL; CALL SWHONE; LOOP
;SWITCHES END WITH A RETURN OR A NULL
;CALL WITH PT POINTING AFTER THE "/" OF THE FIRST SWITCH

SWHMNY:	MOVEM	PT,SAVEAC+4	;SAVE THE POINTER TO THE START OF THE SWITCH
SWHMN1:	ILDB	T1,PT		;GET FIRST SWITCH CHARACTER
	CAIE	T1,"X"		;EXECUTE SWITCH?
	CAIN	T1,"x"
	JRST	SWHMNX		;YES - SPECIAL CASE
	PUSHJ	P,SWHNUL	;NO - FIND, SAVE, AND NULL CHAR. AFTER THE SWH
	PUSHJ	P,SWHONE	;NO - PROCESS THE SWITCH
SWHMN2:	MOVE	PT,SAVEAC+4	;POINT TO THE START OF THE NEXT ONE
	SKIPN	SAVEAC+5	;GOT MORE SWITCHES?
	POPJ	P,		;NO - DONE
	JRST	SWHMN1		;YES - LOOP TO PROCESS THEM

SWHMN3:	JUMPN	T1,SWHMN1	;JUMP IF GOT MORE SWITCHES
	POPJ	P,		;ELSE DONE

;SUBROUTINE TO FIND THE FIRST CHARACTER OF THE NEXT SWITCH,
;SAVE IT AND ITS POINTER IN SAVEAC+5 AND +4, AND CHANGE IT TO A NULL

SWHNUL:	ILDB	T1,PT		;GET THE NEXT CHARACTER
	CAIL	T1,"0"		;IS THE CHARACTER INTERESTING?
	JRST	SWHNUL		;NO - JUST SKIP OVER IT
	JUMPE	T1,SWHNL1	;YES - DONE IF NULL
	CAIN	T1,15		;END OF A LINE?
	JRST	SWHMNS		;YES - SKIP TO LINEFEED AND RETURN
	CAIE	T1,"/"		;START OF ANOTHER SWITCH?
	CAIN	T1,"+"
	TDZA	T0,T0		;YES - GET A NULL AND SKIP
	JRST	SWHNUL		;NO - KEEP SKIPPING
	DPB	T0,PT		;NULL OUT THE CHARACTER
SWHNL1:	EXCH	PT,SAVEAC+4	;SAVE PTR TO NEXT SWITCH; GET PTR TO THIS ONE
	MOVEM	T1,SAVEAC+5	;SAVE THE CHARACTER
	POPJ	P,		;DONE

SWHMNS:	SETZ	T1,		;NULL OUT THE CARRIAGE RETURN
	DPB	T1,PT
SWHMS1:	ILDB	T0,PT		;SKIP UNTIL NULL OR LINEFEED
	JUMPE	T0,SWHNL1	;IF NULL, SAVE POINTERS AND FINISH
	CAIN	T0,12		;LINEFEED?
	JRST	SWHNL1		;YES - FINISH OFF
	JRST	SWHMS1		;ELSE KEEP LOOKING

;HERE TO HANDLE THE EXECUTE SWITCH SEPARATELY

SWHMNX:	MOVE	T3,[POINT 7,PARBUF]
	IDPB	T1,T3		;SAVE THE "X"
	ILDB	T1,PT		;SKIP THE COLON AFTER THE "X"
	CAIE	T1,":"		;  (IF THERE IS ONE)
	JRST	SWHMXL+2
	JRST	SWHMXL+1
SWHMXL:	IDPB	T1,T3
	ILDB	T1,PT		;SAVE BUFFER NAME IN PARM BUFFER
	JUMPE	T1,SWHMN3	;NULL - IGNORE THIS BAD FORMAT
	CAIN	T1,15		;START OF ANOTHER SWITCH?
	JRST	SWHMN3		;YES - IGNORE THIS BAD FORMAT
	CAIN	T1,","		;START OF KEYSTROKE SEQUENCE?
	JRST	SWHMX0		;YES - SET FLAG FOR IT
	CAIE	T1,":"		;START OF CONTENTS?
	JRST	SWHMXL		;NO - KEEP GOING

	TDZA	T1,T1		;CLEAR T1 - NO KEYSTROKE COMING
SWHMX0:	MOVSI	T1,-1		;T1/-1,,0 - KEYSTROKE COMING
	MOVEM	T1,SAVEAC+3	;SAVE KEYSTROKE FLAG
	TLO	F,FLG		;SET TO GET A RETURN FROM XCT ROUTINES
	IDPB	T1,T3		;END PARM BUFFER WITH A NULL
	MOVEM	PT,SAVEAC+4	;SAVE POINTER
	PUSHJ	P,XCTSET	;SET UP THAT BUFFER
	MOVE	PT,SAVEAC+4	;RESTORE POINTER
	SKIPE	SAVEAC+3	;NOW GOT A KEYSTROKE SEQUENCE?
	PUSHJ	P,SWHMXK	;YES - GET KEYSTROKE, TOO

;FIND END OF SWITCH. SAVE IT AND REPLACE IT WITH A NULL.

	MOVEM	PT,SAVEAC+4	;SAVE POINTER TO START OF SEQUENCE
SWHMX1:	ILDB	T1,PT		;GET THE NEXT CHARACTER
	CAIN	T1,"/"		;START OF A NEW SWITCH?
	JRST	SWHMX2		;YES - SET UP CONTENTS
SWMX1A:	JUMPE	T1,SWMX1E	;NULL - TREAT LIKE END OF LINE
	CAIN	T1,15		;END OF LINE?
	JRST	SWMX1E		;YES - SEE IF END OF BUFFER
	CAIE	T1,"^"		;NO - SPECIAL FLAG?
	JRST	SWHMX1		;NO - CONTINUE
	ILDB	T1,PT		;YES - GET NEXT CHARACTER
	CAIE	T1,"/"		;IS IT A REAL SLASH?
	JRST	SWMX1A		;NO - JUST PROCESS NORMALLY
	DPB	T1,T3		;YES - SAVE OVER THE UP-ARROW
	JRST	SWHMX1		;AND THEN CONTINUE

SWMX1E:	ILDB	T1,PT		;END OF A LINE - GET THE LINEFEED
	MOVE	T0,PT		;SAVE THE CURRENT POINTER
	CAIN	T1,12		;IS IT REALLY A LINEFEED?
	ILDB	T1,PT		;YES - GET FIRST CHARACTER OF NEXT LINE
	CAIN	T1,11		;IS IT A TAB?
	JRST	SWHMX1		;YES - IGNORE CRLF AND TAB AND CONTINUE
	MOVE	PT,T0		;NO - END OF THIS DEFINITION - GET POINTER BACK
	SETZ	T1,		;SAVE A NULL AS THE TERMINATOR

SWHMX2:	MOVEM	T1,SAVEAC+5	;SAVE TERMINATING CHARACTER
	SETZ	T1,		;COVER THE TERMINATOR WITH A NULL
	DPB	T1,PT
SWHMX3:	EXCH	PT,SAVEAC+4	;SAVE PTR TO END OF SWITCH; GET PTR TO START
	TLO	F,FLG		;SET FLAG TO GET A RETURN
	PUSHJ	P,XCWRT0	;WRITE THE BUFFER
	JRST	SWHMN2		;FINISH OFF OR PROCESS NEXT SWITCH

;HERE TO READ AND SAVE THE EXECUTE KEY SEQUENCE

SWHMXK:	MOVEI	T4,XCTKEY(T1)	;GET POINTER TO PLACE TO STORE SEQUENCE
	HRLI	T4,440700	;(INDEPENDENT OF T1)
	MOVEM	T4,SAVEAC+5	;SAVE POINTER FOR LATER
	SETZM	XCTKEY(T1)	;CLEAR PREVIOUS KEYSTROKE (IF ANY)
	TRO	T1,200000	;SET EXECUTE COMMAND FLAG
	MOVEM	T1,SAVEAC+6	;SAVE EXECUTE BUFFER INDEX
SWMXK1:	ILDB	T0,PT		;GET CHARACTER OF SEQUENCE
	CAIN	T0,":"		;START OF CONTENTS?
	JRST	SWMXK2		;YES - SEE IF COMMAND IS LEGAL
	JUMPE	T0,SWHMN3	;NULL - IGNORE THIS BAD FORMAT
	CAIN	T0,15		;START OF ANOTHER SWITCH?
	JRST	SWHMN3		;YES - IGNORE THIS BAD FORMAT
	CAIN	T0,"^"		;NO - CONTROL CHARACTER IN SEQUENCE?
	JRST	[ILDB T0,PT	;YES - GET CHARACTER
		 CAIN T0,"?"	;RUBOUT?
		 TROA T0,177	;YES - SET IT UP SPECIALLY
		 ANDI T0,37	;ELSE MAKE A CONTROL CHARACTER
		 JRST .+1]	;GO SAVE THE CHARACTER
	TLNE	T4,760000	;ALREADY GOT 5 CHARACTERS?
	IDPB	T0,T4		;NO - SAVE CHARACTER
	JRST	SWMXK1		;AND GET ANOTHER

SWMXK2:	SKIPE	STTFLG		;INITIALIZING?
	POPJ	P,		;YES - DON'T CHANGE TABLE NOW
	MOVE	T2,SAVEAC+5	;NO - GET POINTER TO SEQUENCE
				;FALL TO CHANGE TABLE AND RETURN

;SUBROUTINE TO CHANGE INPUT TABLE - SET UP OR CLEAR EXECUTE COMMAND
;ENTER WITH EXECUTE INDEX IN SAVEAC+6, POINTER TO EXECUTE SEQUENCE IN T2
;INDEX SHOULD HAVE THE 200000 BIT SET
;IF INDEX IS -1, EDITOR COMMAND IS RESTORED IN TABLE

SUBTBX:	ILDB	T4,T2		;GET FIRST CHARACTER OF SEQUENCE
	CAIN	T4,177		;RUBOUT?
	SETO	T4,		;YES - USE -1 AS OFFSET
	ADD	T4,ITB(TM)	;GET OFFSET IN TERMINAL TABLE
	MOVE	T1,T4		;REMEMBER TABLE ADDRESS
	SKIPGE	T4,(T4)		;IS IT A NORMAL COMMAND?
	JRST	SUBTAS		;NO - GO LOOK IN SUBTABLE
	ILDB	T0,T2		;YES - GET NEXT COMMAND CHARACTER
	SKIPGE	T2,SAVEAC+6	;GET EXECUTE INDEX - NEGATIVE?
	JRST	SUBTX1		;YES - GO RESTORE OLD COMMAND

	TRNE	T4,200000	;WAS SEQUENCE ALREADY SET UP AS AN EXECUTE?
	AOJA	T4,SUBTX0	;YES - BUMP COUNTER AND SAVE
	JUMPE	T0,.+2		;IS EXECUTE SEQUENCE 1 CHARACTER LONG?
	MOVEI	T2,300000	;NO - SET FLAG FOR MORE INPUT & ZERO COUNTER
	DPB	T4,[POINT 9,T2,29]
	MOVEM	T2,(T1)		;NO - SAVE EXECUTE CALL NOW
	POPJ	P,		;DONE

SUBTX0:	MOVEM	T4,(T1)		;SAVE EXECUTE CALL WITH BUMPED COUNTER
	POPJ	P,		;DONE

SUBTX1:	TRNN	T4,100000	;GOT AT LEAST TWO COMMANDS FOR THIS SEQUENCE?
	JRST	SUTX1A		;NO
	TRNE	T4,77
	SOJA	T4,SUTX1B	;YES - JUST DECREMENT COUNT AND SAVE
SUTX1A:	TRZ	T4,300000	;GET ORIGINAL COMMAND BACK
	LSH	T4,-6
SUTX1B:	MOVEM	T4,(T1)		;SAVE IT
	POPJ	P,

SUBTAS:	ILDB	T0,T2		;GET NEXT USER-TYPED CHARACTER
SUBTS2:	SKIPN	T1,(T4)		;GET A SUBTABLE ENTRY - END?
	POPJ	P,		;YES - COMMAND IS NOT LEGAL
	TRNN	T1,-1		;MATCH ON ANY CHARACTER?
	JRST	SUBTS3		;YES - SET UP REAL COMMAND NOW
	CAIE	T0,(T1)		;DO USER'S AND TABLE'S CHARS MATCH?
	AOBJN	T4,SUBTS2	;NO - LOOP ON THE TABLE
	JUMPG	T4,CPOPJ	;NOT LEGAL IF END OF TABLE AND NOT FOUND
SUBTS3:	CAMLE	T1,[137,,0]	;ELSE FOUND - WANT ANOTHER LEVEL?
	JRST	SUBTSS		;YES - SET IT UP
	HLR	T1,(T4)		;NO - GET CURRENT POINTER
	MOVE	T0,SAVEAC+6	;GET EXECUTE INDEX
	JUMPL	T0,SUBTS4	;IF NONE RESTORE OLD COMMAND
	TRNE	T1,200000	;WAS THIS ALREADY SET UP AS AN EXECUTE?
	AOJA	T1,SUBTSX	;YES - BUMP COUNTER AND SAVE
	HLR	T1,T1		;ELSE SAVE OLD COMMAND WITH EXECUTE INDEX
	DPB	T1,[POINT 9,T0,29]
	HRLM	T0,(T4)		;SAVE INDEX AT END OF SUBTABLE
	POPJ	P,		;DONE

SUBTSX:	TRNE	T1,100000	;MORE THAN ONE COMMAND HERE ALREADY?
	JRST	SUTSX1		;YES - JUST SAVE BUMPED COUNTER
	TRO	T1,300001	;NO - THERE IS NOW (SET FLAG, CLEAR COUNTER)
	TRZ	T1,76
SUTSX1:	HRLM	T1,(T4)		;SAVE INDEX AT END OF SUBTABLE
	POPJ	P,		;DONE

SUBTS4:	TRNN	T1,100000	;GOT AT LEAST TWO COMMANDS FOR THIS SEQUENCE?
	JRST	SUTS4A		;NO
	TRNE	T1,77
	SOJA	T1,SUTS4B	;YES - DECREMENT COUNTER AND SAVE
SUTS4A:	LSH	T1,-6		;GET ORIGINAL COMMAND BACK
	TRZ	T1,777000
SUTS4B:	HRLM	T1,(T4)		;SAVE IT IN THE SUBTABLE
	POPJ	P,		;DONE

SUBTSS:	TLZE	T1,200000	;GOT AN EXECUTE COMMAND?
	JRST	SUBTS3+2	;YES - SET IT UP AFTER ALL
	HLRZ	T4,T1		;POINT TO NEW SUBTABLE
	HRLI	T4,-^D40
	JRST	SUBTAS		;AND PICK UP ANOTHER CHARACTER

;SUBROUTINE TO SET UP ALL EXECUTE BUFFER BUTTON SEQUENCES IN THE
;TERMINAL INPUT TABLE. THIS IS DONE ON STARTUP IN CASE THE TABLE WAS
;CHANGED AFTER SWITCH.INI WAS PROCESSED, BY THE USER'S ENTRY ROUTINE

SETXCB:	MOVEI	DO,XBFNUM-1	;LOOP THROUGH ALL EXECUTE BUFFERS
STXCB1:	SKIPN	XCTKEY(DO)	;DOES THIS BUFFER HAVE A BUTTON?
	JRST	STXCB2		;NO - SKIP IT
	MOVEI	T2,200000(DO)	;YES - SET UP EXECUTE INDEX AND POINTER
	MOVEM	T2,SAVEAC+6
	ADD	T2,[440677,,XCTKEY-200000]
	PUSHJ	P,SUBTBX	;CHANGE TABLE IF THE COMMAND IS LEGAL
STXCB2:	SOJGE	DO,STXCB1	;LOOP THROUGH ALL BUFFERS
	POPJ	P,		;THEN DONE

;SUBROUTINE TO PARSE AND HANDLE A SINGLE SWITCH, WHICH IS IN PARAMETER BUFFER.
;ENTER WITH PT/ POINTER TO SWITCH. THE SWITCH MUST BE TERMINATED BY A NULL.

SWHONE:	SETO	T4,		;ASSUME SWITCH WILL BE SET
SWHON1:	PUSHJ	P,SWHLUR	;GET FIRST CHARACTER
SWHON2:	CAIL	T1,"A"		;IS IT ALPHABETIC?
	CAILE	T1,"Z"
	JRST	SWHERR		;NO - ERROR
	MOVE	T2,T1		;YES - SAVE FIRST CHARACTER
	PUSHJ	P,SWHLUR	;GET SECOND CHARACTER
	JRST	@SWHADR-"A"(T2)	;AND DISPATCH TO SWITCH ROUTINE

SWHNNN:	SETZ	T4,		;SAY "NO" HAS BEEN TYPED
	CAIN	T1,"O"		;IS 2ND CHARACTER AN "O"?
	JRST	SWHON1		;YES - INGORE IT
	JRST	SWHON2		;NO - DISPATCH ON IT

SWHLUR:	ILDB	T1,PT		;ROUTINE TO GET NEXT CHARACTER
	CAIN	T1," "		;IS IT A SPACE?
	JRST	SWHLUR		;YES - IGNORE IT
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	POPJ	P,		;RETURN

;ROUTINES TO HANDLE EACH SWITCH
;2ND SWITCH CHARACTER IS IN T1; POPJ WHEN DONE

SWHAAA:	CAIN	T1,"G"		;AGAIN SWITCH?
	JRST	SWHAGN		;YES - HANDLE IT
	CAIN	T1,"P"		;APPEND SWITCH?
	JRST	SWHAPP		;YES - HANDLE IT
	CAIE	T1,"L"		;ALTERNATE FILE SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	CAIE	DO,$SETFI	;DOING A SET-FILE,
	CAIN	DO,$SWTCH	;  OR A SWITCH COMMAND?
	JRST	SAGERR		;YES - SWITCH IS ILLEGAL, THEN
	MOVEI	T1,SPCSIZ-1
	MOVE	T0,FILSPC(T1)	;NO - SWAP CURRENT AND ALTERNATE FILESPECS
	EXCH	T0,OLDSPC(T1)
	MOVEM	T0,FILSPC(T1)
	SOJGE	T1,.-3
	JRST	SWHAN1		;IF THERE'S AN ARGUMENT, SET IT UP

SWHAGN:	SETOM	AGNFLG		;SET THE AGAIN FLAG TO SET TO SAME FILE TWICE
SWHAN1:	PUSHJ	P,SWHAG0	;READ ARGUMENT, IF ANY
	  POPJ	P,		;NO ARG - JUST RETURN
	JRST	SWHPC1		;ARGUMENT - SET UP PERCENT-GOTO

SWHAPP:	JUMPE	T4,.+2		;WANT TO APPEND?
	MOVE	T4,[POINT 7,PIKBUF] ;YES - RESET THE APPEND POINTER
	MOVEM	T4,APPFLG	;SAVE 0 OR APPEND POINTER
	POPJ	P,

SWHUPP:	MOVEM	T4,UPPFLG	;SAVE UPPER-LOWER CASE FLAG
	POPJ	P,

SWHCCC:	CAIN	T1,"R"		;ALWAYS-CREATE SWITCH?
	JRST	SWHCRE		;YES - HANDLE IT
	CAIE	T1,"A"		;AFFECT CASE-DEPENDENCY OF SEARCHING?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	JUMPGE	T4,.+2		;YES - MAKE SEARCHES CASE-DEPENDENT?
	TRZA	F,NLC		;YES
	TRO	F,NLC		;NO
	POPJ	P,

SWHCRE:	MOVEM	T4,CREFLG	;SAVE ALWAYS-CREATE-FILE FLAG
	POPJ	P,

SWHSSS:	CAIN	T1,"L"		;SLIDE SWITCH?
	JRST	SWHSLD		;YES - HANDLE IT
	CAIN	T1,"H"		;SHOW EXECUTE SWITCH?
	JRST	SWHSHW		;YES - HANDLE IT
	CAIN	T1,"A"		;SAVE SWITCH?
	JRST	SWHSAV		;YES - HANDLE IT
	CAIE	T1,"T"		;STRIP LINE NUMBERS SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	MOVEM	T4,STRFLG	;YES - SAVE STRIP FLAG
	POPJ	P,

SWHSHW:	MOVEM	T4,XSHFLG	;SAVE SHOW FLAG
	POPJ	P,

SWHSLD:	JUMPE	T4,SWHSL2	;IF /NOSLIDE DISABLE SLIDING (IGNORE ARG)
	SETO	T4,		;ENABLE SLIDING
SWHSL2:	MOVEM	T4,SLDFLG	;SAVE SLIDE FLAG
	POPJ	P,

SWHSAV:	JUMPE	T4,SWHSV1	;JUMP IF USER SAID /NOSAVE
	PUSHJ	P,SWHAG0	;ELSE READ ARGUMENT
	  JRST	SWGERR		;NO ARG - ERROR
	JUMPG	T3,.+2		;DID USER SAY /SAVE:0?
SWHSV1:	SETO	T3,		;YES - USE -1 (FOR NO SAVES)
	MOVEM	T3,SAVNUM	;ELSE SAVE # COMMANDS BETWEEN SAVES
	MOVEM	T3,SAVCNT	;SAVE AS COUNTDOWN VALUE, TOO
	POPJ	P,

SWHBBB:	CAIN	T1,"E"		;BEEP SWITCH?
	JRST	SWHBEP		;YES - HANDLE IT
	CAIE	T1,"A"		;BACKUP SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	MOVEM	T4,BAKFLG	;YES - SAVE BACKUP FILE FLAG
	POPJ	P,

SWHBEP:	JUMPE	T4,.+2		;SET BEEP-ON-INSERT-MODE FLAG?
	TLOA	TM,BEP		;YES
	TLZ	TM,BEP		;NO
	POPJ	P,

SWHRRR:	CAIN	T1,"A"		;RAISE SWITCH?
	JRST	SWHRAI		;YES - HANDLE IT
	CAIN	T1,"E"		;RESET, READ-ONLY OR RECOVER SWITCH?
	JRST	SWHRR1		;YES - READ ANOTHER CHARACTER
	CAIN	T1,"M"		;RMAR (RIGHT MARGIN) SWITCH?
	JRST	SWHRMR		;YES
	CAIN	T1,"C"		;REPLACE-CURRENT FILE SWITCH?
	JRST	SWHCUR		;YES - HANDLE IT
	CAIE	T1,"O"		;ROLL SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	JUMPGE	T4,.+2		;ROLL IF USER TYPES RETURN ON BOTTOM LINE?
	TRZA	F,NRC		;NO
	TRO	F,NRC		;YES
	POPJ	P,

SWHRAI:	SETCAM	T4,UPCFLG	;SAVE RAISE-CASE FLAG
	SETOM	INVFLG		;DON'T TOGGLE; USE UPCFLG
	POPJ	P,

SWHCUR:	MOVEM	T4,CRRFLG	;SAVE REPLACE-CURRENT-FILE FLAG
	POPJ	P,

SWHRMR:	PUSHJ	P,SWHAG0	;READ NEW RMAR (RIGHT MARGIN) POSITION
	  JRST	SWGERR		;NO ARG - ERROR
	SOJ	T3,		;MAKE THE VALUE ZERO-ORIGIN
	CAMG	T3,LMARGN	;IS IT TO THE RIGHT OF THE LEFT MARGIN?
	JRST	SWGERR		;NO - ERROR
	MOVEM	T3,RMARGN	;YES - SAVE IT
IFE TOPS10,<
IFN FTECHO,<
SWHRM1:	CAML	T3,CPL.1	;OFF THE RIGHT OF THE SCREEN?
	SKIPA	T3,CPL.0	;YES - SET THE FIELD WIDTH TO THE RIGHT
	AOJ	T3,
	MOVEM	T3,FLDWTH	;SAVE THE FIELD WIDTH
>>
	POPJ	P,

SWHRR1:	PUSHJ	P,SWHLUR	;GET 3RD SWITCH CHARACTER
	CAIN	T1,"A"		;REA == READ-ONLY?
	JRST	SWHRDO		;YES
IFN FTJOUR,<
	CAIN	T1,"C"		;REC == RECOVER JOURNAL?
	JRST	SWHREC		;YES
>
	CAIE	T1,"S"		;RES == RESET NOMINALS?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS OR ILLEGAL
	JUMPE	T4,.+2		;SET RESET-NOMINALS FLAG?
	TROA	F,RST		;YES
	TRZA	F,RST		;NO
	JRST	RSTNOM		;IF YES, RESET ALL NOMINALS NOW AND RETURN
	POPJ	P,		;IF NO, JUST RETURN

IFN FTJOUR,<
SWHREC:	MOVEM	T4,JRNFLG	;SAVE RECOVER-JOURNAL FLAG
	POPJ	P,

SWHJJJ:	TLZ	TM,JRW		;ASSUME NO JOURNAL
	JUMPGE	T4,CPOPJ	;WANT ONE AFTER ALL?
	TLO	TM,JRW		;YES
	CAIN	DO,$SWTCH	;SWITCH COMMAND OR SETTING UP A FILE?
	JRST	JRNSTT		;SWITCH - START THE JOURNAL FILE NOW
	POPJ	P,		;SETTING - JUST RETURN
>
SWHLLL:	CAIN	T1,"I"		;LINEFEED SWITCH?
	JRST	SWHLSD		;YES - HANDLE IT
	CAIN	T1,"M"		;LMAR SWITCH?
	JRST	SWHLMR		;YES - HANDLE IT
	CAIE	T1,"E"		;LENGTH SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	PUSHJ	P,SWHAG0	;YES - READ ARGUMENT
	  JRST	SWGERR		;NO ARG - ERROR
	TLNE	TM,WDW		;GOT TWO WINDOWS ON THE SCREEN?
	JRST	SWHERR		;YES - ERROR
	SKIPN	STTFLG		;INITIALIZING?
	JRST	SWHLPP		;NO - SET THE LENGTH UP NOW
	HRRM	T3,STTFLG	;YES - SAVE FOR LATER
	POPJ	P,		;DONE FOR NOW

SWHLPP:	MOVEM	T3,LPP(TM)	;SAVE IN TERMINAL TABLE
	MOVE	T1,T3
	CAMGE	T1,LPP.0	;USING ALL THE LINES ON THE SCREEN?
	JRST	SETLPP-1	;NO - PUT ERRORS ON BOTTOM LINE
	MOVSI	T2,SLW!NEL	;YES - RESTORE SAVED SLW AND NEL FLAGS
	AND	T2,SAVFLG
	TLZ	TM,SLW!NEL
	OR	TM,T2
	JRST	SETLPP		;GO FINISH OFF

	TLO	TM,SLW!NEL	;MAKE ERRORS GO ON BOTTOM LINE
SETLPP:	HRREI	T3,-1(T1)	;(ENTER WITH T1/LINES PER PAGE)
	IDIVI	T1,3
	MOVEM	T1,LINROL
	MOVEM	T3,LPP.1	;SAVE LINES PER PAGE - 1
	MOVEM	T3,LPP.2	;SAVE BOTTOM LINE OF SCREEN
	TLNE	TM,NEL		;IF BOTTOM IS SCRATCH, USE NEXT LINE UP
	SOS	LPP.2
	POPJ	P,

SWHLSD:	JUMPGE	T4,.+2		;SET LINEFEED-CURSOR DOWN FLAG?
	TLZA	TM,LSD		;NO
	TLO	TM,LSD		;YES
	POPJ	P,

SWHLMR:	PUSHJ	P,SWHAG0	;READ NEW LMAR (LEFT MARGIN) POSITION
	  JRST	SWGERR		;NO ARG - ERROR
	SOJGE	T3,.+2		;MAKE THE VALUE ZERO-ORIGIN
	SETZ	T3,		;BUT MAP ZERO INTO ZERO
	EXCH	T3,LMARGN	;SAVE LEFT MARGIN AND GET THE OLD SETTING
	SKIPE	RMARGN		;HAS THE RIGHT MARGIN BEEN SET YET?
	CAMGE	T3,RMARGN	;YES - IS IT TO THE LEFT OF THE RIGHT MARGIN?
	POPJ	P,		;YES - DONE
	EXCH	T3,LMARGN	;NO - PUT OLD SETTING BACK
	JRST	SWGERR		;AND GIVE AN ERROR

SWHOFL:	MOVE	T4,[POINT 7,NEWSPC]
	PUSHJ	P,SWHAGA	;READ THE NEW FILESPECS INTO A TEMPORARY AREA
	  JRST	SWGERR		;NO ARG - ERROR
	SETOM	OUTFLG		;SAY THERE WILL BE A CHANGE OF SPECS
	JUMPE	DO,CPOPJ	;DON'T CHANGE NOW IF INITIALIZING
	CAIN	DO,$SETFI	;O.K. TO MAKE THE CHANGE NOW?
	POPJ	P,		;NO - WAIT UNTIL END OF SET-FILE
				;ELSE FALL INTO:

;SUBROUTINE TO SET UP PARSE THE FILESPECS GIVEN IN THE /OUT: SWITCH
;Note: TOPS-20 doesn't really parse now, so user can stick himself

OUTSET:	HRRZM	P,OUTFLG	;NOTE THAT SPEC IS CHANGING (BY OUTFLG .GT. 0)
	MOVE	T4,[POINT 7,NEWSPC]
	MOVE	T1,[FILSPC,,SVASPC]
	BLT	T1,SVASPC+SPCSIZ-1 ;SAVE THE CURRENT SPECS IN CASE PARSE FAILS
	MOVE	T1,[NEWSPC,,FILSPC]
	BLT	T1,FILSPC+7	;MOVE IN THE NEW FILSPECS
	PUSHJ	P,PARSEF	;PARSE THE SPECS (ERROR ON FAILURE)
	SETZM	OUTFLG		;SAY SPEC CHANGE IS NO LONGER WANTED
	SETOM	CHGSPC		;SAY SPECS HAVE CHANGED
	TLZ	F,SMF		;THIS FILE AND THE ALTERNATE CAN'T BE THE SAME
	TRNN	F,RDO		;IS FILE READ-ONLY?
	TLO	F,CHG		;NO - FORCE THE FILE TO BE SAVED
	POPJ	P,		;DONE

SWHWWW:	CAIN	T1,"R"		;WRITE SWITCH?
	JRST	SWHWRT		;YES - HANDLE IT
	CAIE	T1,"I"		;WIDTH SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	PUSHJ	P,SWHAG0	;YES - READ ARGUMENT
	  JRST	SWGERR		;NO ARG - ERROR
	SKIPN	STTFLG		;INITIALIZING?
	JRST	SWHWID		;NO - SET THE WIDTH UP NOW
	HRLM	T3,STTFLG	;YES - SAVE FOR LATER
	POPJ	P,		;DONE FOR NOW

SWHWID:	MOVEM	T3,CPL(TM)	;SWAP WITH WIDTH IN TERMINAL TABLE
	SOJ	T3,		;ALSO SAVE CPL - 1
	MOVE	T2,T3		;PUT VALUE IN TWO PLACES
	EXCH	T2,CPL.1
	CAMLE	T2,RMARGN	;WAS RIGHT MARGIN .GE. WIDTH?
	CAMGE	T3,RMARGN	;NEED TO MOVE THE RIGHT MARGIN IN?
IFN TOPS10,<
	MOVEM	T3,RMARGN	;YES - DO SO
>
IFE TOPS10,<
IFN FTECHO,<
	MOVEM	T3,RMARGN	;YES - DO SO
>
IFN FTECHO,<
	JRST	[MOVEM T3,RMARGN ;YES - DO SO
		 AOJ   T3,
		 MOVEM T3,FLDWTH ;ADJUST FIELD WIDTH, TOO
		 SOJA  T3,.+1]
>>
	MOVE	T2,SAVFLG	;GET ORIGINAL TERMINAL FLAGS
	TLNN	T2,WRP		;DOES TERMINAL WRAP AROUND?
	POPJ	P,		;NO - IT STILL DOESN'T
	CAMLE	T3,CPL.0	;YES - IS NEW LENGTH SHORTER THAN SCREEN?
	TLOA	TM,WRP		;NO - MAKE IT WRAP
	TLZ	TM,WRP		;YES - NO WRAP
	POPJ	P,

SWHRDO:	SETCA	T4,		;READ-ONLY - COMPLEMENT WRITE FLAG
SWHWRT:	SETCAM	T4,SAVEAC+11	;STAGE THE VALUE IN CASE COMMAND IS SET-FILE
	CAIN	DO,$SETFI	;IS IT SET-FILE?
	POPJ	P,		;YES - DON'T SET THE FLAG NOW
SWHWR1:	JUMPE	T4,.+2		;SET READ-ONLY FLAG?
	TRZA	F,RDO		;NO
	TRO	F,RDO		;YES
	POPJ	P,

SWHDDD:	CAIN	T1,"C"		;DEFINE COMMAND SWITCH?
	JRST	SWHDCM		;YES - HANDLE IT
	CAIE	T1,"T"		;DISPLAY TABS SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
	JUMPE	T4,.+2		;YES - SET DISPLAY TABS FLAG?
	TROA	F,DTB		;YES
	TRZ	F,DTB		;NO
	POPJ	P,

;MOVE KEY SEQUENCE TO TOP OF PARBUF, POINT TO EXECUTE FREE SPACE
;POINT TO START OF COMMAND NAME

;FORMAT: /DC:^[P:^EL
;PROCEDURE: SAVE KEYSTROKES SOMEWHERE. PARSE COMMAND INTO T1

;NOTE: NEED TO KEEP KEYSTROKE/COMMAND UNTIL AFTER INIT, SO THEY
;      GO INTO THE RIGHT TABLE. WHERE SHOULD THEY BE KEPT?

SWHDCM:	HRRZ	T4,XCFPTR	;GET POINTER TO EXECUTE FREE SPACE
	ADD	T4,[440700,,1]
	SETZM	(T4)		;CLEAR PREVIOUS CONTENTS
	ILDB	T0,PT		;SKIP COLON AFTER THE SWITCH, IF ANY
	CAIN	T0,":"
SWHDC1:	ILDB	T0,PT		;GET CHARACTER OF SEQUENCE
	CAIN	T0,":"		;START OF CONTENTS?
	JRST	SWHDC3		;YES - SEE IF COMMAND IS LEGAL
	JUMPE	T0,SDCERR	;NULL - ERROR
	CAIN	T0,15		;START OF ANOTHER SWITCH?
	JRST	SDCERR		;YES - ERROR
	CAIE	T0,"^"		;NO - GOT A CONTROL CHARACTER?
	JRST	SWHDC2		;NO - PROCEED
	ILDB	T0,PT		;YES - GET NEXT CHARACTER
	CAIN	T0,"?"		;RUBOUT?
	TROA	T0,177		;YES - SET IT UP SPECIALLY
	ANDI	T0,37		;ELSE MAKE A CONTROL CHARACTER
SWHDC2:	TLNE	T4,760000	;ALREADY GOT 5 CHARACTERS?
	IDPB	T0,T4		;NO - SAVE CHARACTER
	JRST	SWHDC1		;AND GET ANOTHER

;HERE WHEN KEYSTROKE IS FOUND - GET COMMAND INDEX IN T3

SWHDC3:	ILDB	T2,PT		;GET THE (HOPEFULLY) STARTING UP-ARROW
	CAIN	T2,"$"		;GOT THE ENTER COMMAND?
	JRST	[MOVEI T3,33	;YES - SET UP ITS INDEX
		 JRST  SWHD4A]	;AND SKIP ALL THIS CHECKING
	PUSHJ	P,XCWGET	;PUT 2ND CHARACTER IN WITH THE UP-ARROW
	PUSHJ	P,XCWGET	;DITTO 3RD CHARACTER
	CAME	T2,["^RF"]	;GOT A ROLL FORWARD
	CAMN	T2,["^RB"]	;  OR BACKWARD?
	JRST	SWHDC5		;YES - NEED TO GET ANOTHER CHARACTER
	LSH	T2,^D15		;NO - LEFT-JUSTIFY COMMAND NAME
SWHDC4:	ILDB	T1,PT		;GET NEXT CHARACTER OF COMMAND
	JUMPN	T1,SDCERR	;ERROR IF THERE'S ANYTHING THERE
	MOVEI	T3,CMDLEN-1	;LOOK FOR COMMAND AMONG NAMES
	CAME	T2,CMDNAM(T3)	;IS THIS IT?
	SOJGE	T3,.-1		;NO - KEEP LOOKING
	JUMPL	T3,SDCERR	;ERROR IF NOT FOUND

SWHD4A:	MOVE	PT,XCFPTR	;GET POINTER TO KEYSTROKE SEQUENCE
	SKIPE	STTFLG		;INITIALIZING?
	JRST	CMDSAV		;YES - DON'T CHANGE TABLE NOW
				;ELSE FALL TO SET UP COMMAND, AND RETURN

;SUBROUTINE TO CHANGE THE COMMAND TABLE
;CALL WITH PT/ POINTER TO KEYSTROKE,  T3/ NEW COMMAND

SWHDCS:	ILDB	T4,PT		;GET THE FIRST CHARACTER
	CAIN	T4,177		;RUBOUT?
	SETO	T4,		;YES - USE -1 AS OFFSET
	ADD	T4,ITB(TM)	;GET OFFSET IN TERMINAL TABLE
	MOVE	T1,T4		;REMEMBER TABLE ADDRESS
	SKIPGE	T4,(T4)		;IS IT A NORMAL COMMAND?
	JRST	SWHDC0		;NO - GO LOOK IN SUBTABLE
	ILDB	T0,PT		;YES - GET NEXT CHARACTER OF SEQUENCE
	JUMPN	T0,SDCERR	;ERROR IF SEQUENCE IS NOT 1 CHARACTER LONG
	MOVEM	T3,(T1)		;SAVE THE NEW COMMAND IN THE TABLE
	POPJ	P,		;DONE

SWHDC0:	ILDB	T0,PT		;GET NEXT USER-GIVEN CHARACTER
SWHDS1:	SKIPN	T1,(T4)		;GET A SUBTABLE ENTRY - END?
	JRST	SDCERR		;YES - COMMAND IS NOT LEGAL
	TRNN	T1,-1		;MATCH ON ANY CHARACTER?
	JRST	SWHDS2		;YES - SET UP REAL COMMAND NOW
	CAIE	T0,(T1)		;DO USER'S AND TABLE'S CHARS MATCH?
	AOBJN	T4,SWHDS1	;NO - LOOP ON THE TABLE
	JUMPG	T4,SDCERR	;NOT LEGAL IF END OF TABLE AND NOT FOUND
SWHDS2:	CAMLE	T1,[137,,0]	;ELSE FOUND - WANT ANOTHER LEVEL?
	JRST	SWHDS3		;YES - SET IT UP
	HRLM	T3,(T4)		;SAVE THE NEW COMMAND IN THE SUBTABLE
	POPJ	P,		;DONE

SWHDS3:	TLZE	T1,200000	;GOT AN EXECUTE COMMAND?
	JRST	SWHDS2+2	;YES - SET IT UP AFTER ALL
	HLRZ	T4,T1		;POINT TO NEW SUBTABLE
	HRLI	T4,-^D40
	JRST	SWHDC0		;AND PICK UP ANOTHER CHARACTER

SWHDC5:	PUSHJ	P,XCWGET	;GET REST OF COMMAND NAME
	LSH	T2,^D8		;LEFT-JUSTIFY COMMAND NAME
	JRST	SWHDC4		;GO FIND THE COMMAND

;HERE WHEN INITIALIZING - STORE THE COMMAND CHANGE IN THE CLOSE BUFFER
;CALL WITH PT/ COMMAND SEQUENCE, T3/ NEW COMMAND

CMDSAV:	AOS	T1,CLSBUF+400	;GET THE SAVE POINTER
	MOVE	T2,1(PT)	;GET THE COMMAND SEQUENCE
	MOVEM	T2,CLSBUF+400(T1) ;SAVE THE COMMAND SEQUENCE
	MOVEM	T3,CLSBUF+401(T1) ;SAVE THE NEW COMMAND
	AOS	CLSBUF+400	;ADVANCE THE POINTER
	POPJ	P,		;DONE

;HERE AFTER INITIALIZATION, TO MAKE THE CHANGES TO THE COMMAND TABLE

CMDSET:	SOSGE	T1,CLSBUF+400	;ARE THERE ANY CHANGES?
	POPJ	P,		;NO - JUST RETURN
	MOVEI	PT,CLSBUF+400(T1) ;GET THE POINTER TO THE COMMAND SEQUENCE
	HRLI	PT,440700
	MOVE	T3,CLSBUF+401(T1) ;GET THE NEW COMMAND
	PUSHJ	P,SWHDCS	;MAKE THE CHANGE
	SOS	CLSBUF+400	;SKIP OVER BOTH PIECES OF DATA
	JRST	CMDSET		;LOOP THROUGH ALL THE CHANGES

;NOW ON WITH THE NORMAL SWITCHES

SWHHLP:	JUMPE	T4,.+2		;SET NO-HELP-WANTED FLAG?
	TRZA	F,NHP		;NO
	TRO	F,NHP		;YES
	POPJ	P,

SWHIII:	CAIN	T1,"D"		;I.D. SWITCH?
	JRST	SWHIDD		;YES - HANDLE IT
	CAIN	T1,"M"		;INSERT-MODE SWITCH?
	JRST	SWHIMD		;YES - HANDLE IT
	CAIN	T1,"C"		;INSERT-CR-IN-INSERT-MODE SWITCH?
	JRST	SWHICR		;YES - HANDLE IT
	CAIN	T1,"N"		;INVERT CASE SWITCH?
	JRST	SWHINV		;YES - HANDLE IT
	CAIN	T1,"T"		;INSERT TABS SWITCH?
	JRST	SWHINT		;YES - HANDLE IT
	CAIE	T1,"S"		;INCREMENTAL SAVE SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS

	JUMPE	T4,SWHII1	;YES - JUMP IF USER SAID /NOISAVE
	PUSHJ	P,SWHAG0	;ELSE READ ARGUMENT
	  JRST	SWGERR		;NO ARG - ERROR
	JUMPG	T3,.+2		;DID USER SAY /ISAVE:0?
SWHII1:	SETO	T3,		;YES - USE -1 (FOR NO SAVES)
	MOVEM	T3,ISVNUM	;ELSE SAVE # COMMANDS BETWEEN ISAVES
	MOVEM	T3,ISVCNT	;SAVE AS COUNTDOWN VALUE, TOO
	POPJ	P,

SWHICR:	JUMPE	T4,.+2		;SET NO CR IN INSERT MODE FLAG?
	TRZA	F,NCR		;NO
	TRO	F,NCR		;YES
	POPJ	P,

SWHIMD:	JUMPN	T4,.+2		;SET INSERT-MODE?
	TRZA	F,IMD		;NO - CLEAR FLAG AND RETURN
IFN TOPS10,<
	TRO	F,IMD		;YES - SET FLAG AND RETURN
	POPJ	P,
>
IFE TOPS10,<
IFN FTECHO,<
	TROA	F,IMD		;YES - SET FLAG AND SKIP TO SET ECHOES
	POPJ	P,
	JRST	EKOALL		;SET NO ECHO; BREAK ON ALL CHARACTERS; RETURN
>
IFE FTECHO,<
	TRO	F,IMD		;YES - SET FLAG AND RETURN
	POPJ	P,
>>
SWHIDD:	MOVEM	T4,TAGFLG	;SAVE SETTING OF I.D. SWITCH
	POPJ	P,

SWHINV:	SETCAM	T4,INVFLG	;SAVE SETTING OF INVERT-CASE SWITCH
	POPJ	P,

SWHINT:	SETCAM	T4,INSTBS	;SAVE SETTING OF INSERT-TABS SWITCH
	POPJ	P,

SWHTTT:	JUMPE	T1,SWHTB0	;MAKE "/T" DEFAULT TO /TABS
	CAIE	T1,":"		;DITTO
	CAIN	T1,"A"		;AND /TA IS /TABS, TOO
	JRST	SWHTB0
	CAIE	T1,"S"		;TAB-SET?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS

	PUSHJ	P,SWHAG0	;TAB-SET - READ THE DECIMAL TAB POSITION
	  JRST	SWGERR		;NO ARG - ERROR
	TLO	TM,STB		;TURN ON SETTABLE TABS
SWHTT0:	SOS	T2,T3		;MAKE THE COLUMN ZERO-BASED
        IDIVI	T2,^D36		;GET WORD AND POSITION IN WORD
	MOVN	T3,T3		;NEGATE POSITION
	MOVSI	T0,400000	;GET BIT FOR SHIFTING
	LSH	T0,(T3)		;SHIFT RIGHT TO THE RIGHT POSITION
	JUMPE	T4,SWHTT1	;JUMP IF WANT TO CLEAR THE BIT
	ORM	T0,TABTBL(T2)	;SET THAT BIT
	JRST	SWHTT2		;CONTINUE
SWHTT1:	ANDCAM	T0,TABTBL(T2)	;CLEAR THAT BIT
SWHTT2:	POPJ	P,		;RETURN

SWHTB0:	JUMPE	T4,SWHTBW	;IF NOTABS, SET UP WORDWISE TABS
	JUMPE	T1,SWHTNW	;IF IF JUST "/T" SET UP NORMAL TABS
SWHTAB:	CAIN	T1,":"		;ELSE SKIP UNTIL THE COLON IS FOUND
	JRST	SWHTA1		;GOT IT - PROCEED
	ILDB	T1,PT		;GET THE NEXT CHARACTER
	JUMPN	T1,SWHTAB	;MAYBE THIS IS THE COLON
	JRST	SWHTNW		;IF NO ARG, SET UP NORMAL TABS

SWHTA1:	MOVE	T0,PT		;SAVE POINTER TO START OF ARGUMENT
	PUSHJ	P,SWHLUR	;ELSE GET THE 1ST ARGUMENT CHARACTER
	CAIN	T1,"W"		;WANT WORDWISE TABS?
	JRST	SWHTBW		;YES - GO SET THEM
	CAIE	T1,"S"		;WANT "SETTABLE" TABS (FOR COMPATIBILITY)?
	CAIN	T1,"R"		;WANT REGULAR TABS?
	JRST	SWHTNW		;YES - GO SET THEM
	MOVE	PT,T0		;NO - POINT TO THE ARGUMENT AGAIN
	PUSHJ	P,SWHAG1	;READ THE REST OF THE NUMERIC ARGUMENT
	  JRST	SWHTNW		;NO ARG - SET UP NORMAL TABS
	MOVEM	T3,TABLEN	;SAVE ARG AS LENGTH OF A TAB
	PUSHJ	P,TABINI	;INITIALIZE THE TAB TABLE
	TLZ	TM,STB		;MAKE SURE SETTABLE TAB FLAG IS OFF
SWHTNW:	TRZA	F,WTB		;CLEAR WORDWISE TAB FLAG
SWHTBW:	TRO	F,WTB		;SET WORDWISE TAB FLAG
	POPJ	P,		;DONE

SWHGGG:
SWHPRC:	PUSHJ	P,SWHARG	;GET PERCENTAGE TO GO TO
	  SKIPA	T3,GOPERC	;IF NO ARG USE CURRENT PERCENT
SWHPC1:	JUMPL	T3,SWGERR	;PERCENT MUST BE WITHIN [0,100]
	CAILE	T3,^D100
	JRST	SWGERR		;IT'S NOT - ERROR
	MOVEM	T3,GOPRCT	;O.K. - SAVE STARTING PERCENT VALUE
	POPJ	P,

SWHPPP:	CAIN	T1,"A"		;PAGE-AND-LINE STATUS SWITCH?
	JRST	SWHPAG		;YES - HANDLE IT
	CAIE	T1,"R"		;PROG TO RUN ON EXIT SWITCH?
	JRST	SWAERR		;NO - IT'S AMBIGUOUS
IFN TOPS10,<
	PUSHJ	P,SWHGS0	;READ NAME OF SYSTEM CUSP TO RUN IN SIXBIT
	  JRST	SWGERR		;NO ARG - ERROR
	MOVEM	T3,GOBLK+1	;SAVE IN RUN BLOCK
>
IFE TOPS10,<
	MOVE	T4,[POINT 7,GOBLK]
	PUSHJ	P,SWHAGA	;READ NAME OF CUSP TO RUN IN ASCII
	  JRST	SWGERR		;NO ARG - ERROR
>
	POPJ	P,		;THAT'S ALL

SWHPAG:	MOVEM	T4,PAGFLG	;SAVE PAGE/LINES FLAG
	POPJ	P,

SWHQQQ:	MOVEM	T4,DSPFLG	;SAVE DISPLAY-ON-SETFIL FLAG
	POPJ	P,

SWHTRM:	PUSHJ	P,SWHAGS	;READ NAME OF TERMINAL TO USE
	  JRST	SWGERR		;NO ARG - ERROR
	MOVEM	T3,TRMNAM	;SAVE TERMINAL NAME
	POPJ	P,		;THAT'S ALL

SWHFFF:

;HERE FOR VARIOUS FILE STATUS SWITCHES: FC, FR, FS, FD, FO
;IF THESE ARE USED, /FD MUST APPEAR AND BE FIRST

SWHSTT:	MOVE	T2,T1		;SAVE FLAVOR OF SWITCH
	PUSHJ	P,SWHAG0	;READ ITS ARGUMENT
	  JRST	SWGERR		;NO ARG - ERROR
	CAIN	T2,"C"		;FC (COLUMN POSITION) SWITCH?
	JRST	SWHSTC		;YES - GO DO IT
	CAIN	T2,"R"		;FR (ROW POSITION) SWITCH?
	JRST	SWHSTR		;YES - GO DO IT
	CAIN	T2,"S"		;FS (SLIDE OFFSET) SWITCH?
	JRST	SWHSTL		;YES - GO DO IT
	CAIN	T2,"D"		;FD (DISPLAY POINTER) SWITCH?
	JRST	SWHSTD		;YES - GO DO IT
	CAIN	T2,"O"		;FO (ONE-SHOT) SWITCH?
	JRST	SWHOSH		;YES - GO DO IT
	JRST	SWHERR		;ANYTHING ELSE IS AN ERROR

SWHSTC:	HRLM	T3,PRERW	;SET UP COLUMN POSITION
	POPJ	P,
SWHSTR:	HRRM	T3,PRERW	;SET UP ROW POSITION
	POPJ	P,
SWHSTL:	MOVEM	T3,PRESL	;SET UP SLIDE OFFSET
	POPJ	P,
SWHOSH:	MOVEM	T3,PREONE	;SET UP ONE-SHOT POINTER
	POPJ	P,

SWHSTD:	SETZM	PRERW		;CLEAR THE OTHER POINTERS
	SETZM	PRESL
	IDIVI	T3,5		;SEPARATE INTO WORD, POSITION IN WORD
	ADDI	T3,BUFFER	;MAKE POINTER RELATIVE TO START OF BUFFER
	JUMPE	T4,SWHSD1	;HANDLE POINTING TO START OF WORD SPECIALLY
	HRL	T3,PTRTBL(T4)	;MAKE IT POINT AT THE RIGHT BIGHT
SWHSD0:	MOVEM	T3,PREDP	;SAVE POINTER IN THE RYTE PLACE
	POPJ	P,		;DONE
SWHSD1:	HRLI	T3,010700
	SOJA	T3,SWHSD0

;THE ONE-SHOT ARGUMENT IS THE CHARACTER IN THE FILE WHICH THE CURSOR SHOULD
;POINT TO. IT WILL BE SET UP 1/3 DOWN THE SCREEN. SO NEED TO CALCULATE
;CHRPTR, LINPTR, DISPTR, RW, CM, AND SL

;SWHOSH:	IDIVI	T3,5		;SEPARATE INTO WORD, POSITION IN WORD
;	ADDI	T3,BUFFER	;MAKE POINTER RELATIVE TO START OF BUFFER
;	HRL	T3,PTRTBL(T4)	;MAKE IT POINT AT THE RIGHT BYTE
;	MOVE	PT,T3		;SAVE POINTER IN THE RIGHT PLACE
;	JRST	SRCSET		;SET EVERYTHING UP AND RETURN

;SUBROUTINE TO READ COLON (MAYBE) AND NUMERIC ARGUMENT OF A SWITCH
;RETURNS T3/ VALUE, T1/ DELIMITER (0 OR ",")
;GIVES SKIP RETURN IF VALUE FOUND, NON-SKIP IF NO COLON FOUND
;TO READ THE 2ND AND FURTHER VALUES, ENTER AT SWHAG2

SWHAG0:	ILDB	T1,PT		;GET THE NEXT CHARACTER
SWHARG:	CAIE	T1,":"		;GOT A COLON?
	JUMPN	T1,SWHAG0	;NO - TRY NEXT ONE, IF ANY
SWHAG1:	JUMPE	T1,CPOPJ	;NO COLON - NON-SKIP RETURN
	AOS	(P)		;GOT THE COLON - GIVE SKIP RETURN
SWHAG2:	SETZB	T3,T0		;CLEAR TARGET AND NEGATIVE FLAG
	ILDB	T1,PT		;GET FIRST DIGIT OR DASH
	CAIN	T1,"-"		;WANT TO NEGATE THE RESULT?
	TDOA	T0,[-1]		;YES - REMEMBER THAT FACT
	CAIA			;NO - SKIP TO TREAT CHAR AS A DIGIT

SWHAG3:	ILDB	T1,PT		;GET A DIGIT
	JUMPE	T1,SWHAG4	;DONE IF NULL
	CAIN	T1,","		;GOT ONE NUMBER OF A LIST?
	POPJ	P,		;YES - RETURN
	SUBI	T1,"0"		;ELSE CONVERT TO NUMERIC
	JUMPL	T1,SWGER0	;ERROR IF NOT A NUMBER
	CAILE	T1,9
	JRST	SWGER0		;DITTO
	IMULI	T3,^D10		;ELSE MULTIPLY BY TEN
	ADD	T3,T1		;ADD IN THE NEW DIGIT
	JRST	SWHAG3		;AND GET ANOTHER ONE

SWHAG4:	JUMPE	T0,CPOPJ	;DONE IF NUMBER SHOULD BE POSITIVE
	MOVN	T3,T3		;ELSE NEGATE THE RESULT
	POPJ	P,		;THEN RETURN

;SUBROUTINE TO READ COLON (MAYBE) AND SIXBIT ARGUMENT OF A SWITCH
;RETURNS VALUE, IN SIXBIT, IN T3
;GIVES SKIP RETURN IF VALUE FOUND, NON-SKIP IF NO COLON FOUND

SWHGS0:	ILDB	T1,PT		;GET THE COLON
SWHAGS:	CAIE	T1,":"		;IS IT REALLY?
	JUMPN	T1,SWHGS0	;NO - TRY NEXT ONE, IF ANY
	JUMPE	T1,CPOPJ	;NO COLON - NON-SKIP RETURN
	AOS	(P)		;GOT THE COLON - GIVE SKIP RETURN
	SETZ	T3,		;CLEAR TARGET
	MOVE	T4,[POINT 6,T3] ;AND POINT TO TARGET
	MOVEI	T0,6		;EXPECT A MAXIMUM OF SIX
SWHGS1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;RETURN, IF NULL
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - MAKE IT SIXBIT
	SUBI	T1," "		;CONVERT TO SIXBIT
	JUMPL	T1,SWGER0	;ERROR IF NOT LEGALLY SIXBIT
	IDPB	T1,T4		;ELSE SAVE IT WITH THE REST
	SOJG	T0,SWHGS1	;GET MORE - COUNTED OUT?
	POPJ	P,		;YES - USE ONLY 6 CHARACTERS

IFN TOPS10,<
;SUBROUTINE TO READ COLON (MAYBE) AND SIXBIT ARGUMENT OF A SWITCH
;RETURNS T3/ SIXBIT STRING, T1/ DELIMITER (0 OR ",")
;GIVES SKIP RETURN IF VALUE FOUND, NON-SKIP IF NO COLON FOUND
;FOR ALL BUT THE FIRST VALUE, ENTER AT SWHSC1: (RETURNS +1)

SWHSC0:	ILDB	T1,PT		;GET THE COLON
SWHGSC:	CAIE	T1,":"		;IS IT REALLY?
	JUMPN	T1,SWHSC0	;NO - TRY NEXT ONE, IF ANY
	JUMPE	T1,CPOPJ	;NO COLON - NON-SKIP RETURN
	AOS	(P)		;GOT THE COLON - GIVE SKIP RETURN
SWHSC1:	SETZ	T3,		;CLEAR TARGET
	MOVE	T4,[POINT 6,T3] ;AND POINT TO TARGET
	MOVEI	T2,6		;EXPECT A MAXIMUM OF SIX
SWHSC2:	ILDB	T1,PT		;GET A CHARACTER
	CAIN	T1,","		;END OF THE STRING?
	POPJ	P,		;YES - DONE
	JUMPE	T1,CPOPJ	;RETURN, IF NULL
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - MAKE IT SIXBIT
	SUBI	T1," "		;CONVERT TO SIXBIT
	JUMPL	T1,SWGER0	;ERROR IF NOT LEGALLY SIXBIT
	IDPB	T1,T4		;ELSE SAVE IT WITH THE REST
	SOJG	T2,SWHSC2	;GET MORE - COUNTED OUT?
	POPJ	P,		;YES - USE ONLY 6 CHARACTERS

;SUBROUTINE TO READ ASCII ARGUMENT OF A SWITCH INTO (T4)
;GIVES SKIP RETURN IF VALUE FOUND, NON-SKIP IF NO COLON FOUND
;DELIMITER (0 OR ",") IS RETURNED IN T1
;(LIKE ABOVE, BUT STOPS ON A ",")

SWHGC0:	ILDB	T1,PT		;GET THE COLON
SWHAGC:	CAIE	T1,":"		;IS IT REALLY?
	JUMPN	T1,SWHGC0	;NO - TRY NEXT ONE, IF ANY
	JUMPE	T1,CPOPJ	;NO COLON - NON-SKIP RETURN
	AOS	(P)		;GOT THE COLON - GIVE SKIP RETURN
SWHGC1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,","		;END OF THIS VALUE?
	POPJ	P,		;YES - RETURN
	IDPB	T1,T4		;ELSE SAVE IT WITH THE REST
	JRST	SWHGC1		;AND LOOP
>
;SUBROUTINE TO READ ASCII ARGUMENT OF A SWITCH INTO (T4)
;GIVES SKIP RETURN IF VALUE FOUND, NON-SKIP IF NO COLON FOUND

SWHGA0:	ILDB	T1,PT		;GET THE COLON
SWHAGA:	CAIE	T1,":"		;IS IT REALLY?
	JUMPN	T1,SWHGA0	;NO - TRY NEXT ONE, IF ANY
	JUMPE	T1,CPOPJ	;NO COLON - NON-SKIP RETURN
	AOS	(P)		;GOT THE COLON - GIVE SKIP RETURN
SWHGA1:	ILDB	T1,PT		;GET A CHARACTER
	IDPB	T1,T4		;SAVE IT WITH THE REST
	JUMPN	T1,SWHGA1	;NO - LOOP IF NOT NULL
	POPJ	P,		;ELSE RETURN

IFE TOPS10,<
;SUBROUTINE TO READ ASCII ARGUMENT OF A SWITCH INTO (T4)
;GIVES SKIP RETURN IF VALUE FOUND, NON-SKIP IF NO COLON FOUND
;DELIMITER (0 OR ",") IS RETURNED IN T1
;(LIKE ABOVE, BUT STOPS ON A ",")

SWHGC0:	ILDB	T1,PT		;GET THE COLON
SWHAGC:	CAIE	T1,":"		;IS IT REALLY?
	JUMPN	T1,SWHGC0	;NO - TRY NEXT ONE, IF ANY
	JUMPE	T1,CPOPJ	;NO COLON - NON-SKIP RETURN
	AOS	(P)		;GOT THE COLON - GIVE SKIP RETURN
SWHGC1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,","		;END OF THIS VALUE?
	POPJ	P,		;YES - RETURN
	IDPB	T1,T4		;ELSE SAVE IT WITH THE REST
	JRST	SWHGC1		;AND LOOP
>
;IF SWITCH ERROR OUTPUT MESSAGE, RETURN TO CALLER OF SWHONE

SWHER0:	POP	P,		;RETURN TO CALLER OF SWHONE
SWHERR:	MOVEI	T1,[ASCIZ /############Illegal switch/]
SWHER1:	CAIN	DO,$SETFI	;DOING A SET-FILE?
	JRST	STFERR		;YES - GIVE SET-FILE-FLAVORED ERROR
	JRST	ERROR		;ELSE DISPLAY THE ERROR AND RETURN

SWAERR:	JUMPN	T1,SWHERR	;IF A CHARACTER WAS TYPED IT'S REALLY ILLEGAL
	MOVEI	T1,[ASCIZ /#########Ambiguous switch/]
	JRST	SWHER1		;DISPLAY THE ERROR AND RETURN

SWGER0:	POP	P,		;RETURN TO CALLER OF SWHONE
SWGERR:	MOVEI	T1,[ASCIZ /######Illegal switch argument/]
	JRST	SWHER1		;DISPLAY THE ERROR AND RETURN

SDCERR:	MOVEI	T1,[ASCIZ ?######Illegal argument for /DC:?]
	JRST	SWHER1		;DISPLAY THE ERROR AND RETURN

SAGERR:	MOVEI	T1,[ASCIZ ?####Use /ALT only at monitor level?]
	JRST	ERROR		;(ALWAYS TREAT IT AS A NON-SET-FILE ERROR)

;************************************************************************
;SUBROUTINES TO FILL WITH SPACES OR NULLS (OR CONTENTS OF CHARAC)
;ENTER WITH NUMCHR/ NUMBER OF CHARACTERS TO INSERT
;	    CHRPTR/ PLACE TO START INSERTING THEM (PRESERVED)
;IF ENTER AT MAKCHR, SET UP CHARACTER IN CHARAC
;ON RETURN, CHRPTR WILL POINT TO THE START OF THE STUFF ADDED,
;	    T4 POINTS TO THE FIRST CHARACTER AFTER THE NEW STUFF
;	    MAKPTR POINTS TO LAST REAL CHARACTER ADDED

;NOTE: THIS IS THE only PLACE WHERE THINGS ARE INSERTED INTO THE BUFFER

;AN ADDRESS CAN BE STORED IN ADJWRD (ADDRESS - NOT A POINTER). IF THE
;FILE WORD AT THAT ADDRESS IS MOVED THE ADDRESS WILL BE ADJUSTED SO IT
;STILL POINTS TO THE WORD. THE CALLER MUST CLEAR ADJWRD WHEN THIS ROUTINE
;RETURNS.
;IF ADJWRD IS ZERO HERE AND THE BOTTOM POINTER IS VALID, IT IS ADJUSTED.
;IF ADJWRD IS NON-ZERO BOTPTR IS MARKED INVALID.

MAKSPC:	MOVEI	T1," "		;GET A SPACE
	MOVEM	T1,CHARAC	;SAVE AS THE FILL CHARACTER
	JRST	MAKCHR		;GO PUT THEM IN
MAKNUL:	SETZM	CHARAC		;SET TO FILL WITH NULLS

MAKCHR:	SKIPN	T3,NUMCHR	;GET COUNT OF CHARACTERS TO PUT IN - ANY?
	POPJ	P,		;NO - JUST RETURN

	IDIVI	T3,5		;CONVERT IT TO COUNT OF WORDS
	JUMPE	T4,.+2		;ANY EXCESS?
	AOJ	T3,		;YES - ROUND UP TO NEXT FULL WORD
	MOVEM	T3,NUMWDS	;SAVE NUMBER OF WORDS TO ADD
	HRRZ	T4,CHRPTR	;GET ADDRESS OF START OF INSERT

	HRRZ	T1,BOTPTR	;GET THE ADDRESS OF THE BOTTOM POINTER
	SKIPE	ADJWRD		;DID THE USER GIVE AN ADDRESS TO ADJUST?
	TLO	F,XPB		;YES - THEN THE BOTTOM LINE PTR IS INVALID
	TLNN	F,XPB		;IS THE BOTTOM LINE POINTER INVALID?
	MOVEM	T1,ADJWRD	;NO - SAVE IT FOR ADJUSTING
	SKIPN	@ADJWRD		;ARE THE CONTENTS OF THAT WORD ZERO
	HRROS	@ADJWRD		;YES - MAKE THE WORD -1,,0

;FIRST SEE IF THERE ARE ENOUGH NULL WORDS RIGHT WHERE THE CURSOR IS
;IF SO, JUST GO AND WRITE THEM

	SKIPE	(T4)		;IS THE FIRST WORD NULL?
	JRST	MAKCH0		;NO - GO LOOK AND SQUEEZE
	MOVEI	T1,010700	;YES - POINT CHRPTR BEFORE START OF THAT WORD
	HRLM	T1,CHRPTR
	SOS	CHRPTR

MAKCHL:	SKIPE	(T4)		;COUNT CONSECUTIVE NULLS AT START: GOT ONE?
	JRST	MAKCH0		;NO - GO LOOK AND SQUEEZE
	SOJLE	T3,.+2		;YES - JUMP IF FOUND ENOUGH
	AOJA	T4,MAKCHL	;ELSE LOOK FOR MORE
	CAIL	T4,(EN)		;MOVED BEYOND END OF BUFFER?
	HRRI	EN,1(T4)	;YES - EXTEND END BY THAT PLUS ONE WORD
	JRST	MAKCH4		;GO PUT DATA IN

;HERE IF NOT ENOUGH NULLS WORDS AT CURSOR. LOOK (NOBYTE) WORDS AHEAD AND
;SHUFFLE THOSE UP TO THE TOP

MAKCH0:	MOVEI	T2,NOBYTE	;GET # OF WORDS TO LOOK AHEAD FOR NULLS
MAKCH1:	CAIN	T4,(EN)		;AT END OF BUFFER?
	AOJ	EN,		;YES - EXTEND BUFFER A WORD
	SKIPN	(T4)		;IS THIS WORD NULL?
	AOJA	T4,MKCH1A	;YES - COUNT IT AND LOOP
	AOJ	T4,		;NO - POINT TO NEXT WORD
	SOJGE	T2,MAKCH1	;AND LOOP, IF NOT LOOKED FAR ENOUGH

;HERE IF NOT ENOUGH NULLS FOUND IN RANGE - SHUFFLE REST OF FILE DOWN
;IF ANY NULLS HAVE BEEN FOUND, LEAVE THEM ALONE

	HRRZ	T3,EN		;GET ADDRESS OF END OF FILE
	ADD	EN,NUMWDS	;EXTEND FILE BY THAT AMOUNT
	HRRZ	T4,EN		;GET ADDRESS OF NEW END OF FILE
	HRRZ	T2,CHRPTR	;GET ADDRESS OF LAST WORD TO MOVE

	CAMLE	T2,ADJWRD	;NEED TO ADJUST THE ADJUSTABLE WORD?
	JRST	MAKADD		;NO - SKIP THIS
	MOVE	T1,T4		;YES - FIND DISTANCE THE WORD WILL MOVE
	SUB	T1,T3
	ADDM	T1,ADJWRD	;ADJUST THE WORD FORWARD BY THAT AMOUNT

MAKADD:	MOVE	T1,(T3)		;GET A WORD
	MOVEM	T1,(T4)		;SAVE IT
	SOJ	T4,
	CAME	T3,T2		;BACK TO START?
	SOJA	T3,MAKADD	;NO - KEEP GOING
	AOJA	T4,MAKCH4	;YES - PUT STUFF IN THAT NEW GAP

;HERE FROM MAKCH1, WHEN A WORD OF NULLS IS FOUND

MKCH1A:	SOJGE	T3,MAKCH1	;GOT A NULL - LOOP IF NOT ENOUGH
	SOJ	T4,		;ELSE ADJUST WORD POINTER AND EXIT THIS LOOP

;NOW SQUEEZE ALL THE NULL WORDS UP TO THE LOCATION OF THE FILE POINTER

MAKCH2:	HRRZ	T2,CHRPTR	;GET ADDRESS OF LAST WORD TO SHUFFLE
	MOVE	T3,T4		;POINT TO END OF SHUFFLE
MAKCH3:	CAMGE	T3,T2		;AT STARTING WORD?
	AOJA	T4,MAKCH4	;YES - DONE SHUFFLING BYTES
	SKIPN	T1,(T3)		;GET A WORD - NULL
	SOJA	T3,MAKCH3	;YES - DON'T SHUFFLE
	MOVEM	T1,(T4)		;NO - SAVE FARTHER DOWN
	CAMN	T3,ADJWRD	;IS THIS THE WORD THAT NEEDS ADJUSTING?
	HRRM	T4,ADJWRD	;YES - ADJUST IT
	SOJ	T4,
	SOJA	T3,MAKCH3	;DE-BUMP BOTH POINTERS AND LOOP

;NOW WRITE THE DESIRED STUFF INTO THE OPENED-UP AREA

MAKCH4:	TLNE	F,XPB		;GOT AN ADJUSTED BOTTOM POINTER?
	JRST	MAKCH5		;NO - SKIP THIS
	SETZ	T1,		;YES - SAVE THE ADJUSTED ADDRESS WITH THE PTR
	EXCH	T1,ADJWRD
	HRRM	T1,BOTPTR

MAKCH5:	MOVE	T1,@ADJWRD	;GET THE WORD AT THE POINTER
	CAMN	T1,[-1,,0]	;IS IT -1,,0?
	SETZM	@ADJWRD		;YES - IT SHOULD BE ZERO, SO MAKE IT SO
	HLL	T4,CHRPTR	;GET POINTER TO FIRST CHAR AFTER INSERT
	MOVEM	T4,NUMNUL	;SAVE IT FOR LATER
	MOVE	T4,CHRPTR	;POINT TO START OF INSERTED STUFF
	MOVE	T3,NUMCHR	;GET THE NUMBER OF CHARACTERS TO WRITE
	TLZE	F,WRH		;WANT TO READ FROM THE PICK OR CLOSE BUFFER?
	JRST	MAKPTP		;YES - HANDLE SEPARATELY
	MOVE	T1,CHARAC	;NO - GET THE CHARACTER TO PUT IN
	IDPB	T1,T4		;PUT THE CHARACTER IN
	SOJG	T3,.-1		;LOOP <NOCH> TIMES

;PAD OUT THE REMAINDER OF THE LAST WORD WITH NULLS; THEN RETURN

MAKPT1:	MOVEM	T4,MAKPTR	;SAVE POINTER TO LAST REAL THING ADDED
	SETZ	T1,		;GET A NULL
	CAMN	T4,NUMNUL	;REACHED GOOD STUFF?
	POPJ	P,		;YES - DONE
	IDPB	T1,T4		;NO - PUT THE NULL IN
	JRST	MAKPT1+2	;AND LOOP THROUGH THE DESIRED NUMBER

;HERE TO WRITE FROM THE PICK OR CLOSE BUFFER INTO THE OPENED-UP SPACE

MAKPTP:	SKIPN	PUTJFN		;WANT TO READ FROM DISK?
	JRST	MAKPT0+1	;NO - DON'T INITIALIZE
	PUSHJ	P,MAKPB0	;YES - INITIALIZE
MAKPT0:	PUSHJ	P,MAKPTB	;SET UP A PIECE IN THE BUFFER
	MOVE	PT,PUTPTR
MAKPPT:	ILDB	T1,PT		;GET CHARACTER FROM THE PICK BUFFER
MAKPP0:	IDPB	T1,T4		;SAVE IT IN THE FILE BUFFER
	CAIN	T1,15		;<CR>?
	SOJG	T3,MAKPP1	;YES - SEE IF END OF LINE
	SOJG	T3,MAKPPT	;LOOP <NOCH> TIMES
	SKIPG	MAKCNT		;GOT MORE TO READ FROM BUFFER?
	JRST	MAKPT1		;NO - PUT ENDING NULLS IN, IF ANY
	JRST	MAKPT0		;YES - GET AND PUT IT

MAKPP1:	ILDB	T1,PT		;PICK UP LINEFEED
	CAIN	T1,12		;IS IT REALLY?
	AOS	MAKLNS		;YES - BUMP COUNT OF LINES FOUND
	JRST	MAKPP0		;CONTINUE

;SUBROUTINE FOR WHEN READING FROM DISK: READ NEXT BUFFERFUL OF TEXT
;AND SET UP COUNTS. WHEN LAST BUFFERFUL HAS BEEN READ, CLOSE DISK FILE

MAKPB0:	MOVE	PT,PUTPTR	;SAVE POINTER TO THE PROPER BUFFER
	MOVEM	PT,PTMPTR
	MOVEM	T3,MAKCNT	;SAVE COUNT OF CHARACTERS TO ADD
IFN TOPS10,<
	HRLI	PT,-PCBSIZ	;MAKE IOWD PCBSIZ,(PICK/CLOSE BUFFER)
	MOVEM	PT,PUTCCL
>
	POPJ	P,

MAKPTB:
IFE TOPS10,<
	MOVE	T1,PUTJFN	;GET BUFFER JFN
>
	MOVE	T2,PTMPTR	;GET POINTER TO THE RIGHT BUFFER
	MOVEM	T2,PUTPTR	;SAVE IT
	MOVNI	T3,PCBSIZ*5	;DECREASE CHAR COUNT BY ONE BUFFERFUL
	ADDM	T3,MAKCNT	;UNLESS THERE'S NOT THAT MUCH OUT THERE
	SKIPGE	MAKCNT		;GOT SOMETHING LEFT FOR NEXT TIME?
	JRST	[SUB   T3,MAKCNT ;NO - READ ONLY A PARTIAL BUFFER
IFN TOPS10,<
		 MOVE  T1,T3	;SET UP I/O WORDCOUNT FOR FINAL READ
		 IDIVI T1,5
		 SOJ   T1,
		 HRLM  T1,PUTCCL
>
		 SETZM MAKCNT	;CLEAR COUNT TO INDICATE FINISHED-NESS
		 SETZM PUTJFN	;CLEAR BUFFER JFN
		 JRST  .+1]
IFN TOPS10,<
	INPUT	5,PUTCCL	;READ THE BUFFERFUL
>
IFE TOPS10,<
	PUSH	P,T3
	SIN			;READ THE BUFFERFUL
	POP	P,T3
>
	MOVN	T3,T3		;MAKE COUNT POSITIVE
	SKIPE	PUTJFN		;TIME TO CLOSE THE BUFFER FILE?
	POPJ	P,		;NO - JUST PROCESS THE BUFFER
IFN TOPS10,<
	RELEAS	5,		;YES
>
IFE TOPS10,<
	CLOSF			;YES
	  HALTF
>
	POPJ	P,

;************************************************************************
;SUBROUTINES FOR WHEN THE USER WANTS TO DO SOMETHING IN THE MIDDLE OF A TAB
;CHANGE THE TAB TO SPACES, RE-ADJUST CURSOR POSITION, AND DRIVE ON
;CALL WITH T1/POINTER TO THE TAB

RPLTAB:	SKIPN	TABSPC		;SITTING AT START OF TAB?
	POPJ	P,		;YES - DON'T BUST THE TAB THIS TIME
	MOVE	T1,TABSIZ	;ELSE GET SIZE OF TAB
	MOVEM	T1,NUMCHR	;SAVE AS NUMBER OF CHARACTERS TO MAKE
	SETZ	T1,		;NULL OUT THE TAB
	IDPB	T1,T2
	PUSHJ	P,MAKSPC	;ADD THOSE SPACES
	TLO	F,XPC
	JRST	MAKCPT		;RE-MAKE CURSOR POINTER AND RETURN

;************************************************************************
;PEEL ROUTINES - THESE CONVERT A PART OF THE PARAMETER BUFFER TO
;A NUMBER (PEEL.1), OR MOVE A FILE SPEC TO ITS OWN SPEC-IAL AREA (PELS.1)

;CAN ENTER IN ONE OF THREE SITUATIONS:
;ENTER, PARAMETER
;ENTER, NO PARAMETER		PARPTR UNCHANGED; GET TOKEN (OR SPECIAL)
;ENTER, CURSOR MOVE		CMV SET; TWO PARMS SET UP

;CAN RETURN IN ONE OF THREE SITUATIONS:
;NO ENTER TYPED			ENT FLAG IS NOT SET
;ENTER, BUT NO PARAMETER TYPED	ENT SET; T1/0
;ENTER AND PARAMETER TYPED	ENT SET; T1/NON-0

;SUBROUTINE TO READ A DECIMAL NUMBER FROM BUFFER. RETURN IS IN PARG1
;RETURNS T1/0 IF PARM NULL; ELSE -1

PEEL.1:	SETZB	T1,PARG2	;CLEAR PARM SET BY CURSOR MOVE
	TRNE	F,CMV		;WAS PARM DEFINED USING CURSOR MOVEMENT?
	JRST	PEEL.M		;YES - THAT'S A WHOLE NUTHER STORY
	MOVE	T4,[POINT 7,PARBUF]
	CAMN	T4,PARPTR	;ENTER-NO PARM TYPED?
	JRST	PEEL.C		;YES - MAY WANT TO COUNT UP A TOKEN
	IDPB	T1,PARPTR	;MAKE SURE PARAMETER ENDS WITH A NULL
	SETZB	T1,T3		;CLEAR FLAG AND RETURN VALUE

PEEL1:	ILDB	T2,T4		;GET A CHARACTER
	JUMPE	T2,PEEL3	;DONE IF NULL
	CAIN	T2,177		;DELIMITER CHARACTER?
	JRST	PEEL2		;YES - END OR IGNORE
	SETO	T1,		;ELSE INDICATE A NON-NULL PARAMETER
	SUBI	T2,60		;CONVERT TO OCTAL
	CAIL	T2,12		;IS IT REALLY A NUMBER?
	JRST	PGTERR		;NO - GIVE ERROR MESSAGE
	JUMPL	T2,PGTERR
	IMULI	T3,12		;YES - SHIFT TARGET
	ADD	T3,T2		;ADD IN NEW DIGIT
	JRST	PEEL1		;GET SOME MORE

PEEL2:	CAIE	DO,$SUBST	;GOT DELIMITER - IS THIS SUBSTITUTE COMMAND?
	JRST	PEEL1		;NO - JUST IGNORE IT (ELSE FINISH OFF)
PEEL3:	JUMPE	T1,CPOPJ	;IF NULL PARM FOUND, JUST RETURN
	MOVEM	T3,PARG1	;SAVE PARM
	POPJ	P,		;DONE

PGTERR:	MOVEI	T1,[ASCIZ /#####Argument must be numeric/]
	JRST	ERROR

;HERE IF PARAMETER WAS MADE USING CURSOR MOVEMENT
;SET PARG1 TO ROWS MOVED AND PARG2 TO COLUMNS
;CALLER SHOULD RESTORE MARK AT (RW,CM), THEN GET (RW,CM) FROM (SAVPOS,+1)

PEEL.M:	DMOVEM	RW,SAVEAC	;SAVE ENDING POSITION
	SUB	RW,SAVPOS	;FIND DIFFERENCE IN ROW
	MOVE	T2,RW		;GET ACTUAL DIFFERENCE
	MOVMM	RW,PARG1	;SAVE MAGNITUDE OF DIFFERENCE
	JUMPGE	RW,[MOVE RW,SAVPOS ;IF POSITIVE GO FROM STARTING POSITION
		    JRST PEL.M1]   ;NOW CHECK COLUMN
	MOVE	RW,SAVEAC	;IF NEGATIVE GO FROM ENDING POSITION
	EXCH	RW,SAVPOS
	TLO	F,XPL!XPC	;RE-DO ROW AND COLUMN POINTERS

PEL.M1:	SUB	CM,SAVPOS+1	;FIND DIFFERENCE IN COLUMN
	CAIE	DO,$INSLN	;OPEN-
	CAIN	DO,$DELLN	;  OR CLOSE-LINES COMMAND?
	JRST	PEL.M4		;YES - HANDLE SPECIALLY
	CAIE	DO,$CASE	;SAME WITH THE CASE
	CAIN	DO,$PICK	;  AND PICK COMMANDS
	JRST	PEL.M4		;YES - DON'T ADJUST COLUMN
PEL.M2:	MOVMM	CM,PARG2	;SAVE MAGNITUDE OF DIFFERENCE
	JUMPL	CM,PEL.M5	;JUMP IF NEGATIVE
	MOVE	CM,SAVPOS+1	;IF POSITIVE GO FROM STARTING POSITION
PEL.M3:	MOVE	T1,SAVCPT	;RE-SET ORIGINAL CHARACTER POINTER
	CAME	T1,CHRPTR	;HAS IT CHANGED ANY (W-WISE TABS)?
	TLO	F,XPL!XPC	;YES - RE-DO IT
	POPJ	P,		;AND LET CALLER WORRY ABOUT IT

PEL.M4:	JUMPE	T2,PEL.M2	;IF NO ROW CHANGE, DO IT THE OLD WAY
	MOVEM	CM,PARG2	;ELSE USE ACTUAL COLUMN DIFFERENCE
	JUMPG	T2,PEL.M3-1	;CONTINUE, IF ROW CHANGE POSITIVE
	MOVNM	CM,PARG2	;NEGATIVE - SAVE NEGATIVE DIFFERENCE

PEL.M5:	MOVE	CM,SAVEAC+1	;NEGATIVE - GO FROM ENDING POSITION
	EXCH	CM,SAVPOS+1
	TLO	F,XPC		;RE-DO COLUMN POINTER
	JRST	PEL.M3		;NOW FINISH OFF

;SUBROUTINE TO COUNT THE SIZE OF THE CURRENT FILE TOKEN

PEEL.C:	CAIE	DO,$RLFWL	;IS IT A ROLL LINES COMMAND?
	CAIN	DO,$RLBKL
	POPJ	P,		;YES - SPECIAL NON-TOKEN CASE
	CAIE	DO,$GOTO	;IS IT A PERCENT COMMAND
	CAIN	DO,$EXEC	;  OR AN EXECUTE COMMAND?
	POPJ	P,		;YES - ANOTHER NON-TOKEN CASE
	PUSHJ	P,MAKCPT	;MAKE POINTER TO CURSOR LOCATION
	MOVE	PT,CHRPTR	;GET CURSOR POINTER
	SETZ	T2,		;CLEAR COUNT

PEL.C1:	ILDB	T1,PT		;GET CHARACTER FROM THE BUFFER
	JUMPE	T1,.-1		;IGNORE IF NULL
	CAIGE	T1,"0"		;TOO SMALL FOR A NUMBER?
	AOJA	T2,PEL.C3	;YES - END OF TOKEN
	CAIG	T1,"9"		;IS IT A NUMBER?
	AOJA	T2,PEL.C1	;YES - GOOD
	CAIGE	T1,"A"		;TOO SMALL FOR A UC LETTER?
	AOJA	T2,PEL.C3	;YES - END OF TOKEN
	CAIG	T1,"Z"		;IS IT A UC LETTER?
	AOJA	T2,PEL.C1	;YES - GOOD
	CAIL	T1,"a"		;TOO SMALL FOR A lc LETTER?
	CAILE	T1,"z"		;IS IT A lc LETTER?
	AOJA	T2,PEL.C3	;NOT LC - END OF TOKEN
	AOJA	T2,PEL.C1	;AND GET ANOTHER ONE

PEL.C3:	MOVEM	T2,PARG1	;SAVE SIZE OF TOKEN
	CAIN	DO,$PICK	;DOING A PICK?
	SETZ	T1,		;YES - CLEAR GOT-AN-ARG FLAG
	POPJ	P,		;DONE

;SUBROUTINE TO PEEL OFF A STRING (FOR SEARCHES, SET-FILE, PUT)
;CALL WITH T3/ ASCII POINTER TO STRING SAVE AREA
;RETURNS T1/LENGTH OF STRING

PELS.1:	TRZE	F,CMV		;GOT A CURSOR MOVEMENT PARAMETER?
	JRST	PELS.M		;YES - HANDLE IT
	SETZ	T1,		;CLEAR GOT-A-PARM FLAG
	MOVE	T4,[POINT 7,PARBUF]
	CAMN	T4,PARPTR	;ENTER-NO PARM TYPED?
	JRST	PEEL.T		;YES - MAY WANT TO PICK UP A TOKEN
	IDPB	T1,PARPTR	;MAKE SURE PARAMETER ENDS WITH A NULL
	ILDB	T2,T4		;GET THE FIRST CHARACTER
	JUMPN	T2,PELST2+1	;IF NULL, JUST ENTER WAS TYPED
	POPJ	P,		;SO JUST RETURN

PELST2:	ILDB	T2,T4		;GET A CHARACTER
	CAIN	T2,177		;DELIMITER CHARACTER?
	JRST	PELST3		;YES - IGNORE IT OR END
	IDPB	T2,T3		;SAVE IT WHEREVER USER WANTS
	JUMPE	T2,CPOPJ	;DONE, IF NULL
	AOJA	T1,PELST2	;ELSE COUNT CHARACTER AND LOOP

PELST3:	CAIE	DO,$SUBST	;GOT DELIMITER - IS THIS SUBSTITUTE COMMAND?
	JRST	PELST2		;NO - JUST IGNORE IT
	SETZ	T0,		;YES - END STRING WITH A NULL
	IDPB	T0,T3
	POPJ	P,		;DONE

;HERE TO PEEL A CURSOR MOVEMENT STRING
;CALLER SHOULD RESTORE MARK AT (RW,CM), THEN GET (RW,CM) FROM (SAVPOS,+1)

PELS.M:	CAME	CM,SAVPOS+1	;ONLY LEGAL IF NOT ON THE SAME COLUMN,
	CAME	RW,SAVPOS	;  BUT ON THE SAME LINE - O.K.?
	JRST	CMVERR		;NO - ILLEGAL
	PUSH	P,T3		;SAVE POINTER TO PLACE TO SAVE STRING
	MOVE	T1,CM		;GET LENGTH OF STRING TO PICK UP
	SUB	T1,SAVPOS+1	;(MAKCPT PRESERVES ONLY T1)
	JUMPL	T1,.+2		;IS COUNT NEGATIVE?
	MOVE	CM,SAVPOS+1	;NO - GET ORIGINAL POSITION BACK
	TLO	F,XPC		;ALWAYS RE-DO CHARACTER POINTER
	PUSHJ	P,MAKCPT	;RE-DO IT, ALREADY
	POP	P,T3
	JUMPGE	T1,PELSM1	;IS THE COUNT NEGATIVE?
	TLO	F,XPC		;YES - GET THE CORRECT STARTING COLUMN
	MOVE	CM,SAVPOS+1
PELSM1:	MOVM	T4,T1		;SET UP SIZE OF PICK
	MOVE	PT,CHRPTR	;GET THAT POINTER
	PUSHJ	P,SPCBUF	;PICK UP THE STRING FROM THE BUFFER
	MOVE	T1,SPCCNT	;GET COUNT OF CHARACTERS PICKED
	SETZ	T2,		;END PARAMETER WITH A NULL
	IDPB	T2,T3
	POPJ	P,		;DONE

;SUBROUTINE TO PEEL OFF A TOKEN FROM THE FILE.
;THE TOKEN IS DEFINED AS EXTENDING FROM THE CURSOR LOCATION TO THE
;NEXT NON-ALPHANUMERIC CHARACTER
;TOKEN IS STORED AT AREA POINTED TO BY T3

PEEL.T:	CAIN	DO,$PUT		;GOT A PUT COMMAND?
	POPJ	P,		;YES - DON'T READ TOKEN
	MOVEM	T3,PARPTR	;SAVE SAVE POINTER
	PUSHJ	P,MAKCPT	;MAKE POINTER TO CURSOR LOCATION
	MOVE	T3,[POINT 7,PARBUF]
	EXCH	T3,PARPTR	;RESTORE SAVE POINTER
	SETZ	T1,		;CLEAR LENGTH OF TOKEN
	CAIN	DO,$SETFI	;IS COMMAND A SETFIL?
	JRST	PEEL.F		;YES - GET A FILESPEC-FLAVORED TOKEN
	MOVE	PT,CHRPTR	;GET CURSOR POINTER

PEL.T2:	ILDB	T2,PT		;GET CHARACTER FROM THE BUFFER
	JUMPE	T2,.-1		;IGNORE IF NULL
	CAIGE	T2,"0"		;TOO SMALL FOR A NUMBER?
	JRST	PEL.T3		;YES - END OF TOKEN
	CAIG	T2,"9"		;IS IT A NUMBER?
	JRST	PEL.T1		;YES - GOOD
	CAIGE	T2,"A"		;TOO SMALL FOR A UC LETTER?
	JRST	PEL.T3		;YES - END OF TOKEN
	CAIG	T2,"Z"		;IS IT A UC LETTER?
	JRST	PEL.T1		;YES - GOOD
	CAIL	T2,"a"		;TOO SMALL FOR A lc LETTER?
	CAILE	T2,"z"		;IS IT A lc LETTER?
	JRST	PEL.T3		;NOT LC - END OF TOKEN
PEL.T1:	IDPB	T2,T3		;SAVE CHARACTER IN CALLER'S BUFFER
	IDPB	T2,PARPTR	;SAVE CHARACTER IN PARAMETER BUFFER
	AOJA	T1,PEL.T2	;COUNT IT AND GET ANOTHER ONE

;SUBROUTINE TO PEEL OFF A FILESPEC STRING.
;CALL WITH T3/ ASCII POINTER TO STRING SAVE AREA
;RETURNS T1/LENGTH OF STRING

PELS.F:	SKIPE	CREFLG		;WANT ALWAYS TO CREATE THE FILE
	TRO	F,CRE		;YES - FLAG AS SUCH
	TRZE	F,CMV		;GOT A CURSOR MOVEMENT PARAMETER?
	JRST	PELS.M		;YES - HANDLE IT
	MOVE	T4,[POINT 7,PARBUF]
	CAMN	T4,PARPTR	;ENTER-NO-PARM TYPED?
	JRST	PEEL.T		;YES - MAY WANT TO PICK UP A TOKEN
	SETZB	T1,FILSPC	;CLEAR GOT-AN-ARG FLAG
IFN TOPS10,<
	MOVE	T2,[FILSPC,,FILSPC+1]
	BLT	T2,FILSPC+13	;CLEAR OUT PREVIOUS FILE SPECS
>
	IDPB	T1,PARPTR
	ILDB	T2,T4		;GET THE FIRST CHARACTER
	JUMPN	T2,PELSF1	;IF NULL, JUST ENTER WAS TYPED
	POPJ	P,		;SO JUST RETURN

PELSF0:	ILDB	T2,T4		;GET A CHARACTER
PELSF1:	CAIN	T2,"="		;WANT TO CREATE A FILE?
	JRST	[TRO  F,CRE	;YES - FLAG AS SUCH
		 JRST PELSF0]	;AND GET ANOTHER CHARACTER
	CAIN	T2,"@"		;WANT TO USE THE FILES GIVEN IN THIS FILE?
	JRST	[TRO  F,IND	;YES - FLAG AS SUCH
		 JRST PELSF0]	;AND GET ANOTHER CHARACTER
	IDPB	T2,T3		;SAVE IT WHEREVER USER WANTS
	JUMPE	T2,CPOPJ	;DONE, IF NULL
	AOJA	T1,PELSF0	;ELSE COUNT CHARACTER AND LOOP

;SUBROUTINE TO PEEL OFF A FILESPEC TOKEN FROM THE FILE.
;10:   TOKEN INCLUDES ALL LETTERS AND NUMBERS, PLUS ":.["
;      IF "[" IS FOUND ONLY OCTAL NUMBERS AND ",]" ARE LEGAL
;20:   TOKEN INCLUDES ALL LETTERS AND NUMBERS, PLUS ":.<>-"
;BOTH: OTHER CHARACTERS, OR MORE THAN 64 OF THESE, END THE TOKEN

PEEL.F:	SKIPE	MFLPTR		;WORKING WITH AN INDIRECT FILE?
	JRST	SETMFB		;YES - BACK UP A FILE
	SETZM	FILSPC		;CLEAR FILSPEC BLOCK
IFN TOPS10,<
	MOVE	T2,[FILSPC,,FILSPC+1]
	BLT	T2,FILSPC+13	;CLEAR OUT PREVIOUS FILE SPECS
>
	MOVE	PT,CHRPTR	;GET CURSOR POINTER
	MOVEI	T0,100		;SAVE AT MOST 64 CHARACTERS

PEL.F1:	ILDB	T2,PT		;GET CHARACTER FROM THE BUFFER
	JUMPE	T2,.-1		;IGNORE IF NULL
	CAIL	T2,"a"		;LOWER CASE?
	SUBI	T2,40		;YES - CONVERT TO UPPER
	CAIE	T2,"."		;DOT,
	CAIN	T2,":"		;  OR COLON?
	JRST	PEL.F3		;YES - CONTINUE
IFN TOPS10,<
	CAIN	T2,"["		;OPEN BRACKET?
	AOJA	T1,PEL.F2	;YES - CONTINUE IN PPN MODE
>
IFE TOPS10,<
	CAIE	T2,"<"		;OPEN
	CAIN	T2,">"		; OR CLOSE BRACKET?
	JRST	PEL.F3		;YES - CONTINUE
	CAIN	T2,"-"		;DASH?
	JRST	PEL.F3		;YES - CONTINUE
>
	CAIGE	T2,"0"		;NUMERIC?
	JRST	PEL.T3		;NO - END OF TOKEN
	CAIG	T2,"9"		;NUMERIC?
	JRST	PEL.F3		;YES - CONTINUE
	CAIGE	T2,"A"		;ALPHABETIC?
	JRST	PEL.T3		;NO - END OF TOKEN
	CAIG	T2,"Z"		;ALPHABETIC?
PEL.F3:	SOJLE	T0,PEL.T3	;YES - DONE IF COUNTED OUT
	IDPB	T2,T3		;SAVE CHARACTER IN CALLER'S BUFFER
	IDPB	T2,PARPTR	;SAVE CHARACTER IN PARAMETER BUFFER
	AOJA	T1,PEL.F1	;COUNT IT AND GET MORE

PEL.T3:	SETZ	T2,		;END BUFFER WITH A NULL
	IDPB	T2,T3
	IDPB	T2,PARPTR
	POPJ	P,		;DONE (LENGTH IS RETURNED IN T1)

IFN TOPS10,<
PEL.F2:	IDPB	T2,T3		;SAVE CHARACTER IN CALLER'S BUFFER
	IDPB	T2,PARPTR	;SAVE CHARACTER IN PARAMETER BUFFER

	ILDB	T2,PT		;GET CHARACTER FROM THE BUFFER
	JUMPE	T2,.-1		;IGNORE IF NULL
	CAIN	T2,","		;COMMA?
	JRST	PEL.F4		;YES - CONTINUE
	CAIN	T2,"]"		;CLOSE BRACKET?
	JRST	PEL.F3		;YES - CONTINUE IN NON-PPN MODE
	CAIGE	T2,"0"		;NUMERIC?
	JRST	PEL.T3		;NO - END OF TOKEN
IFN FTSFD,<
	CAIG	T2,"9"		;NUMERIC?
	JRST	PEL.F4		;YES - O.K.
	CAIL	T2,"a"		;LOWER CASE?
	SUBI	T2,40		;YES - CONVERT TO UPPER
	CAIGE	T2,"A"		;ALPHABETIC?
	JRST	PEL.T3		;NO - END OF TOKEN
	CAIG	T2,"Z"		;ALPHABETIC?
>
IFE FTSFD,<
	CAIG	T2,"7"		;OCTAL NUMERIC?
>
PEL.F4:	SOJLE	T0,PEL.T2	;YES - DONE IF COUNTED OUT
	AOJA	T1,PEL.F2	;COUNT IT AND GET MORE
> ;END IFN TOPS10

CMVERR:	SKIPA	T1,[[ASCIZ /######Stay on the same line/]]
CMXERR:	MOVEI	T1,[ASCIZ /###Can't mix characters and moves/]
	MOVE	RW,SAVPOS	;RESTORE SAVED POSITION
	MOVE	CM,SAVPOS+1
	JRST	ERROR

;SUBROUTINE TO PARSE THE FILE SPECS IN FILSPC INTO THE OPEN AND LOOKUP BLOCKS
;ALSO HANDLES SWITCHES. IF TOPS20, PARSEF HANDLES ONLY SWITCHES

PARSFN:
IFN TOPS10,<
	MOVEI	T1,2		;SET UP CURRENT PATH AS DEFAULT
	MOVE	T2,OLDPTH(T1)	;(THIS IS USED ONLY IN SETNPM,
	MOVEM	T2,FILPTH(T1)	; FOR THE 2ND FILE IN .TMP OR
	JUMPE	T2,PARSEF	; AN INDIRECT FILE)
	AOJA	T1,PARSFN+1

PARSEF:	MOVE	PT,[POINT 7,FILSPC]
	MOVEI	T1,16		;SET UP OPEN BLOCK
	MOVSI	T2,'DSK'	;  (MODE AND DEVICE)
	DMOVEM	T1,FILBLK
	SETZB	T1,T2		;ZERO OUT FILE SPEC AREA
	DMOVEM	T1,FILFIL+1	;(NOTE: PATH STAYS THE SAME AS LAST TIME
	DMOVEM	T1,FILFIL+3	; UNTIL USER GIVES A PPN)
	SETZM	FILFIL+5
IFE FTSFD,<
	SETZM	FILPPN
>

PARSF0:	MOVE	T4,[POINT 6,FILFIL+2]
	MOVEI	T0,^D9		;SAVE AT MOST 9 CHARACTERS
PARSF1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE, IF NULL
	CAIN	T1,11		;(TREAT TAB LIKE A NULL)
	POPJ	P,
	CAIN	T1," "		;IGNORE SPACES
	JRST	PARSF1
	CAIN	T1,":"		;END OF DEVICE?
	JRST	PARSED		;YES - GO SET DEVICE UP
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	PARSEE		;YES - GO PARSE IT
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSEP		;YES - GO PARSE IT
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	PARSES		;YES - GO HANDLE THEM
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRSERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRSERR
	CAIG	T1,'9'
	JRST	PARSF2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRSERR

PARSF2:	SOJL	T0,PARSF1	;IGNORE, IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;ELSE SAVE IT
	JRST	PARSF1		;AND GET ANOTHER

PARSED:	SKIPN	T1,FILFIL+2	;GET DEVICE NAME - ANY?
	JRST	PRSERR		;NO - JUST A COLON - ERROR
	MOVEM	T1,FILBLK+1	;SAVE AS DEVICE
	SETZM	FILFIL+2	;CLEAR FILE NAME
	JRST	PARSF0		;GO GET FILE NAME AGAIN

PARSEE:	MOVE	T4,[POINT 6,FILFIL+3]
	MOVEI	T0,3		;SAVE AT MOST 3 CHARACTERS
	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE, IF NULL
	CAIE	T1,11		;IGNORE TABS
	CAIN	T1," "		;  AND SPACES
	JRST	PARSEE+2
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSEP		;YES - GO PARSE IT
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	PARSES		;YES - GO HANDLE THEM
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRSERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRSERR
	CAIG	T1,'9'
	JRST	PARSE2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRSERR

PARSE2:	SOJL	T0,PARSEE+2	;IGNORE, IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;SAVE CHARACTER
	JRST	PARSEE+2	;AND GET ANOTHER

PARSEP:	SETZ	T1,		;CLEAR TARGET
PARSP1:	ILDB	T2,PT		;GET CHARACTER OF PPN
	JUMPE	T2,PARSP3	;DONE IF NULL
	CAIN	T2,","		;END OF PROJECT NUMBER?
	JRST	PARSP2		;YES - SAVE IT AND GET PROG NUMBER
	CAIE	T2,"/"		;END OF PROGRAMMER NUMBER?
	CAIN	T2,"]"
	JRST	PARSP3		;YES - SAVE IT AND QUIT
	CAIL	T2,"0"		;ERROR IF NOT OCTAL
	CAILE	T2,"7"
	JRST	PRSERR
	ROT	T2,-3		;ELSE SHIFT IT INTO TARGET
	LSHC	T1,3
	JRST	PARSP1		;AND GET SOME MORE

IFN FTSFD,<
PARSP2:	TLOE	F,FLG		;IT THIS PROGRAMMER NUMBER?
	JRST	PARSSF		;YES - THERE'S AN SFD COMING
	JUMPE	T1,PARSEP	;NO - IF NOTHING THERE, DON'T SAVE
	HRLM	T1,FILPTH+2	;ELSE SAVE PROJECT NUMBER
	JRST	PARSEP		;AND GET PROGRAMMER NUMBER

PARSSF:	SETZ	T2,		;FINISH OFF PPN
	PUSHJ	P,PARSP3+1
	TLZ	F,FLG		;CLEAR PROJECT NUMBER FLAG
	SETZ	T1,		;CLEAR SFD LEVEL COUNTER
PARSS0:	MOVE	T4,[POINT 6,T3]
	MOVEI	T0,^D6		;SAVE AT MOST 6 CHARACTERS
	SETZ	T3,		;CLEAR TARGET OF SFD NAME
PARSS1:	ILDB	T2,PT		;GET CHARACTER OF SFD
	JUMPE	T2,PARSS3	;DONE IF NULL
	CAIN	T2,","		;START OF ANOTHER SFD LEVEL?
	AOJA	T1,PARSS2	;YES - SET UP FOR IT
	CAIE	T2,"/"		;END OF SFDS?
	CAIN	T2,"]"
	JRST	PARSS3		;YES - SAVE IT AND QUIT
	CAIL	T2,"a"		;LOWER CASE?
	TRZA	T2,100		;YES - CONVERT TO SIXBIT
	SUBI	T2,40		;NO - CONVERT TO SIXBIT
	JUMPL	T2,PRSERR	;ERROR IF ILLEGAL SIXBIT
	CAILE	T2,77
	JRST	PRSERR
	IDPB	T2,T4		;O.K. - ADD TO SFD NAME
	SOJGE	T0,PARSS1	;AND GET SOME MORE
	JRST	PRSERR		;UNLESS COUNTED OUT

PARSS2:	JUMPE	T3,.+2		;USE OLD SFD NAME IF NONE GIVEN
	MOVEM	T3,FILPTH+2(T1)	;ELSE SAVE SFD NAME
	CAIGE	T1,SFDLVL	;DOWN TOO MANY SFD LEVELS?
	JRST	PARSS0		;NO - GO PARSE THE NEXT LEVEL
	JRST	PRFERR		;YES - ERROR

PARSP3:	SETZM	FILPTH+3	;PATH ENDS WITH PPN
	JUMPE	T1,.+2		;IS PROGRAMMER NUMBER NON-0?
	HRRM	T1,FILPTH+2	;YES - SAVE IT
	JUMPE	T2,CPOPJ	;DONE IF LAST CHARACTER WAS NULL
	CAIN	T2,"/"		;ELSE GOT SOME SWITCHES?
	JRST	PARSES		;YES - READ THEM, TOO
	JRST	PARSF0		;NO - SEE WHAT ELSE THERE IS

PARSS3:	JUMPE	T3,.+2		;WANT DEFAULT FOR THIS SFD?
	MOVEM	T3,FILPTH+3(T1)	;NO - SAVE WHAT THE USER TYPED
	SETZM	FILPTH+4(T1)	;CLEAR WORD AFTER LAST SFD NAME
	JUMPE	T2,CPOPJ	;DONE IF LAST CHARACTER WAS NULL
	CAIE	T2,"/"		;ELSE GOT SOME SWITCHES?
	JRST	PARSF0		;NO - SEE WHAT ELSE THERE IS
>
IFE FTSFD,<
PARSP2:	HRLM	T1,FILFIL+1	;SAVE PROJECT NUMBER
	JRST	PARSEP		;AND GET PROGRAMMER NUMBER

PARSP3:	HLL	T1,FILFIL+1	;GET ENTIRE PPN
	TLNN	T1,-1		;MISSING THE PROJECT?
	HLL	T1,USRPPN	;YES - USE THE USER'S OWN
	TRNN	T1,-1		;MISSING THE PROGRAMMER?
	HRR	T1,USRPPN	;YES - USE THE USER'S OWN
	MOVEM	T1,FILFIL+1	;STORE ENTIRE PPN
	MOVEM	T1,FILPPN	;HERE, TOO
PARSS3:	JUMPE	T2,CPOPJ	;DONE IF LAST CHARACTER WAS NULL
	CAIE	T2,"/"		;ELSE GOT SOME SWITCHES?
	JRST	PARSF0		;NO - SEE WHAT ELSE THERE IS
>
PARSES:	SETZ	T1,		;NULL OUT THE FIRST SLASH
	DPB	T1,PT
	JRST	SWHMNY		;HANDLE THE SWITCHES AND RETURN

IFN FTSFD,<
PRFERR:	SKIPA	T1,[[ASCIZ /#########SFD level too deep/]]
>
PRSERR:	MOVEI	T1,[ASCIZ /###########Bad file specs/]
	SKIPG	OUTFLG		;PARSING SPECS FROM AN /OUT: SWITCH?
	JRST	STFERR		;NO - OUTPUT THE ERROR AND CONTINUE
	MOVS	T2,[FILSPC,,SVASPC]
	BLT	T2,FILSPC+SPCSIZ-1 ;YES - RESTORE ORIGINAL FILESPECS
	SETZM	OUTFLG		;SAY NO LONGER PARSING /OUT: SPECS
	MOVEI	T1,[ASCIZ /######Bad file specs in switch/]
	JRST	ERROR		;AND GIVE THE RIGHT ERROR MESSAGE
>
IFE TOPS10,<
PARSEF:	MOVE	PT,[POINT 7,FILSPC]
	SETZM	SAVEAC+12	;CLEAR VERSION-NUMBER-GIVEN FLAG
	SETZB	T3,EXTPTR	;CLEAR FOUND-EXTENSION FLAG
	SETZ	T4,		;CLEAR POINTER TO EXTENSION
PARSF1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PARSF2	;DONE IF NULL
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	PARSFE		;MAYBE - CHECK AND SEE
	CAIN	T1,"<"		;START OF USER I.D.?
	JRST	PARSFU		;YES - GO SKIP OVER IT
	CAIE	T1,"/"		;START OF SWITCHES?
	JRST	PARSF1		;NO - KEEP LOOKING

PARSFS:	SETZ	T1,		;NULL OUT THE FIRST SLASH
	DPB	T1,PT
	PUSHJ	P,PARSF2	;SEE IF EXTENSION FOUND
	JRST	SWHMNY		;HANDLE THE SWITCHES AND RETURN

PARSFE:	JUMPE	T3,.+2		;GOT ONE DOT ALREADY?
	SETOM	SAVEAC+12	;YES - FLAG THE START OF THE VERSION NUMBER
	MOVE	T4,PT		;SAVE POINTER TO THE DOT
	ILDB	T1,PT		;IF EXT IS JUST A DOT IT'S NOT AN EXT
	JUMPE	T1,PARSF2	;LIKE DOT<NULL> - DONE
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	PARSFS		;YES - GO DO THEM
	SETO	T3,		;NO - IT'S A REAL EXTENSION - SET FLAG
	JRST	PARSF1		;AND CONTINUE

PARSFU:	ILDB	T1,PT		;SKIP OVER USER I.D. - READ CHARACTER
	JUMPE	T1,PARSF2	;DONE IF NULL
	CAIN	T1,">"		;END OF USER I.D.?
	JRST	PARSF1		;YES - BACK TO THE FLOW
	JRST	PARSFU		;NO - KEEP LOOKING

PARSF2:	JUMPN	T3,CPOPJ	;IF SOME EXTENSION FOUND JUST RETURN
	SKIPN	T1,T4		;ELSE GET SAVED EXT POINTER, IF ANY
	MOVE	T1,PT		;ELSE USE CURRENT POINTER
	MOVEM	T1,EXTPTR	;SAVE PTR TO END OF SPECS (IE, START OF EXT)
	POPJ	P,
>
;SUBROUTINE TO UNPARSE THE FILE SPEC BLOCKS INTO FILSPC

IFN TOPS10,<
UNPARS:	MOVE	PT,[POINT 7,FILSPC]
	MOVE	T2,FILBLK+1	;GET DEVICE
	PUSHJ	P,PUTSIX	;OUTPUT IT
	MOVEI	T1,":"
	IDPB	T1,PT

	MOVE	T2,FILFIL+2	;SET UP FILE NAME
	PUSHJ	P,PUTSIX
	MOVEI	T1,"."
	IDPB	T1,PT
	HLLZ	T2,FILFIL+3	;SET UP EXTENSION
	PUSHJ	P,PUTSIX
	SKIPN	FILPPN		;IS THERE A PPN?
	JRST	UNPRSX		;NO - DON'T OUTPUT IT
	MOVEI	T1,"["		;START THE PPN
	IDPB	T1,PT

	SETO	T3,
	HLRZ	T1,FILPPN	;GET THE PROJECT
	SKIPA	T4,[","]	;GET SEPARATOR CHARACTER
UNPRSP:	HRRZ	T1,FILPPN	;GET THE PROGRAMMER
	MOVSI	T2,700000
	LSHC	T1,-3
	JUMPN	T1,.-1		;PUT NUMBER ENTIRELY IN T2
UNPSP1:	SETZ	T1,
	LSHC	T1,3		;GET A DIGIT IN T1
	JUMPE	T2,UNPSP2	;DONE IF NOTHING LEFT
	ADDI	T1,"0"
	IDPB	T1,PT
	JRST	UNPSP1

UNPSP2:	IDPB	T4,PT		;SAVE SEPARATOR OR END BRACKET
	MOVEI	T4,"]"		;GET THE END BRACKET
	AOJE	T3,UNPRSP	;IF DID PROJ, GO DO PROG
IFN FTSFD,<
	SETZ	T3,		;CLEAR SFD INDEX
UNPSSF:	SKIPN	T2,FILPTH+3(T3)	;GOT AN(OTHER) SFD NAME?
	JRST	UNPRSX		;NO - FINISH OFF
	MOVEI	T1,","		;YES - CHANGE BRACKET TO A COMMA
	DPB	T1,PT
	PUSHJ	P,PUTSIX	;OUTPUT SIXBIT SFD NAME
	IDPB	T4,PT		;END WITH A RIGHT BRACKET
	AOJA	T3,UNPSSF	;GET NEXT LEVEL, IF ANY
>
UNPRSX:	SETZ	T2,
	IDPB	T2,PT		;END WITH A NULL
	POPJ	P,		;AND RETURN

PUTSIX:	SETZ	T1,		;GET A SIXBIT CHARACTER
	LSHC	T1,6
	JUMPE	T1,PUTSX2	;IF NULL CHECK TO SEE IF DONE
PUTSX1:	ADDI	T1,40		;ELSE CONVERT TO ASCII
	IDPB	T1,PT		;STORE CHARACTER
	JRST	PUTSIX		;AND LOOP

PUTSX2:	JUMPN	T2,PUTSX1	;GOT NULL OR SPACE - IF THERE IS MORE FOLLOWING
	POPJ	P,		;  OUTPUT THE SPACE, ELSE RETURN
>
IFE TOPS10,<
;UNPARSE - READ SPECS BACK FROM MONITOR. FIND EXTENSION AND SAVE FOR
;DEFAULTING NEXT TIME. EXPECTS JFN IN T1

UNPARS:	MOVE	T2,T1		;READ FILESPECS BACK INTO FILSPC
	HRROI	T1,FILSPC
	MOVE	T3,[221100,,1]
	SETZ	T4,
	JFNS			;AND FALL INTO:

;SUBROUTINE TO FIND AN EXTENSION IN THE FILESPECS AT (T4) AND SAVE IT AT (PT)

UNPEX0:	MOVE	T4,[POINT 7,FILSPC]
	MOVE	PT,[POINT 7,EXTTBL]
	MOVEI	T0,5		;SET MAXIMUM EXTENSION SIZE TO 5 CHARACTERS
UNPEXT:	ILDB	T1,T4		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	UNPEXE		;YES - GO SAVE
	CAIE	T1,"<"		;START OF USER I.D.?
	JRST	UNPEXT		;NO - GET MORE

UNPEXU:	ILDB	T1,T4		;GET A CHARACTER OF THE USER I.D.
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,">"		;END OF I.D.?
	JRST	UNPEXT		;YES - BACK TO THE MAIN FLOW
	JRST	UNPEXU		;NO - KEEP SKIPPING

UNPEXE:	ILDB	T1,T4		;GET A CHARACTER OF THE EXTENSION
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIE	T1,"."		;START OF VERSION NUMBER,
	CAIN	T1,"/"		;  OR START OF SWITCHES?
	POPJ	P,		;YES - DONE
	SOJL	T0,UNPEXE	;SAVED MORE THAN FOUR EXTENSION CHARACTERS?
	IDPB	T1,PT		;NO - SAVE THIS ONE, TOO
	JRST	UNPEXE		;AND KEEP LOOKING
>
;HERE TO READ FILE.EXT INTO A NORMAL LOOKUP BLOCK
;FILESPEC TO PARSE IS IN (PT); TARGET ADDRESS IS IN (T3)
;DEFAULT EXTENSION IS IN T4

IFN TOPS10,<
PARSFX:	MOVEM	T4,SAVEAC	;SAVE DEFAULT EXTENSION
	SETZB	T1,T2		;ZERO OUT FILE SPEC AREA
	DMOVEM	T1,0(T3)	;(NOTE: PATH STAYS THE SAME AS LAST TIME
	DMOVEM	T1,2(T3)	; UNTIL USER GIVES A PPN)
PARSP0:	MOVEI	T0,^D9		;SAVE AT MOST 9 CHARACTERS
	MOVE	T4,[POINT 6,(T3)]
PARFP1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PARSPX	;DONE, IF NULL
	CAIN	T1,15		;ALSO DONE IF CR
	JRST	PARSPX
	CAIN	T1," "		;IGNORE SPACES
	JRST	PARFP1
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	PARSPE		;YES - GO PARSE IT
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSPP		;YES - GO PARSE IT
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRPERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRPERR
	CAIG	T1,'9'
	JRST	PARFP2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRPERR

PARFP2:	SOJL	T0,PARFP1	;IGNORE IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;ELSE SAVE IT
	JRST	PARFP1		;AND GET ANOTHER

PARSPE:	MOVE	T4,[POINT 6,1(T3)]
	MOVEI	T0,3		;SAVE AT MOST 3 CHARACTERS
	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PARSPX	;DONE, IF NULL
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSPP		;YES - GO PARSE IT
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRPERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRPERR
	CAIG	T1,'9'
	JRST	PAREP2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRPERR

PAREP2:	SOJL	T0,PARSPE+2	;IGNORE, IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;SAVE CHARACTER
	JRST	PARSPE+2	;AND GET ANOTHER

PARSPP:	SETZ	T1,		;CLEAR TARGET
PARPP1:	ILDB	T2,PT		;GET CHARACTER OF PPN
	JUMPE	T2,PARPP3	;DONE IF NULL
	CAIN	T2,","		;END OF PROJECT NUMBER?
	JRST	PARPP2		;YES - SAVE IT AND GET PROG NUMBER
	CAIN	T2,"]"		;END OF PROGRAMMER NUMBER?
	JRST	PARPP3		;YES - SAVE IT AND QUIT
	CAIL	T2,"0"		;ERROR IF NOT OCTAL
	CAILE	T2,"7"
	JRST	PRPERR
	ROT	T2,-3		;ELSE SHIFT IT INTO TARGET
	LSHC	T1,3
	JRST	PARPP1		;AND GET SOME MORE

PARPP2:	HRLM	T1,3(T3)	;SAVE PROJECT NUMBER
	JRST	PARSPP		;AND GET PROGRAMMER NUMBER

PARPP3:	HRRM	T1,3(T3)	;SAVE PROGRAMMER NUMBER
	JUMPN	T2,PARSP0	;IF NOT END, SEE WHAT ELSE AWAITS
PARSPX:	MOVE	T1,SAVEAC	;GET DEFAULT EXTENSION
	SKIPN	1(T3)		;GOT AN EXTENSION?
	HRLM	T1,1(T3)	;NO - SAVE DEFAULT
	MOVE	T1,USRPPN	;GET USER'S PPN
	SKIPN	3(T3)		;DID USER GIVE ONE HERE?
	MOVEM	T1,3(T3)	;NO - SAVE USER'S
	POPJ	P,		;THEN RETURN

PRPERR:	MOVEI	T1,[ASCIZ /###########Bad file specs/]
	JRST	ERROR
>
IFE TOPS10,<
;TOPS20 - JUST MOVE SPECS FROM (PT) TO (T3)
;APPEND DEFAULT EXTENSION (IN T4) IF NONE GIVEN
;FILESPEC TO PARSE IS IN (PT); TARGET ADDRESS IS IN (T3)

PARSFX:	SETZ	T0,		;CLEAR EXTENSION FLAG
PRSFX1:	ILDB	T1,PT		;GET A CHARACTER
	IDPB	T1,T3		;ELSE SAVE CHARACTER
	CAIN	T1,"."		;GOT AN EXTENSION?
	SETO	T0,		;YES - SET FLAG
	JUMPN	T1,PRSFX1	;LOOP IF NOT NULL
	JUMPN	T0,CPOPJ	;RETURN IF EXTENSION GIVEN
	MOVEI	T1,"."		;ELSE APPEND EXTENSION
	DPB	T1,T3
	MOVEI	T0,4
	ROT	T4,7
	IDPB	T4,T3
	SOJG	T0,.-2
	POPJ	P,		;DONE
>
;************************************************************************
;INITIALIZING SUBROUTINES

;SUBROUTINE TO RESCAN USER'S RUN LINE TO SEE IF HE TYPED "R EDIT;FILESPECS"
;LOOKS FOR AN "E", SKIPS TO NEXT SPACE OR ";", ASSUMES THE REST IS SPECS
;MOVE SPACES TO PARM BUFFER AND SET FLAG SO THEY WILL BE PARSED

IFN TOPS10,<
RSCANL:	RESCAN			;GO TO START OF RUN LINE
	SETZM	RSCANF
RSCAN0:	INCHRS	T1		;IS THERE A CHARACTER WAITING?
	  JRST	RSCANR		;NO - DONE
	CAIN	T1,"E"		;BEGINNING OF EDITOR NAME?
	JRST	RSCAN1		;NO - KEEP LOOKING
	CAIE	T1,"e"		;BEGINNING OF EDITOR NAME?
	JRST	RSCAN0		;NO - KEEP LOOKING

RSCAN1:	INCHRS	T1		;YES - SKIP CHARACTERS
	  JRST	RSCANR		;UNTIL END OF LINE,
	CAIN	T1,"/"		;IF A SLASH IS FOUND
	JRST	RSCA1B		;  JUMP INTO THE GOOD STUFF
	CAIE	T1," "		;IF A SPACE
	CAIN	T1,";"		;  OR SEMICOLON IS FOUND
	JRST	RSCA1A		;  START THE GOOD STUFF
	JRST	RSCAN1		;ELSE KEEP SKIPPING

RSCA1A:	INCHRS	T1		;GET FIRST FILE CHARACTER
	  JRST	RSCAN3		;DONE IF NOTHING WAITING
	CAIN	T1," "		;SKIP ANY LEADING SPACES
	JRST	RSCA1A
RSCA1B:	MOVE	T0,[POINT 7,CLSBUF] ;POINT TO START OF CLOSE BUFFER
	MOVEM	T0,PARPTR
	CAIE	T1,12		;END OF LINE?
	CAIN	T1,15
	JRST	RSCAN3		;YES - SET UP NO FILE
	SETOM	RSCANF		;NO - SET ENTER-PARAMETER FLAG
	JRST	.+3		;GO SAVE THE FILE NAME

RSCAN2:	INCHRS	T1		;YES - SAVE FROM HERE ON AS A PARAMETER
	  JRST	RSCAN3		;DONE IF NOTHING LEFT
	CAIE	T1,12		;END OF LINE?
	CAIN	T1,15
	JRST	RSCAN3		;YES - CLEAN BUFFER OUT AND RETURN
	IDPB	T1,PARPTR	;ELSE SAVE THE CHARACTER
	JRST	RSCAN2		;AND GET ANOTHER ONE

RSCANR:	CLRBFI			;JUST CLEAR INPUT BUFFER AND RETURN
	POPJ	P,

RSCAN3:	CLRBFI
	SETZ	T0,		;END BUFFER WITH A NULL
	IDPB	T0,PARPTR
>
IFE TOPS10,<
RSCANL:	MOVE	T1,[POINT 7,CLSBUF]
	MOVEM	T1,PARPTR	;POINT TO START OF CLOSE BUFFER
	SETZB	T1,RSCANF	;SET TO RE-READ RUN LINE
IFE FTDDT,<
	RSCAN
>
	  POPJ	P,		;IF THERE'S A PROBLEM, FORGET IT
RSCNL1:	PBIN			;GET THE FIRST CHARACTER
	CAIE	T1," "		;SKIP LEADING SPACES
	CAIN	T1,11		;AND TABS
	JRST	RSCNL1
	CAIE	T1,"C"		;GOT THE "CREATE" COMMAND
	CAIN	T1,"c"
	TROA	F,CRE		;YES - FLAG AS SUCH
	CAIA			;NO - SKIP THE PBIN AND FLOW

RSCAN0:	PBIN			;GET A CHARACTER
	CAIN	T1,12		;END OF LINE?
	POPJ	P,		;YES - RETURN
	CAIN	T1,"E"		;BEGINNING OF EDITOR NAME?
	JRST	RSCAN1		;YES - SKIP TO A SPACE
	CAIE	T1,"e"		;BEGINNING?
	JRST	RSCAN0		;NO - KEEP LOOKING

RSCAN1:	PBIN			;GET A CHARACTER
	CAIN	T1,12		;END OF LINE?
	JRST	RSCN30		;YES - COPY SWITCHES, IF ANY; DONE
	CAIN	T1,"/"		;DOES THE LINE START WITH SWITCHES?
	JRST	RSCN1S		;YES - SAVE 'EM OFF
	CAIE	T1," "		;GOT A SPACE YET?
	JRST	RSCAN1		;NO - KEEP SKIPPING

RSCN1A:	PBIN			;GET A FILESPEC CHARACTER
	CAIN	T1,12		;END OF LINE?
	JRST	RSCN30		;YES - COPY SWITCHES, IF ANY; DONE
	CAIN	T1," "		;SKIP ANY LEADING SPACES
	JRST	RSCN1A
	CAIE	T1,15		;DON'T SET FLAG IF END OF THE LINE
	SETOM	RSCANF		;GOT LIVE CHAR - SAY FILESPECS HAVE BEEN FOUND
	CAIN	T1,"/"		;DOES THE LINE START WITH SWITCHES?
	JRST	RSCN1S		;YES - SAVE 'EM OFF
	JRST	RSCN2A		;AND GO SET UP THE SPECS

RSCAN2:	PBIN			;GET A FILESPEC CHARACTER
	CAIN	T1,12		;END OF LINE?
	JRST	RSCAN3		;YES - FINISH OFF
RSCN2A:	CAIN	T1," "		;GOT A SPACE?
	JRST	RSCN2O		;YES - GOT SWITCHES OR START OF OUTPUT FILE
	CAIE	T1,15		;IGNORE CARRIAGE RETURNS
	IDPB	T1,PARPTR	;ELSE SAVE THE CHARACTER
	JRST	RSCAN2		;NO - GET ANOTHER CHARACTER

;HERE IF FOUND A SPACE WHILE SAVING THE FILESPECS. MAY HAVE AN OUTPUT FILE.
;IGNORE NOISE IN PARENS, IF ANY

RSCN2O:	PBIN
	CAIN	T1,12		;END OF LINE?
	JRST	RSCAN3		;YES - GO FINISH OFF
	CAIE	T1," "		;SKIP LEADING SPACES,
	CAIN	T1,15		;  AND A CARRIAGE RETURN
	JRST	RSCN2O
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	RSCN2A		;YES - GO BACK UP TO FILESPEC LOOP
	CAIN	T1,"!"		;START OF NOISE?
	JRST	RSCN2X		;YES - GO SKIP THE NOISE
	CAIN	T1,"("		;START OF NOISE?
	JRST	RSCN2N		;YES - GO SKIP THE NOISE
	MOVE	T4,[ASCII ?/OUT:?]
	LSHC	T3,7		;NO - SET UP AN /OUTPUT: SWITCH
	IDPB	T3,PARPTR
	JUMPN	T4,.-2
	JRST	RSCN2A		;OUTPUT THE OUTPUT FILESPEC

;HERE TO SKIP NOISE, IF "(" IS FOUND

RSCN2N:	PBIN			;GET A NOISE CHARACTER
	CAIN	T1,")"		;END OF THE NOISE?
	JRST	RSCN2O		;YES - PROCEED WITH THE GOOD STUFF
	CAIN	T1,12		;END OF LINE?
	JRST	RSCAN3		;YES - GO FINISH OFF
	JRST	RSCN2N		;NO - SKIP THE CHARACTER

;HERE TO SKIP NOISE, IF "!" IS FOUND

RSCN2X:	PBIN			;GET A NOISE CHARACTER
	CAIN	T1,"!"		;END OF THE NOISE?
	JRST	RSCN2O		;YES - PROCEED WITH THE GOOD STUFF
	CAIN	T1,12		;END OF LINE?
	JRST	RSCAN3		;YES - GO FINISH OFF
	JRST	RSCN2X		;NO - SKIP THE CHARACTER

;HERE WHEN DONE - COPY ANY SWITCHES TO AFTER THE FILESPEC

RSCN30:	TRNN	F,FLG		;WERE ANY SWITCHES SEEN?
	POPJ	P,		;NO - DONE
RSCAN3:	TRZE	F,FLG		;GOT SOME SWITCHES THAT NEED COPYING?
	PUSHJ	P,RSCNSW	;YES - COPY THEM
	SETZ	T0,		;END BUFFER WITH A NULL
	IDPB	T0,PARPTR
>
	TLZ	F,SMF		;CLEAR SAME-FILE FLAG (FROM REDTMP)
	MOVE	PT,[POINT 7,CLSBUF] ;NOW LOOK OVER SPECS AGAIN
RSCAN4:	ILDB	T1,PT		;SEE IF THERE ARE ANY SWITCHES
	JUMPE	T1,CPOPJ	;IF END OF BUFFER, DONE
	CAIE	T1,"/"		;ELSE GOT START OF SWITCHES?
	JRST	RSCAN4		;NO - KEEP LOOKING
	DPB	T0,PT		;YES - NULL OUT THE FIRST SLASH
	CAMN	PT,[350700,,CLSBUF] ;SWITCHES ONLY; NO FILESPECS?
	SETZM	RSCANF		;YES - PRETEND USER DIDN'T TYPE ANYTHING
	JRST	SWHMNY		;GO HANDLE THE SWITCHES AND RETURN

IFE TOPS10,<
RSCN1S:	MOVE	T4,[POINT 7,PARBUF] ;STORE SWITCHES IN PARBUF FOR NOW
	TROA	F,FLG		;AND NOTE THAT THEY'RE THERE
RSCNS2:	PBIN			;GET A SWITCH CHARACTER
	CAIE	T1," "		;SPACE,
	CAIN	T1,15		;  OR CARRIAGE RETURN?
	JRST	RSCNS3		;YES - END OF SWITCHES
	CAIN	T1,12		;LINEFEED?
	JRST	RSCNS3		;YES - END OF SWITCHES
	IDPB	T1,T4		;SAVE IT IN THE STAGING AREA
	JRST	RSCNS2		;AND GET MORE

RSCNS3:	SETZ	T0,		;END SWITCHES WITH A NULL
	IDPB	T0,T4
	CAIN	T1,12		;END WITH A LINEFEED?
	JRST	RSCAN3		;YES - END OF THE LINE
	JRST	RSCN1A		;PROCESS THE REST OF THE COMMAND LINE

;SUBROUTINE TO COPY SWITCHES FROM PARBUF TO COMMAND STRING IN CLSBUF

RSCNSW:	MOVE	T4,[POINT 7,PARBUF]
	ILDB	T1,T4		;MOVE THE SWITCHES
	IDPB	T1,PARPTR	;FROM PARBUF TO CLSBUF
	JUMPN	T1,.-2		;UNTIL A NULL IS FOUND,
	POPJ	P,		;THEN RETURN
>
;HERE ON ENTRY TO TRANSFER RESCANNED SPECS TO PARM BUFFER

SETSCN:	MOVE	T1,[POINT 7,PARBUF]
	MOVE	T2,[POINT 7,CLSBUF]
	ILDB	T0,T2		;GET A CHARACTER FROM THE CLOSE BUFFER
	IDPB	T0,T1		;SAVE IT IN THE PARAMETER BUFFER
	JUMPN	T0,.-2		;LOOP UNTIL A NULL IS FOUND
	MOVEM	T1,PARPTR	;SAVE PARAMETER POINTER
	MOVEI	DO,$SETFI	;PRETEND A SET-FILE COMMAND WAS TYPED
IFN TOPS10,<
IFN FTSFD,<
	MOVE	T1,[FILSPC,,OLDSPC] ;COPY CURRENT SPECS INTO OLD SPECS
	BLT	T1,OLDSPC+SPCSIZ-1
	MOVEI	T1,SFDLVL	;SET UP DEFAULT PATH AS CURRENT ONE
SETSFD:	MOVE	T2,DEFPTH+2(T1)
	MOVEM	T2,FILPTH+2(T1)
	SOJGE	T1,SETSFD
	JRST	SETFLC		;GO DO THAT SET-FILE
>
IFE FTSFD,<
	JRST	SETFLS		;SET TO THE FILE; PRESERVE READ-ONLY FLAG
>>
IFE TOPS10,<
	JRST	SETFLS
>
;HERE TO READ nnnSED.TMP, IF ANY, AND SET UP THE FILE STATUS THERE
;IF NONE, SETS UP FOR THE DEFAULT "WELCOME TO SED" MESSAGE

REDTMP:	HRROI	T2,SEDFIL
IFN TOPS10,<
IFN FTTMPC,<
	MOVE	T1,[1,,TMPBLK]	;TRY TO READ STATS FROM TMPCOR
	TMPCOR	T1,
	  JRST	.+2		;FAILED - GET THEM OFF DISK
	JRST	REDT0A		;O.K. - GO PROCESS THEM
>
	MOVE	T0,SEDFIL+3	;GET THE PPN
>
	PUSHJ	P,SETIN		;GO FIND THE TEMPORARY FILE
	JUMPE	T1,CPOPJ	;IF NONE, JUST RETURN
REDTM0:
IFN TOPS10,<
	MOVEM	T0,SEDFIL+3	;PUT THE RIGHT PPN BACK AGAIN
	MOVEI	T1,-400
	HRLM	T1,SEDCCL	;SET UP SIZE OF FILE
	INPUT	5,SEDCCL	;READ STATUS INTO PICK BUFFER
	RELEAS	5,
REDT0A:
>
IFE TOPS10,<
	MOVE	T2,[POINT 7,PIKBUF+PCBSIZ-400]
	SETZ	T3,		;READ THE FILE INTO THE PICK BUFFER
	SIN
	CLOSF			;CLOSE THE FILE
	  HALTF
>
	SETZB	T2,INDFLG
	MOVE	PT,[POINT 7,PIKBUF+PCBSIZ-400]
	MOVE	T4,[POINT 7,FILSPC]
	MOVEM	T4,MFLPT1	;SAVE POINTER TO 1ST SPEC
	PUSHJ	P,TMPGET	;READ ACTIVE SPECS INTO ACTIVE AREA
	JUMPE	T1,REDTM1	;IS THERE ANOTHER LINE (WITH ALTERNATE SPECS)?
	MOVE	PT,MFLPTR	;YES - GET SPEC POINTER BACK
	MOVEM	PT,MFLPT0	;SAVE IT AS PTR TO 2ND SPEC
	MOVE	T4,[POINT 7,OLDSPC]
	PUSHJ	P,TMPGET	;READ ALTERNATE SPECS INTO OLD AREA

REDTM1:	CAIGE	T1,"0"		;IS THERE AN ALPHANUMERIC ON THE NEXT LINE?
	SETZM	MFLPTR		;NO - FORGET THE POINTER
	SETZM	DISPTR		;CLEAR POINTERS
	SETZM	SAVEDP		;  TO NOTE THAT PARSING MUST BE DONE
	TLO	F,XPL!XPC!XPB	;SAY NO POINTERS ARE VALID
IFE TOPS10,<
	MOVE	T4,[POINT 7,OLDSPC]
	MOVE	PT,[POINT 7,SAVEXP+1]
	PUSHJ	P,UNPEXT	;SET UP THE ALTERNATE FILE'S EXTENSION
	PUSHJ	P,UNPEX0	;AND THAT OF THE CURRENT FILE; FALL INTO
>
;SUBROUTINE TO SEE IF FILE AND ALTERNATE ARE THE SAME
;SETS FLAG SMF IF FILES ARE THE SAME, ELSE CLEARS SMF

SAMFIL:	TLZ	F,SMF		;ASSUME FILES AREN'T THE SAME
IFE TOPS10,<
	SKIPN	SAVEAC+12	;IF USER GAVE VN # FILES CAN'T BE THE SAME
>
	SKIPE	OUTFLG		;CHANGING THE NAME OF THE NEW FILE?
	POPJ	P,		;YES - FILES AREN'T THE SAME
	MOVE	T3,[POINT 7,FILSPC]
	MOVE	T4,[POINT 7,OLDSPC]
SAMFL1:	ILDB	T1,T3		;SEE IF BOTH FILE SPECS ARE THE SAME
	ILDB	T2,T4
	CAIN	T1,"/"		;TREAT START OF SWITCHES
	SETZ	T1,		;  LIKE END OF SPECS
	CAIN	T2,"/"
	SETZ	T2,
	CAME	T1,T2		;ARE SPECS THE SAME SO FAR?
	POPJ	P,		;NO - DONE
	JUMPN	T1,SAMFL1	;ELSE LOOP THROUGH ENTIRE STRING
	TLO	F,SMF		;FILES ARE THE SAME IF CONTROL GETS HERE
	POPJ	P,		;DONE

;SUBROUTINE TO READ A FILESPEC FROM (PT) AND SAVE IN (T4). EXPECTS T2/0
;RETURNS FIRST CHARACTER OF NEXT LINE IN T1

TMPGET:	TDZ	T0,T0		;CLEAR "GOT /FD" FLAG
	ILDB	T1,PT		;GET FIRST CHARACTER
	CAIE	T1,11		;TAB OR
	CAIN	T1," "		;  SPACE?
	JRST	TMPGET+1	;YES - IGNORE IT
	CAIE	T1,";"		;IS THE ENTIRE LINE A COMMENT?
	CAIN	T1,"!"
	JRST	TMPGTI		;YES - IGNORE THE WHOLE LINE
	CAIE	T1,15		;BLANK LINE?
	JRST	TMPGT0		;NO - CONTINUE
	ILDB	T1,PT		;YES - SKIP THE LINEFEED, TOO
	JRST	TMPGET+1	;AND CHECK NEXT LINE

TMPGT2:	ILDB	T1,PT		;READ SPECS INTO ACTIVE OR ALTERNATE AREA
	JUMPE	T1,TMPGT3	;IF NULL, GO FINISH OFF
	CAIN	T1,15		;GOT A CARRIAGE RETURN?
	JRST	TMPGT3		;YES - FINISH OFF
TMPGT0:	CAIN	T1,"/"		;GOT THE /FD SWITCH, MAYBE?
	PUSHJ	P,TMPGTS	;MAYBE - CHECK IT OUT
	CAIE	T1,"!"		;GOT END OF SPECS?
	CAIN	T1,";"
	JRST	TMPGTT		;YES - SAY LINE ENDS HERE
	CAIN	T1,11		;GOT A TAB?
	JRST	TMPGTT		;YES - SAY LINE ENDS HERE
	IDPB	T1,T4		;NO - SAVE CHARACTER
	JRST	TMPGT2		;AND GET ANOTHER

TMPGTT:	ILDB	T1,PT		;FOUND TAB - SKIP UNTIL CR
	CAIE	T1,15
	JUMPN	T1,TMPGTT	;(A NULL CAN END IT, TOO)
TMPGT3:	JUMPN	T0,TMPGTE	;IF GOT /FD, O.K.
	EXCH	T4,TY		;ELSE SET IT UP NOW
	MOVE	T1,[ASCII ?/FD:0?]
	PUSHJ	P,PUTSQ1
	EXCH	T4,TY

TMPGTE:	IDPB	T2,T4		;PUT NULL AT END OF STRING
	ILDB	T1,PT		;SKIP OVER THE LINEFEED
	MOVEM	PT,MFLPTR	;SAVE POINTER TO (MAYBE) NEW SPECS
TMGEE1:	ILDB	T1,PT		;PICK UP FIRST CHARACTER OF NEXT LINE
	CAIE	T1,11		;TAB OR
	CAIN	T1," "		;  SPACE?
	JRST	TMGEE1		;YES - IGNORE IT
	POPJ	P,		;GIVE IT BACK TO CALLER

TMPGTS:	IDPB	T1,T4		;SAVE THE SLASH
	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIE	T1,"F"		;FILE SWITCH?
	POPJ	P,		;NO - CONTINUE
	IDPB	T1,T4		;YES - SAVE IT
	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIN	T1,"D"		;STILL FILE SWITCH?
	AOJ	T0,		;YES - SET FLAG
	POPJ	P,		;RETURN EITHER WAY

TMPGTI:	ILDB	T1,PT		;SKIP UNTIL A LINEFEED
	CAIE	T1,12
	JRST	TMPGTI
	JRST	TMPGET+1	;THEN READ THE NEXT LINE

;SUBROUTINE TO MOVE PRE-SET FILE STATUS INFORMATION INTO THE ACTIVE PLACES
;PNTSTT CAN BE CALLED TO SET UP POINTERS TO START OF FILE (PERCEN, NEWFIL)

PRESET:	HRRZ	T2,PREDP	;GET ADDRESS OF DISPLAY POINTER
	CAIL	T2,(EN)		;DOES IT POINT BEYOND END OF FILE?
	JRST	PNTSTT		;YES - POINT TO START OF FILE
	TLO	F,XPL!XPC!XPB	;NO - NO POINTERS ARE GOOD
	HRRZ	RW,PRERW	;GET PRE-SET ROW
	HLRZ	CM,PRERW	;AND COLUMN
	MOVE	SL,PRESL	;AND SLIDE
	SETZ	T2,		;GET AND ZERO DISPLAY POINTER
	EXCH	T2,PREDP
	MOVEM	T2,DISPTR
	POPJ	P,

PNTSTT:	MOVE	T2,[010700,,BUFFER-1]
	MOVEM	T2,DISPTR	;POINT TO START OF FILE
	MOVEM	T2,LINPTR
	MOVEM	T2,CHRPTR
	SETZB	RW,CM
	SETZ	SL,
	TLZ	F,XPC!XPL	;LINE AND CHARACTER POINTERS ARE O.K.
	TLO	F,XPB		;BUT BOTTOM POINTER IS BAD
	POPJ	P,

;****************************************************************
;SUBROUTINE TO READ THE INIT FILE AND SET UP THE SWITCHES THEREIN
;LOOKS FOR THE FOLLOWING: SED.INI (SED.INIT ON TOPS20) IN PATHED DIRECTORY;
;DITTO, LOGIN DIRECTORY; SWITCH.INI IN PATHED; DITTO LOGIN
;(SED.INIT DOESN'T NEED TO HAVE "SED/" AT THE START OF EVERY LINE)

REDSWH:	SETOM	INIFLG		;ASSUME SED.INIT WILL BE FOUND
	HRROI	T2,INIFIL	;FIND SED.INIT ON CONNECTED DIRECTORY
	PUSHJ	P,SETIN		;  OR LOGIN DIRECTORY
	JUMPN	T1,REDSW0	;IF O.K. GO READ IT IN
	HRROI	T2,SWHFIL	;ELSE LOOK FOR SWITCH.INI
	PUSHJ	P,SETIN
	JUMPE	T1,CPOPJ	;NOT FOUND - JUST RETURN
	SETZM	INIFLG		;FLAG THE FILE AS SWITCH.INI
IFN TOPS10,<
REDSW0:	HRRI	T1,PIKBUF-1
	MOVEM	T1,PIKCCL
	INPUT	5,PIKCCL	;O.K. - READ IT INTO PICK BUFFER
	RELEAS	5,
	MOVEI	T1,-PCBSIZ	;SET PROPER PICK SIZE BACK UP
	HRLM	T1,PIKCCL
>
IFE TOPS10,<
REDSW0:	MOVE	T2,[POINT 7,PIKBUF]
	SETZ	T3,
	SIN			;READ THE FILE INTO THE PICK BUFFER
	CLOSF			;CLOSE THE FILE
	  HALTF
>
	MOVE	PT,[POINT 7,PIKBUF]
REDSW1:	PUSHJ	P,REDCHR	;GET 1ST CHARACTER OF A LINE
	JUMPE	T1,REDSWE	;IF NULL CLEAR OUT PICK BUFFER AND RETURN
	SKIPE	INIFLG		;READING SED.INIT?
	JRST	REDSW2+1	;YES - MAYBE THERE'S NO "SED"
	CAIN	T1," "		;IGNORE SPACES
	JRST	REDSW1
	CAIE	T1,"S"		;START OF "SED"?
	JRST	REDSWS		;NO - SKIP THE LINE
	PUSHJ	P,REDCHR	;YES - GET THE "E"
	CAIE	T1,"E"		;IS IT?
	JRST	REDSWS		;NO - SKIP THE LINE
	PUSHJ	P,REDCHR	;YES - GET THE "D"
	CAIE	T1,"D"		;IS IT?
	JRST	REDSWS		;NO - SKIP THE LINE

REDSW2:	ILDB	T1,PT		;YES - LOOK FOR THE "/"
	JUMPE	T1,REDSWE	;IF NULL CLEAR OUT PICK BUFFER AND RETURN
	CAIN	T1,12		;AT END OF LINE?
	JRST	REDSW1		;YES - TRY OUT THE NEXT LINE
	CAIE	T1,"/"		;GOT A SLASH?
	JRST	REDSW2		;NO - KEEP LOOKING
	PUSHJ	P,SWHMNY	;YES - HANDLE ALL THE SWITCHES
	JRST	REDSW1		;SEE IS THERE'S ANOTHER LINE

REDSWS:	ILDB	T1,PT		;SKIP REST OF LINE - GET CHARACTER
	JUMPE	T1,REDSWE	;IF AT END OF FILE, FINISH OFF
	CAIE	T1,12		;GOT A LINEFEED?
	JRST	REDSWS		;NO - LOOP
	JRST	REDSW1		;YES - CHECK NEXT LINE

REDSWE:	MOVEI	T1,XBFNUM-1	;MAKE SURE NULL EXECUTE BUFFER'S STILL ACTIVE
	MOVEM	T1,XCTACW
	SETZM	PIKBUF		;END OF FILE - CLEAR OUT PICK BUFFER
	MOVE	T1,[PIKBUF,,PIKBUF+1]
	BLT	T1,PIKBUF+PCBSIZ-1
	POPJ	P,		;AND RETURN FROM SWITCH.INI PROCESSING

REDCHR:	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	POPJ	P,		;RETURN

;****************************************************************
;TERMINAL DEPENDENT OUTPUT SECTION
;STORE VARIOUS CHARACTER SEQUENCES IN THE TYPE BUFFER

CBOTOM:	PUSHJ	P,CMVBTM	;MOVE TO BOTTOM LINE
				;AND FALL INTO CLEAR-IT CODE
CLRLNA:	TDOA	T0,[-1]		;SET TO CLEAR ENTIRE LINE
CLRLNR:	MOVE	T0,CM		;SET TO CLEAR TO END OF LINE
	SKIPE	T1,CLN(TM)	;CAN TERMINAL CLEAR TO END OF LINE?
	JRST	PUTSEQ		;YES - GO DO IT
	PUSH	P,T2		;NO - DO IT IN SOFTWARE
	PUSH	P,T0		;SAVE SOME ACS
	JUMPGE	T0,.+2		;IS T0/-1?
	SETZ	T0,		;YES - MAKE IT ZERO
	SUB	T0,CPL(TM)	;FIND NUMBER OF SPACES TO OUTPUT
	MOVNS	T0
	MOVEI	T1," "		;GET A SPACE
	MOVEI	T2,TYPBUF+TYPSIZ+1 ;SET UP END-OF-TYPE-BUFFER ADDRESS
	PUSHJ	P,CLRLN1	;SPACE OVER
	EXCH	CM,(P)
	JUMPL	CM,[MOVEI T1,15	;IF WANT A CR, GET ONE
		    IDPB  T1,TY	;OUTPUT IT AND OUTPUT THE BUFFER
		    PUSHJ P,PUTTYP
		    JRST  .+2]	;SKIP THE REPOSITION AND CONTINUE
	PUSHJ	P,POSCUR	;RE-POSITION CURSOR
	POP	P,CM		;GET REAL COLUMN BACK
	POP	P,T2		;RESTORE T2, TOO
	POPJ	P,

CLRLN1:	SUBI	T0,2
	IDPB	T1,TY		;SPACE OVER
	CAMG	T2,(TY)		;IS TYPE BUFFER FULL?
	JRST	[PUSHJ P,PUTTYP	;YES - OUTPUT IT
		 MOVEI T1," "	;GET THE SPACE AGAIN
		 JRST  .+1]	;CONTINUE
	SOJG	T0,CLRLN1+1	;DO ALL THE SPACES
	POPJ	P,		;DONE

CHOME:	SKIPN	HOMPOS		;IS HOME REALLY HOME?
	SKIPA	T1,CHM(TM)	;YES - GET SEQUENCE FOR CURSOR HOME
	TDZA	T4,T4		;NO - POSITION TO THE FAKE HOME
	JRST	PUTSEQ
	JRST	POSLIN

CLRALL:	TLNN	TM,WDW		;IN A WINDOW?
	SKIPA	T1,HCP(TM)	;NO - GO HOME AND CLEAR PAGE
	TDZA	T4,T4		;YES - POSITION TO THE FAKE HOME
	JRST	PUTSEQ
	PUSHJ	P,POSLIN	;POSITION HOME
	SKIPE	HOMPOS		;IN LOWER WINDOW?
	JRST	[SKIPE T1,CPG(TM) ;YES - CAN TERMINAL CLEAR TO EOP?
		 JRST  PUTSEQ	  ;YES - DO IT
		 JRST  .+3]	  ;NO - CONTINUE
	MOVE	T4,LPP(TM)	;IN UPPER WINDOW - CLEAR ONE LINE FEWER
	SOJA	T4,.+3
	SKIPA	T4,LPP(TM)	;OUTPUT A BUNCH OF CLEAR-LINES
	PUSHJ	P,CDOWN
	PUSHJ	P,CLRLNA
	SOJG	T4,.-2
	JRST	CHOME		;GO HOME, OUTPUT, AND RETURN

CLEARP:	MOVE	T1,CPG(TM)	;CLEAR TO END OF PAGE
	JRST	PUTSEQ
IFN FTIMD,<
IMODON:	SKIPA	T1,IMO(TM)	;TURN INSERT MODE ON
IMODOF:	MOVE	T1,IMF(TM)	;TURN INSERT MODE OFF
	JRST	PUTSEQ

IMDOFN:	MOVE	T1,IMF(TM)	;TURN INSERT MODE OFF NOW
	PUSHJ	P,PUTSEQ
	JRST	PUTTYP
>
PROTON:	SKIPN	T1,PON(TM)	;CAN PROTECTION BE TURNED ON?
	POPJ	P,		;NO - NOTHING TO DO
	JRST	PUTSEQ		;YES - DO IT
PROTOF:	SKIPN	T1,POF(TM)	;CAN PROTECTION BE TURNED OFF?
	POPJ	P,		;NO - NOTHING TO DO
	JRST	PUTSEQ		;YES - DO IT
CMVBTM:	MOVE	T1,MVB(TM)	;CURSOR TO BOTTOM
	JRST	PUTSEQ
CRIGHT:	SKIPA	T1,CRG(TM)	;CURSOR RIGHT
CLEFT:	MOVE	T1,CLF(TM)	;CURSOR LEFT
	JRST	PUTSEQ
CURUP:	SKIPA	T1,CUP(TM)	;CURSOR UP
CDOWN:	MOVE	T1,CDN(TM)	;CURSOR DOWN
	JRST	PUTSEQ
ROLLUP:	SKIPA	T1,RUP(TM)	;ROLL UP AND CLEAR LINE
ROLLDN:	MOVE	T1,RLD(TM)	;ROLL DOWN AND CLEAR LINE

;SUBROUTINE TO OUTPUT UP TO 5 CHARACTERS IN T1 (PUTSQ1)

PUTSEQ:	TLNN	T1,777777	;GOT A ROUTINE ADDRESS?
	JRST	@T1		;YES - DISPATCH TO THAT ROUTINE
	TLNN	T1,774000	;GOT THE ADDRESS OF A LONG ASCII STRING?
	JRST	PUTSTG		;YES - GO OUTPUT THE STRING
PUTSQ1:
IFE TOPS10,<
IFN FTECHO,<
	SETZ	T0,
>>
	LSHC	T0,7		;SHIFT IN A CHARACTER
	IDPB	T0,TY		;SAVE IT IN TYPE BUFFER
	JUMPN	T1,PUTSQ1	;LOOP THROUGH ALL CHARACTERS
	POPJ	P,		;THEN DONE

;SUBROUTINE TO MOVE TO BOTTOM, CLEAR, PROTECT, AND OUTPUT (T1)

PUTBTM:	MOVEM	T1,SAVEAC+12	;SAVE MESSAGE ADDRESS
	PUSHJ	P,CBOTOM	;PUT MESSAGE ON BOTTOM LINE
	PUSHJ	P,PROTON	;PROTECT
	MOVE	T1,SAVEAC+12	;GET ADDRESS BACK AND FALL INTO PUTSTG

;SUBROUTINE TO OUTPUT A STRING. ADDRESS IN T1 (FRAGGED)

PUTSTG:	HRLI	T1,440700	;MAKE ADDRESS A BYTE POINTER
PUTSG1:	ILDB	T0,T1		;GET A CHARACTER
	JUMPE	T0,CPOPJ	;DONE IF NULL
	IDPB	T0,TY		;ELSE SAVE IN TYPE BUFFER
	JRST	PUTSG1		;AND LOOP

;SUBROUTINE TO OUTPUT A STRING. ADDRESS IN T1 (FRAGGED). USES T0, T2
;SAME AS PUTSTG, BUT CONTROL CHARACTERS ARE SIMULATED BY BEING PROTECTED
;IF STRING BEING OUTPUT IS ALREADY PROTECTED ENTER PUTSTC; ELSE PUTSTS

PUTSTS:	TDZA	T2,T2		;CLEAR FLAG TO GET SIMULATION
PUTSTC:	SETO	T2,		;SET FLAG SO NO SIMULATION
	HRLI	T1,440700	;MAKE ADDRESS A BYTE POINTER
PUTSC1:	ILDB	T0,T1		;GET A CHARACTER
	CAIN	T0,177		;GOT A DELIMITER?
	JRST	PUTSCD		;YES - SIMULATE IT
	CAIGE	T0,40		;GOT A CONTROL CHARACTER?
	JRST	PUTSC2		;YES - SIMULATE IT
	IDPB	T0,TY		;SAVE CHARACTER IN TYPE BUFFER
	JRST	PUTSC1		;AND LOOP

PUTSCD:	MOVEI	T0,">"-100	;MAKE 177 COME OUT AS PROTECTED ">"
PUTSC2:	JUMPE	T0,CPOPJ	;DONE, IF NULL
	PUSH	P,T1		;ELSE SAVE CHARACTER
	PUSH	P,T0
	JUMPN	T2,.+2		;WANT TO PROTECT?
	PUSHJ	P,PROTON	;YES - DO SO
	POP	P,T0
	ADDI	T0,100		;OUTPUT PRINTING CHARACTER
	IDPB	T0,TY
	JUMPN	T2,.+2		;WANT TO PROTECT
	PUSHJ	P,PROTOF	;YES - DO SO
	POP	P,T1
	JRST	PUTSC1		;CONTINUE

;SUBROUTINE TO OUTPUT AN ERROR MESSAGE (ADDRESS IN T1, FRAGGED)
;SAME AS PUTSTG, BUT #'S ARE CONVERTED TO SPACES

PUTSTX:	HRLI	T1,440700	;MAKE ADDRESS A BYTE POINTER
	ILDB	T0,T1		;GET A CHARACTER
	JUMPE	T0,CPOPJ	;DONE IF NULL
	CAIN	T0,"#"		;ELSE GOT AN ARTIFICIAL SPACE?
	MOVEI	T0," "		;YES - MAKE IT A REAL ONE
	IDPB	T0,TY		;SAVE IN TYPE BUFFER
	JRST	PUTSTX+1	;AND LOOP

;SUBROUTINE TO OUTPUT FILESPECS (FOR THE SWITCH COMMAND)
;SAME AS PUTSTG, BUT OUTPUTS ONLY UNTIL FIRST "/"

PUTSTF:	HRLI	T1,440700	;MAKE ADDRESS A BYTE POINTER
	ILDB	T0,T1		;GET A CHARACTER
	JUMPE	T0,CPOPJ	;DONE IF NULL
	CAIN	T0,"/"		;ELSE GOT START OF SWITCHES?
	POPJ	P,		;YES - DONE
	IDPB	T0,TY		;SAVE IN TYPE BUFFER
	JRST	PUTSTF+1	;AND LOOP

;SUBROUTINE TO OUTPUT THE TYPE BUFFER

IFN FTNIHO,<
PUTTYH:	PUSH	P,T0
	PUSH	P,T2
	JRST	PUTTY0

PUTONE:	IDPB	T1,TY
>
PUTTYP:	TRNE	F,XCT		;EXECUTING?
	JRST	PUTTY2		;YES - THROW BUFFER AWAY
	CAMN	TY,TYPPTR
	POPJ	P,		;DO NOTHING IF NOTHING TO OUTPUT
PUTTYF:	SETZ	T1,		;ELSE OUTPUT TYPE BUFFER:
	IDPB	T1,TY		;  END IT WITH A NULL
IFN FTNIHO,<
        PUSH    P,T0
        PUSH    P,T2
	MOVE	T0,[POINT 7,TYPBUF]
PUTTY0:	ILDB	T1,T0
	JUMPE	T1,PUTTY1
	MOVE	T2,T1
	ANDI	T2,3
	ASH	T1,-2
	LDB	T1,PARPTX(T2)
	IONEOU	T1		;GAWDAWFUL, AIN'T IT?
	JRST	PUTTY0
>
IFN TOPS10,<
	OUTSTR	TYPBUF		;OUTPUT THE BUFFER
>
IFE TOPS10,<
IFN FTECHO,<
	PUSH	P,T2
	PUSH	P,T3
	MOVE	T1,TTYJFN
	MOVE	T2,TYPPTR
	SETZ	T3,
	SOUT
	POP	P,T3
	POP	P,T2
>
IFE FTECHO,<
	HRROI	T1,TYPBUF
	PSOUT			;OUTPUT THE BUFFER
>>
PUTTY1:
IFN FTNIHO,<
	POP     P,T2
        POP     P,T0
>
PUTTY2:	MOVE	TY,TYPPTR
	POPJ	P,		;RESTORE TYPE POINTER AND RETURN

;TABLE OF CHARACTERS WITH PARITY ATTACHED. PICKS UP PARTBL[T2,T1]

IFN FTNIHO,<
PARPTX:	POINT	9,PARTBL(T1),8
	POINT	9,PARTBL(T1),17
	POINT	9,PARTBL(T1),26
	POINT	9,PARTBL(T1),35

PARTBL:	BYTE (9) 000,201,202,003
	BYTE (9) 204,005,006,207
	BYTE (9) 210,011,012,213
	BYTE (9) 014,215,216,017
	BYTE (9) 220,021,022,223
	BYTE (9) 024,225,226,027
	BYTE (9) 030,231,232,033
	BYTE (9) 234,035,036,237
	BYTE (9) 240,041,042,243
	BYTE (9) 044,245,246,047
	BYTE (9) 050,251,252,053
	BYTE (9) 254,055,056,257
	BYTE (9) 060,261,262,063
	BYTE (9) 264,065,066,267
	BYTE (9) 270,071,072,273
	BYTE (9) 074,275,276,077
	BYTE (9) 300,101,102,303
	BYTE (9) 104,305,306,107
	BYTE (9) 110,311,312,113
	BYTE (9) 314,115,116,317
	BYTE (9) 120,321,322,123
	BYTE (9) 324,125,126,327
	BYTE (9) 330,131,132,333
	BYTE (9) 134,335,336,137
	BYTE (9) 140,341,342,143
	BYTE (9) 344,145,146,347
	BYTE (9) 350,151,152,353
	BYTE (9) 154,355,356,157
	BYTE (9) 360,161,162,363
	BYTE (9) 164,365,366,167
	BYTE (9) 170,371,372,173
	BYTE (9) 374,175,176,377
>
;SUBROUTINE TO OUTPUT A DECIMAL NUMBER
;ENTER WITH NUMBER IN T1; USES T0, T1

PUTNPO:	AOJ	T1,		;OUTPUT (T1) + 1
PUTNUM:	MOVE	T0,T1		;SET TO USE T0 AND T1
	IDIVI	T0,^D10		;GET A DIGIT IN T2
	HRLM	T1,(P)		;SAVE IT ON THE STACK
	JUMPE	T0,.+2		;IF ZERO, START POPPING
	PUSHJ	P,PUTNUM+1	;ELSE CALL RECURSIVELY
	HLRZ	T1,(P)		;GET A DIGIT OFF THE STACK
	ADDI	T1,"0"		;CONVERT TO ASCII
	IDPB	T1,TY		;PUT IT IN THE TYPE BUFFER
	POPJ	P,		;RETURN RECURSIVELY AND FINALLY

;************************************************************************
IFE TOPS10,<
IFN FTECHO,<

;SUBROUTINES TO PLAY GAMES WITH THE TERMINAL:
;BRKALL - BREAK ON ALL CHARACTERS
;BRKNPT - BREAK ON NON-PRINTING CHARACTERS
;EKOALL - NO ECHO AND BREAK ON ALL CHARACTERS
;EKONPT - ECHO PRINTING, AND BREAK ON NON-PRINTING, CHARACTERS
;ALL ROUTINES USE T1, T2, T3

EKOALL:	SKIPN	EKOFLG		;ALREADY ECHOING ALL?
	POPJ	P,		;YES - NOTHING TO DO
	SETZM	EKOFLG		;NO - SAY ECHOING ALL NOW
	MOVEI	T1,.PRIIN
	MOVE	T2,SMDSAV	;GET SED'S MODE WORD
	TRZ	T2,4000		;MAKE NOTHING ECHO
	SFMOD			;SET IT AND FALL TO SET THE BREAK SET

BRKALL:	SKIPN	BRKFLG		;ALREADY BREAK ON EVERYTHING?
	POPJ	P,		;YES - NOTHING TO DO
	SETZM	BRKFLG		;NO - SAY BREAK ON EVERYTHING NOW
	MOVEI	T3,[EXP 4,-1,-1,-1,-1] ;BREAK ON EVERYTHING
BRKSET:	MOVEI	T1,.PRIOU
	MOVEI	T2,.MOSBM
	MTOPR
	POPJ	P,

EKONPT:	TRNN	F,IMD		;IN INSERT MODE,
	SKIPGE	EKOFLG		;  OR ALREADY ECHOING NON-PRINTING?
	POPJ	P,		;EITHER - NOTHING TO DO
	SETOM	EKOFLG		;NOT BOTH - SAY ECHOING NPT NOW
	MOVEI	T1,.PRIIN
	MOVE	T2,SMDSAV	;RESTORE SED'S MODE WORD - TURN ECHO ON
	SFMOD			;FALL TO SET UP THE BREAK SET AND RETURN

BRKNPT:	TRNN	F,IMD		;IN INSERT MODE?
	SKIPGE	BRKFLG		;  OR ALREADY BREAK ON NON-PRINTING?
	POPJ	P,		;EITHER - NOTHING TO DO
	SETOM	BRKFLG		;NOT BOTH - SAY BREAK ON NPT NOW
	MOVEI	T3,[EXP 4,-1,0,0,20] ;NO - BREAK ONLY ON CONTROL CHARACTERS
	JRST	BRKSET		;GO SET THE BREAK MASK
>>
;************************************************************************
IFN FTJOUR,<

;SUBROUTINES TO MANIPULATE THE JOURNAL FILE
;(CONTROLLED BY THE /JOURN AND /RECOV SWITCHES

;SUBROUTINE TO START UP THE JOURNAL FILE (SEDJRN.TMP)
;T1 T2 PRESERVED; FRAGS T3

JRNSTT:	MOVEM	TY,JRNPTR	;SAVE TYPE-OUT POINTER; POINT TO JRN BUFFER
	MOVE	TY,[POINT 7,JOURNL]
	MOVEI	T1,FILSPC	;GET CURRENT FILE SPECS
	MOVE	T4,DISPTR	;AND DISPLAY POINTER
	PUSHJ	P,EXIFIL	;OUTPUT THE STATUS OF THE ACTIVE FILE
	SKIPN	OLDSPC		;IS THERE AN ALTERNATE FILE?
	JRST	JRNST0		;NO - DON'T OUTPUT ITS STATUS
	MOVEI	T1,OLDSPC	;GET ALTERNATE FILE SPECS
	MOVE	T4,SAVEDP	;AND DISPLAY POINTER
	DMOVEM	RW,SAVEAC+2
	HRRZ	RW,SAVERW
	HLRZ	CM,SAVERW
	EXCH	SL,SAVESL
	PUSHJ	P,EXIFIL	;OUTPUT THE STATUS OF THE ACTIVE FILE
	DMOVE	RW,SAVEAC+2
	EXCH	SL,SAVESL
JRNST1:	EXCH	TY,JRNPTR	;SAVE JOURNAL BUFFER PTR; GET TYPE-OUT PTR
	SETOM	JRNBIT		;NOTE THAT FIRST FILE WRITE HAS NOT BEEN DONE
	MOVE	T1,[POINT 7,JOURNL+JRNSIZ-1,34]
	MOVEM	T1,JRNENP	;SAVE POINTER TO END OF JOURNAL
IFN TOPS10,<
	TLZ	TM,JRO		;NOTE THAT JOURNAL FILE IS CLOSED
	SETZM	JRNDSK		;SAY WRITING DISK BLOCK 1
>
	POPJ	P,		;FINISH OFF AND RETURN

JRNST0:	PUSHJ	P,EXIFL1	;NO ALTERNATE FILE - OUTPUT A CRLF
	JRST	JRNST1		;AND FINISH OFF

;SUBROUTINE TO SAVE A CHARACTER IN THE JOURNAL BUFFER & OUTPUT IT IF FULL
;CALL WITH CHARACTER IN T1; T3 IS FRAGGED

JRNSVA:	MOVEM	T1,SAVEAC	;PRESERVE THE CHARACTER
	CAIE	T1,"^"		;GOT A REAL UP-ARROW,
	CAIN	T1,"$"		;  OR A REAL DOLLAR SIGN?
	JRST	JRSVA1		;YES - PREPEND AN UP-ARROW
	ROT	T1,-7		;LEFT-JUSTIFY IT
	JRST	JRSVC0		;OUTPUT	THE CHARACTER AND RETURN

JRSVA1:	ROT	T1,-^D14	;LEFT-JUSTIFY TWO CHARACTERS
	TLO	T1,570000	;PRECEDE THE CHARACTER WITH AN UP-ARROW
	JRST	JRSVC0		;OUTPUT THEM AND RETURN

;SUBROUTINE TO SAVE A COMMAND IN THE JOURNAL BUFFER & OUTPUT IT IF FULL
;CALL WITH COMMAND INDEX IN AC DO; T1, T3 FRAGGED

JRNSVC:	CAIN	DO,$ABORT	;GOT AN ABORT COMMAND?
	POPJ	P,		;YES - DON'T SAVE IT (IN CASE OF REENTER)
	CAIN	DO,$HELP	;GOT A HELP OR RECOVER COMMAND?
	TLNE	F,ENT		;YES - IN A PARAMETER?
	SKIPA	T1,CMDNAM(DO)	;NOT HELP (MAY BE RECOVER) - GET COMMAND NAME
	POPJ	P,		;HELP - IGNORE THE HELP COMMAND
	CAMN	T1,CMDNAM+$RETRN ;IS IT A RETURN COMMAND?
	TRO	T1,6424		;YES - FOLLOW IT WITH A REAL CRLF
JRSVC0:	TRNE	F,XCT!XBN	;EXECUTING OR RESTORING A JOURNAL?
	JRST	JRSVC2		;YES - DON'T DO ANY SAVING
	EXCH	T2,JRNPTR	;NO - SAVE T2 AND GET PTR TO JOURNAL BUFFER
JRSVC1:	LSHC	T0,7		;SHIFT IN A CHARACTER
	IDPB	T0,T2		;SAVE IT IN THE JOURNAL BUFFER
	CAMN	T2,JRNENP	;IS BUFFER FULL?
	PUSHJ	P,JRNSVO	;YES - OUTPUT IT
	JUMPN	T1,JRSVC1	;LOOP THROUGH COMMAND NAME
	EXCH	T2,JRNPTR	;SAVE JOURNAL POINTER AND GET T2 BACK
JRSVC2:	MOVE	T1,SAVEAC	;RESTORE AC T1
	POPJ	P,		;DONE

;SUBROUTINE TO SAVE AN EXECUTE CALL IN THE JOURNAL BUFFER & OUTPUT IT IF FULL
;CALL WITH EXECUTE INDEX IN DO;  T1, T3 FRAGGED

JRNSVX:	MOVE	T1,DO		;GET EXECUTE INDEX
	OR	T1,[5,,726140]	;PRECEDE INDEX WITH "^X" AND LIGHT 140 (REALLY)
	LSH	T1,^D15		;LEFT-JUSTIFY THE STRING
	JRST	JRSVC0		;OUTPUT THE STRING AND RETURN

;SUBROUTINE TO WRITE OUT THE JOURNAL BUFFER

JRNSVO:	MOVEM	T1,SAVEAC+1	;OUTPUT BUFFER: SAVE T1
	SETZ	T3,		;END THE BUFFER WITH A NULL
	MOVE	T1,T2		;(BUT DON'T HURT THE POINTER IN T2)
	IDPB	T3,T1
IFN TOPS10,<
	TLOE	TM,JRO		;IS THE JOURNAL ALREADY OPEN?
	JRST	JRSVO1		;YES - SKIP THIS
	MOVEI	T3,.FOAPP	;NO - ASSUME THIS IS NOT THE FIRST TIME
	SKIPE	JRNBIT		;HAS THE FILE BEEN WRITTEN TO?
	MOVEI	T3,.FOWRT	;OF COURSE NOT - OPEN FOR THE FIRST TIME
	HRRM	T3,JRNFIL+.FOFNC
	SETZM	JRNBIT		;MARK JOURNAL FILE AS OPEN
	MOVE	T3,USRPPN	;OPEN IT IN THE USER'S TOP-LEVEL DIR
	MOVEM	T3,JRNLKB+3
	MOVE	T3,[6,,JRNFIL]	;OPEN OR APPEND TO THE FILE
	FILOP.	T3,
	  JRST	JRSERR		;OOPS - CAN'T DO IT
	HLLZS	JRNLKB+1	;CLEAN UP THE BLOCK FOR NEXT TIME
	SETZM	JRNLKB+2

JRSVO1:	MOVE	T1,JRNDSK	;GET NUMBER OF CURRENT DISK BLOCK
	MOVE	T3,JRNENP	;IF NOT FIRST OUTPUT TO THIS BLOCK,
	CAME	T3,[POINT 7,JOURNL+JRNSIZ+-1,34]
	USETO	11,1(T1)	;  SET TO THE BLOCK'S START
	OUTPUT	11,JRNCCL	;OUTPUT THE JOURNAL RECORD
	CAME	T3,[POINT 7,JOURNL+JRNSIZ+-1,34]
	JRST	JRSVO2		;IF FIRST OUTPUT TO BLOCK, DO CHECKPOINT
	MOVEI	T1,.FOURB	;GET THE CHECKPOINT FILE FUNCTION
	HRRM	T1,JRNFIL+.FOFNC
	MOVE	T1,[1,,JRNFIL]	;POINT TO THE ARGUMENT BLOCK
	FILOP.	T1,		;CHECKPOINT THE FILE
	  CAIA			;COULDN'T - DO IT THE OLD WAY
	JRST	JRSVO2		;SUCCESS - CONTINUE
	TLZ	TM,JRO		;(OLD WAY) MARK FILE AS CLOSED
	RELEAS	11,		;CLOSE AND RELEASE THE FILE
JRSVO2:	CAMN	T3,[POINT 7,JOURNL+177,34]	;AT END OF BUFFER?
	JRST	[AOS   JRNDSK			;YES - BUMP DISK BLOCK NUMBER
		 SETZM JOURNL+JRNSIZ-1 		;CLEAN OUT THE JOURNAL BUFFER
		 MOVE  T3,[JOURNL+JRNSIZ-1,,JOURNL+JRNSIZ]
		 BLT   T3,JOURNL+177
		 MOVE  T2,[POINT 7,JOURNL]	;WRITE FROM START OF BUFFER
		 MOVE  T3,[POINT 7,JOURNL+JRNSIZ-1,34]
		 JRST  JRSVO3]			;RE-START EO-BUFFER PTR; FLOW
	ADDI	T3,JRNSIZ			;NOT AT END - BUMP END POINTER
	CAMLE	T3,[POINT 7,JOURNL+177,34]	;BEYOND END NOW?
	MOVE	T3,[POINT 7,JOURNL+177,34]	;YES - POINT AT THE END
JRSVO3:	MOVEM	T3,JRNENP	;SAVE END-OF-JOURNAL POINTER
>
IFE TOPS10,<
	MOVE	T1,[GJ%SHT]
	HRROI	T2,JRNFIL	;POINT TO THE JOURNAL NAME
	GTJFN
	  JRST	JRSERR
	HRRZM	T1,JRNJFN	;SAVE JFN FOR LATER

	SKIPN	JRNBIT		;WRITING THE FILE FOR THE FIRST TIME?
	JRST	JRSVO1		;NO - APPEND TO THE FILE
	SETZM	JRNBIT		;SAY IT'S NO LONGER THE FIRST WRITE
	SKIPA	T2,[7B5+OF%WR]	;SET TO OPEN UP A NEW JOURNAL FILE
JRSVO1:	MOVE	T2,[7B5+OF%APP]	;SET TO APPEND TO THE EXISTING FILE
	OPENF
	  JRST	JRSERR

	HRROI	T2,JOURNL	;OUTPUT THE JOURNAL BUFFER
	SETZ	T3,
	SOUT
	CLOSF			;CLOSE THE JOURNAL
	  JRST	JRSERR		;(IT REALLY OUGHT TO WORK)
	MOVE	T2,[POINT 7,JOURNL] ;RESET JOURNAL BUFFER POINTER
>
	MOVE	T1,SAVEAC+1	;RESTORE THE SAVED T1
	POPJ	P,		;DONE

;HERE TO READ FROM JOURNAL - FROM XCTGET, WHEN JRC (AND XCT OR XBN) IS SET

LOPJRN:	PUSHJ	P,LOPJRR	;GET A REAL CHARACTER FROM THE JOURNAL
	CAIN	T1,"$"		;GOT AN ESCAPE COMMAND?
	JRST	[MOVEI T1,33	;YES - GET ITS INDEX
		 JRST  LOOP2]	;AND USE IT
	CAIE	T1,"^"		;GOT A TYPE-IN CHARACTER?
	JRST	LOPJRA		;NO - JUST PUT IT IN FILE OR BUFFER
	PUSHJ	P,LOPJRR	;YES - GET FIRST CHARACTER OF COMMAND
	CAIE	T1,"$"		;REALLY WANT A REAL DOLLAR SIGN,
	CAIN	T1,"^"		;  OR AN UP-ARROW?
	JRST	LOPJRA		;YES - HANDLE IT LIKE A CHARACTER

	MOVEI	PT,"^"		;NO - GET AN UP-ARROW
	PUSHJ	P,LOPJRC+1	;PUT NEW CHARACTER IN WITH IT
	PUSHJ	P,LOPJRC	;GET REST OF COMMAND NAME
	CAME	PT,["^RF"]	;GOT A ROLL FORWARD
	CAMN	PT,["^RB"]	;  OR BACKWARD?
	JRST	LOPJR2		;YES - NEED TO GET ANOTHER CHARACTER
IFE TOPS10,<
	CAME	PT,["^PU"]	;PUSH COMMAND?
>
	CAMN	PT,["^RW"]	;RE-WRITE COMMAND?
	JRST	LOPJRN		;YES - IGNORE IT
	LSH	PT,^D15		;NO - LEFT-JUSTIFY COMMAND NAME
LOPJR1:	MOVEI	T1,CMDLEN-1	;LOOK FOR COMMAND AMONG NAMES
	CAME	PT,CMDNAM(T1)	;IS THIS IT?
	SOJGE	T1,.-1		;NO - KEEP LOOKING
	JUMPGE	T1,LOOP2	;PROCESS COMMAND, IF THAT'S WHAT IT IS

	MOVE	T1,PT		;ELSE LOOK AT FIRST TWO CHARACTERS OF NAME
	SETZ	T0,
	LSHC	T0,^D14
	CAIE	T0,"^X"		;GOT AN EXECUTE BUFFER?
	JRST	JRRERR		;NO - IT'S AN ERROR
	ROT	T1,7		;YES - GET EXECUTE INDEX (+ 140) IN RH
	JRST	ILCER0		;GO PROCESS THE EXECUTE

LOPJR2:	PUSHJ	P,LOPJRC	;GET REST OF COMMAND NAME
	LSH	PT,^D8		;LEFT-JUSTIFY COMMAND NAME
	JRST	LOPJR1		;GO FIND THE COMMAND

LOPJRA:
IFE TOPS10,<
IFN FTECHO,<
	TRNN	F,XBN		;DOES THE USER WANT TO SEE THE ACTION?
	JRST	ALPNUM		;NO - GO HANDLE IT LIKE A CHARACTER
	TLNN	F,ENT		;IN A PARAMETER?
	TYPCHA			;NO - DISPLAY THE CHARACTER
>>
	JRST	ALPNUM		;GO HANDLE IT LIKE A CHARACTER

LOPJRC:	PUSHJ	P,LOPJRR	;GET CHARACTER FROM THE JOURNAL
	LSH	PT,7		;SHIFT OVER ALREADY-GOTS
	OR	PT,T1		;PUT NEW CHARACTER IN WITH THEM
	POPJ	P,		;DONE

LOPJRR:	ILDB	T1,JRNPTR	;GET CHARACTER FROM THE JOURNAL
	CAIL	T1," "		;CONTROL CHARACTER OR NULL?
	POPJ	P,		;NO - RETURN
	JUMPN	T1,LOPJRR	;YES - IGNORE CONTROL CHARACTERS
	PUSHJ	P,JRNRED	;IF NULL READ ANOTHER PIECE OF THE JOURNAL
	JRST	LOPJRR		;GET A CHARACTER FROM IT AND CONTINUE

;SUBROUTINE FOR RECOVERING THE JOURNAL:
;OPEN THE JOURNAL, READ THE FIRST BUFFERFUL OF COMMANDS,
;AND SET UP THE FILE AND ALTERNATE

JRNGET:	SETZM	JRNFLG		;SAY THERE'S MORE FILE TO COME
	SETZM	RSCANF		;FORGET FILE GIVEN IN RESCAN
IFN TOPS10,<
	MOVEI	T1,.FORED	;SET UP THE FILE FOR READING
	HRRM	T1,JRNFIL+.FOFNC
	MOVE	T1,USRPPN	;LOOP FOR THE FILE IN THE USER'S DIRECTORY
	MOVEM	T1,JRNLKB+3
	MOVE	T1,[6,,JRNFIL]	;LOOP UP THE FILE
	FILOP.	T1,
	  JRST	JRNERR		;ERROR
	HLLZS	JRNLKB+1	;CLEAN UP THE BLOCK FOR NEXT TIME
	SETZM	JRNLKB+2
	SETOM	JRNDSK		;NOTE WILL BE READING THE FIRST DISK BLOCK
>
IFE TOPS10,<
	MOVE	T1,[GJ%OLD+GJ%SHT]
	HRROI	T2,JRNFIL
	GTJFN
	  JRST	JRNERR
	HRRZ	T1,T1		;CLEAR FLAGS OUT OF LH OF T1
	MOVEM	T1,JRNJFN	;SAVE JFN FOR LATER
	MOVE	T2,[7B5+OF%RD]
	OPENF
	  JRST	JRNERR
>
	PUSHJ	P,JRNRED	;READ FIRST BLOCK OF THE JOURNAL
	MOVE	T2,[POINT 7,JOURNL]
	MOVEI	T3,FILSPC	;READ OLD FILESPECS
	PUSHJ	P,JRNCPY
	MOVEI	T3,OLDSPC	;AND CURRENT FILESPECS
	PUSHJ	P,JRNCPY
	MOVEM	T2,JRNPTR	;SAVE THE POINTER INTO THE JOURNAL
	POPJ	P,		;DONE

JRNRED:	SKIPE	JRNFLG		;IS THERE MORE FILE TO READ?
	JRST	JRNEND		;NO - DONE
	MOVE	T2,[POINT 7,JOURNL]
	MOVEM	T2,JRNPTR	;YES - RESET POINTER INTO BUFFER
IFN TOPS10,<
	INPUT	11,JRNCCL	;READ THE NEXT BUFFERFUL OF COMMANDS
	STATZ	11,760000	;REACHED END OF FILE (OR AN ERROR)?
	JRST	JRNDUN		;YES - NOTE THAT END OF FILE HAS BEEN REACHED
	AOS	JRNDSK		;NO - BUMP NUMBER OF DISK BLOCK JUST READ
>
IFE TOPS10,<
	MOVE	T1,JRNJFN	;GET JFN
	HRROI	T2,JOURNL	;AND A BUFFERFUL OF COMMANDS
	MOVNI	T3,5*JRNSIZ
	SIN
	  ERJMP	JRNDUN		;ON END OF FILE GIVE A NON-SKIP RETURN
>
	POPJ	P,		;READ SUCCEEDED - DONE

;SUBROUTINE TO COPY FILESPECS FROM (T2) TO (T3) UNTIL A CARRIAGE RETURN

JRNCPY:	HRLI	T3,440700	;MAKE TARGET ADDRESS A POINTER
	ILDB	T1,T2		;GET A CHARACTER
	CAIN	T1,15		;CARRIAGE RETURN?
	JRST	JRNCP1		;YES - FINISH OFF
	IDPB	T1,T3		;NO - SAVE THE CHARACTER
	JRST	JRNCPY+1	;AND GET MORE

JRNCP1:	ILDB	T1,T2		;SKIP OVER THE LINEFEED
	SETZ	T1,		;END FILESPECS WITH A NULL
	IDPB	T1,T3
	POPJ	P,		;DONE

;HERE WHEN RECOVERNG, WHEN END OF JOURNAL FILE IS REACHED

JRNDUN:	SETOM	JRNFLG		;SAY END OF FILE HAS BEEN REACHED
IFN TOPS10,<
	RELEAS	11,		;CLOSE AND RELEASE THE JOURNAL FILE
				;FALL INTO THE CODE AT JRNEND
>
IFE TOPS10,<
	MOVE	T1,JRNJFN	;THROW AWAY THE JOURNAL FILE
	CLOSF			;CLOSE IT
	  POPJ	P,		;IT BETTER WORK
	POPJ	P,		;DONE
>
JRNEND:	MOVE	T2,[POINT 7,JOURNL]
	MOVEM	T2,JRNPTR	;INITIALIZE THE JOURNAL BUFFER POINTER
	SKIPN	JRNBIT		;WANT TO KEEP APPENDING TO THIS JOURNAL?
	JRST	JRNEN1		;NO - DON'T INITIALIZE
	TLO	TM,JRW		;YES - NOTE THAT JOURNAL IS NOW BEING WRITTEN
IFN TOPS10,<
	SETZM	JOURNL+JRNSIZ-1 ;CLEAN OUT THE JOURNAL BUFFER
	MOVE	T3,[JOURNL+JRNSIZ-1,,JOURNL+JRNSIZ]
	BLT	T3,JOURNL+177
>
	MOVE	T1,[POINT 7,JOURNL+JRNSIZ-1,34]
	MOVEM	T1,JRNENP	;SAVE POINTER TO END OF JOURNAL BUFFER
	SETZM	JRNBIT
JRNEN1:	SKIPA	T1,[[ASCIZ /#########File recovered/]]
JRNERR:	MOVEI	T1,[ASCIZ /#####Can't find journal file/]
	TRZ	F,XCT!XBN	;END THE JOURNAL RESTORE
IFN TOPS10,<
	TLZ	TM,JRC!JRO	;CLEAR RECOVERY BIT; NOTE FILE IS NOT OPEN
>
IFE TOPS10,<
	TLZ	TM,JRC		;CLEAR RECOVERY BIT
>
	SETZM	JRNFLG
	JRST	STFER1		;TELL USER THAT RECOVERY IS DONE

JRRERR:	MOVEI	T1,[ASCIZ /######Bad command in journal/]
	JRST	JRNERR+1

JRSERR:	MOVEI	T1,[ASCIZ /#####Can't write journal file/]
	TLZ	TM,JRW		;DON'T DO JOURNALING
	JRST	STFER1		;TELL USER THAT RECOVERY IS DONE
>
;************************************************************************
;SUBROUTINE TO OUTPUT THE FENCE (FNCCLR CLEARS TO END OF SCREEN)

FNCCLR:	PUSHJ	P,CLEARP	;CLEAR TO END OF SCREEN
FNCPUT:	MOVEI	T1,3(RW)	;GET ROW+3
	CAML	T1,LPP.1	;CLOSE TO THE BOTTOM OF THE SCREEN?
	JRST	PUTTYP		;YES - NO FENCE
	MOVEI	T1,FENCE	;OUTPUT THE FENCE ON THE BOTTOM LINE
	PUSHJ	P,PUTBTM
	PUSHJ	P,PROTOF
	TLO	F,FNC		;SET FLAG TO SAY FENCE IS UP
	JRST	PUTTYP

;************************************************************************
;HERE TO REENTER EDITOR AFTER AN ABORT. RESTORES SAVED ACS AND FLIES

REEERR:	MOVS	T1,[5,,SAVEAC]	;RESTORE ACS
	BLT	T1,P
IFE TOPS10,<
	TRNN	F,GFL		;IS THE FILE LEFT TO EDIT?
	JRST	STARTR		;NO - JUST DO A NORMAL STARTUP
>
	PUSHJ	P,INITTY	;SET UP THE TTY AGAIN
	PUSHJ	P,@RTE(TM)	;CALL USER'S ENTRY ROUTINE
	PUSHJ	P,INITT1	;DO MORE TTY INITTING
IFE TOPS10,<
	PUSHJ	P,INITTF	;DISABLE TOPS-20 INTERRUPTS, TOO
>
	TLNE	TM,SLW		;PUTTING ERRORS ON THE BOTTOM LINE?
	PUSHJ	P,DISPLL	;YES - DISPLAY NOW, THEN
	MOVEI	T1,[ASCIZ /#########Re-entering SED/]
	JRST	ERROR		;(THIS IS IF USER TYPES ^C, REE)

;SUBROUTINE TO INITIALIZE THE TTY FOR INPUT AND OUTPUT

IFN TOPS10,<
INITTY:	SETO	T1,		;FIND TERMINAL NUMBER
	TRMNO.	T1,
	  HALT
	MOVEM	T1,BRKADR+1	;SET IT UP IN VARIOUS LOCATIONS
	MOVEM	T1,PAGADR+1
	MOVEM	T1,XOFADR+1
	MOVEM	T1,CRRADR+1
	MOVEM	T1,CRWADR+1
	MOVEM	T1,CHRIN+1
	MOVEM	T1,TSTIN+1
	OPEN	1,TTYBLK	;OPEN TERMINAL IN PIM MODE
	  HALT
	MOVE	T1,[XWD 3,BRKADR]
	TRMOP.	T1,		;SET UP TO BREAK ON ALL CHARACTERS
	  HALT
	MOVE	T1,[XWD 2,CRRADR]
	TRMOP.	T1,		;READ SETTING OF TTY CRLF
	  HALT
	JUMPN	T1,CPOPJ	;DONE IF TTY NO CRLF SET
	MOVE	T1,[XWD 3,CRWADR]
	TRMOP.	T1,		;ELSE SET TTY NO CRLF
	  HALT
	SETZM	CRWADR+2	;AND MAKE SURE IT'LL BE RESET ON EXIT
	POPJ	P,
>
IFE TOPS10,<
INITTY:	MOVEI	T1,-1		;READ THE STARTING CCOC WORD
	RFCOC
	DMOVEM	T2,SAVCOC	;SAVE IT
IFN FTECHO,<
	SETZB	T2,T3		;MAKE ALL CONTROL CHARACTERS NOT ECHO
>
IFE FTECHO,<
	MOVE	T2,[525252,,525252]
	MOVE	T3,T2		;MAKE ALL CONTROL CHARACTERS GIVE THEIR CODE
>
	SFCOC

;	MOVEI	T2,.MOXOF	;CLEAR PAUSE-ON-END-OF-PAGE BIT
;	SETZ	T3,		;this is off because it can't be sensed,
;	MTOPR			;so it can't be restored on exit

;	MOVEI	T1,.FHSLF	;READ USER'S CAPABILITIES
;	RPCAP
;	MOVSI	T1,(SC%CTC)	;ENABLE CONTROL-C TRAPPING
;	EPCAP
IFN FTECHO,<
	MOVEI	T1,4
	MOVEM	T1,SAVWKU
	MOVEI	T3,SAVWKU	;READ THE STARTING WAKE-UP SET FOR EXITING
	MOVEI	T1,.PRIOU
	MOVEI	T2,.MORBM
	MTOPR
	PUSHJ	P,BRKNPT	;SET TO BREAK ONLY ON CONTROL CHARACTERS

	MOVE	T1,[GJ%SHT]	;OPEN UP THE TERMINAL FOR OUTPUT
	HRROI	T2,[ASCIZ /TTY:/] ;SO OUTPUT WON'T BE TRANSLATED
	GTJFN
	  HALTF
	HRRZ	T1,T1
	MOVEM	T1,TTYJFN
	MOVE	T2,[10B5+OF%RD+OF%WR]
	OPENF
	  HALTF
>
	POPJ	P,

INITTF:	MOVEI	T1,-5		;DISABLE INTERRUPTS ON ALL CHARACTERS
	SETZ	T2,		;  SO MONITOR WON'T TRAP ANYTHING
	STIW
	MOVEI	T1,.PRIIN	;READ MODE WORD
	RFMOD
	MOVEM	T2,FMDSAV	;SAVE IT FOR EXIT
IFN FTECHO,<
	TDZ	T2,[37777,,0020] ;ZERO PAGE LENGTH, WIDTH
	TDO	T2,[200000,,300] ;TURN ON FORMF, NO-TRANS-OUTPUT BITS
	MOVEM	T2,SMDSAV	;SAVE SED'S NORMAL MODE WORD
>
IFE FTECHO,<
	TDZ	T2,[37777,,4020] ;ZERO PAGE LENGTH, WIDTH; MAKE NOTHING ECHO
	TDO	T2,[200000,,300] ;TURN ON FORMF, NO-TRANS-OUTPUT BITS
>
	SFMOD
	STPAR
	SETOM	ITTFLG		;MARK INTERRUPTS AS DISABLED
	POPJ	P,
>
;SUBROUTINE TO DO MORE TTY INITIALIZATION, AFTER USER'S ENTRY ROUTINE IS RUN

IFN TOPS10,<
INITT1:	MOVEI	T1,GETAK	;SET UP SO AN ILL MEM REF
	HRRM	T1,.JBAPR	;  EXPANDS CORE AUTOMATICALLY
	MOVEI	T1,420000
	APRENB	T1,
	TLNE	TM,NPG		;LEAVE XON AND XOFF ALONE?
	POPJ	P,		;YES - DONE
	JRST	INIT1B		;NO - SKIP THE SLEEP THE FIRST TIME

INIT1A:	MOVEI	T1,1		;SLEEP A BIT
	SLEEP	T1,
INIT1B:	MOVE	T1,[XWD 3,XOFADR]
	TRMOP.	T1,		;SEE IF XOFF IS CURRENTLY IN EFFECT
	  HALT
	JUMPN	T1,INIT1A	;IF SO, WAIT FOR USER TO CLEAR IT
	SETZM	PAGADR+2	;O.K. - RESET PAGE WORD IN CASE OF AN ABORT
	MOVE	T1,[XWD 3,PAGADR]
	TRMOP.	T1,		;NOW IT'S SAFE TO SET UP TTY NO PAGE
	  HALT
	POPJ	P,		;DONE
>
IFE TOPS10,<
INITT1:	MOVEI	T1,.PRIIN
	RFMOD			;READ MODE WORD (AGAIN)
	TLNN	TM,NPG		;ENABLE CTRL-S AND CTRL-Q AS COMMANDS?
	TRZA	T2,2		;YES - CLEAR ECHO
	TRO	T2,2		;NO - SET THE BIT
	STPAR
IFN FTECHO,<
	MOVEM	T2,SMDSAV	;SAVE IT AS SED'S NORMAL MODE WORD
>
	POPJ	P,		;DONE
>
;HERE (ERROR:) TO CLEAR SCREEN, OUTPUT AN ERROR MESSAGE, REWRITE SCREEN,
;AND GO GET ANOTHER COMMAND. THE COMMAND THAT CAUSED THE ERROR IS IGNORED

;THIS ROUTINE CAN BE CALLED FROM ANY LEVEL SINCE IT RESETS THE P-D STACK

ALPERR:	TLNE	F,ERF		;JUST HAD AN ERROR?
	JRST	RDOERR		;YES - SKIP THIS
	PUSHJ	P,MAKCPT	;NO - MAKE SURE THE CHARACTER POINTER IS O.K.
	PUSHJ	P,DISLIN	;AND REPAIR THE FRAGGED LINE
RDOERR:	MOVEI	T1,[ASCIZ /######File cannot be modified/]

ERROR:	TLNE	TM,JRC		;NO - RESTORING A JOURNAL?
	JRST	ERRORZ		;YES - JUST CONTINUE PROCESSING
	TLOE	F,ERF		;JUST HAD AN ERROR?
	JRST	ERRORX		;YES - DON'T OUTPUT THIS ONE, THEN
	TRZN	F,XCT!XBN	;EXECUTING?
	TLZA	F,FLG		;NO - CLEAR XCT AND FLG
	TLO	F,FLG		;YES - CLEAR XCT AND SET FLG
	PUSHJ	P,ERRDSP	;ELSE DISPLAY THE ERROR MESSAGE
	TRNN	F,GFL		;GOT A FILE TO EDIT?
	JRST	ERRORY		;NO - DISPLAY CHEERY MESSAGE
	TLNN	TM,SLW		;SLOW TERMINAL?
	PUSHJ	P,DISPLL	;NO - REWRITE THE SCREEN
	PUSHJ	P,ERASPM	;IF ENTER TYPED CLEAN LINE UP
ERRORX:	PUSHJ	P,POSCUR
ERRORZ:	MOVE	P,[IOWD STKSIZ,STACK] ;CLEAN UP THE STACK
	TDZ	F,[FLG,,ENT]	;STOP DOING COMMANDS; CLEAR ENTER MODE
	JRST	LOOP		;AND GET ANOTHER COMMAND

ERRORY:	MOVE	P,[IOWD STKSIZ,STACK] ;CLEAN UP THE STACK
	TDZ	F,[FLG,,ENT]	;STOP DOING COMMANDS; CLEAR ENTER MODE
	SKIPE	STTFLG		;INITIALIZING?
	JRST	INIERR		;YES - FINISH THE INITIALIZATION
	JRST	REDNO		;NO - GO DISPLAY CHEERY MESSAGE

;HERE TO HANDLE ERRORS FROM SETTING FILES. THEY ARE SPECIAL SINCE SED CAN'T
;JUST REDISPLAY THE SCREEN - THERE MIGHT NOT BE A FILE TO REDISPLAY
;ACTION: RESTORE CURRENT AND ALTERNATE SPECS
;IF GFL DO A NORMAL ERROR, ELSE GET CURRENT FILE OR CHEERY MESSAGE

STFERR:	MOVS	T2,[FILSPC,,OLDSPC] ;RESTORE THE CURRENT SPECS
	BLT	T2,FILSPC+SPCSIZ-1
	HLRZ	CM,SAVERW	;GET ROW AND COLUMN BACK
	HRRZ	RW,SAVERW
	MOVE	T2,SAVEDP	;GET DISPLAY POINTER
	MOVEM	T2,DISPTR
	MOVE	SL,SAVESL	;SET UP SLIDE
	MOVS	T2,[OLDSPC,,SVASPC] ;AND THE OLD SPECS AND POINTERS
	BLT	T2,OLDSPC+SPCSIZ+2
IFN TOPS10,<
IFE FTSFD,<
	MOVE	T2,FILFIL+3	;RESTORE THE PPN
	MOVEM	T2,FILPPN
>>
	TLO	F,XPC!XPL!XPB	;NO POINTERS ARE VALID
	SETOM	GOPRCT		;IF USER GAVE A /G: SWITCH CANCEL IT
	SETZM	OUTFLG		;DITTO AN /OUT: SWITCH
	SKIPE	PT,MFLPTR	;GOT ANOTHER SPEC IN STAT.TMP FILE?
	JRST	[PUSH  P,T1	;YES - SAVE ERROR MESSAGE
		 PUSHJ P,SETMFE	;READ NEW SPECS INTO OLDSPC
		 POP   P,T1	;GET ERROR MESSAGE BACK
		 JRST  .+1]	;AND CONTINUE
STFER1:	TRNE	F,GFL		;GOT A FILE TO REDISPLAY?
	JRST	ERROR		;YES - OUTPUT THE ERROR NORMALLY
	TLZ	F,FLG		;NO - TURN OFF ERROR ROUTINE'S EXECUTE FLAG
	PUSHJ	P,ERRDSP	;OUTPUT THE MESSAGE
	SKIPN	FILSPC		;ARE THERE ANY OTHER FILESPECS?
	JRST	REDNO		;NO - GO SET UP CHEERY MESSAGE
	SKIPE	DISPTR		;YES - NEED TO PARSE SPECS?
	JRST	SETFL1		;NO - GO TRY THE OTHER FILE
	PUSHJ	P,PARSEF	;YES - DO SO
	SETZM	SVASPC		;CLEAR OUT THE SAVED SPECS
	MOVE	T2,[SVASPC,,SVASPC+1]
	BLT	T2,SVASPC+SPCSIZ+2
	JRST	SETFL1		;GO TRY THE OTHER FILE

;SUBROUTINE TO OUTPUT THE ERROR MESSAGE IN (T1)

ERRDSP:	PUSH	P,T1		;SAVE MESSAGE ADDRESS
	TLNE	TM,SLW		;GOT A SLOW TERMINAL?
	JRST	ERRDSW		;YES - OUTPUT ONLY ON FIRST LINE
	SKIPN	STTFLG		;INITIALIZING?
 	PUSHJ	P,CLRALL	;NO - MOVE HOME AND CLEAR THE SCREEN
	MOVEI	T1,STARS	;PUT UP UPPER STARS
	PUSHJ	P,PUTSTG
	POP	P,T1
	PUSHJ	P,PUTSTX
	MOVEI	T1,STARS	;PUT UP LOWER STARS
	PUSHJ	P,PUTSTG
	PUSHJ	P,PUTTYP	;OUTPUT THE MESSAGE
	SNOOZE	^D1500		;SLEEP A BIT
	TLZ	F,FLG		;CLEAR (EXECUTE) FLAG
	POPJ	P,		;DONE

;IF TERMINAL IS SLOW (SLW FLAG) PUT ERROR MESSAGE ON BOTTOM LINE

ERRDSW:	PUSHJ	P,CBOTOM	;GO TO BOTTOM LINE
	MOVEI	T1,7		;BEEP ONCE
	IDPB	T1,TY
	PUSHJ	P,PROTON	;TURN PROTECTION ON
	POP	P,T1		;RESTORE MESSAGE ADDRESS
	PUSHJ	P,PUTSTX	;OUTPUT MESSAGE
	PUSHJ	P,PROTOF	;TURN PROTECTION OFF AGAIN
	PUSHJ	P,PUTTYP	;OUTPUT THE MESSAGE
	TLNE	TM,NEL		;CAN BOTTOM LINE STAY FRAGGED?
	JRST	ERRDW1		;YES - NO DELAY THEN
	SNOOZE	^D1000		;SLEEP A BIT
ERRDW1:	TLZE	F,FLG		;EXECUTING?
	JRST	DISPLL		;YES - RE-DISPLAY THE SCREEN AND RETURN
	TLO	F,FBL		;SAY BOTTOM LINE WILL BE FRAGGED
	TLNN	TM,NEL		;NO - CAN BOTTOM LINE REMAIN FRAGGED,
	TLNE	F,ENT		;  OR HAS ENTER BEEN TYPED?
	POPJ	P,		;ANY OF THESE - DONE
	SKIPE	DISPTR		;IS THERE A CURRENT FILE
	TRNN	F,GFL		;  (DITTO)?
	POPJ	P,		;NO - DONE
	JRST	FIXBLN		;YES - REPAIR THE BOTTOM LINE AND RETURN

;************************************************************************
;TOPS10 INTERRUPT ROUTINE TO EXPAND CORE BY 1K

IFN TOPS10,<
GETAK:	PUSH	P,T1		;SAVE AN AC
	HRRZ	T1,.JBREL	;FIND CURRENT LIMIT
	ADDI	T1,1000		;PLUS ONE K
	CORE	T1,		;EXPAND
	  JRST	GAKERR		;OOPS (PROBABLY RAN OUT)
	POP	P,T1		;RESTORE AC
	JRST	2,@.JBTPC	;RETURN FROM THE INTERRUPT

;HERE ON A FATAL CORE GRAB, PROBABLY A ILL MEM REF
;IF THIS HAPPENS, IT'S A BUG, BUT JUST TRY TO ISOLATE IT

GAKERR:	MOVE	P,[IOWD STKSIZ,STACK] ;CLEAN UP THE STACK
	MOVEI	T1,[ASCIZ /####Fatal error - save and exit/]
	PUSHJ	P,ERRDSP	;DISPLAY THE ERROR
	JRST	EEXIT		;SAVE FILE AND EXIT
>
;************************************************************************
;HISEG DATA

CMVTBL:	CDOWN		;CURSOR MOVE TABLE -
	CRIGHT		;  USED BY AJDONE TO MOVE CURSOR
	CURUP
	POSCUR

PTRTBL:	440700		;TABLE OF ASCII POINTER LH'S
	350700
	260700
	170700
	100700
	010700

;COMMAND DISPATCH TABLE

CMDTBL:	XRESET,,RESNPM	;    RESET (LOOKS LIKE A NULL)
	OPENSP,,OPSNPM	; A  OPEN SPACES
	SETFIL,,SETNPM	; B  SET UP A FILE FOR EDITING
	ABOPAR,,ABORT	; C  ABORT
	OPENLN,,OPENLN	; D  OPEN LINES
	SRCBAK,,SRBNPM	; E  SEARCH BACKWARD
	CLOSLN,,CLOSLN	; F  CLOSE LINES
	PUT,,PUT	; G  PUT
	LFTARG,,LEFT	; H  CURSOR LEFT
	TABARG,,TAB	; I  TAB
	LNFPAR,,LNFEED	; J  LINEFEED
IFN NEWTAB,<
	SLIDEL,,SLLNPM	; K  SLIDE LEFT
	SLIDER,,SLRNPM	; L  SLIDE RIGHT
	RETARG,,RETURN	; M  CARRIAGE RETURN
	SWITCH,,SWHNPM	; N  SET SWITCHES
>
IFE NEWTAB,<
	PICK,,PIKNPM	; K  PICK
	SLIDEL,,SLLNPM	; L  SLIDE LEFT
	RETARG,,RETURN	; M  CARRIAGE RETURN
	BTBARG,,BAKTAB	; N  BACK-TAB
>
	ENTCCH,,ENTCCH	; O  ENTER CONTROL CHARACTER
	PERCEN,,PERNPM	; P  PERCENT GOTO
	ROLBKP,,RBKNPM	; Q  ROLL BACK PAGES
	SRCFWD,,SRFNPM	; R  SEARCH FORWARD
	CLOSSP,,CLOSSP	; S  CLOSE SPACES
	ROLFWL,,RFLNPM	; T  ROLL FORWARD LINES
IFN NEWTAB,<
	BTBARG,,BAKTAB	; U  BACK-TAB
	PICK,,PIKNPM	; V  PICK
>
IFE NEWTAB,<
	SLIDER,,SLRNPM	; U  SLIDE RIGHT
	SWITCH,,SWHNPM	; V  SET SWITCHES
>
	ROLBKL,,ROLBKL	; W  ROLL BACK LINES
	EXECUT,,EXCNPM	; X  DO COMMAND SEQUENCE
	ROLFWP,,RFPNPM	; Y  ROLL FORWARD PAGES
	EXIPAR,,EEXIT	; Z  NORMAL EXIT
	ENTERA,,ENTERA	; [  ENTER PARAMS
	DWNARG,,DOWN	; \  CURSOR DOWN
	RGTARG,,RIGHT	; ]  CURSOR RIGHT
	UPARG,,UP	; ^  CURSOR UP
	HOMARG,,HOME	; _  HOME
	RECARG,,RECALL	;40  RECALL
	0,,INSMOD	;41  INSERT MODE
	LFTAG0,,DELCHR	;42  DELETE CHAR
	REALTB,,REALTB	;43  TYPE A REAL TAB (SAME AS E-C-C I)
	MRKARG,,MARK	;44  MARK POSITION FOR PICK AND CLOSE
	LINARG,,LINE	;45  MOVE TO BEGINNING OR END OF LINE
	CHGCAS,,CHGCAS	;46  CHANGE CASE OF LETTER AT CURSOR
IFN FTTST,<
	DELFIR,,WINSET	;47  SET OR CLEAR WINDOWING
>
IFE FTTST,<
	0,,WINSET	;47  SET OR CLEAR WINDOWING
>
	LNFPAR,,ERASLN	;50  ERASE TO END OF LINE
	TABCLR,,TABSET	;51  SET/CLEAR TAB STOPS
	UPTARG,,UPTAB	;52  UP-TAB (UP 6 LINES)
	DNTARG,,DNTAB	;53  DOWN-TAB (DOWN 6 LINES)
	0,,DISALL	;54  REWRITE SCREEN
	0,,SAVEIT	;55  SAVE FILE
IFN FTTST,<
	RECOVR,,HELPER	;56  GIVE HELP (SAME AS ENTER ENTER)
>
IFE FTTST,<
	HELPER,,HELPER	;56  GIVE HELP (SAME AS ENTER ENTER)
>
	BLIARG,,BLINE	;57  MOVE TO START OF LINE
	ELIARG,,ELINE	;60  MOVE TO END OF LINE
	BTBARG,,ERASWD	;61  ERASE PREVIOUS WORD
IFN TOPS10,<
	0,,0		;62  PUSH (ILLEGAL ON TOPS-10)
>
IFE TOPS10,<
	PSHARG,,PUSHER	;62  PUSH TO EXEC
>
	SUBSTI,,SUBNPM	;63  SUBSTITUTE
	ILLCMD,,ICMNPM	;64  ILLEGAL COMMAND (GIVES AN ERROR)
CMDLEN=.-CMDTBL

DEFINE TEXT1,<
;COMMAND NAMES (FOR EXECUTE, MAINLY)

CMDNAM:	ASCII	/^RS/	; @ RESET
	ASCII	/^IS/	; A INSERT SPACES
	ASCII	/^FL/	; B SET UP A FILE FOR EDITING
	ASCII	/^AB/	; C ABORT
	ASCII	/^IL/	; D INSERT LINES
	ASCII	/^SB/	; E SEARCH BACKWARD
	ASCII	/^DL/	; F DELETE LINES
	ASCII	/^PT/	; G PUT
	ASCII	/^CL/	; H CURSOR LEFT
	ASCII	/^TB/	; I TAB
	ASCII	/^LF/	; J LINEFEED
IFN NEWTAB,<
	ASCII	/^SL/	; K SLIDE LEFT
	ASCII	/^SR/	; L SLIDE RIGHT
	ASCII	/^RT/	; M CARRIAGE RETURN
	ASCII	/^SW/	; N SET SWITCHES
>
IFE NEWTAB,<
	ASCII	/^PK/	; K PICK
	ASCII	/^SL/	; L SLIDE LEFT
	ASCII	/^RT/	; M CARRIAGE RETURN
	ASCII	/^BT/	; N BACK-TAB
>
	ASCII	/^EC/	; O ENTER CONTROL CHARACTER
	ASCII	/^GO/	; P PERCENT GOTO
	ASCII	/^RBP/	; Q ROLL BACK PAGES
	ASCII	/^SF/	; R SEARCH FORWARD
	ASCII	/^DS/	; S DELETE SPACES
	ASCII	/^RFL/	; T ROLL FORWARD LINES
IFN NEWTAB,<
	ASCII	/^BT/	; U BACK-TAB
	ASCII	/^PK/	; V PICK
>
IFE NEWTAB,<
	ASCII	/^SR/	; U SLIDE RIGHT
	ASCII	/^SW/	; V SET SWITCHES
>
	ASCII	/^RBL/	; W ROLL BACK LINES
	ASCII	/^EX/	; X DO COMMAND SEQUENCE
	ASCII	/^RFP/	; Y ROLL FORWARD PAGES
	ASCII	/^XT/	; Z NORMAL EXIT
	ASCII	/$/	; [ ENTER PARAMS
	ASCII	/^CD/	; \ CURSOR DOWN
	ASCII	/^CR/	; ] CURSOR RIGHT
	ASCII	/^CU/	; ^ CURSOR UP
	ASCII	/^CH/	; _ HOME
	ASCII	/^RC/	;   RECALL
	ASCII	/^IN/	;   INSERT MODE
	ASCII	/^DC/	;   DELETE CHAR
	ASCII	/^TA/	;   REAL TAB
	ASCII	/^MK/	;   MARK POSITION FOR PICK OR CLOSE
	ASCII	/^LN/	;   MOVE TO BEGINNING OR END OF LINE
	ASCII	/^CS/	;   CHANGE CASE OF LETTER AT CURSOR
	ASCII	/^WI/	;   SET OR CLEAR WINDOWING
	ASCII	/^EL/	;   ERASE LINE
	ASCII	/^TS/	;   TAB SET/CLEAR
	ASCII	/^UT/	;   UP-TAB
	ASCII	/^DT/	;   DOWN-TAB
	ASCII	/^RW/	;   REWRITE SCREEN
	ASCII	/^SV/	;   SAVE FILE
	ASCII	/^HL/	;   GIVE HELP
	ASCII	/^LB/	;   MOVE TO START OF LINE
	ASCII	/^LE/	;   MOVE TO END OF LINE
	ASCII	/^EW/	;   ERASE PREVIOUS WORD
IFN TOPS10,<
	ASCII	/ /	;   PUSH (NOT ON TOPS-10)
>
IFE TOPS10,<
	ASCII	/^PU/	;   PUSH TO EXEC
>
	ASCII	/^SU/	;   SUBSTITUTE
	ASCII	/^IC/	;   ILLEGAL COMMAND

;TABLE OF EXECUTE CONSTRUCTS WHICH ARE NOT COMMANDS, AND THEIR CODES
;CONDITIONAL FLAGS: COND; DO, FR, FC, IF, DW, NOT
;OTHER CODES CAN'T GO BEYOND 37
;OTHER CODES IN USE: 100, 101: END OF CONDITIONALS; 77: <RESET>
;	"$", ")", "^": REAL CHARACTERS AS GIVEN

CMDCON:	BYTE	(7) "^","F","R" (15) 120	;^FR - IF ROW
	BYTE	(7) "^","F","C" (15) 110	;^FC - IF COLUMN
	BYTE	(7) "^","F","." (15) 130	;^F. - IF COUNTER
	BYTE	(7) "^","I","F" (15) 104	;^IF - IF CHARACTER
	BYTE	(7) "^","D","W" (15) 102	;^DW - DO WHILE
	BYTE	(7) "^","X","B" (15) 005	;^XB - EXIT BLOCK
	BYTE	(7) "^","C","B" (15) 006	;^CB - CONTINUE BLOCK
	BYTE	(7) "^","X","X" (15) 007	;^XX - EXIT BUFFER
	BYTE	(7) "^","C",".","(" (8) 010	;^C. - ITERATE COUNTER
	BYTE	(7) "^","C","=" (15) 011	;^C= - CLEAR COUNTER
	BYTE	(7) "^","C","+" (15) 012	;^C+ - BUMP COUNTER
	BYTE	(7) "^","C","-" (15) 013	;^C- - DEBUMP COUNTER
	BYTE	(7) "^","C","T" (15) 014	;^CT - USE COUNTER
	BYTE	(7) "^","S","T","(" (8) 015	;^ST - START (INITIALIZATION)
	BYTE	(7) "^","O","U","(" (8) 016	;^OU - IMAGE OUTPUT
	BYTE	(7) "^","S","C" (15) 017	;^SC - SET COUNTER
	BYTE	(7) "^","N","D" (15) 020	;^ND - NO DISPLAY
	BYTE	(7) "^","D","F","(" (8) 021	;^DF - DO ON SEARCH FAILURE
CMDCLN=.-CMDCON

XCTREL:	BYTE (7) 0,0,0,"G",0	;RELATIONS: G-2, L-3, E-4, N-5
XCTCLS:	BYTE (7) 0,0,0,"L",0	;CLASSES: L-1, E, N, A, S, U-6
	BYTE (7) 0,0,0,"E",0
	BYTE (7) 0,0,0,"N",0
	BYTE (7) 0,0,0,"A",0
	BYTE (7) 0,0,0,"S",0
	BYTE (7) 0,0,0,"U",0

;SWITCH DISPATCH ADDRESSES

SWHADR:	EXP	SWHAAA,SWHBBB,SWHCCC,SWHDDD,SWHERR	  ;A, B, C, D, E
IFE FTJOUR,<
	EXP	SWHFFF,SWHGGG,SWHHLP,SWHIII,SWHERR	  ;F, G, H, I, J
>
IFN FTJOUR,<
	EXP	SWHFFF,SWHGGG,SWHHLP,SWHIII,SWHJJJ	  ;F, G, H, I, J
>
	EXP	SWHERR,SWHLLL,SWHERR,SWHNNN,SWHOFL	  ;K, L, M, N, O
	EXP	SWHPPP,SWHQQQ,SWHRRR,SWHSSS,SWHTTT	  ;P, Q, R, S, T
	EXP	SWHUPP,SWHERR,SWHWWW,SWHERR,SWHERR,SWHTRM ;U, V, W, X, Y, Z

FENCE:	ASCII	/   *** This FENCE marks the last page of the file /
	ASCII	/but is NOT a part of it */
	BYTE	(7)"*","*"," "," "
STARS:	BYTE	(7) 15,12,15,12,40
	BYTE	(7) 40,40,40,40,40
	BYTE	(7) 40,40,40,40,40
	BYTE	(7) 40,"*","*","*","*"
	ASCII	/******************************/
	BYTE	(7) "*","*",15,12,15
	BYTE	(7) 12,40,40,40,40
	BYTE	(7) 40,40,40,40,40
	BYTE	(7) 40,40,40,0
>
	XLIST
	TEXT1
	LIT
	LIST		;DUMP THE LITERALS (IN THE HISEG, FOR TOPS-10)
IFN TOPS10,<
	RELOC	0	;*** LOWSEG STARTS HERE ***
>
;SOFTWARE INTERRUPT TABLES

IFN TOPS10,<
INTERR:	4,,GAKERR	;SAVE AND EXIT ON FATAL ERRORS
	100
	BLOCK	2
TTYBLK:	2
	SIXBIT	/TTY/
	0
BRKADR:	2037
	0
	0
CHRIN:	20
	0
TSTIN:	1
	0
PAGADR:	2021		;SET UP TTY NO PAGE
	0
	0
XOFADR:	1022		;SEE IF XOFF IS IN EFFECT
	0
	0
CRRADR:	1010		;READ SETTING OF TTY CRLF
	0
CRWADR:	2010		;SET UP TTY NO CRLF
	0
	1
>
STACK:	BLOCK	STKSIZ

;NOMINAL PARAMETERS TO COMMANDS (FROM HERE TO SAVPML ARE SAVED DURING EXECUTE)

PARAMS:
ADDSPC:	BLOCK	1	;SPACES TO ADD OR DELETE (OPENSP, CLOSSP)
ADDSLN:	BLOCK	1	;NUMBER OF LINES TO DO A RECTANGULAR OPEN/CLOSE ON
ADDLNS:	BLOCK	1	;LINES TO ADD OR DELETE (OPENLN, CLOSLN)
ADDLSP:	BLOCK	1	;SPACES TO ADD OR DELETE ALONG WITH LINES
ROLLIN:	BLOCK	1	;LINES TO ROLL (ROLFWL, ROLBKL)
ROLPGS:	BLOCK	1	;PAGES TO ROLL (ROLFWP, ROLBKP)
GOPERC:	BLOCK	1	;PERCENT TO GO TO (PERCEN)
SRCKEY:	BLOCK	10	;SEARCH KEY (SRCFWD, SRCBAK)
PICKLN:	BLOCK	1	;NUMBER OF LINES TO PICK (PICK)
PICKSP:	BLOCK	1	;NUMBER OF SPACES TO PICK (PICK, WITH CURSOR MOVE)
SLIDES:	BLOCK	1	;LENGTH OF ONE SLIDE (SLIDEL, SLIDER)
CASSPS:	BLOCK	1	;SPACES TO CHANGE THE CASE OF (CHGCAS)
CASLNS:	BLOCK	1	;DITTO, LINES (CHGCAS)

;SWITCH FLAG WORDS (THE ???FLG ARE ALSO SAVED)

SLDFLG:	BLOCK	1	;0 == DISABLE ^L AND ^U
UPPFLG:	BLOCK	1	;0 == CONVERT ALPHABETICS TO UPPER CASE
BAKFLG:	BLOCK	1	;0 == NO BACKUP FILE WILL BE WRITTEN
PAGFLG:	BLOCK	1	;0 == SWITCH OUTPUTS PAGES-LINES; ELSE LINES
INSTBS:	BLOCK	1	;0 == MAKSPC INSERTS TABS IF IT CAN, ELSE ALL SPACES
INVFLG:	BLOCK	1	;0 == CHGCAS INVERTS CASE, ELSE USE UPCFLG
UPCFLG:	BLOCK	1	;0 == CHGCAS CONVERTS TO UPPER CASE; ELSE LOWER
STRFLG:	BLOCK	1	;0 == ERROR ON SOS LINE NUMBERS; ELSE STRIP THEM
XSHFLG:	BLOCK	1	;0 == SUPPRESS EXECUTE DISPLAY; ELSE SHOW IT
APPFLG:	BLOCK	1	;-1 == APPEND TO THE PICK BUFFER ON A PICK
SAVPML=.-PARAMS
			;THESE ARE NOT SAVED:
DSPFLG:	BLOCK	1	;0 == DISPLAY THE FILE WHEN SETTING TO IT
AGNFLG:	BLOCK	1	;-1 == SETFIL TO SAME FILE AGAIN
CRRFLG:	BLOCK	1	;-1 == SETFIL SHOULD REPLACE CURRENT, NOT OLD, FILE
CREFLG:	BLOCK	1	;-1 == SETFIL: ALWAYS CREATE FILE IF IT'S NOT FOUND

SAVPRM:	BLOCK	SAVPML	;PARMS & FLAGS SAVED DURING EXECUTE (SEE BELOW)
SAVFGS:	BLOCK	1	;SAVED LH OF TM ,, RH OF F

ADDLNX:	BLOCK	1	;FRAGGABLE ADDLNS AND ADDLSP (FOR CLOSLN, MARK)
ADDLSX:	BLOCK	1
TRMNAM:	BLOCK	1	;NAME OF TERMINAL GIVEN BY USER
SROKEY:	BLOCK	10	;PREVIOUS SEARCH KEY (SRCFWD, SRCBAK, RECALL)
ROLLS:	BLOCK	1	;HOLDS ROLLIN OR LPP*ROLPGS, FOR ROLBK & ROLFW
SRCPTR:	BLOCK	1	;SAVED BUFFER POINTER FOR SEARCHES
GOPRCT:	BLOCK	1	;PERCENT GOTO SET UP BY SWITCH
ADDSPS:	BLOCK	1	;FRAGGABLE SPACES TO INS/DEL (OPENSP, CLOSSP)
CASLIN:	BLOCK	1	;FRAGGABLE LINES TO CHANGE THE CASE OF (CHGCAS)
XCTNUM:	BLOCK	1	;CURRENT # OF TIMES TO ITERATE EXECUTE BUFFER (EXECUT)
XCTITR:	BLOCK	1	;NOMINAL # OF TIMES TO ITERATE EXECUTE BUFFER (EXECUT)
XCTPTW:	BLOCK	1	;USED ACTIVE EXECUTE BUFFER POINTER (WRITING)
XCTACW:	BLOCK	1	;STARTING ACTIVE EXECUTE BUFFER POINTER (WRITING)
XCTPTR:	BLOCK	1	;USED ACTIVE EXECUTE BUFFER POINTER (READING)
XCTACR:	BLOCK	1	;STARTING ACTIVE EXECUTE BUFFER POINTER (READING)
XCTISV:	BLOCK	1	;SAVED # OF ITERATIONS (EXECUT, STACKED)
XCTNSV:	BLOCK	1	;SAVED NOMINAL ITERATIONS (EXECUT, STACKED)
XCTPSV:	BLOCK	1	;SAVED EXECUTE BUFFER READ POINTER
XCTASV:	BLOCK	1	;SAVED STARTING EXECUTE BUFFER READ POINTER
XCTRPT:	BLOCK	1	;NUMBER OF TIMES TO REPEAT THIS EXECUTE COMMAND
XCTRPR:	BLOCK	1	;POINTER TO COMMAND TO REPEAT
XCTINI:	BLOCK	1	;XCTACR SAVED DURING INITIALIZATION
XCTLVL:	BLOCK	1	;LEVEL OF NESTING OF EXECUTE BLOCKS
XCTCTR:	BLOCK	1	;EXECUTE COUNTER
XCTSNM:	BLOCK	1	;VALUE TO SAVE IN EXECUTE COUNTER ON ^SC CONSTRUCT
WINDIS:	BLOCK	1	;FLAG -1 == BOTTOM WINDOW HAS A FILE
SUBCNT:	BLOCK	1	;NUMBER OF TIMES TO SUBSTITUTE
SUBNUM:	BLOCK	1	;NUMBER OF TIMES TO SUBSTITUTE, DECREMENTABLE
SRCKLN:	BLOCK	1	;LENGTH OF SEARCH KEY
SUBSLN:	BLOCK	1	;LENGTH OF SUBSTITUTE STRING
SUBSTG:	BLOCK	10	;SUBSTITUTE STRING
PRERW:	BLOCK	1	;PRE-SET ROW AND COLUMN
PRESL:	BLOCK	1	;PRE-SET SLIDE
PREDP:	BLOCK	1	;PRE-SET DISPLAY POINTER
PREONE:	BLOCK	1	;PRE-SET ONE-SHOT POINTER

NEWMSG:	ASCII	/; This file is /	;THIS IS 3 WORDS LONG
IFE TOPS10,<
FILSPC:	BLOCK	14	;FILE SPECS (SETFIL)
BAKSPC:	BLOCK	14	;BACKUP FILE SPECS
FILBSZ:	BLOCK	1	;SIZE OF FILE, IN BLOCKS
>
IFN TOPS10,<
FILSPC:	BLOCK	13	;FILE SPECS (SETFIL)
	BYTE (7) 15,12
IFN FTSFD,<
FILPTH:	-2		;PATH OF CURRENT FILE
	0
	BLOCK	1
	BLOCK	SFDLVL+1
>
FILBLK:	BLOCK	3
FILFIL:	LUKLEN		;EXTENDED LOOKUP BLOCK FOR CURRENT FILE
	BLOCK	LUKLEN	;(PPN, NAME, EXT, PROT, SIZE, ... DEVICE
>
FILSIZ:	BLOCK	1	;SIZE OF FILE, IN BYTES
INJFN:	BLOCK	1	;JFN FOR THE FILE ON INPUT
OLDSPC:	BLOCK	14	;OLD FILE SPECS, FROM LAST SETFIL
IFN TOPS10,<
IFN FTSFD,<
OLDPTH:	-2		;PATH OF DITTO
	BLOCK	SFDLVL+3
>
OLDBLK:	BLOCK	3	;OPEN BLOCK FOR ALTERNATE FILE
OLDFIL:	LUKLEN		;EXTENDED LOOKUP BLOCK FOR DITTO
	BLOCK	LUKLEN
>
SAVERW:	BLOCK	1	;OLD ROW AND COLUMN ACS
SAVEDP:	BLOCK	1	;OLD DISPLAY POINTER
SAVESL:	BLOCK	1	;OLD SLIDE OFFSET
SAVEFG:	BLOCK	1	;OLD FLAG WORD
IFN TOPS10,<
SVASPC:	BLOCK	13	;SAVED ALTERNATE FILE SPECS
	BYTE (7) 15,12
IFN FTSFD,<
SVAPTH:	-2
	BLOCK	SFDLVL+3
>
	BLOCK	3
	LUKLEN
	BLOCK	LUKLEN
>
IFE TOPS10,<
SVASPC:	BLOCK	SPCSIZ+3 ;SAVED ALTERNATE FILE INFO, IN CASE OF /RCUR
>
	BLOCK	4	;SAVED POINTERS
NEWSPC:	BLOCK	10	;NEW FILESPEC - UNPARSED FROM /OUT: SWITCH
OUTFLG:	BLOCK	1	;-1==MUST PARSE NEWSPC INTO FILSPC; 1==PARSE IN PROGRESS
CHGSPC:	BLOCK	1	;-1==FILSPECS HAVE CHANGED (BY /O: SWITCH)

IFN TOPS10,<
GOBLK:	SIXBIT	/SYS/	;RUN BLOCK FOR EXIT AND GO
	SIXBIT	/COMPIL/
	EXP	0,0,0,0
IFN FTSFD,<
DEFPTH:	-1		;RUNNER'S STARTING PATH
	BLOCK	SFDLVL+3
>
FILPPN:	BLOCK	1	;USER'S FILE'S PPN
USRPPN:	BLOCK	1	;PPN OF RUNNER OF EDITOR
GENBLK:	16		;GENERAL OPEN BLOCK
	SIXBIT	/DSK/
	0
FILCCL:	IOWD	0,BUFFER	;CHANNEL COMMAND FOR INPUTTING EDITABLE FILE
	0
PIKFIL:	SIXBIT	/000PIK/	;FILE BLOCK FOR PICK FILE
	SIXBIT	/TMP/
	EXP	0,0
PIKCCL:	IOWD	PCBSIZ,PIKBUF	;CHANNEL COMMAND FOR PICK BUFFER
	0
PKACCL:	IOWD	200,PIKBUF	;DITTO FOR APPENDING TO THE PICK BUFFER
	0
CLSFIL:	SIXBIT	/000CLS/	;FILE BLOCK FOR CLOSE FILE
	SIXBIT	/TMP/
	EXP	0,0
CLSCCL:	IOWD	PCBSIZ,CLSBUF	;CHANNEL COMMAND FOR CLOSE BUFFER
	0
SEDFIL:	SIXBIT	/000SED/	;FILE BLOCK FOR STATISTICS FILE
	SIXBIT	/TMP/
	EXP	0,0
SEDCCL:	IOWD	1,PIKBUF+PCBSIZ-400
	0			;CHANNEL COMMAND FOR STATISTICS FILE
IFN FTTMPC,<
TMPBLK:	XWD	'SED',0		;TMPCOR BLOCK
	IOWD	30,PIKBUF+PCBSIZ-400
>
DELFIL:	BLOCK	4		;FILE BLOCK FOR DELETING
BAKFIL:	BLOCK	4		;FILE BLOCK FOR RENAMING BACKUP FILE
PRTFIL:	BLOCK	4		;FILE BLOCK FOR LOWERING FILE PROTECTION
NEWCCL:	IOWD	13,NEWMSG	;CHANNEL COMMAND FOR NEW FILE
	0
PUTCCL:	BLOCK	2		;CHANNEL COMMAND FOR PICK OR CLOSE BUFFER
SWHFIL:	SIXBIT	/SWITCH/	;FILE BLOCK FOR SWITCH.INI
	SIXBIT	/INI/
	EXP	0,0
INIFIL:	SIXBIT	/SED/		;FILE BLOCK FOR SED.INI
	SIXBIT	/INI/
	EXP	0,0
EXTTBL:	SIXBIT	/   MAC/	;EXTENSIONS TO BE TRIED IN SETFIL
	SIXBIT	/TXTRNO/
	SIXBIT	/FORCBL/
	SIXBIT	/DAT   /
	SIXBIT	/      /
	SIXBIT	/      /	;(RH OF LAST WORD MUST BE ZERO)
REDACC:	5,,0			;CHKACC BLOCKS FOR READING
	BLOCK	2
WRTACC:	2,,0			;  AND WRITING
	BLOCK	2
HLPFIL:	SIXBIT	/SEDONL/	;FILE BLOCK FOR ON-LINE HELP FILE
	SIXBIT	/HLP/
	EXP	0,0
HLPCCL:	IOWD	200,PIKBUF+PCBSIZ-200 ;CHANNEL COMMAND FOR HELP FILE
	0
> ;END IFN TOPS10
EEEPTR:	BLOCK	1	;POINTER INTO EXTENSION TABLE
INIFLG:	BLOCK	1	;-1==SED.INIT FOUND, 0==SWITCH.INI FOUND

IFE TOPS10,<
ITTFLG:	BLOCK	1	;FLAG: -1 == MONITOR CHAR. TRAPPING IS OFF
NEWJFN:	BLOCK	1	;JFN OF NEW FILE BEING SET-FILED TO
GOBLK:	1		;ARGUMENT TO PASS TO EXEC TO DO EXIT AND GO
	4B2+17B12+2	;(MAY GET OVERWRITTEN WITH A PROGRAM NAME)
	0
	BLOCK	10
EXTPTR:	BLOCK	1	;POINTER TO WHERE TO FILE EXT SHOULD BE
EXTTBL:	0		;EXTENSIONS TO BE TRIED IN SETFIL
	ASCII	/MAC/	;(FIRST WORD: EXT OF PREVIOUS FILE)
	ASCII	/TXT/
	ASCII	/RNO/
	ASCII	/FOR/
	ASCII	/CBL/
	ASCII	/DAT/
	BLOCK	5
SAVEXP:	BLOCK	2	;EXTPTR AND EXTTBL OF OLD FILE
PIKFIL:	ASCIZ	/000PIK.TMP/
CLSFIL:	ASCIZ	/000CLS.TMP/
SEDFIL:	ASCIZ	/000SED.TMP/
	BLOCK	4
SWHFIL:	ASCIZ	/SWITCH.INI/
INIFIL:	ASCIZ	/SED.INIT/
INIJFN:	GJ%OLD		;LONG GTJFN BLOCK FOR SED.INIT
	.NULIO,,.NULIO	;NO I/O FOR NAME
	-1,,INIDEV	;POINTER TO DEVICE NAME (PS:)
	-1,,USRNAM	;POINTER TO USER NAME
	BLOCK	5
INIDEV:	ASCIZ	/PS/
USRNAM:	BLOCK	10	;USER'S NAME
HLPFIL:	ASCIZ	/HLP:SEDONL.HLP/
OUTJFN:	BLOCK	1	;JFN FOR THE FILE ON OUTPUT
EXCHDL:	BLOCK	1	;HANDLE OF EXEC FORK RUNNING UNDER SED
>
SAVSED:	BLOCK	1	;SAVED 1ST WORD OF STAT FILE NAME

;GENERAL DATA

TABLEN:	10		;LENGTH OF AN ENTIRE TAB
TABSIZ:	BLOCK	1	;LENGTH OF TAB THAT CURSOR POINTS TO
TABSPC:	BLOCK	1	;NUMBER OF SPACES TO LEFT OF CURSOR, IF IT'S IN A TAB
TABPTR:	BLOCK	1	;POINTER TO TAB, IN FILE BUFFER
TABTBL:	BLOCK	4	;TABLE OF SETTABLE TABS
COMAND:	BLOCK	1	;COMMAND SEQUENCE FROM TERMINAL
SAVEAC:	BLOCK	13	;PLACE TO SAVE ACS ON EXIT, IN CASE OF REE
SAVFLG:	BLOCK	1	;SAVED TERMINAL FLAGS
LPP.0:	BLOCK	1	;SAVED LINES PER PAGE
LPP.1:	BLOCK	1	;LINES PER PAGE - 1
LPP.2:	BLOCK	1	;NUMBER OF BOTTOM LINE (NEXT TO BOTTOM IF NEL SET)
CPL.0:	BLOCK	1	;SAVED CHARACTERS PER LINE
CPL.1:	BLOCK	1	;CHARACTERS PER LINE - 1
LMARGN:	BLOCK	1	;LEFT MARGIN FOR TYPE-IN INDENT
RMARGN:	BLOCK	1	;RIGHT MARGIN FOR TYPE-IN WRAPAROUND
LINROL:	BLOCK	1	;LINES PER ROLL
HOMPOS:	BLOCK	1	;ROW OF SCREEN WHERE HOME IS (NON-0 ONLY FOR WINDOWING)
SAVRUP:	BLOCK	1	;ROLL-UP SEQUENCE (SAVED WHILE THERE'S WINDOWING)
SAVRLD:	BLOCK	1	;DITTO ROLL-DOWN SEQUENCE
SAVILN:	BLOCK	1	;DITTO INSERT-LINE SEQUENCE
SAVDLN:	BLOCK	1	;DITTO DELETE-LINE SEQUENCE
SAVCPG:	BLOCK	1	;DITTO CLEAR-TO-EOP SEQUENCE
SAVLPP:	BLOCK	1	;DITTO NUMBER OF LINES PER PAGE
CHRCUR:	BLOCK	1	;CHARACTER AT THE CURSOR POSITION, BLIPPED
SAVPOS:	BLOCK	2	;CURSOR POSITION SAVED ON ENTER
SVPMRK:	BLOCK	2	;CURSOR POSITION SAVED WHEN MARK COMMAND IS TYPED
TYPCHR:	BLOCK	1	;CHARACTER TYPED USER DURING A DISPLAY
WRTNUM:	BLOCK	1	;NUMBER OF CHARACTERS TO NULL OUT (WRTNUL)
NUMCHR:	BLOCK	1	;NUMBER OF CHARACTERS TO DEAL WITH (MAKSPC, &C)
NUMWDS:	BLOCK	1	;NUMBER OF WORDS TO DEAL WITH (MAKSPC, &C)
NUMNUL:	BLOCK	1	;NUMBER OF EXTRA NULLS PUT IN
CHARAC:	BLOCK	1	;CHARACTER TO DEAL WITH (IN MAKSPC, &C)
MAKPTR:	BLOCK	1	;POINTER TO LAST REAL CHAR ADDED BY MAKSPC &C.
ADJWRD:	BLOCK	1	;WORD FOR MAKSPC &C TO ADJUST
SPCCNT:	BLOCK	1	;COUNT OF CHARACTERS MOVED BY SPCBUF
SQZCNT:	BLOCK	1	;COUNT OF COMMANDS REMAINING UNTIL NEXT SQUEZW
DISPPT:	BLOCK	1	;POINTER TO LAST LINE; SET BY DISPLL
MAKLNS:	BLOCK	1	;NUMBER OF <CRLF>S IN PICK OF CLOSE BUFFER
RSCANF:	BLOCK	1	;FLAG - SET IF USER GAVE A FILE IN THE RUN COMMAND
SAVCPT:	BLOCK	1	;CHRPTR SAVED WHEN ENTER IS TYPED
MRKPTR:	BLOCK	1	;MARK POINTER, FOR PICK AND CLOSE-LINES
MRLPTR:	BLOCK	1	;SAVED LINPTR FOR DITTO
MRCPTR:	BLOCK	1	;SAVED CHRPTR FOR DITTO
ISVNUM:	BLOCK	1	;NUMBER OF COMMANDS BETWEEN INCREMENTAL SAVES
SAVNUM:	BLOCK	1	;NUMBER OF TYPEIN CHARACTERS BETWEEN INC'L SAVES
ISVCNT:	BLOCK	1	;COMMAND INCREMENTAL SAVE COUNTER
SAVCNT:	BLOCK	1	;TYPEIN INCREMENTAL SAVE COUNTER
INDFLG:	BLOCK	1	;FLAG TO SEE IF INDIRECT FILE NEEDS TO BE READ AGAIN
MFLPTR:	BLOCK	1	;POINTER TO START OF NEXT FILE IN nnnSED.TMP
MFLPT0:	BLOCK	1	;DITTO, ALTERNATE FILE
MFLPT1:	BLOCK	1	;DITTO, CURRENT FILE
;MFLBLK:	BLOCK	1	;BLOCK OF nnnSED.TMP WHICH POINTER IS IN
STTFLG:	BLOCK	1	;NON-ZERO == INITIALIZING (HOLDS WID,,LEN FOR LATER)
TAGFLG:	BLOCK	1	;-1 == SAVE SPEC/DATE/USER TAG AT TOP OF FILE
IFE TOPS10,<
SAVCOC:	BLOCK	2	;SAVED CCOC WORDS		(TOPS20)
FMDSAV:	BLOCK	1	;SAVED FMOD BITS		(TOPS20)
IFN FTECHO,<
SMDSAV:	BLOCK	1	;SAVED SED'S FMOD BITS		(TOPS20)
SAVWKU:	BLOCK	5	;SAVED STARTING WAKE-UP SET	(TOPS20)
FLDWTH:	BLOCK	1	;FIELD WIDTH: MIN(CPL,RMARGN+1)	(TOPS20)
TTYJFN:	BLOCK	1	;TERMINAL'S JFN, FOR OUTPUT	(TOPS20)
EKOFLG:	BLOCK	1	;0 == ECHO ALL; -1 == ECHO NONPRINTING
BRKFLG:	BLOCK	1	;0 == BREAK ON ALL; -1 == BREAK ON NONPRINTING
>>
;VARIOUS BUFFERS

PUTPTR:	BLOCK	1	;POINTER, FOR MAKSPC, TO CLOSE OR PICK BUFFER
PTMPTR:	BLOCK	1	;COPY OF ABOVE SET UP BY MAKSPC
MAKCNT:	BLOCK	1	;COUNT OF CHARACTERS TO INSERT, FOR MAKSPC
PUTJFN:	BLOCK	1	;JFN OF PICK OR CLOSE BUFFER, FROM PUT TO MAKSPC
DELCNT:	BLOCK	1	;COUNT OF CHARACTERS IN THE DELETE BUFFER
DELBUF:	BLOCK	40	;BUFFER FOR STUFF DELETED BY ^DS, ^DW, ^DC, ^EL
PIKCNT:	BLOCK	1	;COUNT OF CHARACTERS IN THE PICK BUFFER
PIKJFN:	BLOCK	1	;JFN FOR PICK FILE ON DISK (GENERATED ON OVERFLOW)
PIKBUF:	BLOCK	PCBSIZ	;PICK BUFFER (PICK, PUT)
	BLOCK	1	;ZERO AT THE END OF PICK BUFFER
CLSCNT:	BLOCK	1	;COUNT OF CHARACTERS IN THE CLOSE BUFFER
CLSJFN:	BLOCK	1	;JFN FOR CLOSE FILE ON DISK (GENERATED ON OVERFLOW)
CLSBUF:	BLOCK	PCBSIZ	;CLOSE BUFFER (CLOSELN, PUT)
	BLOCK	1	;ZERO AT THE END OF CLOSE BUFFER

IFN TOPS10,<
TYPPTR:	010700,,TYPBUF-1 ;TYPE BUFFER POINTER FOR 7-BIT CHARACTERS
>
IFE TOPS10,<
IFN FTECHO,<
TYPPTR:	011000,,TYPBUF-1 ;TYPE BUFFER POINTER FOR 8-BIT CHARACTERS
>
IFE FTECHO,<
TYPPTR:	010700,,TYPBUF-1 ;TYPE BUFFER POINTER FOR 7-BIT CHARACTERS
>>
TYPBUF:	BLOCK	TYPSIZ	;BUFFER FOR OUTPUTTING TO TERMINAL
	BLOCK	10	;OVERFLOW FOR TYPE BUFFER

XCTKEY:	BLOCK	XBFNUM	;SEQUENCES GIVEN BY TERMINAL KEYS WHICH INVOKE BUFFERS
XCTNAM:	BLOCK	XBFNUM-1 ;EXECUTE BUFFER NAMES
	1		;NO-NAME BUFFER (MARKED IN USE)
XCTADR:	BLOCK	XBFNUM	;POINTERS TO EXECUTE BUFFERS
XCFPTR:	BLOCK	1	;POINTER TO START OF UNUSED FREE SPACE
XCTOVF:	BLOCK	1	;POINTER TO END OF EXECUTE FREE SPACE
XCTFRE:	BLOCK	XCFSIZ	;FREE SPACE FOR EXECUTE BUFFERS

IFN FTJOUR,<
JRNPTR:	BLOCK	1	;POINTER INTO JOURNAL BUFFER
JRNBIT:	BLOCK	1	;JOURNALING: -1 == DO FIRST FILE WRITE
			;RECOVERING: -1 == START JOURNALING WHEN DONE
JRNFLG:	BLOCK	1	;FLAG: RECOVER JOURNAL, THEN -1 == END OF FILE
JRNENP:	BLOCK	1	;POINTER TO END OF JOURNAL BUFFER
IFN TOPS10,<
JOURNL:	BLOCK	201	;TOPS-10 BUFFER == 1 DISK BLOCK (PLUS WORD OF SLACK)
JRNDSK:	BLOCK	1	;NUMBER-1 OF LATEST DISK BLOCK OF JOURNAL
JRNCCL:	IOWD	200,JOURNL
	0		;CHANNEL COMMAND FOR JOURNAL FILE I/O
JRNLKB:	SIXBIT	/SEDJRN/
	SIXBIT	/TMP/
	EXP	0,0
JRNFIL:	11,,0		;(CHANNEL 11)
	.IODMP		;DUMP MODE
	SIXBIT	/DSK/	;DEVICE
	0		;BUFFER HEADER ADDRESS (NONE)
	0		;NUMBER OF BUFFERS (NONE)
	JRNLKB		;ADDRESS OF LOOKUP BLOCK
>
IFE TOPS10,<
JOURNL:	BLOCK	JRNSIZ+1
JRNFIL:	ASCIZ	/SEDJRN.TMP/
JRNJFN:	BLOCK	1	;JFN FOR THE JOURNAL FILE
>>
LINPTR:	BLOCK	1	;POINTER TO START OF LINE
CHRPTR:	BLOCK	1	;POINTER TO CHARACTER AT CURSOR
DISPTR:	BLOCK	1	;POINTER TO FIRST CHARACTER DISPLAYED
BOTPTR:	BLOCK	1	;POINTER TO START OF LAST LINE OF SCREEN

PARPTR:	BLOCK	1	;POINTER INTO PARAMETER BUFFER
PARG1:	BLOCK	1	;STORAGE AREAS FOR CONVERTED PARAMETERS
PARG2:	BLOCK	1
PARBUF:	BLOCK	PARBLN+1 ;PARAMETER BUFFER

;*** NOTE: FOR TOPS-20, PARBUF MUST BE THE LAST ITEM BEFORE BUFFER ***

IFN TOPS10,<
	6424		;PRECEDE BUFFER WITH A NONZERO, NON-ODD WORD
BUFFER:
>
IFE TOPS10,<
BUFBLK==27		;START BUFFER IN NEXT BLOCK
BUFFER==BUFBLK_11
	LOC	BUFFER-1
	6424		;PRECEDE BUFFER WITH A NONZERO, NON-ODD WORD
>
DEFINE TEXT2,<
ASCIZ	/**************************************************************************

     Hi!  This is SED, the full screen editor.	It is easier and  more
natural to use than line or character editors, and is generally faster
too.  To  use  it, just  type.  You can move the cursor (which is that
blinking mark in the upper left corner) to other parts of the  screen.
To change existing text, just type over it.

     There  are  also  commands  to the editor.  They move the viewing
window around, insert or delete lines or spaces,  move text  from  one
place to another, search, and other useful things.

     For a summary of the editor commands see the file HLP:SED.HLP.
     For a tutorial manual see the file                DOC:SED.MAN.
     For complete editor documentation see the file    DOC:SED.DOC.

You  can  also get on-line help. Type "3" on the keypad and then any
command to get a description of that command.

To exit from SED type CTRL-Z.





/
	0
>
	XLIST
	TEXT2
	LIST	;OUTPUT TEXT2 (SAVING LISTING PAPER)
BUFFEN==.
IFN FTDDT,<
.TEXT ?/SYMSEG:HIGH?
>
IFN TOPS10,<END	START>
IFE TOPS10,<END	<ENTLEN,,ENTVEC>>

;EXPENDABLE STUFF AT THE END