Google
 

Trailing-Edge - PDP-10 Archives - steco_19840320_1er_E35 - 7,3/sed/sed1mv.mac
There are 10 other files named sed1mv.mac in the archive. Click here to see a list.
TITLE	SED1MV - GENERAL SED NON-FILE-MODIFYING COMMANDS
SUBTTL	A CHRISTOPHER HALL FECIT

;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979,1983.

	SEARCH	SEDSYM
	SALL

IFN TOPS10,<
	SEARCH	UUOSYM
	TWOSEG
	RELOC	400000
>
IFE TOPS10,<
	SEARCH	MONSYM
>

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

ILLCMD::PUSHJ	P,RESTPM	;CLEAR UP THE PARAMETER STUFF ON THE SCREEN
ICMNPM::JRST	ILCER2		;SAY 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
	SKIPE	RLCFLG		;YES - WANT TO ROLL OR WRAP AROUND?
	AOJA	RW,DWNROL	;ROLL - GO DO IT
	SETZ	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
	TLO	F,XPL!XPC	;LINE POINTER IS NO LONGER GOOD
	SOJGE	RW,AJDON0	;MOVE UP - OFF THE TOP?
	JRST	UPWRAP		;YES - ALWAYS WRAP AROUND

UPARG::	TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
UP::	TLO	F,XPL!XPC	;LINE POINTER IS NO LONGER GOOD
	SOJGE	RW,AJDONE	;MOVE UP - OFF THE TOP?
	SKIPE	RLCFLG		;YES - WANT TO ROLL OR WRAP AROUND?
	JRST	UPROLL		;ROLL - GO DO IT
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	AJDON2		;NO - NO OUTPUT, THEN
	PUSHJ	P,@CMVTBL-34(DO) ;YES - MOVE THE CURSOR THE RIGHT WAY
AJDON1:	PUSHJ	P,PUTTYP
AJDON2:	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

;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
	CAIGE	T2,0		;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
	MOVE	T4,LMARGN	;INSERT A CRLF PLUS ENOUGH SPACES
	ADDI	T4,2		;  TO GET TO THE LEGT MARGIN
	MOVEM	T4,NUMCHR
	PUSHJ	P,MAKSPC
	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		;PUT IT OVER THE FIRST SPACE
	MOVEI	T1,12		;GET A LINEFEED
	IDPB	T1,PT		;PUT IT NEXT TO THE CR
	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,		;  OF THE NEXT LINE
	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 **NOTE: MAY NOT RETURN**
	PUSHJ	P,DISONE	;RE-WRITE LINE
	PUSHJ	P,FIXBLW	;PUT MESSAGES, IF ANY, ON THE BOTTOM LINE
	JRST	DISCUR		;POSITION CURSOR, OUTPUT, AND LOOP

;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
DWNROL:	TLNE	F,ENT		;NO - ENTERING A PARAMETER?
	SOJA	RW,LOOP		;YES -  DO NOTHING
	MOVEI	T4,1		;NO - SET TO ROLL ONE LINE
	JRST	RFLNP1		;DO THE ROLL AND LOOP

;HERE WHEN RLCFLG IS ON, THE CURSOR WAS ON THE TOP LINE, AND CURSOR-UP
;WAS TYPED. ROLL THE SCREEN DOWN A LINE

UPROLL:	MOVE	T1,DISPTR	;NO - ALREADY AT THE TOP OF THE FILE?
	CAMN	T1,[010700,,BUFFER-1]
	AOJA	RW,LOOP		;YES - DO NOTHING
	TLNE	F,ENT		;NO - ENTERING A PARAMETER?
	JRST	LOOP		;YES - DO NOTHING
	MOVEI	T4,1		;NO - SET TO ROLL ONE LINE
	JRST	RBLNPM		;DO THE ROLL AND LOOP

;**********************************************************************
;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
;NOTE: THE SEARCH CAN'T GO PAST THE END OF THE FILE BECAUSE THE FILE IS
;      GUARANTEED TO END WITH A CRLF

ELIARG::TRON	F,CMV		;ALREADY DOING CURSOR MOVEMENT?
	PUSHJ	P,MARKUP	;NO - PUT CURSOR BACK IN TEXT
ELINE::	TLZE	F,XPL		;IS THE LINE POINTER GOOD?
	PUSHJ	P,MAKLPT	;NO - RE-MAKE IT
	MOVE	PT,LINPTR	;GET THAT POINTER
	SETZ	CM,		;START AT COLUMN ZERO
	TLZ	F,XPC		;SAY CURSOR POINTER WILL BE GOOD, TOO
	MOVE	T4,CPL.1	;GET POSITION OF RIGHT SIDE OF THE SCREEN
	ADD	T4,SL

ELINE1:	MOVE	T2,PT		;SAVE POINTER BEFORE THE CHARACTER
	MOVE	T3,CM		;AND THE CORRESPONDING COLUMN POSITION
ELINE2:	CAML	CM,T4		;AT THE RIGHT OF THE SCREEN?
	JRST	ELIEE1		;YES - THAT'S AS FAR AS THE CURSOR CAN GO
	ILDB	T1,PT		;GET A CHARACTER
