Google
 

Trailing-Edge - PDP-10 Archives - scratch - 10,7/unscsp/sos/sosalt.mac
There are 3 other files named sosalt.mac in the archive. Click here to see a list.
	TITLE	SOSALT - The ALTER Mode Family
;		------------------------------
; This file contains the processing for ALTER mode as follows:
;	1. The A command
;	2. Command dispatching
;	3. SETALT - Set up a line for altering
;	4. GNCH1 - Get an alter mode character
;	5. Alter mode command processing
;	6. The extend (X) command
; 
 
 
	SEARCH	SOSTCS
	$INIT

 
	SUBTTL	The X Command

$XPAND::SETOM	XCMDF		; Flag we are doing an X command
	JRST	ALTER1		; And do an alter

	SUBTTL	The A Command
 
; Here for the A command - Beginning of Alter Mode
 
$ALTER::SETZM	XCMDF		; This is not an extend

; Join here for the X-command

ALTER1:	SETOM	PRVSIZ		; Fix count
	SETZM	SSW		; Clear suppress switch
	PUSHJ	P,GET2SD##	; Get the range
	SKIPN	XCMDF		; If X-command then
	JRST	ALTER2
	CAIN	C,";"		; Check for legal delimiter
	JRST	[PUSHJ P,SCAN	; Get number
		 TRNN FL,NUMF	; Is there a number
		 NERROR ILC	; No, quit
		 MOVE T2,INCR
		 MOVEM T2,TEMINC
		 JRST XCMD1]	; Join processing
	CAIE	C,","		; Is there a switch or new increment
	JRST	ALTER2		; No, check for end of line
	PUSHJ	P,SCAN##	; Get it
	TRNN	FL,NUMF		; Is there a number?
	JRST	XCMD2		; No, look for switch
XCMD1:	CAMN	T1,LNZERO##	; Line zero?
	NERROR	ILC		; Is illegal
	MOVEM	T1,INCR		; Save increment
	PUSHJ	P,SCAN##	; Scan next
	CAIE	C,","		; Still have a switch?
	JRST	ALTER2		; No, so better be the end
	PUSHJ	P,SCAN##	; Scan the switch
XCMD2:	MOVS	T1,ACCUM	;  to T1
	CAIE	T1,'S  '	;  or ,S switch
	NERROR	ILC		; it's and error
	SETOM	SSW		; Else note suppress and continue
	PUSHJ	P,SCAN##	; To reach end of line
ALTER2:	PUSHJ	P,CKTRMF##
	PUSHJ	P,FINDLO##	; Get first line of range
	TRZ	FL,LINSN	; Not seen yet
				CONT.
ALT1:	PUSHJ	P,ONMOV##	; Check for in range
	  JRST	ALT2		; No, finish up
	TRO	FL,LINSN	; We did see something
	CAMN	T1,PGMK 	; Check for a page
	JRST	ALT3		; Do not try to change this
	MOVEM	T1,CLN		; Now, in case we said altmode
	MOVE	T1,CPG		; Same for page
	MOVEM	T1,CPGL
	SKIPE	SSW		; If S-switch
	TRO	FL2,SUPN	; Do suppress thing
	MOVEI	T5,CPOPJ	; Assume alter command
	SKIPE	XCMDF		; True?
	MOVEI	T5,ALTELX	; First free command
	PUSHJ	P,ALTLIN##	; Do the Alter (or eXtend)
	  PJRST	LEVINS##	; He said altmode
	PUSHJ	P,AINSED	; Go insert
ALT4:	PUSHJ	P,FINDN##	; Get the next line
	JRST	ALT1		; Continue loop

ALT3:	MOVE	T2,CPG		; We are on a later page now
	ADDI	T2,1		; Add fudge factor
	MOVEM	T2,CPGL 	; Save as .
	PUSHJ	P,PGPRN##	; Print him a message
	MOVE	T1,LNZERO##	; Set to first? line
	MOVEM	T1,CLN		; For .
	JRST	ALT4		; Continue past it

