Google
 

Trailing-Edge - PDP-10 Archives - BB-FP64A-SB_1986 - 10,7/sed/sed1su.mac
There are 10 other files named sed1su.mac in the archive. Click here to see a list.
TITLE	SED1SU - SED GENERAL UTILITY SUBROUTINES
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
>

;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,	;JUST IGNORE THIS COMMAND
		 TRZ  F,CMV	;AND GET THE NEXT ONE
		 JRST LOOP]
	SKIPN	NEWMSG+1	;IS /NOMESSAGE IN EFFECT?
	JRST	MARKU1		;YES - DON'T TALK ABOUT CURSOR MOVEMENT
	PUSHJ	P,CMVBTM	;NO - 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
MARKU1:	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
	CAIE	T1,0		;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?
	SKIPN	TRLFLG		;NO - WANT TO STRIP TRAILING STUFF?
	MOVE	T2,PT		;YES - SAVE THE POINTER
	JRST	TRAIL3		;AND LOOP

;************************************************************************
;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
;SETINL LOOKS ONLY IN THE USER'S LOGGED-IN AREA

IFN TOPS10,<
SETINL:	MOVE	T0,USRPPN	;SET UP USER'S LOGGED-IN PPN
	JRST	SETIN1		;JUST LOOK IN THE LOGGED-IN AREA