ELINE3:	JUMPE	T1,ELINE2	;SKIP NULLS
	CAIN	T1,15		;CARRIAGE RETURN?
	JRST	ELINEE		;YES - CHECK FOR CRLF
	CAIN	T1," "		;SPACE?
	AOJA	CM,ELINE2	;YES - COUNT IT BUT DON'T SAVE POSITION
	CAIE	T1,11		;TAB?
	AOJA	CM,ELINE1	;NO - COUNT THE CHARACTER AND LOOP
	ORI	CM,7		;YES - COUNT ITS LENGTH
	AOJA	CM,ELINE2	;COUNT IT BUT DON'T SAVE POSITION

ELINEE:	MOVE	T0,PT		;GOT A CR - GET A FRAGGABLE POINTER
	ILDB	T1,T0		;GET (MAYBE) THE LF
	CAIE	T1,12		;IS IT A LINEFEED?
	AOJA	CM,ELINE1	;NO - COUNT THE CR; BACK TO THE FLOW
	MOVEM	T2,CHRPTR	;YES - SAVE THE POINTER TO THE EOL
	MOVE	CM,T3		;AND THE COLUMN POSITION
	SUB	CM,SL		;  ADJUSTED FOR SLIDE
	JRST	DISCUR		;DISPLAY THE CURSOR AND LOOP

ELIEE1:	MOVEM	PT,CHRPTR	;YES - SAVE THE POINTER TO THE EOL
	SUB	CM,SL		;ADJUST COLUMN POSITION FOR SLIDE
	JRST	DISCUR		;DISPLAY THE CURSOR 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:	CAMLE	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?
	CAIA			;NO - CONTINUE
	JRST	WTABT		;YES - DO A NORMAL TAB AFTER END OF LINE
	CAIN	T1,11		;TAB?
	JRST	WTABS1		;YES - CHECK FOR TRAILING SPACES
	SKIPE	DELIM		;GOT ANY EXTRA DELIMITERS?
	PUSHJ	P,ISDELM	;YES - SEE IF THERE'S A MATCH
	  CAIN	T1," "		;SPACE?
	AOJA	CM,WTABS	;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
	SKIPE	DELIM		;GOT ANY EXTRA DELIMITERS?
	PUSHJ	P,ISDELM	;YES - SEE IF THERE'S A MATCH
	  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
	SKIPE	DELIM		;GOT ANY ADDITIONAL DELIMITERS?
	PUSHJ	P,ISDELM	;YES - CHECK FOR THEM (SKIP IF MATCH)
	  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
	SKIPE	DELIM		;GOT ANY ADDITIONAL DELIMITERS?
	PUSHJ	P,ISDELM	;YES - CHECK FOR THEM (SKIP IF MATCH)
	  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:	TRO	CM,7		;GOT A TAB - TAB OVER
	AOJA	CM,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

;SUBROUTINE TO CHECK THE CHARACTER IN T1 AGAINST THE LIST IN DELIM
;RETURNS +1 IF NO MATCH, +2 IF A CHARACTER IN THE LIST MATCHES

ISDELM:	DMOVEM	T1,SAVEAC+1	;SAVE THE FRAGGED ACS (T1, T2)
	IDIVI	T1,^D9		;GET WORD AND POSITION IN WORD
	LDB	T0,CHRTAB(T2)	;READ THE RIGHT FLAGS BYTE
	DMOVE	T1,SAVEAC+1	;RESTORE THE FRAGGED ACS
	TRNE	T0,1		;IS THIS A DELIMITER CHARACTER?
	AOS	(P)		;YES - GIVE A SKIP RETURN
	POPJ	P,

;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
TABT1A:	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,TABT1A	;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
	CAMLE	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	BTBG1A		;NO - KEEP CHECKING
	CAIG	T1,"9"
	JRST	BTBAG2		;YES - PHASE TWO
BTBG1A:	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	BTBG2A		;NO - KEEP CHECKING
	CAIG	T1,"9"
	AOJA	T3,BTBAG2	;YES - SKIP OVER IT
BTBG2A:	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
	CAIGE	T2,0
	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	BAKTB2		;  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
BAKTB2:	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	WBTBS1		;START WITH CHARACTER AT CURSOR

WBTABS:	ADD	PT,[70000,,0]	;SKIP SPACES AFTER WORD
	CAIGE	PT,0
	SUB	PT,[430000,,1]
WBTBS1:	LDB	T1,PT		;GET IT
	JUMPE	T1,WBTABS	;IGNORE IF NULL
	SKIPE	DELIM		;GOT ANY EXTRA DELIMITERS
	PUSHJ	P,ISDELM	;YES - SEE IF THERE'S A MATCH
	CAIN	T1," "		;SPACE?
	JRST	WBTABS		;YES - SKIP UNTIL NOT ONE OF THOSE
	CAIN	T1,11		;TAB?
	JRST	WBTABS		;YES - SKIP THAT, TOO
	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
	CAIGE	PT,0
	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
	SKIPE	DELIM		;GOT ANY EXTRA DELIMITERS
	PUSHJ	P,ISDELM	;YES - SEE IF THERE'S A MATCH
	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
	CAIGE	PT,0
	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
	CAIGE	T4,0
	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
	CAIGE	T4,0
	SUB	T4,[430000,,1]