ALT2:	TRNN	FL,LINSN	; Was there anything there?
	JRST	[SKIPE XINSRT##	; Auto insert on X command?
		  SKIPN XCMDF	; X command?
		   NERROR NLN	; No, give error message
		 TRZ FL,CNTF	; Don't handle these here
		 JRST INSGO##]	; Yes, treat as an insertion
	MOVE	T1,CPG		; Get the current page
	MOVEM	T1,CPGL 	; Save as .
	SKIPE	XINSRT##	; Auto insert on X command?
	SKIPG	XCMDF		; Go back to insert?
	JRST	COMND## 	; No, next command
	MOVE	T1,CLN		; Current line
	MOVEM	T1,HILN		; Save for INSRTX
	JRST	INSRTX##	; Join insert routine
	SUBTTL	AINSED -- Insert Altered line into the buffer

;AINSED -- Insert Altered line into the Buffer
;
;Call with PNTR pointing to unaltered line in buffer and
;altered line in LIBUF.  Checks to see if line was actually changed
;by doing a string compare.  If it was, it inserts the new line in
;the buffer with INSED, and handles the decrement and test on SAVEN
;for auto-save.

AINSED:	MOVE	T1,NCNT		; Get new count
	CAME	T1,OCNT		; Is it the same?
	JRST	AINSD1		; No, must update the line
	MOVN	T1,T1		; Minus count
	MOVSS	T1		; To left half
	HRRI	T1,LIBUF	; Point to Alter buffer
	MOVEI	T2,(PNTR)	; Point to line in edit buffer
	HRLI	T2,(POINT 36,)	; Make a word pointer
AINCMP:	ILDB	T3,T2		; Word from the buffer
	CAME	T3,(T1)		; Compare with Altered line
	JRST	AINSD1		; Different, go update line
	AOBJN	T1,AINCMP	; Loop over whole line
	POPJ	P,		; All same, therefore no changes

AINSD1:	PUSHJ	P,INSED##	; Update line in buffer
	SKIPE	SSAVEN		; Is save activated?
	SOSLE	SAVEN		; Yes, decrement count and check
	POPJ	P,		; No, just return
	PUSH	P,HILN		; Save current hiln
	MOVE	T1,CLN		; Get current line...
	MOVEM	T1,HILN 	; And establish as hiln for auto-save
	PUSHJ	P,ASVCOD##	; Do the auto-save
	POP	P,HILN		; Restore hiln
	POPJ	P,
	SUBTTL	Command Dispatching for ALTER Mode
 
; Here to alter a line
 
$ATLIN::SKIPN	T1,CRLFSW	; If not set
	PJRST	ALTLNX		; Just do the alter
	MOVEM	T1,SVCRLF	; Save, in case of errors
	SETZM	CRLFSW		; Clear
	PUSHJ	P,SETTTY##	; Re-set to zero
	PUSHJ	P,ALTLNX	; Do the alter
	  CAIA
	AOS	(P)		; If skip return

; Call ALTLNX if a user supplied procedure should be executed
; after SETALT has set things up

ALTLNX:	PUSHJ	P,SETALT	; Set up line for alteration
IFN	%UAHPQ,<
	PUSHJ	P,HPQON##	;[UA WRS]  Use HPQ for ALTER mode
>
 	PUSHJ	P,(T5)		; Call user routine
$ATLN1::			; Here if you don't want SETALT called
ALTLP2: TLZ	FL,NEGF 	; Turn off "-" seen flag
	PUSHJ	P,V52TPN	; Type line again
	SETZM	CHGLNF##	; Reset this flag
	SETZB	T2,DELBAK	; Reset 'deleting backward' flag
ALTLP:	TRZ	FL2,SUPN!ALTDUP	; Turn duplexing back off
	PUSHJ	P,GNCH1## 	; Get on chr in ddt submode
	TLNE	CS,LETF_16	; Check for letter
	TRZ	C,40		; And convert to upper case
	MOVSI	T1,-ALTLG	; Get length of command table
; 
ALTLP3: HRRZ	T3,ALTAB(T1)	; Fetch an entry
	TRZ	T3,XNEGF!XAM	; Clear flags in right half
	CAIE	C,(T3)		; Check for character match
	AOBJN	T1,ALTLP3	; No match, look at next
	JUMPGE	T1,ALTBEL	; Ring the bell if not found
	MOVS	T3,ALTAB(T1)	; Re-fetch entry (need flags)
	TRNE	FL,READOF	; Read-only?
	TLNN	T3,XAM		; and command modifies the file?
	CAIA
	JRST	ALTBEL		; Yes, error
	TLNN	T3,XNEGF	; Minus sign permitted?
	TLNN	FL,NEGF 	; No: is it set?
	JRST	ALTDSP		; Ok to execute command
ALTBEL: OUTCHR	[7]		; Bong a gong
	CLRBFI			; Clear type ahead
	JRST	ALTLP2		; Try again
 
ALTDSP:	PUSHJ	P,(T3)		; Execute command
	  JRST	ALTLP2		; Reset repeat count and get new command
	JRST	ALTLP		; Skip return from digits no count reset
 
; Here to ring bell after a command detected error
 
ALTFS2: POP	P,ALTCNT
ERARTN: POP	P,ALTP
ER1RTN: POP	P,(P)		; Clear junk off stack
ERRRTN: OUTCHR	[7]
	SETO	T2,		; Flag meaning error
	POPJ	P,		; Then return
	SUBTTL	ALTER Mode Commands Table
 
; Flags
 
XNEGF==400000			; Command may take a - sign
XAM==200000			; Command modifies the line
 
	DEFINE	ACMNDS,<
I==0
	REPEAT	^D10,<
	X	I+"0",	ALTDG, XNEGF	;; Accumulate a number
I==I+1>
	X	" ", ALTSP##, XNEGF	;; Skip a character
	X	"H", ALTAMP, XNEGF!XAM	;; Amputate and insert
	X	":", ALTXDL, XNEGF!XAM	;; Amputate
	X	"B", INSBLK, XAM	;; Insert blanks
	X	"C", ALTCN, XNEGF!XAM	;; Change some characters
	X	"D", ALTDL, XNEGF!XAM	;; Delete some characters
	X	"E", ALTEX,		;; Exit w/no print
	X	"F", ALTFS, XNEGF	;; Find a string
	X	"G", ALTGT, XNEGF	;; Find a string (rpos)
	X	"I", ALTIN, XAM		;; Insert text
	X	"J", AJOIN, XNEGF!XAM	;; Insert CRLF and join
	X	"K", ALTKL, XNEGF!XAM	;; Kill some characters
	X	"L", ALTLN,		;; List and continue
	X	"M", ALTAMD, XNEGF!XAM	;; Y followed by I
	X	"N", ALTNXL, XNEGF	;; Advance to next line
	X	"O", INSONE, XAM	;; Insert one character
	X	"P", APRINT,		;; Print and save pos
	X	"Q", ALTALT,		;; Quit while ahead
	X	"R", ALTRP, XNEGF!XAM	;; Replace some characters
	X	"S", ALTSR, XNEGF	;; Search for a character
	X	"T", ALTWX, XNEGF!XAM	;; Delete a word and i
	X	"W", ALTWD, XNEGF	;; Skips a word
	X	"X", ALTEOL,XNEGF!XAM	;; Extend the line
	X	"Y", ALTYK, XNEGF!XAM	;; Find string and delete
	X	"Z", ALTZNK, XNEGF!XAM	;; Delete words
	X	"^", ALTCHG, XNEGF!XAM	;; Invert case
	X	"V", ALTXCH, XNEGF!XAM	;; Invert case to EOL
	X	"/", ALTSL, XNEGF!XAM	;; Transpose 2 chars
	X	"\", ALTBSL, XNEGF!XAM	;; Transpose previous 2
	X	"-", ALTNEG,		;; Command goes left
	X	"#", ALTCHW, XNEGF!XAM	;; Like ^, but on words
	X	42, ALTSIC, XNEGF!XAM	;; Search and invert case
	X	"!", ALTKI, XNEGF!XAM	;; K followed by I
	X	"+", INSNXT, XAM	;; Don't ask
	X	73, INSCRF, XAM		;; Break the line
	X	"'", INSQT, XAM		;; Make ^<ch>
	X	"U"-100+200, ALTCU,	;; Restore and restart
	X	11, ALTTAB##, XNEGF	;; Move to end of line
	X	12, ALTFN,		;; Done with alter
	X	15, CPOPJ1,		;; Ignore CR's
	X	177, ALTBS,		;; Backspace in line
	X	"H"-100+200, ALTBS,	;; Backspace in line
	X	"R"-100+200, ALTCTR,	;; P up to current only
	X	"W"-100+200, ALTBSW	;; Backspace one word
	>
 
; The commands table
 
	DEFINE	X(A,B,C),<XWD	B,A!C>
ALTAB:	ACMNDS
ALTLG==.-ALTAB
 
 
	SUBTTL	SETALT - Set Up a Line for ALTER
 
; Routine to set up a line for altering
 
SETALT:	MOVEI	T1,0		; Be sure TTY TAB is off
	PUSHJ	P,SETTAB##	; (but remember old value)
	PUSHJ	P,LOADCL##
SALT1:	MOVE	ALTP,[POINT 7,LIBUF+1,13]	; Set up pointer
	SETZM	ALTCNT		; So far we are 0 chrs into line
	HRRZM	T1,OCNT 	; And save it for insed
	OFFECHO 		; Turn off echo
	TRZ	FL2,RUBF!ALTDUP!RUBF2; Clear rubout and echoing flags
	SETZM	ALTFLG		; Nothing inserted so far
	MOVE	T1,LIBUF	; Print line number and tab
	PUSHJ	P,OUTSN##	; Sequence number
	SETOM	PRVSIZ		; Force typeout if on VT52
	POPJ	P,
 
 
; Macros for rubout control
 
DEFINE	OFFRUB<
	PUSHJ	P,.OFFRB
>
.OFFRB:	SKIPE	DPYFLG
	POPJ	P,
	TRZE	FL2,RUBF2
	OUTSTR	[ASCIZ /\\/]
	TRZE	FL2,RUBF
	OUTCHR	["\"]
	POPJ	P,
 
 
DEFINE	ONRUB<
	PUSHJ	P,.ONRUB
>
.ONRUB: SKIPE	DPYFLG
	POPJ	P,
	TRZE	FL2,RUBF2
	OUTSTR	[ASCII /\\/]
	TRON	FL2,RUBF
	OUTCHR	["\"]
	POPJ	P,
	SUBTTL	The -, Space, Tab, X, ^ and V Commands
 
; The - command
 
ALTNEG: TLO	FL,NEGF
	JRST	CPOPJ1##
 
; Here to accumulate digits
 
ALTDG:	IMULI	T2,^D10 	; Accumulate repeat count
	ADDI	T2,-"0"(C)
	JRST	CPOPJ1		; Skip return so at not to 0 rpt. cnt.
 
; The tab and space commands

ALTBOL:	PUSHJ	P,SAVR##	; Save T3-T5
	PUSHJ	P,CSRPOS	; Compute number of wraps
	PUSHJ	P,FIXWPC##	; Account for multiple of LINEW
	PJRST	UPCRSR##		; And position

$ATTAB::SKIPE	VT52FL
	TLNN	FL,NEGF		; -<TAB> on VT52?
	CAIA
	PJRST	ALTLN		; Yes, use more efficient ALTLN routine
	MOVSI	T2,1		; Large count
;	  ; Fall into space
$ALTSP::TLNE	FL,NEGF 	; Check backwards
	PJRST	ALTBS		; Yes: back space
	OFFRUB
	  ; 
ALTSP2: LDB	C,ALTP		; Get the chr we are pointing at
	CAIN	C,15		; If return then as far as can go
	PJRST	FORCE##
	TRNN	FL2,SUPN	; Special hack for xtend
	PUSHJ	P,OCHR##	; Print it
	IBP	ALTP		; Advance pointer
	AOS	ALTCNT		; And count
	SOJG	T2,ALTSP2	; Do correct number of times
	PJRST	FORCE## 	; Dump it
 
; Here for the V command (change case to end of line)
 
ALTXCH: SKIPN	NEWCMD		; SEE IF IN COMPATIBILY MODE
	  JRST	CLTCHW		; YES--TREAT LIKE #
CLTXCH:	MOVSI	T2,1		; Huge repeat count
;;	PJRST	ALTCHG		; Fall through to ^ command

; Here for the ^ command

ALTCHG: TRO	FL2,ALTDUP	; Start duplexing again
	TLNN	FL,NEGF 	; If going forward
	JRST	ALTCG0
	PUSH	P,T2		; Save count
	PUSHJ	P,ALTBS 	; Backspace
	EXCH	T2,(P)		; Restore count
	SUB	T2,(P)		; In case count was too large
ALTCG0: OFFRUB			; Terminate deletes and backspaces
ALTCG1: LDB	C,ALTP		; Get character
	CAIN	C,15		; Test for end of line
	JRST	ALTCG2		;  Yes, done
	MOVE	CS,CTBL(C)	; Get character's flag bits
	TLNE	CS,LETF_16	; Test for a letter
	TRC	C,40		;  Yes, invert the case
	DPB	C,ALTP		; Put character back
	PUSHJ	P,OCHR		; Type character
	IBP	ALTP		; Incr byte pointer
	AOS	ALTCNT		;  & character count
	SOJG	T2,ALTCG1	; Decr count & repeat
ALTCG2: TLNE	FL,NEGF 	; If going backward
	POP	P,T2		; Get garbage of the stack
	PJRST	FORCE		; Force typing out
 
; The X command
 
ALTELX:	SETZ	T2,		; Come here initially for the X command
	TLZA	FL,NEGF		; Clear negative flag
ALTEOL:	SKIPE	NEWCMD		; COMPATIBILITY MODE?
	 SKIPA			; NO
	  JRST	CLTWX		; YES--TREAT LIKE T
CLTEOL:	PUSH	P,T2		; SAVE POSSIBLE INCREMENT
	PUSHJ	P,ALTTAB##	; Go to end of line
	POP	P,T2		; Restore increment
	TLZ	FL,NEGF
	PJRST	ALTIN		; And go merge with insert
	SUBTTL	 The R and D Commands

; The R command

ALTRP:	PUSHJ	P,ALTDL		; Delete
	PUSHJ	P,V52TYP	; Type line so far
	PJRST	ALTINZ		; Then insert

; The D command
 
ALTXDL: MOVSI	T2,1		; Large repeat count
; 
ALTDL:	SETOM	CHGLNF		; Note can change print size of line
	TLNE	FL,NEGF 	; Backwards?
	JRST	ALTBDL		; Yes:
	MOVEM	ALTP,SVALTP	; Save current pointer posithon
ALTDL1: LDB	C,ALTP		; Get current chr
	CAIN	C,15		; At end of line?
	JRST	ALTDL5		; Yes, go finish off
	SKIPN	EXPFLG		; Print only if non-expert
	SKIPE	VT52FL		; Or in fancy disply mode
	CAIA
	PUSHJ	P,ALTDPN	; Yes: print char
	IBP	ALTP		; Advance pointer
	SOJG	T2,ALTDL1	; Check count and continue
ALTDL5: SKIPN	VT52FL		; If on a display
	SKIPN	DPYFLG		; Are we on a display?
	JRST	ALTDL6		; No--skip extra blank stuff
	MOVEI	C," "		; Yes--put out one more...
	PUSHJ	P,OCHR		; Blank to delete last character
	MOVE	C,BACCHR##	; Then put out a backspace...
	PUSHJ	P,OCHR		; To puts us back at the right point
ALTDL6: PUSHJ	P,FORCE 	; Force output
ALTDL3: MOVE	T3,SVALTP	; Get back pointer
ALTDL4: LDB	C,ALTP		; Move line down
	DPB	C,T3
	JUMPE	C,ALTDL2	; Done?
	IBP	ALTP		; Advance pointers
	IBP	T3
	JRST	ALTDL4
ALTDL2: MOVE	ALTP,SVALTP	; Restore pointer again
	POPJ	P,
 
; THE H COMMAND (Amputate the line from here and insert)
 
ALTAMP: MOVSI	T2,1		; Huge count
	PJRST	ALTRP		; Now do replace
 
; The P and ^R commands
 
ALTCTR:	SKIPN	VT52FL		; Display?
	PJRST	RPRINT		; No standard function
V52RTP:	SETOM	PRVSIZ		; Force retype
	PJRST	V52TPP		; and do it

RPRINT:	PUSH	P,ALTCNT	; Save current count
	PUSHJ	P,ALTLNN	; Restart the line
	PJRST	APRNT1
 
APRINT: SKIPE	VT52FL
	PJRST	V52RTP		; Do special thing for displays
	PUSH	P,ALTCNT	; Save current count
	PUSHJ	P,ALTLN 	; Print rest of line and start over
APRNT1: POP	P,T2		; Get back count
	JUMPN	T2,ALTSP##
	POPJ	P,
 
; Here to print characters as they are deleted
 
ALTDPN: SKIPE	DPYFLG		; On a display?
	JRST	DISDPN		; Do it right then
	PUSH	P,C
	MOVEI	C,"\"
	TRNN	FL2,RUBF2
	PUSHJ	P,OCHR
	TRZE	FL2,RUBF
	PUSHJ	P,OCHR
	TRON	FL2,RUBF2
	PUSHJ	P,OCHR
	POP	P,C
	JRST	OCHR
DISDPN: TLNN	FL,NEGF 	; Going backward?
	JRST	DSDPN2		; No, then go forward
	SETOM	DELBAK		; Set 'deleting backward' flag
	PUSHJ	P,RUBAK## 	; Backspace over the character
	PJRST	TYPSTR##	; Type eraser--returned in T1 by RUBAK##
; 
DSDPN2: CAIG	C," "		; Use blank to for non-printing chars
	MOVEI	C," "		; Map all special characters into a blank
	PUSHJ	P,OCHR		; Output deleted character
	MOVE	C,BACCHR##	; Code for backspace
	PJRST	OCHR		; Output and return
	SUBTTL	The I Command


;  The I command -- text insertion
 
ALTINZ: TLZ	FL,NEGF 	; Commands join here to terminate with
				; an I command.  R, T, !, H and M.
	SETZ	T2,		; Clear increment
; 
ALTIN:	TRO	FL2,ALTDUP	; Turn on duplexing
	MOVEM	T2,ALTINC	; Save in case he inserts a return
	MOVEI	T1,GNCH1##
ALTIN0:	MOVEM	T1,IGNCH##	; Set up routine to get characters
ALTIN1:	PUSHJ	P,@IGNCH##	; Get a character
	CAIN	C,233		; Finish on altmode
	POPJ	P,
	SETOM	CHGLNF		; Can change print size of line
	SETOM	DELBAK		; Like deleting backward
	CAIN	C,15		; Finish on CR
	JRST	ALTFNZ
	CAIN	C,12
	JRST	INSCR		; Go insert a CRLF
	CAIN	C,"U"-100+200	; A ^U?
	JRST	ALTCU		; Abort this disaster
	CAIE	C,"H"-100+200	; Is this a special delete char?
	CAIN	C,177		; Check for backspace
	JRST	ALTIBS		; And delete chr to left
	CAIN	C,"R"-100+200	; Did he type ^R?
	JRST	[PUSHJ	P,RPRINT
		 JRST	ALTIN1] ; Re-echo and loop for more
	CAIN	C,"W"-100+200	; ^W?
	JRST	ALTIWS		; Wordspace backward
	MOVE	T3,ALTP 	; Get set to shift things
	PUSH	P,ALTCNT	; Save this for later
	LDB	T1,T3		; Get chr from line
ALTIN2: DPB	C,T3		; Shift line
	JUMPE	C,ALTIN3	; Done
	AOS	ALTCNT		; Count it
	ILDB	C,T3
	DPB	T1,T3
	JUMPE	T1,ALTIN3	; Done
	AOS	ALTCNT		; Count
	ILDB	T1,T3
	JRST	ALTIN2
ALTIN3: MOVE	T2,ALTCNT	; See if overflow happened
	CAIL	T2,MXWPL*5
	NERROR	LTL		; Yes
	POP	P,ALTCNT	; Restore old count
	IBP	ALTP		; Advance pointer
	AOS	ALTCNT		; And count
ALTIN4:	PUSHJ	P,V52TPI	; Type if in VT52 mode
	JRST	ALTIN1		; Go get more
 
; Here to insert a CRLF (i.e. a new line)
 
INSCR:	OFFRUB
	SETOM	PRVSIZ		; Zap this, new line
	SKIPE	VT52FL		; Vt52?
	XCT	TMFCLN		; Clear to end of line
	OCRLF
	SKIPN	T1,ALTINC	; Did he specify an increment?
	SKIPA	T3,INCR 	; No, use standard
	PUSHJ	P,ASCON##	; Convert to ASCII
	MOVE	T1,T3		; Find the new line number
	MOVE	T2,LIBUF	; Current one
	PUSHJ	P,ASCIAD##	; Add
	PUSH	P,T1		; Save result
	PUSHJ	P,FINDN 	; Get the next one
	POP	P,T2
	CAMG	T2,LIBUF	; Is there a war problem
	JRST	INCBAD		; Yes, we must try to compute one
	JUMPE	T1,INCOK	; End of file, any inc is ok
	CAME	T1,PGMK 	; Also ok if a page mark
	CAMGE	T2,T1		; Or in correct order
	JRST	INCOK
INCBAD: CAME	T1,PGMK
	SKIPN	T1
	MOVE	T1,LNOVER##	; One over the top of the world
	MOVEM	T2,LIBUF2	; Save in case nothing will work
	MOVE	T2,LIBUF	; Get current
	PUSHJ	P,ASCAV##	; Find average
	CAME	T2,LIBUF	; There may have only been a dif of 1
	JRST	INCOK		; All is well
	RERROR	ORDER		; Tell him
	PUSHJ	P,FINDB##	; Get back where we belong
	PUSHJ	P,RPRINT 	; Type out line to current point
	JRST	ALTIN4		; And continue insert

INCOK:	MOVEM	T2,LIBUF2	; Save it
	MOVEM	T2,CLN		; And set as current line
	PUSHJ	P,FINDB 	; Back up to where we belong
	MOVE	T1,[XWD LIBUF+1,LIBUF2+1]
	BLT	T1,LIBUF2+MXWPL+1; Save old buffer
	PUSH	P,ALTP		; Save pointer
	MOVEI	C,15
	DPB	C,ALTP		; And terminate this line
	MOVEI	C,12
	IDPB	C,ALTP
	MOVEI	C,0		; Fill out line with nulls
AINSC2: TLNN	ALTP,760000
	JRST	AINSC3
	IDPB	C,ALTP
	JRST	AINSC2
AINSC3: SUBI	ALTP,LIBUF-1	; Find count
	HRRZM	ALTP,NCNT
	PUSHJ	P,INSED 	; Replace old line
	PUSHJ	P,FINDN 	; Move up to next
	SETZM	OCNT		; This is a new line going in
	MOVE	T1,LIBUF2	; Move line number over
	CAMLE	T1,HILN		; Is it smaller than HILN?
	MOVEM	T1,HILN		; No, make HILN consistent
	MOVEM	T1,LIBUF
	SETZM	LIBUF+1
	MOVE	T1,[XWD LIBUF+1,LIBUF+2]
	BLT	T1,LIBUF+MXWPL+1; Zero out rest
	POP	P,T2		; Restore pointer to rest of line
	MOVE	ALTP,[POINT 7,LIBUF+1]; Dest pointer
	ADD	T2,[XWD 70000,MXWPL+3]; Adjust input pointer
	MOVEI	C,11		; And set up the tab
MOVNEW: IDPB	C,ALTP
	CAIN	C,12
	JRST	DONNEW		; Finished moving rest of line
	ILDB	C,T2		; Pick up one
	JRST	MOVNEW
DONNEW: SUBI	ALTP,LIBUF	; Get count
	MOVEI	ALTP,1(ALTP)	; Used to be - movei ac,1-libuf(ac)
	MOVEM	ALTP,NCNT
	PUSH	P,ALTP		; And save
	PUSHJ	P,INSED 	; Insert
	MOVE	ALTP,[POINT 7,LIBUF+1,13]; Set up for alter
	SETZM	ALTCNT
	POP	P,OCNT		; Set for old count
	MOVE	T1,LIBUF
	PUSHJ	P,OUTSN##
	SETOM	ALTFLG		; We have inserted 
	JRST	ALTIN4		; And continue inserting
	POPJ	P,
 
; Here if he types a rubout in insert mode
 
ALTIBS: MOVEI	T2,0		; Set count to 0
	MOVEM	ALTP,SVALTP	; Save pointer
	PUSHJ	P,ALTBS 	; Do a backspace
	JUMPE	T3,ALTIN1	; If hit beginning of the line
	EXCH	ALTP,SVALTP	; Get back and save current
	PUSHJ	P,ALTDL3	; Delete that chr
	SKIPE	DPYFLG		; On a display?
	PUSHJ	P,TYPSTR##
	JRST	ALTIN4		; Get more
 
; Here on ^W in insert mode

ALTIWS:	MOVEI	T2,0		; Set count to 0
	TLO	FL,NEGF		; Set negative flag
	PUSHJ	P,ALTZNK	; Backup
	TLZ	FL,NEGF		; Clear it now
	JRST	ALTIN4		; Get next
;  THE O COMMAND -- Insert a single character
 
INSONE:	OFFRUB			; Issue pending backslashes
	MOVEI	T1,INSO1	; Next entry when insert want a character
	MOVEM	T2,INOCNT##	; Rep count for insertion
	SETOM	V52SPF
	PJRST	ALTIN0		; Start the insertion
; 
INSO1:	MOVEI	T1,INSO2	; Next entry
	MOVEM	T1,IGNCH	; Save it
	PUSHJ	P,AGNCH1##	; Read up next character
	MOVEM	C,INOCHR##
	CAIE	C,15		; Don't duplex carriage return
	CAIN	C,12		; or linefeed
	POPJ	P,
	PJRST	OCHR		; Duplex the character
; 
INSO2:	SOSG	INOCNT		; Count satisfied?
	JRST	INSO3		; Terminate
	MOVE	C,INOCHR	; Restore character to insert
	CAIE	C,12		; Don't print a linefeed
	PJRST	OCHR		; Output it again
	POPJ	P,		; Return to insert routine
; 
INSO3:	MOVEI	C,233		; Termination character
	SETZM	V52SPF
	PJRST	FORCE
 
;  The semicolon command -- insert a <CR> <LF> to break the current line

INSCRF:	MOVEI	C,12
	PJRST	INSCHR

;  THE B COMMAND -- Insert one or more blanks (short for nO<blank>)
 
INSBLK:	MOVEI	C," "		; Blank character
INSCHR:	MOVEM	C,INOCHR	; Pass it for one character insert code
	SETOM	V52SPF		; Kill typeout by insert for awhile
	SKIPN	T2		; Zero implies one
	MOVEI	T2,1		; Adjust it
	AOS	T2		; Fudge count
	MOVEM	T2,INOCNT	; Set up the count
	MOVEI	T1,INSO2	; Address for character repetition
	PJRST	ALTIN0		; Go insert the characters

; The + command -- duplicate the current character
 
INSNXT:	OFFRUB
	PUSHJ	P,ALTBAK	; Peek at previous character
	JUMPE	T3,CPOPJ##	; If at beginning of line
	MOVE	C,T3		; Character under cursor
	IBP	ALTP		; Reset pointer
	CAIN	C,15		; If a null line
	JRST	ERRRTN		; This is an error
	PJRST	INSCHR		; Else output it
 
; Here for the ' command
 
INSQT:	OFFRUB			; As usual
	PUSHJ	P,AGNCH1##	; Go get his character
	CAIG	C,100		; Make sure it will be gt 0
	JRST	ERRRTN		; Nope, bong the gong
	TRZ	C,777640	; Clear parity and convert to UC
	SUBI	C,100		; Make it a control character
	CAIE	C,15		; Bare carriage returns confuse SOS
	CAIN	C, 12		; and so do linefeeds
	JRST	ERRRTN		; Bong the gong
	JRST	INSCHR		; Do, O, + and B thing
 
	SUBTTL	The F Command
 
;  The F command
 
ALTFS:	PUSHJ	P,ALTFG 	; Get search string
; 
ALTFSR: PUSH	P,T2
	PUSH	P,ALTP
	PUSH	P,ALTCNT
	SETZM	INOCNT
; 
ALTFS1: LDB	C,[POINT 7,AFSBUF##,6]; Break character for search
	MOVEI	T2,1
	TLNE	FL,NEGF 	; Skip if going forward
	PUSHJ	P,[PUSH P,ALTP
		   AOS	-1(P)
		   JRST ALTBC1]
	PUSHJ	P,ALTCS 	; Look for instance of initial character
	ADDM	T2,INOCNT
	CAIN	T3,15		; Give up if the search fails
	JRST	ALTFS2
	JUMPE	T3,ALTFS2	; If search fails going backward
	SKIPE	T2		; Don't space if zero
	PUSHJ	P,ALTSSP	; Space over to it
	PUSHJ	P,ALTCMP	; Is it the one we're looking for
	  JRST	ALTFS1		; No, try for another
	POP	P,ALTCNT	; Restore count
	POP	P,ALTP		; And pointer
	SKIPE	T2,INOCNT	; Get count
	PUSHJ	P,ALTSP## 	; Space over that many
	POP	P,T2
	SOJG	T2,ALTFSR	; Do search specified number of times
	POPJ	P,
 
	SUBTTL	Subroutine to Read in a Search String
 
ALTFG:	OFFRUB			; Terminate any rubouts or deletes
	MOVEI	T4,^D19 	; Max search string length
	MOVE	T3,[POINT 7,AFSBUF##-1,34]; Pointer to buffer
ALTG1:	PUSHJ	P,GNCH1## 	; Get a character for search string
	CAIN	C,15		; Is it <CR>
	JRST	ALTG2		; Denotes string at eol
	CAIN	C,233		; End of search string
	JRST	ALTG3		; Yep
	CAIN	C,"U"-100+200	; Negative acknowlege?
	JRST	ALTFG		; Take it again from the top
	CAIE	C,"H"-100+200	; Yes, do we have a backspace?
	CAIN	C,177		; Rubout?
	JRST	[CAMN	T3,[POINT 7,AFSBUF-1,34]
		 JRST	ALTG1
		 ADD T3,[POINT 0,0,28]
		 TLNE T3,(1B0)
		 SUB T3,[POINT 0,1,0]
		 AOJA T4,ALTG1]
	TRZ	C,200		; Clear special bits for anything else
	CAIL	C,140		; Skip if not lower case
	TDZ	C,AEXACF	; Conditionally convert to upper
	IDPB	C,T3		; Save this character in sstr buffer
	SOJG	T4,ALTG1	; Try for another
; 
	JRST	ER1RTN		; The search string is too long
 
ALTG2:	IDPB	C,T3		; Put <CR> in search string
	PUSHJ	P,GNCH1## 	; Swallow the line feed
; 
ALTG3:	SETZ	C,		; End of string marker
	CAIE	T4,^D19 	; If null string, T4 is still 19
	IDPB	C,T3		; Mark it
	POPJ	P,		; Return
 
	SUBTTL	The G Command
 
ALTGT:	MOVEI	T1,ALTSP##	; Set up for spacing
	MOVEM	T1,ALTWPR##	; Leave it for indirect branch
ALTGTS: PUSHJ	P,ALTFG 	; Get string to search for
	CAIN	T2,0
	MOVEI	T2,1		; Make positive
	TLNN	FL,NEGF 	; Going backward
	JRST	ALTG1A		; If not
	PUSH	P,[ALTG1B]
	PUSH	P,T2
	PUSH	P,ALTP
	PUSH	P,ALTCNT	; Save state in case search fails
	PUSHJ	P,LFSBUF
	MOVEM	T2,INOCNT
	PUSHJ	P,ALTSSP	; Silent space over the string
	JRST	ALTFS1		; Do the search
 
ALTG1A: TLO	FL2,L2.SSI	; Allow G to skip F string
	PUSHJ	P,ALTFSR	; Do the search
ALTG1B: JUMPL	T2,CPOPJ	; If search failed
	PUSHJ	P,LFSBUF	; Get length of search string
	TLZ	FL,NEGF 	; Clear negative flag
	JRST	@ALTWPR##	; Process search string
 
;  Routine to compute length of the search string (Returned in T2)
 
LFSBUF: MOVE	T1,[POINT 7,AFSBUF]; Start of search string
	SETZ	T2,		; Initialize count
; 
LFSBF1: ILDB	C,T1		; Get character from search string
	JUMPE	C,CPOPJ
	AOJA	T2,LFSBF1	; Increment count
	SUBTTL	The Y and M Commands


; The y command
 
ALTYK:	MOVEI	T1,ALTDL	; Process is deletion
	MOVEM	T1,ALTWPR##	; Pass it
	PJRST	ALTGTS		; And do like G command
 
; The m command
 
ALTAMD: PUSHJ	P,ALTYK 	; First do a Y
	JUMPL	T2,CPOPJ##	; Just quit on error
	PUSHJ	P,V52TYP	; Now type the results
	PJRST	ALTINZ		; Then an insert
	SUBTTL	The Character-Search Commands: S, K, ! and "


; The ! command -- K followed by I
 
ALTKI:	PUSHJ	P,.ALTSR	; Get the count
	JUMPLE	T2,CPOPJ	; If nothing to do
	PJRST	ALTRP		; Else make like replace
 
; The S, K and " commands
 
ALTKL:	PUSHJ	P,.ALTSR	; Go do search thing
	JUMPLE	T2,CPOPJ	; If nothing to do
	PJRST	ALTDL		; Then go delete
 
ALTSIC: PUSHJ	P,.ALTSR	; Search
	JUMPLE	T2,CPOPJ	; If nothing to do
	PJRST	ALTCHG		; and change case

ALTSR:	PUSHJ	P,.ALTSR	; Get the count
	JUMPLE	T2,CPOPJ	; If nothing to do
	PJRST	ALTSP##		; And then space over

.ALTSR: PUSHJ	P,AGNCH1##	; Get character to search for
	CAIN	C,15		; Carriage return is end of line
	JRST	.ALTSC		; Fake it
	CAIL	C,140		; Lower case
	TDZ	C,AEXACF	; Map upper/lower if desired
	PUSH	P,ALTP
	PUSH	P,ALTCNT	; Save these
	SETZM	INOCNT		; Clear counter
	MOVEM	C,INOCHR	; Save targent character
; 
.ALTS1: PUSH	P,T2
	MOVE	C,INOCHR	; Restore character
	PUSHJ	P,ALTCS
	CAIE	T3,0		; Off front end - skip
	CAIN	T3,15		; or if reached end of line
	JRST	[OUTCHR [7]	; Type a bell
		SETZM  (P)	; Clear remaining count
		JRST   .ALTS2]	; And use what we have
	ADDM	T2,INOCNT	; Accumulate repitition count
	PUSHJ	P,ALTSSP	; Space over
.ALTS2: POP	P,T2
	SOJG	T2,.ALTS1
	POP	P,ALTCNT	; Restore counter
	POP	P,ALTP		; and pointer
	MOVE	T2,INOCNT	; Restore count
	TLNE	FL,NEGF 	; Backward?
	SUBI	T2,1		; Go one less
	POPJ	P,
 
 
 
.ALTSC: PUSHJ	P,GNCH1## 	; Swallow line feed
	MOVSI	T2,1		; Force end of line with huge count
	POPJ	P,		; And return
 
; Common search routine
 
ALTCS:	MOVEI	T2,1		; Create a repeat count
	TLNE	FL,NEGF 	; Backwards?
	JRST	ALTBCS		; Yes: search backwards
	LDB	T3,ALTP 	; Chec to see if at end of line
	CAIN	T3,15
	POPJ	P,
	MOVE	T1,ALTP 	; Get a copy of the pointer
	TLNE	FL2,L2.SSI	; Suppress?
	MOVEI	T2,0		; Yes, clear space count
ALTCS1: TLZN	FL2,L2.SSI	; Suppress incrementing?
	IBP	T1		; No, increment pointer
	LDB	T3,T1		; Get a character
	CAIL	T3,140		; Lower case
	TDZ	T3,AEXACF	; Conditionally convert
	CAIE	T3,15		; Done if end of line
	CAMN	T3,C		; Or a match
	POPJ	P,
	AOJA	T2,ALTCS1	; Else keep count and keep looking
 
ALTCMP: MOVE	T3,[POINT 7,AFSBUF##]; Pointer to alter search buf
	MOVE	T4,ALTP 	; Copy of current pointer
	LDB	C,T4		; Current source character
ALTCM1:	CAIL	C,140
	TDZ	C,AEXACF
	ILDB	T1,T3		; Next target character
	JUMPE	T1,CPOPJ1	; Done, it matched!
	CAIL	T1,140		; Lower case?
	TDZ	T1,AEXACF##	; Conditionally fix
	CAIE	C,(T1)		; Do they match
	POPJ	P,		; No match this time
	ILDB	C,T4		; Get next source character
	JRST	ALTCM1		; And compare it too
 
	SUBTTL	Commands that Exit the Line:  Q, ^U, E, <CR>, <LF> and N


; The Q command
 
ALTALT: OFFRUB
	SKIPE	VT52FL		; On a display?
	PUSHJ	P,[PUSHJ P,ALTBOL ; Position to front of line
		XCT TMFCTE	; Clear rest of screen
		PUSHJ	P,SETALT	; Setup unmodified line
		TLZ	FL,NEGF		; And let ALTTAB go forward
		PJRST	ALTTAB##]
	SKIPE	ALTFLG
	PUSHJ	P,FINDN##
	ONECHO
	JRST	T1POPJ##


; The N command--advance to next or previous line

ALTNXL:	PUSH	P,T2		; Save count
	PUSH	P,[0]		; Save a zero as a flag
	TLZE	FL,NEGF		; Clear this before ALTFN
	SETOM	(P)		; Note that command is negative
	PUSHJ	P,[PUSHJ P,ALTFN] ; End this line.  ALTFN prunes PDL.
	  JFCL			; Ignore skip return
	PUSHJ	P,AINSED	; Insert corrected line
	SKIPE	(P)		; Negative argument?
	OUTSTR	[ASCIZ/ 
/]				; Blank line, even if TTY NO BLANKS
ALTNX1:	SKIPN	(P)		; Forward?
	PUSHJ	P,FINDN		; Find next
	SKIPE	(P)		; Backward?
	PUSHJ	P,FINDB		; Find previous
	JUMPE	T1,ALTNLN	; If no next line
	CAMN	T1,PGMK		; Page mark?
	JRST	ALTNPG		; No next line
	PUSHJ	P,SETALT	; Setup next line for alter
	POP	P,T2		; Get negative flag
	SKIPE	T2		; Was NEGF set?
	TLO	FL,NEGF		; Yes, relight it in the flag register
	POP	P,T2		; Restore the count
	MOVE	T1,LIBUF	; New line number
	MOVEM	T1,CLN		; Make this current now
;	MOVEM	T1,HILN		; Redefine top of range
	MOVE	T1,CPG		; Current page
	MOVEM	T1,CPGL		; Make it the current logical page
;	MOVEM	T1,HIPG		; ..and page at top of range
	SOJG	T2,ALTNXL
	POPJ	P,		; Continue with this stuff

ALTNLN:	RERROR	NLN
ALTNL0:	SKIPN	(P)		; Negative
	PUSHJ	P,FINDB		; Backup to previous
	CAME	T1,PGMK		; Is this a page mark?
	JRST	ALTNL1		; No
	MOVE	T2,CPG		; Get the current page
	SKIPE	(P)		; Going backward?
	AOS	T2		; Yes, off by one
	PUSHJ	P,PGPRN##	; Retype
	JRST	ALTNL0		; Go look again

ALTNL1:	ADJSP	P,-1
	POP	P,T2
	PJRST	SETALT
 
ALTNPG:	MOVE	T2,CPG		; Current page
	SKIPN	(P)		; If negative
	AOS	T2		; Do not adjust
	PUSHJ	P,PGPRN##	; Type it so he knows
	JRST	ALTNX1

; The CR command
 
ALTFNZ:	PUSHJ	P,GNCH1##
	LDB	C,ALTP		; Current character
	CAIN	C,15		; End of line?
	MOVMS	XCMDF		; Indicate CR end
	PJRST	ALTFN
; 
; Here if <LF> was typed without CR
; 
ALTEX:	SKIPN	VT52FL		; On a display?
	TRO	FL2,SUPN	; No, E means suppress typeout
ALTFN:	PUSHJ	P,V52TPP	; Make sure display is okay.
	SKIPE	VT52FL		; On a display?
	TRO	FL2,SUPN	; Yes, suppress unecessary typeout
	PUSHJ	P,CSRPOS	; Get cursor position
	PUSHJ	P,FIXWPC##	; Fix wrap count for wrap waiting
	MOVE	T5,WRPCNT	; Save count of wraps
	PUSHJ	P,ALTTAB##	; Space to end of line
	TRZ	FL2,SUPN	; Clear suppress flag
	SKIPN	VT52FL		; VT52?
	JRST	ALTFNX		; No, line was just typed
	PUSHJ	P,PRNTSZ	; Get the print size of the line
	PUSHJ	P,FIXWPC##	; Fix wrap count for wrap waiting
	SUB	T5,WRPCNT	; Difference in line position
LFLUP:	JUMPGE	T5,ALTFNX	; If none
	OUTCHR	[12]		; Extra line feed
	AOJA	T5,LFLUP	; Keep checking

ALTFNX:	PUSHJ	P,ALTFNL	; Finish the line
	JRST	T1PPJ1##	; Prune PDL and give skip return

; Routine to finish up line currently being altered and setup NCNT
; for INSED.

ALTFNL:	OCRLF
	ONECHO			; Get out of non-duplex mode
ALTFN1: ILDB	C,ALTP		; Look one chr over
	CAIE	C,12		; This should be the line feed
	NERROR	ILFMT		; Something is wrong
	MOVEI	C,0		; Zero remainder of line
ALTFN2: TLNN	ALTP,760000	; All done?
	JRST	ALTFN3		; Yes
	IDPB	C,ALTP		; No, put in another 0
	JRST	ALTFN2
ALTFN3: SUBI	ALTP,LIBUF-1	; Get size of new line
	HRRZM	ALTP,NCNT	; And save for insed
	POPJ	P,
 
; The ^U command
 
ALTCU:	SKIPE	VT52FL
	JRST	[PUSHJ	P,ALTBOL
		 XCT TMFCTE ; Clear rest of screen
		 SETOM  PRVSIZ	; For retype of whole line
		 PJRST SETALT]
	OFFRUB
	OUTSTR	[ASCIZ /^U
/]
	PJRST	SETALT		; Go restart line and forget edit so far
 
	SUBTTL	The \ and / commands


; THE / COMMAND -- Transpose the next two letters
 
; THE \ COMMAND  (Same as -/)
 
ALTBSL: TLC	FL,NEGF 	; Complement neg flag and do / command
; 
ALTSL:	TLNE	FL,NEGF 	; Backward?
	JRST	ALTSLB		; Backup a couple
ALTSL1: LDB	T1,ALTP 	; Next character in buffer
	MOVE	T2,ALTP 	; Save its position
	ILDB	C,ALTP		; and the next one after that
	CAIE	T1,15		; Is it carriage return?
	CAIN	C,15		; Same
	JRST	ALTSL2		; Command not valid at end of line
	CAIL	C,40		; Special?
	CAIGE	T1,40		; (either one)
	SETOM	CHGLNF		; Yes, line size might change
	OFFRUB
	PUSHJ	P,OCHR		; Output 2nd character
	DPB	C,T2		; And make it the first
	MOVE	C,T1		; Now for the second
	PUSHJ	P,OCHR		; Output it too
	DPB	C,ALTP		; Add first character to buffer
	IBP	ALTP		; And advance pointer
	PUSHJ	P,FORCE 	; Make them visible
	AOS	ALTCNT
	AOS	ALTCNT		; Increment alter count by two
	POPJ	P,		; And return
; 
ALTSLB: MOVEI	T2,2		; Count for backspace
	PUSHJ	P,ALTSP## 	; Space back two
	JRST	ALTSL1		; Join common processing 
; 
ALTSL2: MOVE	ALTP,T2 	; Restore pointer
	ADJSP	P,-1		; Pop junk off the PDL
	JRST	ALTBEL		; Signal error
	SUBTTL	The J command.  Join to Next Line

; The J command
 
AJOIN:	OFFRUB
	SETOM	PRVSIZ		; Zap this, new line configuration
	TLNE	FL,NEGF		; Backward?
	JRST	MJOIN		; This is special
AJOIN0:	PUSH	P,T2
	PUSHJ	P,FINDN 	; Go see if next line is really there
	CAME	T1,PGMK
	SKIPN	T1
	JRST   [RERROR  NNN
		PUSHJ	P,FINDB	; Refind the line
		POP	P,T2
		JRST	RPRINT]
	PUSHJ	P,GETLTH##	; Get line length, make sure it in core
	PUSH	P,T1		; Save length for later
	PUSHJ	P,ALTTAB##	; Space to end of line
	MOVEI	T2,1(PNTR)	; Point past line number
	HRLI	T2,(POINT 7,0,6); Point to first character
	MOVEI	T3,MXWPL*5-6	; Maximum length
	SUB	T3,ALTCNT	; Minus what we already have
	PUSH	P,ALTP		; Save pointer to this line
JOIN1:	ILDB	C,T2		; Fetch a character
	DPB	C,ALTP		; Store the character in the line
	IBP	ALTP		; Advance the pointer
	CAIN	C,12		; Line feed?
	JRST	JOIN2		; Yes, end of line
	SOJG	T3,JOIN1	; Loop to end of line
	MOVE	ALTP,(P)	; Restore ALTP
	MOVEI	C,15		; Line feed
	IDPB	C,ALTP		; Store
	MOVEI	C,12		; Line feed
	IDPB	C,ALTP		; Store
	RERROR	LTL		; Line too long
	POP	P,ALTP
	PUSHJ	P,FINDB
JOINER:	POP	P,T1
JOINR1:	POP	P,T2
	PJRST	RPRINT		; Re-type it

JOIN2:	PUSHJ	P,INSTRZ	; Add trailing zeros
	POP	P,ALTP		; Restore ALTP
	PUSHJ	P,FINDB		; And back to old line
	POP	P,T1		; Restore line length
	ADDM	T1,OCNT		; Increase words to delete
	PUSHJ	P,INSJLN	; Insert the joined lines
	POP	P,T2		; Restore remaining count
	SOJG	T2,AJOIN0	; Join as many as he wants
	PJRST	V52TPN		; Then type line on VT52
	SUBTTL	The -J command -- Join to Previous Line

; Here for -J command.

MJOIN:	PUSH	P,T2
	PUSHJ	P,BUFLEN	; Get length of line
	PUSH	P,T1		; Save word count
	PUSHJ	P,FINDB		; Find the previous line
	CAME	T1,PGMK
	SKIPN	T1
	JRST	[RERROR NLN	; No such line
		 CAMN   PNTR,BUFFIR
		 PUSHJ	P,FINDN
		 JRST   JOINER]
	PUSHJ	P,GETLTH	; Get length of this one
	MOVE	T2,T1		; Make a copy
	ADD	T2,(P)		; Compute sum
	POP	P,(P)
	CAILE	T2,MXWPL+1	; See if it will fit
	JRST	[RERROR LTL
		 CAMN	PNTR,BUFFIR
		 PUSHJ	P,FINDN
		 JRST	JOINR1]
	ADDM	T1,OCNT		; Increment count of words to delete
	MOVSI	T1,-MXWPL	; Max line length
	SETZM	LIBUF2(T1)	; Clear a word
	AOBJN	T1,.-1		; Loop over whole buffer
	SKIPE	VT52FL		; On a display?
	PUSHJ	P,ALTBOL	; Go to beginning of the line
	MOVE	T4,[POINT 7,LIBUF2]
	MOVE	T2,[POINT 7,LIBUF+1,6]	; Point to data
; 
MJOIN1:	ILDB	C,T2		; Get a character from current line
	IDPB	C,T4		; Stash in second line buffer
	CAIE	C,12		; End yet?
	JRST	MJOIN1		; No
	PUSHJ	P,LOADCL##	; Load that line
	MOVE	ALTP,[POINT 7,LIBUF+1,6]	; Point to that data
	SETZM	ALTCNT		; Set count at beginning
MJOIN3:	ILDB	C,ALTP		; Get a character
	CAIN	C,15		; Is it end of text line
	JRST	MJOIN4		; Yes
	AOS	T2,ALTCNT	; Increment count
	JRST	MJOIN3		; Loop over whole line

MJOIN4:	MOVE	T3,[POINT 7,LIBUF2]	; Point to old line
MJOIN5:	ILDB	C,T3		; Fetch a character
	DPB	C,ALTP		; Store this one next
	IBP	ALTP		; Then increment the pointer
	CAIE	C,12		; End of line yet?
	JRST	MJOIN5		; No, keep looking
	PUSHJ	P,INSTRZ	; Add trailing zeros
	TLZ	FL,NEGF		; Clear neg-flag
	PUSHJ	P,INSJLN	; Insert the line into the buffer
	PUSHJ	P,RPRINT
	POP	P,T2		; Restore this
	SOJG	T2,MJOIN
	POPJ	P,
	SUBTTL	Support Routines for J and -J Commands


; Subroutine to compute the length of the line in LIBUF
; 
BUFLEN:	MOVE	T2,[POINT 7,LIBUF+1,6]	; First character
	MOVEI	T1,7		; Minimum length
BUFLN1:	ILDB	C,T2		; Character
	CAIE	C,12		; End of line?
	AOJA	T1,BUFLN1	; Increment count and keep looking
	ADDI	T1,4		; Round to whole words
	IDIVI	T1,5		; Compute words required
	POPJ	P,


; Subroutine to install a joined line
; Call
; New line in LIBUF, OCNT setup with length of old lines
; Returns with OCNT set to old value of NCNT, line in buffer
; 
INSJLN:	PUSHJ	P,BUFLEN	; Words in joined line
	MOVEM	T1,NCNT		; Insert that many
	PUSHJ	P,INSED		; Install the new line
	MOVE	T1,NCNT
	MOVEM	T1,OCNT		; Make that the old count
	POPJ	P,


; Routine to add trailing zeros to the last word in the line
; Call with ALTP setup pointing to first character after the LF

INSTRZ:	MOVEI	C,0		; Get a zero
INSTR1:	DPB	C,ALTP		; Add one
	TRNN	ALTP,760000	; At end of word?
	POPJ	P,		; Yes, done
	IBP	ALTP		; No, advance one character
	JRST	INSTR1		; And clear next
	SUBTTL	The W Command -- Space Over by Words

; The W command
 
ALTBSW:	TLC	FL,NEGF		; Same as space only backward
ALTWD:	MOVEI	T1,ALTSP##	; Set spacing routine
; 
.ALTWD: MOVEM	T1,ALTWPR	; Process to perform for word stuff
	OFFRUB
; 
ALTWD1: PUSH	P,ALTP		; Save pointer
	TLNN	FL,NEGF 	; Going backward
	TDZA	T1,T1		; Set T1 to zero and skip
	SETO	T1,		; Set T1 to -1
	PUSH	P,T1		; Sum of characters seen in word skip
	PUSH	P,T2		; Save count if any
; 
ALTWD2: TLNE	FL,NEGF 	; If forward
	JRST	ALTWD3		; If going backward
; 
	PUSHJ	P,ALTWS 	; Skip over word
	JRST	ALTWD4		; 
; 
ALTWD3: PUSHJ	P,ALTWBS	; Move to beginning of previous word
	AOS	-1(P)		; Fudge factor
; 
ALTWD4: ANDI	T2,-1		; Clr flag in case
	ADDM	T2,-1(P)	; Tally spacing count
	SOSLE	(P)		; Count down number of words
	JRST	ALTWD2		; Loop again if more to do
; 
	POP	P,(P)		; Clear counter from stack
	POP	P,T2		; Get length of words skipped
	POP	P,ALTP
	PJRST	@ALTWPR 	; Do specified operation
 
; Routine to skip over next word
 
ALTWS:	HRROI	T2,0		; Set flg and count
	LDB	T3,ALTP 	; Get current character
	JRST	.+2		; Skip increment
ALTWS1: ILDB	T3,ALTP 	; Get a character
	CAIN	T3,15		; Done if end of line
ALTWS2: POPJ	P,		; Quit
	MOVE	T3,CTBL(T3)	; Fetch character table entry
	JUMPE	T3,ALTWS4	; Skip blanks etc...
	ANDI	T2,-1		; Clr flag
	JUMPG	T3,ALTWS3	; Skip letters & numbers
	TRNN	FL2,QSEPF	; Separators
	TRNN	T3,NSEPF	; Today
	JRST	IPOPJ		; Real break - quit!
ALTWS3: AOJA	T2,ALTWS1	; Keep count and continue
ALTWS4: JUMPL	T2,ALTWS3	; First blnks
	AOS	T2
ALTWS5: ILDB	T3,ALTP
	CAIE	T3,15		; Quit on CR
	SKIPE	CTBL(T3)	; Or first non-blank
	POPJ	P,
	AOJA	T2,ALTWS5
 
IPOPJ:	TRNE	T2,777777	; Test count for zero
	POPJ	P,		; Non-zero:  just return
	IBP	ALTP		; Increment alter pointer
	AOJA	T2,CPOPJ	; Increment count and return
	SUBTTL	Commands that Process by Words.  T, Z, and #.
 
 
; The T command
 
ALTWX:	SKIPN	NEWCMD		; COPATIBILITY MODE?
	  JRST	CLTEOL		; YES--TREAT LIKE X
CLTWX:	PUSHJ	P,ALTZNK	; Delete the words
	PUSHJ	P,V52TYP	; Fix line
	PJRST	ALTINZ		; Do insert
 
;  THE Z COMMAND -- Zonk the next word
 
ALTZNK: MOVEI	T1,ALTDL	; Processing is deleting
	PJRST	.ALTWD
 
; The # command; change case for words
 
ALTCHW: SKIPN	NEWCMD		; COMPATIBILITY MODE?
	  JRST	CLTXCH		; YES--TREAT LIKE V
CLTCHW:	MOVEI	T1,ALTCHG	; Processing is case change
	PJRST	.ALTWD		; Now go do it
 
	SUBTTL	The C Command

; The C command
 
ALTCN:	OFFRUB
	TLNN	FL,NEGF 	; Going forward?
	JRST	ALTCN2
	PUSH	P,T2		; Save count
	PUSHJ	P,ALTSP## 	; Backup
	EXCH	T2,(P)
	SUB	T2,(P)
	POP	P,T1
ALTCN2: LDB	C,ALTP		; At end of line?
	CAIN	C,15
	POPJ	P,		; Yes, stop
	CAIGE	C," "		; Normal graphic character?
	SETOM	CHGLNF		; No, line size may change then
ALTCN1: PUSHJ	P,AGNCH1##	; Get a character
	CAIE	C,177		; Do not let him insert a rubout
	CAIN	C,12		; Ignore carriage return
	JRST	ALTCN1
	CAIE	C,33		; Stop on altmode and line feed
	CAIN	C,15
	POPJ	P,
	CAIGE	C," "		; Normal graphic character?
	SETOM	CHGLNF		; No, line size may change then
	PUSHJ	P,FOCHR##	; Duplex character
	DPB	C,ALTP		; Replace it
	IBP	ALTP		; Advance pointer
	AOS	ALTCNT		; And count
	PUSHJ	P,V52TPN	; Clean up the line
	SETZM	CHGLNF		; Clear flag if set
	SOJG	T2,ALTCN2	; Continue
	POPJ	P,
	SUBTTL	Spacing Routines 

; Subroutine to move alter pointer without changing display
; Call like ALTSP
 
ALTSSP: TLNE	FL,NEGF 	; Silent Space backward?
	JRST	ALTSBS		; Do silent back space then
ALTSS1: LDB	C,ALTP		; Fetch a character
	CAIN	C,15		; See if it is a CR
	POPJ	P,		; It is, so stop
	IBP	ALTP		; No, increment pointer
	AOS	ALTCNT		;  and count
	SOJG	T2,ALTSS1	; Loop until space request satisfied
	POPJ	P,		; Then return
 
; Here for silent space backward
 
ALTSBS: PUSHJ	P,ALTBAK	; Backup
	JUMPE	T3,CPOPJ	; Stop if beginning of line
	SOS	ALTCNT		; Decrement counter
	SOJG	T2,ALTSBS	; Loop until request satisfied
	POPJ	P,		; Then return
 
; The backspace command
 
ALTBS:	PUSHJ	P,ALTBAK	; Get previous char
	JUMPE	T3,ALTCBS	; Jump if done
	ONRUB
	SOS	ALTCNT		; Decrease count
	MOVE	C,T3
	SKIPN	DPYFLG		; Non display device?
	PUSHJ	P,OCHR
	SKIPE	DPYFLG		; On a display?
	PUSHJ	P,RUBAK## 	; Backspace the real way
	SOJG	T2,ALTBS	; More, more
	PJRST	FORCE

ALTCBS: PUSHJ	P,FORCE 	; Finish buffer
	SKIPN	DPYFLG		; Just return if on display
	JRST	ALTCB1		; Normal mode, output SN.
	SETZ	T1,		; Clear T1 to avoid ill mem ref
	POPJ	P,

PRNTSN: PUSHJ	P,FORCE 	; Finish print line
ALTCB1: OFFRUB			; No more rub
	SKIPN	VT52FL
	OCRLF
	SKIPE	VT52FL
	OUTCHR	[15]
	MOVE	T1,LIBUF	; Also print seq num
	PJRST	OUTSN
 
; The L command
 
ALTLN:	SKIPE	VT52FL		; On a fancy display?
	JRST	[PUSHJ P,ALTBOL	; Position to front
		 JRST ALTLNN]	; Then re-type sequence number
	MOVEI	T2,1000 	; Finish printing the line
	PUSHJ	P,ALTSP##
ALTLNN: MOVE	ALTP,[POINT 7,LIBUF+1,13]; Pointer to start
	SETZM	ALTCNT		; Reset count
	PJRST	PRNTSN		; And reprint line number
 
; Common routines to backup in a line
 
ALTBAK: CAMN	ALTP,[POINT 7,LIBUF+1,13]
	PJRST	ALTRTZ		; Return zero if at beginning
	ADD	ALTP,[POINT 0,0,28]
	TLNE	ALTP,(<1B0>)	; Check word overflow
	SUB	ALTP,[POINT 0,1,0]
	LDB	T3,ALTP 	; Get char
	POPJ	P,
; 
ALTRTZ: MOVEI	T3,0		; Return 0
	POPJ	P,
 
	SUBTTL	Backward Deletion Routine

; Routine to do backwards deletion
 
ALTBDL: MOVEM	ALTP,SVALTP	; Save pntr
ALTBD1: PUSHJ	P,ALTBAK	; Back a char
	JUMPE	T3,ALTBD2	; Done if no more
	SOS	ALTCNT		; Decrement count
	MOVE	C,T3		; For printing
	PUSHJ	P,ALTDPN
	SOJG	T2,ALTBD1
ALTBD2: PUSHJ	P,FORCE 	; Force printing
	PUSH	P,ALTP		; Save new pntr
	MOVE	T3,SVALTP	; Get set to move line
ALTBD3: LDB	C,T3
	DPB	C,ALTP		; Move char
	JUMPE	C,APOPJ		; Done if zero
	IBP	T3		; Advance pntrs
	IBP	ALTP
	JRST	ALTBD3

;CSRPOS -- Routine to return the relative cursor position
;
;Call with
;	PUSHJ	P,CSRPOS
;	<Return here with position in T4, wrap count in WRPCNT>
;Uses T1, T2, T4 and C

CSRPOS:	MOVE	T2,[POINT 7,LIBUF+1,6]; Initialize pointer a line start
	LDB	T4,PMTSZP##	; Get prompt length
	SETZM	WRPCNT##	; Zero the wraparound count
	JSP	T1,.+1		; Set up T1 for later returns
RBK0:	ILDB	C,T2		; Next character from buffer
	CAME	T2,ALTP 	; Up to current position yet
	JRST	RBC##		; Compute length of this character
	POPJ	P,		; Return, size is in T4
 
; Routine to do backwards search
 
ALTBCS: PUSH	P,ALTP		; Save pntr
	ADDI	T2,1		; Advance pointer
	PUSHJ	P,ALTBAK	; Don't look at first character
ALTBC1: PUSHJ	P,ALTBAK	; Prev char
	JUMPE	T3,APOPJ	; End of line
	CAIL	T3,140
	TDZ	T3,AEXACF
	CAME	T3,C		; Match?
	AOJA	T2,ALTBC1	; No: count and continue
	JRST	APOPJ## 	; Restore ALTP and return


; Routine to do a backward word search

ALTWBS:	HRROI	T2,0		; Set flag and count
ALTWB1: PUSHJ	P,ALTBAK	; Get the previous character
	JUMPE	T3,CPOPJ	; and return if at beginning of line
	MOVE	T3,CTBL(T3)	; Look up character in the char table
	JUMPE	T3,ALTWB3	; Skip over spaces and so forth
	ANDI	T2,-1		; and signal that we found something
	JUMPG	T3,ALTWB2	; Skip letters and numbers
	TRNN	FL2,QSEPF	; 
	TRNN	T3,NSEPF	; Seperator flag set?
	POPJ	P,		; Restore ALTP and return
ALTWB2: AOJA	T2,ALTWB1	; Increment character count and loop 
ALTWB3: JUMPGE	T2,CPOPJ	; If not first blanks
	AOJA	T2,ALTWB1	; Continue looking
	SUBTTL	Support Routines for Fancy Display Version of ALTER Mode

; Routine to re-type line after a control-C
; Call with
;	PUSHJ	P,CCRTYP
;	<Return here>

$CRTYP::
	MOVEI	T1,0		; Be sure tabs are clear
	PUSHJ	P,SETTAB##	; ...
	PUSHJ	P,RPRINT	; Re-type the first part
	SETOM	PRVSIZ		; Force typeout
	PJRST	V52TPN		; Go retype the line without delay

; V52TYP -- Routine to retype the line currently being altered
; 
; This routine checks VT52FL so it can be used even if this flag has
; not been selected.  Ensures that the current screen image matches
; the internal line image.  The refresh is not performed if there
; is a character waiting to be typed, or the specified refresh delay
; has not elapsed. (/REFDLY).
;
; Call V52TPN if the line should be refreshed immediately without
; waiting for REFDLY milliseconds.

V52TPI:	SKIPE	V52SPF##	; Suppressing intermediate typeout?
	POPJ	P,		; Yes, return
	PUSHJ	P,V52TYP	; Type the line again
	SETZM	CHGLNF		; Clear typeout flag
	POPJ	P,		; And return

V52TYP:	SKIPE	T1,REFDLY	; Does he want a delay (slow terminal)
	HIBER	T1,		; Yes wait for time or next character
	  JFCL			; No HIBER or no wait
V52TPN:	SKIPLE	T1,TSPEED	; GET USER TERMINAL SPEED
	 CAML	T1,BAUD		; FAST ENOUGH FOR UPDATE?
	  CAIA			; YES
	   POPJ P,		; NO--DONT DO IT
V52TPP:	SKPINC			; Is he ahead?
	  SKIPN	VT52FL		; Or not on a VT52?
	POPJ	P,		; Yes, skip this stuff then
	TRNE	FL2,SUPN	; Suppressing?
	POPJ	P,		; Yes, no typeout
	LDB	C,ALTP		; Current character
	CAIN	C,15		; End of line
	SKIPN	DELBAK		; and deleting backward
	CAIA
	PJRST	SETPVS##		; Yes, line is okay.  Update PRVSIZ.
	PUSH	P,FL		; Save flags
	PUSH	P,T2		; and count
	TLZ	FL,NEGF		; Always type forward
				 CONT.
; 
;  Get the length of the new line it can be compared with the old
; 
	PUSHJ	P,PRNSZC	; Get display length in characters
	MOVE	T4,T1		; Save in T4
	CAME	T4,PRVSIZ##	; Same as last time?
	JRST	V52TP2		; No
	SKIPN	CHGLNF		; Does this command change line size?
	JRST	V52TP4		; No, just return after restoring AC's
; 
;  We must have done a insert, delete or change.  Since the whole
;  line is the same length, there must be a tab taking up the
;  difference.  Type all characters until we find a tab or EOL.
; 
	PUSH	P,ALTP		; Save the pointer
CHKTB1:	LDB	C,ALTP		; Load next character
	PUSHJ	P,OCHR##	; No, type it
	CAIE	C,15		; End of line
	CAIN	C,"I"-100	; or tab
	JRST	CHKTB2		; If yes
	IBP	ALTP		; Increment the pointer
	JRST	CHKTB1		; And type till we find a tab

CHKTB2:	PUSH	P,T4		; Save line size
	PUSHJ	P,CSRPOS	; Get cursor position
	PUSHJ	P,FIXWPC##	; Fix line wrap count
	POP	P,T4		; Get T4 back
	POP	P,ALTP		; and the pointer
	JRST	V52TP6		; Go retype the first part of the line
				 CONT.
;  Here if the line size is different than it was last time
; 
V52TP2:	EXCH	T4,PRVSIZ	; Get old size, save new
	JUMPL	T4,V52TP5	; If explicit request to retype the line
	SUB	T4,PRVSIZ	; Compute difference
	JUMPG	T4,V52TP5	; If new size smaller
	LDB	C,ALTP		; Look at current character
	CAIN	C,15		; Is it a carriage return
	JRST	V52TP4		; If line grew at EOL, screen still OK
V52TP5:	PUSH	P,ALTCNT	; Save count
	PUSHJ	P,ALTTAB##	; Print rest of the line
	POP	P,ALTCNT	; Restore the alter character count
	MOVEI	C," "		; Blank to use as eraser
	SKIPG	T4		; Line shrank?
	MOVEI	T4,0		; No
	SKIPE	T1,T4		; Save difference
ERSLUP:	PUSHJ	P,OCHR		; Type a blank
	SOJG	T4,ERSLUP	; Over and over till done
	ADD	T1,PRVSIZ	; Get previous size
	SUBI	T1,1		; End of line causes special problems
	IDIV	T1,LINEW	; Compute number of wraps
	MOVEM	T1,WRPCNT	; and set it up
V52TP6:	PUSHJ	P,FORCE##	; Force pending output
	PUSHJ	P,UPCRSR##	; Move cursor up if needed
	PUSHJ	P,RPRINT	; Reprint the first part of the line
V52TP4:	POP	P,T2		; Restore the count
	POP	P,FL		; and the flags
	POPJ	P,		; Finally, return
;PRNSZC -- Get print size in characters
;
;Call
;	PUSHJ	P,PRNSZC
;	<Return here with character count in T1>
;Uses T1, C

PRNSZC:	PUSHJ	P,SAVR##	; Preserve T3-T5
	PUSH	P,T2		; Save T2
	PUSHJ	P,PRNTSZ	; Measure print size of line
	MOVE	T1,WRPCNT	; Get number of whole lines
	IMUL	T1,LINEW	; Times width of one line
	ADD	T1,T4		; Plus characters on last line
	JRST	T2POPJ##		; Restore T2 and return


;PRNTSZ -- Get the print size of the current line
;
;Call
;	PUSHJ	P,PRNTSZ
;	<Size in T4, line count in WRPCNT>
;Uses C, T1, T2, T4

PRNTSZ:	SETZB	T4,WRPCNT	; Size counter
	MOVE	T2,[POINT 7,LIBUF+1,6]
	TLNE	FL2,LNUMF	; Printing line numbers?
	MOVEI	T4,^D8		; If yes, line number is 1 tab stop
CNTLUP:	ILDB	C,T2		; Get a character
	CAIN	C,15		; End of line?
	POPJ	P,
	JSP	T1,RBC##	; Size chacacter, return through T1
	JRST	CNTLUP		; Loop over whole line


	END