SETINP::MOVE	T0,3(T2)	;GET THE PPN FROM THE BLOCK
	CAIA			;  (CAN'T USE SKIPA WITH T0)
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,<
SETINL:	MOVEI	T1,INIJFN	;LOOK IN USER'S LOGGED-IN DIRECTORY ONLY
	JRST	SETIN0

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
SETIN0:	SKIPE	USRNAM		;(DON'T DO IT IF NO USER NAME)
	GTJFN
	  JRST	SETIN2		;NO SUCH FILE - 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,
>
;************************************************************************
;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
	CAIGE	PT,0
	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
	CAIGE	PT,0
	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
MAKCP4:	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,MAKCP4	;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]
	CAIGE	T2,0
	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
MAKCK0:	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,MAKCK0	;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
	CAIGE	T1,0
	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
	CAIGE	T2,0
	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
	CAIGE	PT,0
	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>
	CAIGE	PT,0
	SUB	PT,[430000,,1]
	MOVEM	PT,LINPTR	;SAVE LINE POINTER
	TLO	F,XPL!XPC	;BUT SAY IT'S INVALID
	POPJ	P,		;AND RETURN

CCREOL::MOVE	T1,PT		;MAKE SURE THE FILE ENDS WITH A CRLF
CCREL1:	ILDB	T2,T1		;GET A CHARACTER
	CAMN	T1,EN		;REACHED END OF THE FILE?
	JRST	ADDCR		;YES - PUT IN A CARRIAGE RETURN AND RETURN
	JUMPE	T2,CCREL1	;NO - LOOP UNTIL END OR NON-NULL CHARACTER
	POPJ	P,		;END OF FILE IS NOW O.K.

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
	CAIGE	T4,0		;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 FIND IF THERE ARE ANY TABS FROM THE CURSOR TO THE END
;OF THE LINE, OR IF THE LINE WILL GO OFF THE RIGHT OF THE SCREEN

;ASSUMES CHRPTR IS VALID; FRAGS T1, T2
;CALL WITH  T4/ NUMBER OF SPACES THAT WILL BE ADDED TO THE LINE
;RETURNS +1 IF LINE IS TOO LONG OR A TAB IS FOUND, ELSE +2
;WITH	T1/ POSITION OF LAST CHARACTER

FNDEOL::MOVE	T1,CM		;GET POSITION OF STARTING CHARACTER
	MOVE	T2,CHRPTR	;GET THE POINTER TO THE FIRST CHARACTER
FNDEO1:	CAMLE	T1,CPL(TM)	;AT 80TH COLUMN?
	POPJ	P,		;YES - DONE NOW
	ILDB	T0,T2		;NO - GET A CHARACTER
FNDEO2:	JUMPE	T0,.-1		;SKIP IT IF NULL
	CAIN	T0,11		;TAB?
	JRST	FNDEOT		;YES - HANDLE SPECIALLY
	CAIE	T0,15		;END OF LINE?
	AOJA	T1,FNDEO1	;NO - KEEP LOOKING
	ILDB	T0,T2		;YES - GET THE NEXT CHARACTER
	CAIE	T0,12		;IS IT A LINEFEED?
	AOJA	T1,FNDEO2	;NO - COUNT THE CR AND CHECK THE LF FURTHER
	AOS	(P)		;YES - GIVE SKIP RETURN
	POPJ	P,

FNDEOT:	TRO	T1,3		;GOT A TAB - TAB OVER
	AOJA	T1,CPOPJ	;AND RETURN

;************************************************************************
;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
	CAIA			;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

;************************************************************************
;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
	CAIE	T4,0		;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,MAKCL1	;YES - JUMP IF FOUND ENOUGH
	AOJA	T4,MAKCHL	;ELSE LOOK FOR MORE
MAKCL1:	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
MAKPT2:	CAMN	T4,NUMNUL	;REACHED GOOD STUFF?
	POPJ	P,		;YES - DONE
	IDPB	T1,T4		;NO - PUT THE NULL IN
	JRST	MAKPT2		;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
	CAIN	DO,$JUSTI	;HOW ABOUT JUSTIFY?
	POPJ	P,		;YES - LIKEWISE
	PUSHJ	P,MAKCPT	;MAKE POINTER TO CURSOR LOCATION
	MOVE	PT,CHRPTR	;GET CURSOR POINTER
	SETZ	T2,		;CLEAR COUNT
	CAIN	DO,$SETCT	;IS IT A SET-COUNTER EXECUTE CONSTRUCT?
	JRST	PEL.CN		;YES - READ THE NUMBER AT THE CURSOR POSITION

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
	ANDI	T1,137		;CONVERT LOWER CASE TO UPPER
	CAIL	T1,"A"		;GOT A LETTER (IN EITHER CASE)?
	CAILE	T1,"Z"
	AOJA	T2,PEL.C3	;NOT A LETTER - END OF TOKEN
	AOJA	T2,PEL.C1	;LETTER - GO GET ANOTHER ONE

;HERE TO READ A NUMBER FROM FILE AS THE TOKEN

PEL.CN:	ILDB	T1,PT		;GET CHARACTER FROM THE BUFFER
	JUMPE	T1,.-1		;IGNORE IF NULL
	CAIL	T1,"0"		;IS IT A NUMBER?
	CAILE	T1,"9"
	JRST	PEL.C3		;NO - END OF TOKEN
	SUBI	T1,"0"		;YES - CONVERT TO A DIGIT
	IMULI	T2,^D10		;SHIFT OVER WHAT'S THERE ALREADY
	ADD	T2,T1		;ADD IN THE NEW DIGIT
	JRST	PEL.CN		;AND GO GET MORE

;DONE - SAVE THE TOKEN VALUE AND RETURN

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,PELS2A	;IF NULL, JUST ENTER WAS TYPED
	POPJ	P,		;SO JUST RETURN

PELST2::ILDB	T2,T4		;GET A CHARACTER
PELS2A:	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)
	CAIL	T1,0		;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
	MOVE	T0,T2		;CONVERT LOWER CASE TO UPPER
	ANDI	T0,137
	CAIL	T0,"A"		;GOT A LETTER (IN EITHER CASE)?
	CAILE	T0,"Z"
	JRST	PEL.T3		;NOT A LETTER - 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::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,74		;OPEN
	CAIN	T2,76		; 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.
	ANDI	T2,137		;CONVERT LOWER CASE 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

;************************************************************************
;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	RSCA2A		;GO SAVE THE FILE NAME

RSCAN2:	INCHRS	T1		;YES - SAVE FROM HERE ON AS A PARAMETER
	  JRST	RSCAN3		;DONE IF NOTHING LEFT