WBTBB2:	LDB	T1,T4		;GET PREVIOUS CHARACTER
	JUMPE	T1,WBTBB1	;SKIP NULLS (AND MAYBE LINEFEED)
WBTBB3:	CAIE	T1," "		;TRAILING SPACE
	CAIN	T1,11		;  OR TAB?
	JRST	WBTBB1		;YES - SKIP IT
	SKIPE	DELIM		;GOT ANY EXTRA DELIMITERS
	PUSHJ	P,ISDELM	;YES - SEE IF THERE'S A MATCH
	CAIN	T1,15		;CARRIAGE RETURN?
	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
	CAMGE	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
BTBTB0:	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,BTBTB0

;**********************************************************************
;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
  	ANDI	T1,137		;FORCE IT TO UPPER CASE
	CAIN	T1,"C"		;SOME TYPE OF "C"?
	JRST	TBCLRC		;YES - CLEAR ALL TAB SETTINGS
	CAIN	T1,"D"		;SOME TYPE OF "D"?
	JRST	TBCLRD		;YES - DISPLAY THE SETTINGS AND A RULER
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
	MOVEI	T0,"/"		;GET THE LEFT-MARGIN-MARKING CHARACTER
	MOVE	PT,LMARGN	;ADD THE LEFT-MARGIN SETTING
	SETZ	T3,		;START THE COUNT AT ZERO

TBCRD0:	HRLI	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
	CAIN	PT,(T3)		;AT THE LEFT OR RIGHT MARGIN?
	JRST	TBCRDL		;YES - MARK THIS POSITION
	TRNE	T2,1		;IS THERE A TAB THERE?
	JRST	TBCRDM		;YES - MARK THIS POSITION
	IBP	SAVEAC		;ELSE SKIP OVER THAT SPACE IN THE RULER
TBCRD2:	AOBJN	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

TBCRDM:	IDPB	T1,SAVEAC	;SAY THERE'S A TAB IN THAT SPACE
	JRST	TBCRD2		;CONTINUE

TBCRDL:	IDPB	T0,SAVEAC	;MARK THE LEFT OR RIGHT MARGIN
	MOVEI	T0,"\"		;GET THE RIGHT-MARGIN-MARKING CHARACTER
	MOVE	PT,RMARGN	;AND THE RIGHT-MARGIN SETTING
	JRST	TBCRD2		;CONTINUE

;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 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
	CAIE	T1,0		;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::PUSHJ	P,PUSMKS	;PUSH DISPLAY POINTER ON THE MARKER STACK
	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
	CAIGE	T2,0
	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
	  AOSA	RW,		;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
	JUMPE	DO,NEWFL0	;IF /GO SWITCH, FINISH THE SETTING-UP
	JRST	DISALL		;ELSE RE-DISPLAY THE SCREEN AND LOOP

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

;**********************************************************************
;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,^D24		;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 THE HOLE

	PUSH	P,RW		;SAVE CURRENT POSITION
	PUSH	P,CM
	MOVE	PT,LPP.1	;GET NUMBER OF LINES ON THE SCREEN, LESS BOTTOM
	MOVE	CM,CPL(TM)	;AND NUMBER OF CHARS THAT CAN STAY AROUND
	SUB	CM,T4
	SETZ	RW,
	PUSHJ	P,POSCUR	;POSITION THE CURSOR
	CAIA			;AND SKIP

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

	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
	PUSHJ	P,CHOME		;MOVE THE CURSOR HOME
	PUSHJ	P,IMODON	;TURN ON INSERT MODE
	TLZ	TM,WRP!TBS
	MOVE	T4,LPP.1	;GET SCREEN SIZE, MINUS THE BOTTOM LINE
	PUSHJ	P,DISPS0	;DO THE DISPLAY
	POP	P,TM
	POP	P,CPL(TM)	;RESTORE THE LINE SIZE
	PUSHJ	P,IMODOF	;TURN OFF INSERT MODE
	MOVE	T1,SLIDNM
	TRNE	F,RST		;WANT TO RESTORE THE NOMINAL PARAMETER?
	MOVEM	T1,SLIDES	;YES - SET IT BACK TO THE DEFAULT
	PUSHJ	P,FIXBLF	;MAKE SURE THE BOTTOM LINE IS O.K.
	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:	MOVE	T1,SLIDNM
	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 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::SKIPE	T4,ROLPGS	;SET UP LAST TIME'S ROLL AS NOMINAL - ANY?
	PUSHJ	P,PUSMKS	;YES - PUSH THE DISPLAY PTR ON THE MARKER STACK
	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::SKIPE	T4,ROLPGS	;SET UP LAST TIME'S ROLL AS NOMINAL - ANY?
	PUSHJ	P,PUSMKS	;YES - PUSH THE DISPLAY PTR ON THE MARKER STACK
	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
RFLNP1:	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,FIXBLW ;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
	PUSHJ	P,ROLBK		;DO THE ACTUAL WORK
	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)

;SUBROUTINE TO ROLL BACKWARDS (CALLED BY ROLBKL AND ROLBKP)

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	ROLBK2		;NO - O.K.
	SETZB	RW,CM		;YES - PUT IT AT UPPER LEFT
	TLZ	F,FBL		;BOTTOM LINE IS ALL RIGHT
ROLBK2:	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	ROLBK3		;EITHER - JUST REWRITE THE SCREEN

	PUSHJ	P,CHOME		;NEITHER - HOME THE CURSOR
	PUSHJ	P,ROLLDN	;ROLL AND CLEAR A LINE
	SOJG	T4,.-1		;LOOP THROUGH ALL LINES TO ROLL

	MOVE	PT,DISPTR	;POINT TO DESIRED POSITION IN BUFFER
	MOVE	T4,ROLLS	;GET NUMBER OF LINES TO REWRITE
	PUSHJ	P,DISPLY	;REWRITE THEM
	PUSHJ	P,FIXBLW	;DISPLAY FENCE OR INSERT MODE MESSAGE
	JRST	POSCUR		;RE-POSITION THE CURSOR AND RETURN

ROLBK3:	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
	JRST	RESNP1 		;AND JOIN THE FLOW

RESNPM::TLZE	F,FBL		;IS THE BOTTOM LINE FRAGGED?
	PUSHJ	P,FIXBLN	;YES - REPAIR IT
RESNP1:	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 ON ENTER-REWRITE - RE-WRITE THE SCREEN WITH THE LINE THE CURSOR
;IS ON AT THE CENTER OF THE SCREEN
;(REWRITE, WITHOUT THE ENTER, JUMPS TO DISALL)

RWRARG::PUSHJ	P,RESTPM	;CLEAR THE PARAMETER QUICKLY
	MOVE	T4,LPP(TM)	;GET THE NUMBER OF LINES ON THE SCREEN
	LSH	T4,-1		;DIVIDE IT BY TWO
	EXCH	T4,RW		;THE CURSOR WILL NOW BE IN THE CENTER ROW
	SUB	T4,RW		;FIND DIFFERENCE BETWEEN CENTER AND CURSOR
	JUMPG	T4,RWRTDN	;JUMP IF THE CURSOR IS BELOW THE CENTER
	JUMPE	T4,DISALL	;JUMP IF THE CURSOR IS ALREADY AT THE CENTER
	MOVN	T4,T4		;ELSE GET NUMBER OF LINES TO BACK UP
	PUSHJ	P,BAKDPT	;BACK UP THE DISPLAY POINTER
	SUB	RW,T4		;ADJUST ROW IN CASE START OF FILE WAS REACHED
	JRST	DISALL		;RE-WRITE THE SCREEN AND LOOP

RWRTDN:	PUSHJ	P,ADVDPT	;ADVANCE THE DISPLAY POINTER
	JRST	DISALL		;RE-WRITE THE SCREEN AND LOOP

;**********************************************************************
;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
	CAIGE	T1,0
	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 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
	JUMPE	T3,SRCBK3	;ERROR IF NOTHING TO SEARCH FOR
	CAIE	T3,12		;ELSE DOES THE KEY START WITH A LINEFEED?
	JRST	SRCBK3		;NO - JUMP INTO THE LOOP
	CAMN	PT,[010700,,BUFFER-1] ;YES - AT START OF FILE YET?
	JRST	SRCERR		;YES - NOT-FOUND ERROR
	LDB	T1,PT		;GET THE FIRST FILE CHARACTER
	CAIE	T1,12		;IS IT A LINEFEED?
	JRST	SRCBK3		;NO - PROCEED

SRCBK1:	ADD	PT,[70000,,0]	;BACK FILE POINTER UP A NOTCH
	CAIGE	PT,0
	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	;DOES THE USER WANT TO INTERRUPT?
	  JRST	SABERR		;YES - STOP THE SEARCH
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

;SUBROUTINE TO SEE IF THE USER HAS TYPED A RUBOUT.
;RETURNS +1 IF SO, ELSE +2

SRCIPT::GOTINP			;SKIP IF USER TYPED SOMETHING
	  JRST	SRCIP1		;NO - SKIP RETURN
	GETCHR			;YES - READ THE CHARACTER INTO T1
	CAIE	T1,177		;IS IT A RUBOUT?
SRCIP1:	AOS	(P)		;NO - GIVE SKIP RETURN
	POPJ	P,		;YES - GIVE +1 RETURN

;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	;DOES THE USER WANT TO INTERRUPT?
	  JRST	SABERR		;YES - STOP THE SEARCH
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
	CAIGE	PT,0
	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,PUSMKS	;NO - PUSH THE DISPLAY PTR ON THE MARKER STACK
	PUSHJ	P,SRCSET	;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
	CAIGE	PT,0
	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,