RSCA2A:	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
	SETZM	SAVEAC+10	;CLEAR GOT-AN-OUTPUT-FILE FLAG
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"
	TRO	F,CRE		;YES - FLAG AS SUCH
	CAIE	T1,"P"		;GOT THE "PERUSE" COMMAND?
	CAIN	T1,"p"
	SETOM	GREFLG		;YES - SET THE GLOBAL READ-ONLY FLAG
	CAIA			;SKIP THE FIRST 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 THE FIRST 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, SKIP COMMENTS, 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	RSCN2N		;YES - GO SKIP THE NOISE
	CAIE	T1,"!"		;START OF A COMMENT?
	CAIN	T1,";"
	JRST	RSCN2S		;YES - SKIP THE REST OF THE LINE
	MOVE	T4,[ASCII ?/OUT:?]
	SKIPE	SAVEAC+10	;NO - ALREADY HAD AN OUTPUT SPEC?
	JRST	RSCN2E		;YES - ERROR
	SETOM	SAVEAC+10	;NO - THERE'S ONE NOW
	LSHC	T3,7		;SET UP AN /OUTPUT: SWITCH
	IDPB	T3,PARPTR
	JUMPN	T4,.-2
	JRST	RSCN2A		;OUTPUT THE OUTPUT FILESPEC

RSCN2E:	MOVEI	T1,.PRIIN	;CLEAR THE INPUT BUFFER
	CFIBF
	HRROI	T1,[ASCIZ /#More than one output filespec given/]
	JRST	ERROR

;HERE TO SKIP THE REST OF A LINE IF A COMMENT IS FOUND

RSCN2S:	MOVEI	T1,.PRIIN	;CLEAR THE INPUT BUFFER
	CFIBF
	JRST	RSCAN3		;AND GO FINISH OFF

;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 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,
	  CAIA			;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
TMPGT1:	ILDB	T1,PT		;GET FIRST CHARACTER
	CAIE	T1,11		;TAB OR
	CAIN	T1," "		;  SPACE?
	JRST	TMPGT1		;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	TMPGT3		;NO - CONTINUE
	ILDB	T1,PT		;YES - SKIP THE LINEFEED, TOO
	JRST	TMPGT1		;AND CHECK NEXT LINE

TMPGT2:	ILDB	T1,PT		;READ SPECS INTO ACTIVE OR ALTERNATE AREA
	JUMPE	T1,TMPGT4	;IF NULL, GO FINISH OFF
	CAIN	T1,15		;GOT A CARRIAGE RETURN?
	JRST	TMPGT4		;YES - FINISH OFF
TMPGT3:	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)
TMPGT4:	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	TMPGT1		;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,SETINL	;  IN THE LOGGED-IN DIRECTORY ONLY
	JUMPE	T1,CPOPJ	;NOT FOUND - JUST RETURN
	SETZM	INIFLG		;FLAG THE FILE AS SWITCH.INI
IFN TOPS10,<
REDSW0:	HRRI	T1,PIKBUF-1	;READ THE FILE INTO THE PICK BUFFER
	MOVEM	T1,PIKCCL
	INPUT	5,PIKCCL
	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
	JUMPL	T1,REDSWS	;IF A COMMENT LINE, SKIP IT
	SKIPE	INIFLG		;READING SED.INIT?
	JRST	REDSW3		;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 "/"
REDSW3:	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 IF 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]
	HRLI	PT,(BLT T1,)	;TO END OF STUFF THAT'S JUST BEEN PROCESSED
	XCT	PT
	POPJ	P,		;RETURN FROM SWITCH.INI PROCESSING

REDCHR:	ILDB	T1,PT		;GET NEXT CHARACTER
	CAIE	T1,";"		;START OF A COMMENT?
	CAIN	T1,"!"
	SETO	T1,		;YES - SET TO SKIP IT
	CAIL	T1,"a"		;LOWER CASE?
	SUBI	T1,40		;YES - CONVERT TO UPPER
	POPJ	P,		;RETURN

;************************************************************************
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
>>
;************************************************************************
;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
	TLZ	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
	TLZ	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
	MOVEI	T1," "		;FOLLOW THE MESSAGE WITH A SPACE
	IDPB	T1,TY
	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 ROUTINE TO INITIALIZE PSI INTERRUPTS FOR KSYS

IFN TOPS10,<
PSIKSY::SKIPE	KSYVEC+.PSVNP	;ALREADY INIT'D FOR KSYS PSI?
	POPJ	P,		;YES, JUST RETURN
	XMOVEI	T1,KSYINT	;GET KSYS INTERRUPT ROUTINE ADDRESS
	MOVEM	T1,KSYVEC+.PSVNP ;SAVE IN INTERRUPT VECTOR
	MOVEI	T1,KSYVEC	;GET VECTOR ADDRESS
	PIINI.	T1,		;TELL MONITOR VECTOR ADDRESS
	  POPJ	P,		;OH WELL, WE TRIED
	MOVE	T1,[EXP PS.FON+PS.FAC+[
		    EXP .PCKSY
		    EXP 0
		    EXP 0]]	;GET ARG BLOCK TO ENABLE FOR KSYS INTERRUPTS
	PISYS.	T1,		;TELL THE MONITOR
	  TRN			;WHO USES KSYS ANYWAY?
	POPJ	P,		;RETURN

;************************************************************************
;TOPS10 ROUTINE TO HANDLE KSYS PSI INTERRUPTS

KSYINT:	SKIPN	KSYVEC+.PSVIS	;A VALID KSYS TIME
	DEBRK.			;NO, JUST RETURN
	MOVEM	T1,KSYSAV	;SAVE AN AC
	MOVE	T1,KSYVEC+.PSVIS ;GET KSYS VALUE
	CAIG	T1,KSYMIN	;TIME FOR A WARNING?
	SETOM	KSYFLG		;YES, FLAG IT
	MOVE	T1,KSYSAV	;RESTORE AC
	DEBRK.			;RETURN FROM INTERRUPT
	HALT	.

;************************************************************************
;TOPS10 ROUTINE TO WARN OF AN IMPENDING KSYS

KSYWRN::SETZM	KSYFLG		;CLEAR WARNING FLAG
	PUSHJ	P,CBOTOM	;POSITION TO BOTTOM LINE
	PUSHJ	P,PROTON	;TURN ON PROTECTION
	PUSHJ	P,PUTTYP	;MAKE SURE TERMINAL KNOWS
	SKIPG	T1,KSYVEC+.PSVIS ;GET TIME TILL KSYS
	JRST	KSYW.1		;MUST BE OVER OR PRE-7.03 COUNTDOWN BUG
	PUSH	P,T1		;SAVE MINUTES TILL KSYS
	MOVEI	T1,[ASCIZ\ Timesharing will end in \] ;GET INITIAL TEXT
	PUSHJ	P,PUTSTG	;DUMP IT
	MOVE	T1,(P)		;GET MINUTES
	PUSHJ	P,PUTNUM	;DUMP IT
	MOVEI	T1,[ASCIZ\ minute\] ;GET ENDING TEXT
	PUSHJ	P,PUTSTG	;DUMP IT
	POP	P,T1		;GET TIME BACK
	SOJE	T1,SWHNPE	;IF JUST 1, WE'RE DONE...
	MOVEI	T1,[ASCIZ\s\]	;...OTHERWISE WE MUST BE CORRECT
	PUSHJ	P,PUTSTC
	JRST	SWHNPE		;GO CLEAN UP AND RETURN (BUM SOME CODE)

;HERE IF TIMESHARING IS OVER

KSYW.1:	AOSE	T1		;IS IT -1, TIMESHARING OVER?
	POPJ	P,		;NOPE, JUST RETURN
	MOVEI	T1,[ASCIZ\ Timesharing is over!\] ;YES, GET TEXT!
	PUSHJ	P,PUTSTG	;DUMP IT
	JRST	SWHNPE		;HOPE IT'S NOT TO LATE

;************************************************************************
;TOPS10 ROUTINE TO INPUT A CHAR. CHAR IS RETURNED IN T1.

GETCHR::INCHRS	T1		;CHARACTER WAITING?
	TRNA			;NO
	POPJ	P,		;YES, RETURN WITH IT IN T1
	MOVSI	T1,(HB.RTC+HB.RTL) ;GET HIBER BITS
	HIBER	T1,		;WAIT FOR INPUT (OR PSI)
	  HALT	.		;SHOULDN'T HAPPEN
	SKIPE	KSYFLG		;IMPENDING KSYS?
	PUSHJ	P,KSYWRN	;YES, TELL USER
	JRST	GETCHR		;SEE IF A CHARACTER IS AVAILABLE

;************************************************************************
;TOPS10 INTERRUPT ROUTINE TO EXPAND CORE BY 1K

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
>

	END