SABERR:	SKIPA	T1,[[ASCIZ /##########Search aborted/]]
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 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,76		;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,12	;  OR A LINEFEED?
		 MOVEI T3," "	;YES - USE A SPACE INSTEAD
		 CAIN  T3,11	;HOW EABOUT 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	ENHL2A		;YES - CONTINUE
	PUSHJ	P,SUBTAB	;NO - READ MORE CHARACTERS
	  JRST	HLPERR		;ILLEGAL - TRY AGAIN
ENHL2A:	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
	CAIN	PT,$HELP	;IS THIS THE HELP COMMAND?
	TDZA	PT,PT		;YES - FUDGE AN INDEX OF ZERO
	ADDI	PT,4		;NO - FUDGE IN AN EXTRA PAGE
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
	PUSHJ	P,CLRALL	;GO HOME AND CLEAR SCREEN
	PUSHJ	P,PUTTYP	;(NOW)
	PUSHJ	P,ENTHO1	;OUTPUT THE HELP
	JUMPE	PT,[INPUT 5,HLPCCL ;IF THE COMMAND IS HELP HELP
		    PUSHJ P,ENTHO1 ;OUTPUT THE NEXT THREE PIECES OF THE HELP
		    INPUT 5,HLPCCL
		    PUSHJ P,ENTHO1
		    INPUT 5,HLPCCL
		    PUSHJ P,ENTHO1
		    JRST  .+1]
	RELEAS	5,		;GET RID OF SEDONL.HLP
>
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

IFN TOPS10,<
;SUBROUTINE TO OUTPUT THE HELP TEXT

ENTHO1:
IFE FTNIHO,<
	OUTSTR	PIKBUF+PCBSIZ-200 ;OUTPUT THE HELP
	POPJ	P,		;DONE
>
IFN FTNIHO,<
	MOVE	T0,[POINT 7,PIKBUF+PCBSIZ-200]
	JRST	PUTTYH		;OUTPUT HELP THE HARD WAY AND RETURN
>>
;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
		 CAIN T1,77	;YES - IS IT RESET?
		 MOVEI T1,$RESET ;YES - SET UP THE REAL INDEX
		 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
	MOVE	T2,[POINT 7,PIKBUF]
	SKIPE	APPFLG		;APPENDING TO THE PICK BUFFER?
	MOVEM	T2,APPFLG	;YES - WIPE WHAT'S ALREADY THERE
	POPJ	P,		;DONE

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

HELPER::TRNE	F,NHP		;REALLY WANT HELP?
	JRST	LOOP		;NO - DO NOTHING
	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)

;**********************************************************************
;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,JRNJFN	;GET THE JOURNAL'S JFN
	DELF
	  JFCL			;IGNORE ANY ERROR
>
EEXIT1:
>
	SKIPE	FILSPC		;GOT A CURRENT FILE?
	JRST	EEXIT2		;YES - CONTINUE
	SKIPN	OLDSPC		;NO - GOT AN OLD FILE?
	JRST	ABORT		;NEITHER - DON'T WRITE nnnSED.TMP

EEXIT2:	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,<
	MOVN	TY,TY		;NEGATE THE NUMBER OF WORDS
IFN FTTMPC,<
	HRLM	TY,TMPBLK+1	;SET UP NEGATIVE THE NUMBER OF WORDS TO WRITE
	MOVE	T1,[3,,TMPBLK]	;TRY TO SAVE IN TMPCOR
	TMPCOR	T1,
	  CAIA			;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
	HRLM	TY,SEDCCL	;SAVE NEGATIVE WORDCOUNT IN COMMAND BLOCK
	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
IFN FTECHO,<
	MOVE	T1,TTYJFN	;CLOSE THE TTY
	CLOSF
	  JFCL
>
	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 - JUST QUIT

	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
	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
>
IFN FTJOUR,<
IFE TOPS10,<
	TLZN	TM,JRW		;WRITING A JOURNAL?
	JRST	ABORT1		;NO - SKIP THIS
	MOVE	T1,JRNJFN	;RELEASE THE JOURNAL'S JFN
	RLJFN
	  JFCL			;IGNORE ANY ERROR
>>
	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
 	TRNE	F,RDO		;IS THE FILE READ-ONLY?
	SKIPA	T1,[ASCII ?/READ?]
	MOVE	T1,[ASCII ?/WRI?]
	PUSHJ	P,PUTSQ1	;MARK THE FILE READ-ONLY OR WRITEABLE
	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 THE 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 FOR THE MARKER COMMAND
;SETS AND GOES TO MARKERS OF THE GIVEN NAME AT THE SCREEN POSITION;
;KILLS SOME OR ALL MARKERS; LISTS THE MARKER NAMES
;ALSO POPS, OR MOVES FORWARD IN, THE MARKER STACK

MARNPM::MOVE	T1,DISPTR	;SAVE THE MARKED DISPLAY POINTER
	MOVEM	T1,MRKPTB-1	;AS THE DEFAULT MARKER
	JRST	LOOP		;AND GO GET A NEW COMMAND

MARKER::TRZE	F,CMV		;DID USER USE CURSOR MOVEMENT?
	JRST	SUMERR		;YES - ERROR
	SETZ	T4,		;END BUFFER WITH A NULL
	IDPB	T4,PARPTR
	LDB	T1,[POINT 7,PARBUF,6] ;GET FIRST CHARACTER OF PARAMETER
	JUMPE	T1,MRKDGO	;IF TOKEN FORMAT, GO TO THE DEFAULT MARKER
	ANDI	T1,137		;IF IT'S LOWER CASE, MAKE IT UPPER
	CAIN	T1,"S"		;SET A MARKER?
	JRST	MARKST		;YES - DO IT
	CAIN	T1,"G"		;GO TO A MARKER?
	JRST	MARKGO		;YES - DO IT
	CAIN	T1,"K"		;KILL A MARKER?
	JRST	MARKKL		;YES - DO IT
	CAIN	T1,"N"		;DISPLAY THE MARKER NAMES?
	JRST	MARKNM		;YES - DO IT
	CAIN	T1,"P"		;POP THE MARKER STACK?
	JRST	POPMKS		;YES - DO IT
	CAIN	T1,"F"		;"POP" THE MARKER STACK FORWARD?
	JRST	POPMKF		;YES - DO IT
	MOVEI	T1,[ASCIZ /#######Unknown MARKER command/]
	JRST	ERROR		;ERROR IF NONE OF THE ABOVE

;HERE TO SET A MARKER

MARKST:	PUSHJ	P,GTMNAM	;GET THE NAME OF THE MARKER IN T2, T3
	PUSHJ	P,FNMNAM	;FIND THE NAME IN THE TABLE (INDEX IN T4)
	 AOSA	T4,MRKEND	;NOT THERE - ADD IT
	JRST	MRKST2		;IT'S THERE - REPLACE THE DEFINITION
	CAILE	T4,MRKSIZ	;GOT TOO MANY?
	JRST	MRKSTH		;YES - LOOK FOR A HOLE; ERROR IF NONE
MRKST1:	MOVEM	T2,MRKNTB-1(T4)	;NO - SAVE THE NEW NAME IN THE TABLE
	MOVEM	T3,MRKNT1-1(T4)
MRKST2:	MOVE	T1,DISPTR	;SAVE THE MARKED DISPLAY POINTER
	MOVEM	T1,MRKPTB-1(T4)
	MOVEM	T1,MRKLAT	;SAVE ALSO AS THE LATEST-SET MARKER
	JRST	LOOP		;AND GO GET A NEW COMMAND

MRKSTH:	MOVEI	T4,MRKSIZ	;LOOK FOR A HOLE IN THE MARKER TABLE
	SOS	MRKEND		;SET THE END INDEX BACK TO THE MAX VALUE
MRKSH1:	SKIPN	MRKNTB-1(T4)	;IS THIS A HOLE?
	JRST	MRKST1		;YES - USE IT
	SOJG	T4,MRKSH1	;NO - LOOP - COUNTED OUT?
	SKIPA	T1,[[ASCIZ /######All markers are in use/]]
GOMERR:	MOVEI	T1,[ASCIZ /######Can't find that marker/]
	JRST	ERROR		;AND GIVE THE ERROR

;HERE FOR THE GOTO-MARKER COMMAND - POSITION TO THE MARKER OF THE GIVEN NAME
;<ENTER>G<MARKER> GOES TO THE LATEST-SET MARKER

MARKGO:	PUSHJ	P,GTMNAM	;GET THE NAME OF THE MARKER IN T2, T3
	JUMPE	T2,MRKGO1	;IF NO NAME, USE LATEST-SET MARKER
	PUSHJ	P,FNMNAM	;FIND THE NAME IN THE TABLE (INDEX IN T4)
	 JRST	SMXERR		;NOT THERE - ERROR
	SKIPA	T3,MRKPTB-1(T4)	;FOUND - GET THE MARKED DISPLAY POINTER
MRKGO1:	MOVE	T3,MRKLAT	;NO NAME - USE LATEST-SET MARKER
MRKGO2:	HRRZ	T1,T3		;GET THE ADDRESS FROM THE POINTER
	CAIL	T1,(EN)		;AT THE END OF THE BUFFER?
	JRST	GOMERR		;YES - CAN'T FIND THE MARKER
	PUSHJ	P,PUSMKS	;NO - PUSH THE DISPLAY PTR ON THE MARKER STACK
MRKGO3:	MOVEM	T3,DISPTR	;SAVE THE CURRENT POINTER
	SETZB	RW,CM		;PUT THE CURSOR HOME
	TLO	F,XPL!XPC!XPB	;SAY NO POINTERS ARE GOOD
	LDB	T1,T3		;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
	JRST	DISALL		;RE-DISPLAY THE SCREEN AND GET A NEW COMMAND

;HERE ON ENTER-MARKER - GO TO THE DEFAULT MARKER

MRKDGO:	PUSHJ	P,RESTPM	;CLEAN UP THE PARAMETER
	SKIPE	T3,MRKPTB-1	;GET THE DEFAULT MARKER - IS IT SET?
	JRST	MRKGO2		;YES - GO SET IT UP
	JRST	GOMERR		;NO - ERROR

;HERE TO KILL THE GIVEN MARKER (CALLED WITH T4/ 0)

MARKKL:	PUSHJ	P,GTMNAM	;GET THE NAME OF THE MARKER IN T2, T3
	CAMN	T2,[ASCIZ /*/]	;WANT TO CLEAR ALL THE MARKERS?
	JRST	MRKKLA		;YES - DO SO
	PUSHJ	P,FNMNAM	;FIND THE NAME IN THE TABLE (INDEX IN T4)
	 JRST	SMXERR		;NOT THERE - ERROR
	SETZM	MRKNTB-1(T4)	;FOUND - KILL IT
	JRST	LOOP		;GO GET A NEW COMMAND

MRKKLA:	SKIPG	T1,MRKEND	;CLEAR ALL THE MARKERS IN USE - ARE ANY?
	JRST	LOOP		;NO - NOTHING TO DO
	SETZB	T4,MRKEND	;GET A NULL AND RESET THE HIGHEST-IN-USE
	SETZM	MRKNTB-1(T1)	;CLEAR A MARKER
	SOJGE	T1,.-1		;LOOP THROUGH ALL THE MARKERS
	JRST	LOOP		;THEN GO GET A NEW COMMAND

;HERE TO OUTPUT THE NAMES OF ALL THE DEFINED MARKERS

MARKNM:	PUSHJ	P,SWHBOT	;SET UP THE BOTTOM LINE
	SKIPN	MRKPTB-1	;IS THERE A DEFAULT MARKER?
	JRST	MRKNMX		;NO - HANDLE SPECIALLY
	MOVEI	T1,[ASCIZ /<Default> /]
	PUSHJ	P,PUTSTG	;YES - SAY SO
MRKNM0:	MOVE	T2,MRKEND	;START WITH THE LAST-DEFINED ONE
	MOVEI	T3," "		;GET A SPACE AS A SEPARATOR

MRKNM1:	SKIPN	T1,MRKNTB-1(T2)	;GET A NAME - ANY?
	JRST	MRKNM2		;NO - SKIP THIS ENTRY
	PUSHJ	P,PUTSQ1	;YES - OUTPUT THE NAME
	SKIPE	T1,MRKNT1-1(T2)	;IS THERE A SECOND PART?
	PUSHJ	P,PUTSQ1	;YES - OUTPUT IT, TOO
	IDPB	T3,TY		;SEPARATE NAME FROM NEXT NAME
MRKNM2:	SOJG	T2,MRKNM1	;LOOP THROUGH ALL THE NAMES
	JRST	SWHNPE		;THEN OUTPUT THEN AND LOOP

MRKNMX:	SKIPLE	MRKEND		;ARE ANY MARKERS DEFINED?
	JRST	MRKNM0		;YES - CONTINUE
	MOVEI	T1,[ASCIZ /(None defined)/]
	PUSHJ	P,PUTSTG	;YES - SAY SO
	JRST	SWHNPE		;DONE

;ERRORS FROM THE SET-MARKER OR GOTO-MARKER COMMANDS

SMXERR:	MOVEI	T1,[ASCIZ /#######Marker name not found/]
	JRST	ERROR

;SUBROUTINE TO GET THE NAME OF THE MARKER IN T2, T3
;CALL WITH T4/ 0

GTMNAM:	PUSHJ	P,ERASPM	;CLEAN UP THE PARAMETER FROM THE SCREEN
	MOVE	T4,[POINT 7,T2]	;GET POINTERS TO SOURCE AND TARGET
	MOVE	PT,[POINT 7,PARBUF,6]
	SETZB	T2,T3		;CLEAR THE TARGET ACS
	MOVEI	T0,^D10		;SET TO GET AT MOST 10 CHARACTERS
GTMNM1:	ILDB	T1,PT		;GET A CHARACTER OF THE NAME
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIL	T1,"a"		;ELSE IS IT LOWER CASE?
	CAILE	T1,"z"
	CAIA			;NO - O.K.
	SUBI	T1,40		;YES - CONVERT TO UPPER
	IDPB	T1,T4		;SAVE THE CHARACTER
	SOJG	T0,GTMNM1	;LOOP THROUGH ALL CHARACTERS (UP TO 10)
	POPJ	P,		;DONE

;SUBROUTINE TO FIND THE MARKER WHOSE NAME IS GIVEN IN T2, T3
;RETURNS +2 IF FOUND, WITH INDEX IN T4; RETURNS +1 IF NOT FOUND

FNMNAM:	SKIPG	T4,MRKEND	;GET INDEX OF LAST ENTRY IN MARKER TABLE - ANY?
	POPJ	P,		;NO - RETURN FAILURE
FNMNM1:	CAMN	T2,MRKNTB-1(T4)	;IS THIS THE MARK?
	JRST	FNMNM3		;MAYBE - CHECK THE SECOND WORD
FNMNM2:	SOJGE	T4,FNMNM1	;NO - LOOP THROUGH THE TABLE
	POPJ	P,		;NOT FOUND - RETURN FAILURE

FNMNM3:	CAME	T3,MRKNT1-1(T4)	;DOES THE SECOND NAME WORD MATCH?
	JRST	FNMNM2		;NO - KEEP LOOKING
	AOS	(P)		;YES - RETURN SUCCESS
	POPJ	P,

;SUBROUTINES TO WORK WITH THE MARKER STACK
;CLEAR THE ENTIRE STACK (ON A SET-FILE)

CLRMKS::SETZM	MRKSTP		;POINT TO THE TOP OF THE STACK
	SETZM	MRKSTK		;ZERO OUT THE ENTIRE STACK
	MOVE	T1,[MRKSTK,,MRKSTK+1]
	BLT	T1,MRKSTK+MRKSTL-1
	POPJ	P,		;DONE

;SUBROUTINE TO PUSH A DISPLAY POINTER ON THE MARKER STACK

PUSMKS::MOVE	T1,DISPTR	;GET THE CURRENT DISPLAY POINTER
	MOVE	T2,MRKSTP	;GET THE STACK POINTER
	MOVEM	T1,MRKSTK(T2)	;SAVE THE DISPLAY POINTER ON THE STACK
	MOVEI	T1,MRKSTL-1	;POINT TO THE TOP OF THE STACK
	SOSG	MRKSTP		;BUMP THE STACK - WRAPPED AROUND?
	MOVEM	T1,MRKSTP	;YES - SAVE POINTER TO TOP
	POPJ	P,		;DONE

;SUBROUTINE TO POP A DISPLAY POINTER FROM THE MARKER STACK

POPMKS:	PUSHJ	P,RESTPM	;CLEAN UP THE PARAMETER ON THE SCREEN
	AOS	T1,MRKSTP	;BUMP AND GET THE STACK POINTER
	CAILE	T1,MRKSTL-1	;WRAPPED AROUND?
	SETZB	T1,MRKSTP	;YES - SET TO THE BOTTOM OF THE STACK
POPMK1:	SKIPE	T3,MRKSTK(T1)	;GET DISPLAY POINTER FROM STACK - ANY?
	JRST	MRKGO3		;YES - GO SET UP THE SCREEN
	AOS	T1,MRKSTP	;NO - BUMP AND GET THE STACK POINTER
	CAIG	T1,MRKSTL-1	;WRAPPED AROUND?
	JRST	POPMK1		;NO - SEE IF THERE'S SOMETHING HERE
POPMK2:	SETZM	MRKSTP		;POINT TO START OF MARKER LIST
	MOVEI	T1,[ASCIZ /##########Stack is empty/]
	JRST	ERROR

;SUBROUTINE TO GO BACK TO THE PREVIOUS ENTRY ON THE MARKER STACK
;(ALIAS POP FORWARD)

POPMKF:	PUSHJ	P,RESTPM	;CLEAN UP THE PARAMETER ON THE SCREEN
	SOS	T1,MRKSTP	;DE-BUMP AND GET THE STACK POINTER
	JUMPGE	T1,POPMF1	;WRAPPED AROUND?
	MOVEI	T1,MRKSTL-1	;YES - SET TO THE TOP OF THE STACK
	MOVEM	T1,MRKSTP
POPMF1:	SKIPE	T3,MRKSTK(T1)	;GET DISPLAY POINTER FROM STACK - ANY?
	JRST	MRKGO3		;YES - GO SET UP THE SCREEN
	SOS	T1,MRKSTP	;NO - BUMP AND GET THE STACK POINTER
	JUMPGE	T1,POPMF1	;IF NOT WRAPPED AROUND, CHECK AGAIN
	JRST	POPMK2		;ELSE GIVE STACK-IS-EMPTY 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
IFN FTLSR,<
	PUSHJ	P,ULMSCR	;UNLIMIT SCROLLING REGION, IF POSSIBLE
>
	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:
IFN FTLSR,<
	MOVE	T2,LPP(TM)	;LIMIT TERMINAL'S SCROLLING REGION, IF POSSIBLE
	AOJ	T2,
	MOVE	T3,SAVLPP	;  TO THE BOTTOM HALF OF THE SCREEN
	PUSHJ	P,LIMSCR
>
	SKIPE	HOMPOS		;WINDOWING - IN BOTTOM WINDOW NOW?
	TDZA	T4,T4		;YES - POSITION HOME
	MOVE	T4,LPP(TM)	;NO - POSITION TO START OF LOWER WINDOW
PSHWI0:	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
PSHWI2:	PUSHJ	P,CDOWN
	PUSHJ	P,CLRLNA
	SOJG	T4,PSHWI2
	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
	RPCAP			;GET THE USER'S CAPABILITIES
	  ERJMP	RUNFR1		;FAILED - SKIP THIS
	TLZ	T2,(SC%LOG)	;DON'T LET THE USER LOG OUT
	EPCAP			;  FROM THE LOWER FORK
	  ERJMP	RUNFR1		;FAILED - PROCEED
RUNFR1:	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
>

	END