Google
 

Trailing-Edge - PDP-10 Archives - tops20tools_v6_9-jan-86_dumper - tools/sed2/sedvax.mar
There are 5 other files named sedvax.mar in the archive. Click here to see a list.
.TITLE	SED - VAX-11 Screen Editor
.SUBTITLE	Definitions

;This VAX version of SED is a translation of the DEC-10/20 version
;of SED written by Chris Hall.  The translation was done at
;Brigham Young University by Paul Malquist

.LIBRARY /SEDITB.MLB/	;Define SED's macro library

.ENABLE DEBUG
.DISABLE GLOBAL		;Show undefined variables as errors
.PSECT CODE,NOWRT,EXE,LONG

.NOCROSS	;Disable cross-referencing of definitions
$IODEF		;Define the I/O function values
$TTDEF		;  and the terminal status values
$TT2DEF		;  and the extended terminal status values
$CHFDEF		;  and the condition handler values
$DVIDEF		;  and the $GETDVI symbols
$DCDEF		;  and the device class symbols
$DSCDEF		;  and the string descriptor symbols
$LIBCLIDEF	;  and the library symbols
FLGDEF		;Define the flag bits
SEQDEF		;And the character sequence definitions
TRMDEF		;And the words in the terminal output table
PRMDEF		;Define the SED parameters
.CROSS		;Re-enable cross-referencing

.EXTERNAL TERMNL,TRMERR,DECIDE
.EXTERNAL LIB$GET_SYMBOL,LIB$SET_SYMBOL,LIB$DELETE_SYMBOL
.EXTERNAL LIB$DISABLE_CTRL,LIB$ENABLE_CTRL,LIB$RUN_PROGRAM
.EXTERNAL NAMLEN,TRMNAM,NAMTAB

;Define the registers we will use
;T0=R0		;Scratch registers
;T1=R1
;T2=R2
;T3=R3
;T4=R4
;TY=R5		;Pointer into the type buffer
;PT=R6		;General pointer into the file
;RW=R7		;Row cursor is on
;CM=R8		;Column cursor is on
;DO=R9		;Command user typed
;TM=R10		;Terminal index
.SUBTITLE	Startup Routine

START: 	.WORD	0		;Entry mask
	CLRL	R9		;Make sure function is clear
	CVTBL	#-1,STTFLG	;Say SED is initializing
	MOVAB	TYPBUF,R5	;Set up the type buffer pointer
	MOVL	SP,STACK	;Save the stack pointer for later use
	JSB	INITTY		;Make the editor receive what's really typed
	JSB	CHECK_TERM_LOGICAL ;See if user has defined the terminal
				;     type by logical name
	MOVL	#XBFNUM-1,XCTACW ;Make last (null) execute buffer active
	MOVAB	XCTFRE,XCFPTR	;Save pointer to start of free space
	ADDL3	#XCFSIZ-1,XCFPTR,XCTOVF ;  and end of f.s. for overflow checking
	MOVL	#1,XCTSNM	;Set up nominal for execute counter
	MOVL	#1,XCTITR	;Set up number of times to iterate an execute
	CVTBL	#-1,ISVNUM
	CVTBL	#-1,SAVNUM
	CVTBL	#-1,SLDFLG
	MOVB	#-1,BAKFLG
	CVTBL	#-1,GOPRCT
	MOVB	#-1,MSGFLG	;Set /MESSAGE
	MOVB	#-1,INSTBS	;Set /INSTBS
	MOVB	#-1,KEYPAD	;Indicate no KEYPAD switch has been seen
	MOVB	#-1,FNCFLG	;Set /FENCE
	CLRL	F		;Clear flags
	CLRL	F1		;and second flag word
	CLRB	UPPFLG		;Upper case flag is initially off
	CLRL	PREDP		;Say there's no pre-set display pointer
	CLRL	PIKOPN		;Clear the pick file open flag
	CLRL	CLSOPN		;Clear the close file open flag
	BISL	#M_NLC,F	;Searches are case independent
	BISL	#M_JRW,F1	;Journaling is on by default
	CLRL	SL		;Clear slide offset
	MOVAB	BUFFEN,EN	;Set up end of buffer pointer
	BISL	#M_RST!M_NCR,F	;Reset nominals, don't insert CR in insert mode
	MOVL	#1,SAVEAC+36	;set set-file's r-w flag positive (ie none)
	JSB	TABINI		;Preset tabs for ruler
	MOVL	TERMNL,R10	;Set up right type of terminal
	JSB	REDSWH		;Go read SED.INI, if available
	JSB	REDTMP		;Read SED.TMP if any
	JSB	RSCANL		;If user entered with filespecs, set them up

;The error routine jumps to INIERR when there is an error in the command
;line (like a bad switch).  It goes to REDNO (below) when the user has erred
;while editing the cheery message

INIERR::JSB	DECIDE		;Call user's entry routine
	BISL	TCH(R10),F1	;Set terminal-specific flags
	TSTL	RUP(R10)	;Can terminal roll up?
	BNEQ	10$		;Yes
	BISL	#M_NRC,F	;No - don't automatically roll from last line
10$:	CLRL	JRNBIT		;Make sure journal flag is clear
	TSTL	JRNFLG		;Want to restore a journal?
	BEQL	JRSTNO		;No - skip this
	BISL	#M_JRC,F1	;Yes - say journal restore is happening
	TSTB	XSHFLG		;Want to display the execute?
	BNEQ	20$
	BISL	#M_XCT,F1	;No - just display when done
	BRB	30$
20$:	BISL	#M_XBN,F1	;Yes - set up show it all
30$:	CLRB	XSHFLG		;Clear execute display flag
	BBCC	#V_JRW,F1,JRSTNO;Don't journal while recovering - want to?
	CVTBL	#-1,JRNBIT	;Yes - remember for later
JRSTNO:	JSB	INITT1		;Do TTY init stuff which comes after entry rtn
	MOVL	LPP(R10),R1	;Set lines per roll
	MOVL	R1,LPP.0	;Save in case of change
	JSB	SETLPP		;Set up lines per page
	MOVL	CPL(R10),R1	;Set up characters per line variables
	MOVL	R1,CPL.0	;Save in case of change
	DECL	R1
	MOVL	R1,CPL.1
	TSTL	RMARGN		;Has user set the right margin?
	BNEQ	10$		;Yes
	MOVL	R1,RMARGN	;No - set it at the right of the screen
10$:	MOVL	F1,SAVFLG	;Save terminal flags

	CVTWL	STTFLG+2,R3	;Has the terminal length changed?
	BLEQ	20$		;No
	JSB	SWHLPP		;Yes - set it in the right table
20$:	CVTWL	STTFLG,R3	;Has the terminal width changed?
	BLEQ	30$		;No
	JSB	SWHWID		;Yes - set it in the right table
30$:	CLRL	STTFLG		;Say no longer initializing
	JSB	CMDSET		;Set up changes to command table, if any
	JSB	SETXCB		;Likewise execute buttons, if any, in new table
	BSBW	RSTNOM		;Set up default parameters
	BBC	#V_JRC,F1,35$	;Recovering a journal file?
	JSB	JRNGET		;Yes - set up and read the journal
35$:	TSTB	RSCANF		;Got a file from rescan?
	BEQL	40$		;No
	JMP	SETSCN		;Yes - set it up and go to LOOP1
40$:	TSTL	FILSPC		;Got a file from nnnSED.TMP?
	BEQL	REDNO		;No - start out with cheery message
INDIRE::MOVL	R10,-(SP)	;Yes - disable error messages
	CLRL	R10
	JSB	PARSEF		;Parse the filespecs
	MOVL	(SP)+,R10
	MOVL	#$SETFI+^X80000000,R9
	JMP	SETFL1		;and go set up that file

REDNO::	JSB	PNTSTT		;Else display cheery message
	TSTB	MSGFLG		;Want cheery message?
	BNEQ	NEWFIL		;Yes - (message is in the buffer)
	MOVAB	NFTEDT,R1	;No - say why
	JSB	ERRDSP
	JMP	ABORT1		;and just abort
NFTEDT:	.ASCIZ	/##########No file to edit/

NEWFIL::BICL	#M_ENT!M_CHG,F	;File unchanged, enter off
NEWFL1::BISL	#M_XPB,F	;Last-line pointer is invalid
	MOVQ	ISVNUM,ISVCNT	;Set up # of commands between ISAVEs
				;and # of typein chars between SAVEs
	MOVL	#SQZVAL,SQZCNT	;Set up # of commands to skip between squeezes
	TSTL	GOPRCT		;Yes - want to start some percent in?
	BLSS	NEWFL0		;No
	MOVL	GOPRCT,GOPERC	;Yes - set up the right percent
	CVTBL	#-1,GOPRCT	;Forget that it was given
	CLRL	R9
	JMP	PERNPM		;and let the percentage command do the display
NEWFL0::TSTB	DSPFLG		;Want to omit starting display?
	BNEQ	10$		;Yes
	JSB	DISPLL		;No - display a screenful
10$:	CLRB	DSPFLG		;Clear omit-display flag
	JSB	POSCUR		;Position the cursor
.SUBTITLE	Fetch and Dispatch Commands

;Now accept characters and do things
;All commands eventually loop back to loop

LOOP::	TSTL	CLAFLG		;Remembering a delete-lines?
	BEQL	5$		;No
	BSBW	DLLCHK		;Yes - see if it's time to forget
5$:	TSTL	SAVCNT		;Time to do an incremental save?
	BEQL	10$		;Yes
	TSTL	ISVCNT
	BNEQ	20$		;No
10$:	JSB	INCSAV		;Yes - do it
20$:	CLRL	R9		;Say no command is being handled
	BBC	#V_RST,F,30$	;Restore nominals?
	BSBW	RSTNOM		;Yes - do so
30$:	BITL	#M_CWT,F	;Anything special?
	BEQL	40$		;Yes
35$:	BRW	LOPSPC
40$:	BITL	#M_XCT!M_XBN,F1
	BNEQ	35$		;Yes - do it specially (maybe go to LOOP0)
	$QIOW_S	FUNC=#IO$_TTYREADALL!IO$M_NOECHO,- ;Read a physical block
		CHAN=TTCHAN,-	    ;from the terminal channel
		P1=TTYBUF,-	    ;into the terminal buffer
		P2=#1,-		    ;reading 1 byte
		IOSB=TTY_STATUS_BLOCK ;with status in the terminal status block
	MOVZBL	TTYBUF,R1	;Get the character
;Need to have an error check here...
LOOP1:	BBC	#V_CCH,F,LOOPC2	;Canceled enter-control-char flag - on?
	BRW	LOOPCC
LOOPC2:	CMPB	R1,#^A/ /	;Some control character?
	BLSS	LOOPC3		;Yes
	BRW	ALPNUM		;No - just put in the file or buffer
LOOPC3::MOVAB	COMAND,R6	;Yes - point to the command buffer
	CLRQ	COMAND		;and clear the buffer
	MOVB	R1,(R6)+	;Save the start of command
	BICL	#M_ERF!M_CCH,F	;Clear consecutive error flag
	MULL	#4,R1		;Convert offset from bytes to words
	ADDL2	ITB(R10),R1	;Get offset in terminal table
	MOVL	(R1),R1		;Is it a normal command?
	BGEQ	LOOP2		;Yes
	BSBW	SUBTAB		;No - read more characters
	BLBS	R0,LOOP2	;Legal - continue
	BRW	ILCERR		;Illegal command - error
LOOP2::	BBC	#15,R1,10$	;Is this command really an execute buffer?
	BRW	ILCERT		;Yes - set buffer up
10$:	BBC	#V_XSV,F1,20$	;Save command in execute buffer?
	CMPB	R1,#^A" "	;Got a high-numbered command?
	BGEQ	15$
	TSTB	R1		;  or reset (==0)?
	BNEQ	16$
15$:	MOVB	#^A"^",@XCTPTW	;Yes - save up-arrow as flag
	INCL	XCTPTW
16$:	MOVB	R1,@XCTPTW	;Save command
	INCL	XCTPTW
	CMPL	XCTPTW,XCTOVF	;See if buffer will overflow
	BNEQ	20$		;No overflow - continue
	JMP	XCTERR		;Else give error message
20$:	BBS	#V_ENT,F,30$	;Entering a parameter?
	MOVL	CMDTB2[R1],R2	;No - get proper dispatch address
	BRB	40$
30$:	MOVL	CMDTB1[R1],R2	;Yes - get proper dispatch address
40$:	MOVL	R1,R9		;Save the command that was typed
	BBC	#V_JRW,F1,50$	;Saving a journal?
	JSB	JRNSVC		;Yes - save the command
50$:	BBCC	#V_TIM,F1,55$	;Is the terminal in insert mode?
	JSB	IMDOFN		;Yes - turn insert mode off now
55$:	TSTL	R2		;Is there an address?
	BNEQ	60$
	BRW	ILCER1		;No - error
60$:	JMP	(R2)		;Yes - go to it and do it
LOOPCC:	CMPB	R1,#^O33	;CCH is on - was an escape typed?
	BEQL	10$
	BRW	LOOPC2		;No - continue
10$:	MOVZBL	#^A"[",R1	;Yes - handle it like ECC "["
	BRW	ALPNUM

;Subroutine to see if close buffer should be appended to or not if the next
;command is delete-lines.  This allows "consecutive" delete-lines to act as
;if they were all typed as one big delete (to help recovering).

DLLCHK:	BITL	#M_ENT!M_PCM,F	;Entering a parameter or got a mark?
	BNEQ	10$		;Yes
	CMPL	R9,#$DELLN	;No - got a delete-lines command?
	BEQL	10$		;Yes
	CMPL	R9,#$RESET	;Got a reset command?
	BEQL	10$		;Yes
	CLRL	CLAFLG		;No - clear consecutive-delete flag
10$:	RSB			;Done

;Here if command sequence is not found in terminal input table
;Scan the execute buffers to see if it is one of them

ILCERR:	MOVL	#1,R3		;Convert lower case to upper in command string
	MOVAB	COMAND+1,R2	;Point to the command buffer
ILCCAP:	MOVZBL	(R2)+,R1	;Get the next character
	BEQL	ILCCP2		;Done if null
	CMPB	R1,#^A"a"	;Lower case?
	BLSS	ILCCP1		;No - loop
	CMPB	R1,#^A"z"	;Is it really lower?
	BGTR	ILCCP2		;No
	SUBL	#^O40,R1	;Yes - convert to upper
	MOVB	R1,-1(R2)	;Store the corrected character
ILCCP1:	ACBB	#8,#1,R3,ILCCAP	;Loop thru the command characters
	DECL	R3		;Adjust character count if fall through

ILCCP2:	MOVL	R3,SAVEAC	;Save the number of characters found
	MOVL	#XBFNUM-1,R4
ILCXLP:	MOVAQ	XCTKEY[R4],R3	;Point to a buffer name
	CMPC	SAVEAC,COMAND,(R3) ;Is this what the user typed?
	TSTL	R0
	BEQL	10$		;Yes
	SOBGEQ	R4,ILCXLP	;No - loop
	BRW	ILCER1		;No match - command is illegal
10$:	MOVAQ	XCTKEY[R4],R3	;Point to the key sequence
	CMPL	COMAND,(R3)	;Got the entire command sequence?
	BNEQ	20$
	CMPL	COMAND+4,4(R3)
	BEQL	ILCE00		;Yes - execute the buffer

20$:	$QIOW_S	FUNC=#IO$_TTYREADALL!IO$M_NOECHO,-
		CHAN=TTCHAN,-	;No - read a character from the terminal
		P1=TTYBUF,-
		P2=#1,-
		IOSB=TTY_STATUS_BLOCK
	MOVZBL	TTYBUF,R1	;Get the character
	CMPB	R1,#^A"a"	;Lower case?
	BLSS	30$		;No
	CMPB	R1,#^A"z"	;Is it really lower?
	BGTR	30$
	SUBB	#^O40,R1	;Yes - convert it to upper
30$:	MOVB	R1,(R6)+	;Save the character in COMAND
	INCL	SAVEAC		;Increment the number of characters
	BRW	ILCXLP		;Go find a longer sequence

;Here if the command is an execute buffer - go do it

ILCE00:	MOVL	R4,R1		;Get execute index
ILCER0::BICL	#^C^O77,R1	;Keep only good index bits
	MOVL	XCTADR[R1],R2	;Get pointer to this buffer
	MOVL	R2,XCTPTR	;Save as active pointer
	MOVL	R1,R9		;Save execute index for journaling

	MOVZBL	(R2)+,R1	;Get first character from buffer
	CMPB	R1,#^A"^"	;Special character flag?
	BNEQ	10$
	MOVZBL	(R2)+,R1	;Get command from execute buffer
	CMPB	R1,#^O37	;Is it a real command?
	BLEQ	ILCE0A		;No (an execute construct) - handle normally
	CMPB	R1,#^O77	;Got a reset command?
	BNEQ	10$		;No
	CLRL	R1		;Yes - get the real code
10$:	MOVZBL	(R2)+,R0	;Get the next command
	BNEQ	ILCE0A
	BRW	LOOP2		;If there's only one command, go use it

ILCE0A:	BBC	#V_JRW,F1,10$	;Writing a journal?
	JSB	JRNSVX		;Yes - save the execute index
10$:	MOVL	#1,XCTNUM	;Do one iteration of buffer
	PUSHR	#^M<R1,R2,R3,R4,R5>
	MOVC3	#SAVPML,PARAMS,SAVPRM ;Save all parameters
	POPR	#^M<R1,R2,R3,R4,R5>
	MOVL	F,SAVFGS	;Save flag longword 1
	MOVL	F1,SAVFGS+4	;  and longword 2
	BICL	#M_XCT!M_JRC,F1	;Clear journal-restore flags
	BISL	#M_XBN,F1	;Set to execute and display
	BBC	#V_ENT,F,20$	;Got a parameter?
	JSB	ERSPM0		;Yes - clean up screen; don't clear flag
	JSB	PUTTYP		;Output everything now
20$:	BRW	LOOP		;Go take commands from buffer

;Here if command really is illegal = give error

ILCER1:	BBC	#V_ENT,F,ILCER2	;Is there a parameter to clean up?
	CLRB	@PARPTR		;Yes, save a null at the end of the paramete
	INCL	PARPTR
	JSB	ERSPM2		;Restore the saved position
ILCER2::MOVAB	ILCMSG,R1	;Point to the error message
	JMP	ERROR		;and go output it
ILCMSG:	.ASCIZ	/#########Illegal command/

ILCERT:	BBC	#14,R1,10$	;Got enough type-in?
	BRW	ILCERR		;No - get more
10$:	BRW	ILCER0		;Yes - go execute buffer

;Here for special handling: restore nominals, read from execute buffer,
;or get typed-ahead (or journaled) character

LOPSPC:	BITL	#M_XCT!M_XBN,F1	;Execute buffer or journal restore?
	BEQL	10$		;No
	JMP	XCTGET		;Yes - take commands from an execute buffer
10$:	BICL	#M_CWT,F	;No - say no character is waiting
	MOVZBL	TYPCHR,R1	;Pick up typed character
	BRW	LOOP1		;and use it as current terminal input

;Subroutine to restore nominals, if RST flag is set

RSTNOM::CLRL	GOPERC		;Reset %GOTO
	CLRL	ADDLSP		;and lines to do rectangular open/close on
	CLRL	PICKSP		;and spaces to pick
	CLRL	CASLNS		;and lines to case
	MOVL	#1,SUBCNT	;and substitutes to do
	MOVL	#1,ADDLNS	;and lines to add or delete
	MOVL	#1,ADDSPC	;and spaces to add or delete
	MOVL	#1,PICKLN	;and number of lines to pick
	MOVL	#1,ROLPGS	;and pages to roll
	MOVL	#1,CASSPS	;and spaces to change the case of
	MOVL	#1,JUSLNS	;Justify one line
	MOVL	LINROL,ROLLIN	;Set default lines to roll
	MOVL	SLIDNM,SLIDES	;Set user's default slide size
	BNEQU	10$		;Did he have one?
	MOVL	#8,SLIDES	;No - set it to 8
10$:	RSB			;Then return
;Subroutine to reference a terminal's subtables
;Return success if sequence found, else return error

SUBTAB::MOVL	R1,TEMP		;Set up address of subtable
SUBTB1:	$QIOW_S	FUNC=#IO$_TTYREADALL!IO$M_NOECHO,-
		CHAN=TTCHAN,-	    ;from the terminal channel
		P1=TTYBUF,-	    ;into the terminal buffer
		P2=#1,-		    ;reading 1 byte
		IOSB=TTY_STATUS_BLOCK ;with status in the terminal status block
	MOVZBL	TTYBUF,R1	;Get the character
;Need to have an error check here...
	BBS	#9,R9,10$	;In the help processor?  Yes, don't save char
	MOVB	R1,(R6)+	;Save the character
10$:	CVTWL	TEMP,R4		;Compute address of subtable
	ADDL	R10,R4
	CVTWL	TEMP+2,R3	;Get the length of the subtable
SUBTB2:	TSTL	(R4)		;End of the subtable?
	BNEQ	10$		;No
5$:	CLRL	R0		;Yes - indicate illegal command
	RSB			;and return
10$:	CVTWL	(R4),R2		;Get character from subtable
	BEQL	SUBTB3		;Match any character?  Yes
	CMPB	R1,R2		;Do user's and table's chars match?
	BEQL	20$		;Yes
	ADDL	#4,R4		;Increment to next entry
	ADDL	#4,R3		;Also increment the count
	BLSS	SUBTB2		;Not at end yet
20$:	TSTL	R3		;Error if end of table and not found
	BGEQ	5$

SUBTB3:	CVTWL	2(R4),R2	;Get the command
	CMPL	#^O137,R2	;Found it - want another level?
	BLEQU	SUBTBS		;Yes - set it up
SUBTB4:	MOVL	R2,R1		;Set up real command
	MOVZBL	#1,R0		;Indicate success return
	RSB

SUBTBS:	BBS	#15,R2,SUBTB4	;Got an execute command?  Yes
	MOVW	2(R4),TEMP	;Point to the new subtable
	MOVW	#-160,TEMP+2	;Indicate the maximum length
	BRW	SUBTB1		;Go read another character from terminal
.SUBTITLE	Put Characters in the Buffer

;*************************************************************************
;Here if a non-control character was typed - put it in file or
;parameter buffer, and adjust cursor position one to the right

ALPNUM::CMPB	R1,#^O173	;Got a high character?
	BLSS	ALPNU0		;No
	BRW	ALPHGH		;Yes - maybe it's a command
ALPNU0:	BBC	#V_JRW,F1,5$	;Writing a journal?
	JSB	JRNSVA		;Yes - save the character
5$:	CVTBL	#-1,R9		;Note that a command is active
	TSTB	UPPFLG		;Want upper case alphabetics?
	BEQL	10$		;No
	CMPL	R1,#^A"a"	;Yes - is character lower case?
	BLEQ	10$		;No
	CMPL	R1,#^A"z"
	BGTR	10$		;No - O.K.
	SUBL	#^O40,R1	;Yes - convert to upper
10$:	BBC	#V_XSV,F1,20$	;Save command in execute buffer?
	MOVB	R1,@XCTPTW	;Yes - do so
	INCL	XCTPTW
	CMPB	R1,#^A"^"	;Is character a real up-arrow?
	BNEQ	15$		;No
	MOVB	R1,@XCTPTW	;Yes - save two of them
	INCL	XCTPTW
15$:	CMPL	XCTPTW,XCTOVF	;See if buffer will overflow
	BNEQ	20$		;No overflow - continue
	JMP	XCTERR		;Otherwise give error message
20$:	BBCC	#V_CCH,F,ALPNU1	;Want a control character?
	BICB	#^C^O37,R1	;Yes - make it one
ALPNU1::BBC	#V_ENT,F,40$	;Entering a parameter?
	BRW	ALPENT		;Yes - handle separately

40$:	BBC	#V_RDO,F,50$	;No - is file read-only?
	JMP	ALPERR		;Yes - command is illegal
50$:	DECL	SAVCNT		;De-bump typein save counter
	BISL	#M_CHG!M_INS,F	;Let line be extended if necessary
	JSB	MAKCPT		;Re-make cursor position
	BICL	#M_INS!M_PCM,F
	CMPB	R3,#^X0D	;At end of line?
	BEQL	60$		;Yes
	BBC	#V_IMD,F,60$	;No - in insert mode?
	BRW	ALPIMD		;Insert mode, not at EOL - handle separately

;Here to put character in file (non-insert-mode)

60$:	CLRL	R4		;Clear (maybe) pointer to first null
ALPNM2:	MOVZBL	@CHRPTR,R2	;Get character that will be overwritten
	INCL	CHRPTR
	TSTL	R2		;If null, save pointer
	BNEQ	10$
	BRW	ALPNUL
10$:	CMPL	R2,#9		;Tab?
	BNEQ	20$
	BRW	ALPTAB		;Yes - need to break the tab apart
20$:	CMPL	R2,#^O15	;Carriage return?
	BNEQ	ALPNM3
	BSBW	ALPEXT		;Yes - may need to extend line
ALPNM3:	MOVL	CHRPTR,R2	;Get character pointer
	MOVB	R1,-1(R2)	;Save character in buffer
	CMPL	EN,CHRPTR	;At the end of the file?
	BNEQ	ALPDIS		;No
	INCL	EN		;Yes - increase file size by one character

;Here to display character, from replace mode or parameter

ALPDIS:	MOVB	R1,CHARAC	;Save user's character
	BBS	#V_XCT,F1,ALPDS1 ;Executing?  Yes - position, but no echo
	CMPL	R7,LPP.1	;At last line?
	BNEQ	20$		;No
	BBCC	#V_FNC,F,20$	;Yes - is fence up?
	MOVL	R1,-(SP)	;Yes - save character typed
	JSB	CBOTOM		;Take fence down
	JSB	POSCUR		;Re-position cursor
	MOVL	(SP)+,R1	;Get the character back
20$:	CMPB	R1,#^A" "	;Got a control character?
	BGEQ	30$		;No
	BRW	ALPCCH		;Yes - display specially
30$:	MOVB	R1,ECHBUF	;Echo the character
	$QIOW_S	CHAN=TTCHAN,-
		FUNC=#IO$_WRITEVBLK!IO$M_NOFORMAT,-
		P1=ECHBUF,-
		P2=#1
ALPDS1:	CMPL	R8,RMARGN	;Beyond the right margin?
	BGEQ	10$		;Yes
	BRW	ALPPOS
10$:	CLRL	SAVEAC+8	;Clear count of characters backed over
	MOVL	CHRPTR,R6	;Get current character pointer
	MOVZBL	-(R6),R1	;Get current character
	CMPL	R1,#^A" "	;Is it a space?
	BEQL	ALPDS2
	CMPB	R1,#9		;or a tab?
	BEQL	ALPDS2		;Yes - put new line here
	MOVL	#1,R2		;No - set not-space flag
20$:	BSBW	ALPBAK		;Else back up over the last word
	TSTL	R2
	BGTR	20$
	BEQL	40$
30$:	BRW	ALPNSP		;If no spaces in line just wrap last char
40$:	MOVL	R6,R3		;Save pointer to start of word
50$:	BSBW	ALPBKS		;See what's before the spaces
	TSTL	R2
	BEQL	50$
	BLSS	30$		;If line starts with spaces wrap last char
	MOVL	R3,R6		;Else get back pointer to start of word
	INCL	R6
	MOVL	R6,CHRPTR	;Save pointer to start of last word

ALPDS2:	MOVL	#2,NUMCHR	;Set to insert two characters:
				;  a return and a linefeed
	MOVB	#^O12,CHARAC
	JSB	MAKCHR		;Insert two linefeeds
	MOVL	CHRPTR,R6	;Restore the character pointer
	MOVB	#^O15,(R6)+	;and change one of them to a return
	INCL	R6		;Jump over the linefeed, for redisplay

	MOVL	LMARGN,R1	;Get the left margin offset
	BEQL	ALPDS3		;Any ?  No - skip this
	MOVL	R1,NUMCHR	;Yes - add that many spaces
	MOVL	R6,CHRPTR	;  at the start of the new line
	JSB	MAKSPC

ALPDS3:	MOVL	SAVEAC+8,R1	;Was anything moved?
	BEQL	ALPDS4		;No - don't erase
	SUBL	R1,R8		;Erase the last word - position to it
	JSB	POSCUR
	JSB	CLRLNR		;and erase to the end of the line
ALPDS4:	INCL	R7		;Position to the start of the next line
	MOVL	R7,R4
	CMPL	R7,LPP.1	;Moved to the last line?
	BNEQ	5$		;No
	BICL	#M_FNC,F	;Yes - fence will be cleared, if it's there
5$:	ADDL3	SAVEAC+8,LMARGN,R8 ;and set cursor pos'n to the end of the line
				;      (adding in the margin offset)
	BISL	#M_XPC!M_XPB,F	;Character and bottom pointers are bad
	MOVL	R6,LINPTR	;Save pointer to the start of the new line
	CMPL	R7,LPP(R10)	;About to move off the screen?
	BLSS	10$
	JMP	RETROL		;Yes - do a roll
10$:	JSB	POSLIN		;Else position to the start of the new line

	MOVL	#1,R4		;Set to insert one line
	MOVL	ILN(R10),R1	;Can terminal do an insert-lines?
	BNEQ	20$		;Yes
	JMP	DISDWN		;No - re-draw the screen from there down
20$:	PUSHR	#^M<R8>		;Yes - fudget the column position to zero
	CLRL	R8
	JSB	PUTSEQ		;Insert the line
	POPR	#^M<R8>		;Get the column position back again
	JSB	DISPLY		;Display the new line
	JSB	FIXBLW		;Put back fence and insert mode messages
	JMP	DISCUR		;Position to the end and loop (whew)

ALPNSP:	CLRL	SAVEAC+8	;If no spaces in line just wrap last char
	MOVL	CHRPTR,R6
	BRW	ALPDS2

;Subroutine to read the character previous to R6.
;Returns character in R1; R2/0 if character is space, tab, -1 if LF
;Also keeps a count of characters backed over in SAVEAC+8

ALPBKS:	MOVL	#1,R2		;Set found-a-character flag
ALPBAK:	MOVZBL	-(R6),R1	;Get the previous character
	BEQL	ALPBAK		;Skip it, if null
	CMPB	R1,#^A" "	;Is it a space?
	BEQL	10$		;Yes
	CMPB	R1,#9		;or a tab?
	BEQL	10$		;Yes
	CMPB	R1,#^O12	;How about a linefeed?
	BNEQ	20$		;Nope
	CVTBL	#-1,R2		;Yes - mark it specially
	BRB	20$
10$:	CLRL	R2		;Flag it as a spacer
20$:	TSTL	R2		;Got a real character?
	BLEQ	30$		;No
	INCL	SAVEAC+8	;Yes - count up one more character skipped
30$:	RSB			;Done

;Here to see if a high character is really a command

ALPHGH:	BBC	#V_HTB,F1,ALPHGR ;Got a high table to use? No - check for rubout
	MOVZBL	R1,R2		;Save character
	ADDL	ITB(R10),R1	;Get table entry
	SUBL	#^O200,R1
	MOVL	(R1),R1		;Is there one?
	BLSS	20$		;No
	BRW	LOOPC3		;Yes - handle as a command
20$:	MOVL	R2,R1		;No - get character back
	BRW	ALPNU0		;and go put it in file

ALPHGR:	CMPB	#^O177,R1	;Got a rubout?
	BEQL	10$		;Yes
	BRW	ALPNU0		;No - treat like a character
10$:	MOVL	ITB(R10),R1	;Yes - get its command
	MOVL	-4(R1),R1
	BRW	LOOP2		;and process it

;Here to output a protected control character

ALPCCH:	ADDB3	#^O100,R1,R2	;Get character as a real character
	CMPB	R1,#^O11	;Got a tab?
	BEQL	ALPDTB		;Yes - handle specially
	MOVL	R1,-(SP)	;Save knocked character
	JSB	PROTON		;Output the character protected
	MOVB	R2,(R5)+
	JSB	PROTOF
	JSB	PUTTYP		;Output it now
	MOVL	(SP)+,R1	;Get control char back again
	JMP	RIGHT1

ALPDT1:	MOVZBL	#$CURHM,R9	;Cause positioning to occur
ALPDTB:	DECL	CHRPTR		;Move pointer behind the latest character
	BBCC	#V_TIM,F1,10$	;Turn off insert flag - on?
	JSB	IMODOF		;Yes - turn off insert mode
10$:	JSB	DISLIN		;Rewrite remainder of line
	INCL	CHRPTR		;Make character position right
	MOVZBL	CHARAC,R1	;Get latest-typed character
ALPPOS:	CMPB	#^O11,R1	;Tab?
	BEQL	10$		;Yes
	JMP	RIGHT1		;No - move to the right and loop
10$:	BICL	#7,R8		;Point to character after tab
	ADDL	#8,R8
	JMP	DISCUR		;Re-position and loop

;Here if null found where character pointer points

ALPNUL:	TSTL	R4		;If not the first null, don't save pointer
	BNEQ	10$
	MOVL	CHRPTR,R4	;Else save pointer to first null
10$:	CMPL	EN,CHRPTR	;At end of file?
	BEQL	20$		;Yes
	BRW	ALPNM2		;No - loop
20$:	MOVL	CHRPTR,R4	;Point back to first null
	BNEQ	30$		;Error if no null found (shouldn't happen)
	MOVAB	ALPERM,R1
	JMP	ERROR
30$:	BRW	ALPNM3		;Save character there
ALPERM:	.ASCIZ	/########BUG - No null found/

;Here if character to overwrite is a tab - precede it with spaces and char
;If character is going into the 7th position of the tab, take the tab out

ALPTAB:	MOVL	R1,-(SP)	;Save character user typed
	DECL	CHRPTR		;Back pointer up before the tab
ALPTB0:	INCL	TABSPC		;Increment spaces (+ char) to add before tab
	MOVL	TABSPC,NUMCHR	;Add that many spaces to the file
	JSB	MAKSPC		;Note: R4 has ptr to last thing added

;CHRPTR points to start of added spaces
;MAKPTR	  "	  one beyond last space added
;R4	  "	  the tab

	CLRB	(R4)		;Null out the former tab
	MOVL	(SP)+,R1	;Get user's character back again
	SUBL3	#1,MAKPTR,R4
	MOVB	R1,(R4)+	;Save character over the last thing typed
	MOVL	R4,CHRPTR	;Save as current position
	SUBL3	TABSPC,TABSIZ,R2 ;See if an entire tab has been used up
	CLRL	TABSPC		;No longer any spaces to left of tab
	MOVL	R2,TABSIZ
	BGTR	10$		;Is tab now expressed entirely in characters?
	CLRL	R2		;Yes - null out the tab
	BRB	20$
10$:	MOVZBL	#9,R2		;No - move tab over
20$:	MOVB	R2,(R4)+
	BRW	ALPDIS		;Done - go display

ALPTBI:	MOVL	R1,-(SP)	;Save character user typed
	BRB	ALPTB0		;Jump into the break-up-tab routine

;Subroutine for if going to overwrite a <CR>. If it's <CRLF> extend line
;However, if a null was passed over, save character there; leave <CR> alone

ALPEXT:	TSTL	R4		;If found a null, save character there
	BNEQ	ALPEX1
	MOVL	CHRPTR,R3
	MOVZBL	(R3)+,R2
	CMPL	R2,#^O12	;Is it a linefeed?
	BNEQ	20$
	MOVL	R1,-(SP)	;Yes - save the character user typed
	DECL	CHRPTR		;Move pointer behind the <CR>
	MOVL	#24,NUMCHR	;Go add 24 nulls to the file
	JSB	MAKNUL		;Put in those nulls
	MOVL	(SP)+,R1	;Get character back
	INCL	CHRPTR		;Point back to real character position
20$:	RSB			;and go put it into the buffer

ALPEX1:	MOVL	R4,CHRPTR	;Go save character over that null
	RSB
;Here if editor is in insert mode - add character at cursor; don't replace

ALPIMD::CMPL	R8,CPL.1	;At 80th column?
	BLSS	10$		;No
	BRW	ALPIBP		;Yes - insert not allowed
10$:	MOVL	CHRPTR,R6	;Get character position
	MOVB	R1,CHARAC	;Save user's character
	MOVZBL	(R6),R2		;Get character at pointer
	BNEQ	20$		;If null,
	BRW	ALPIM4		;  save new char there
20$:	CMPB	R2,#9		;Is it a tab?
	BNEQ	25$		;No
	BRW	ALPTBI		;Yes - break the tab apart
25$:	MOVZBL	-(R6),R2	;Else get character before pointer
	BNEQ	30$		;If null,
	BRW	ALPIM5		;save new char there
				;Else need to insert some space:
30$:	MOVL	#1,NUMCHR	;Tell MAKCHR to insert one character
	JSB	MAKCHR		;Insert that character
	INCL	CHRPTR		;Point to character after this one
ALPIM1:	CMPB	CHARAC,#9	;Is latest-typed character a tab?
	BNEQ	10$		;No
	BRW	ALPDTB		;Yes - rewrite the rest of the line
10$:	MOVL	IMO(R10),R3	;Can the terminal set insert mode?
	BEQL	ALPIM2		;No - insert the character some other way
	JSB	FNDEOL		;Yes - see if there are tabs from here to EOL
	BLBC	R0,20$
	BRW	ALPDT1		;Yes - re-display entire remainder of line
20$:	BBSS	#V_TIM,F1,ALPIM3 ;Is the terminal already in insert mode?
	JSB	IMODON		;No - turn on insert mode
	BRB	ALPIM3		;Output the character, adjust position, & loop

ALPIM2:	MOVL	#1,R4		;Set to open line one character
	MOVL	ISP(R10),R3	;Can terminal open spaces on its own?
	BEQL	20$		;No
	JSB	OPNSPI		;Yes - open up the line
	BLBC	R0,30$
20$:	BRW	ALPDT1		;No - rewrite the line cursor is on
30$:	JSB	POSCUR		;Get back to start of newly-opened space
ALPIM3:	MOVZBL	CHARAC,R1	;Get latest-typed character
	CMPL	R1,#^A" "	;Got a control character?
	BGEQ	40$
	BRW	ALPCCH		;Yes - display specially
40$:	MOVB	R1,(R5)+	;Display it
	INCL	R8
	JMP	DISCUR		;Re-display the cursor; done

ALPIBP:	MOVB	#7,ECHBUF	;If at 80th column just beep
	$QIOW_S CHAN=TTCHAN,-
		FUNC=#IO$_WRITEVBLK!IO$M_NOFORMAT,-
		P1=ECHBUF,-
		P2=#1
	BRW	LOOP

;Here if null found at (ALPIM4) or before (ALPIM5) cursor position
;Save new character there; no insert necessary

ALPIM4:	INCL	CHRPTR		;Skip over this new character
ALPIM5:	MOVB	CHARAC,(R6)	;Save new character just before pointer
	BRW	ALPIM1		;Go display what happened
;Here for a character typed as part of a parameter

ALPENT:	BBCC	#V_CMV,F,10$	;Doing cursor movement?
	JMP	CMXERR		;Yes - can't mix cursor and otherwise
10$:	CMPL	PARPTR,#PARBUF+PARBLN ;Is buffer about to overflow?
	BGEQ	ALPIBP		;Yes - beep and don't save the character
	MOVB	R1,@PARPTR	;Save this character in parameter buffer
	INCL	PARPTR
	BICL	#M_PST,F1	;Clear start-of-parameter flag
	BITL	#M_XCT!M_XBN,F1	;Executing?
	BNEQ	20$		;Yes - no output
	CMPB	R1,#^A" "	;Got a control character?
	BLSS	ALPENC		;Yes - output it protected
	MOVB	R1,ECHBUF	;Save it in the echo buffer
	$QIOW_S	CHAN=TTCHAN,-	;Echo the character
		FUNC=#IO$_WRITEVBLK!IO$M_NOFORMAT,-
		P1=ECHBUF,-
		P2=#1
20$:	BRW	LOOP

ALPENC:	MOVL	R1,R4		;Save character
	JSB	PROTON		;Protect character
	ADDB3	#^O100,R4,(R5)+	;Get real character back and save it
	JSB	PROTOF
	JSB	PUTTYP
	BRW	LOOP		;Get another command
.SUBTITLE	Routines to manipulate DCL CLI symbols

;Routine to write a new CLI symbol for restart
;Pointer to the descriptor for the name is in R4

WRTSYM::BSBB	DELSYM		;Delete the old symbol
	SUBL3	#PIKBUF+PCBSIZ-400,R5,R1 ;Compute length of the string
	MOVW	R1,SYMBOL_DESC+DSC$W_LENGTH ;Save it
	PUSHAL	SYMBOL_DESC
	PUSHL	R4
	CALLS	#2,G^LIB$SET_SYMBOL ;Define the new symbol value
	RSB			;and return

DELSYM::PUSHL	R4		;Save descriptor block address
	CALLS	#1,G^LIB$DELETE_SYMBOL ;Delete the old symbol
	RSB

;Subroutine to read the value of a symbol
;Call with the pointer to the symbol name descriptor in R4

REDSYM::MOVW	#400,SYMBOL_DESC+DSC$W_LENGTH ;Set length of buffer
	PUSHAL	SYM_BUFF_LEN	;Put the arguments on the stack
	PUSHAL	SYMBOL_DESC
	PUSHL	R4
	CALLS	#3,G^LIB$GET_SYMBOL ;Read the value of the symbol
	BLBS	R0,10$
	RSB
10$:	ADDL3	#PIKBUF+PCBSIZ-400,SYM_BUFF_LEN,R1
	CLRB	1(R1)		;Make sure it ends with a null
	RSB			;then return
.SUBTITLE Terminal Initialization Routines
;Subroutine to initialize the TTY for input and output

REINIT_TTY::	;Routine to reinit the TTY after a spawn.  Channel is already
	MOVQ	SAVE_TTY_BITS,SETCHBF+4	;assigned, so skip that part
	BRW	INITT2

INITTY::$TRNLOG_S LOGNAM=SYSDEV,RSLLEN=TTYLEN,RSLBUF=TTYDESC
				;Translate the logical name for SYS$INPUT
	CMPB	TTYNAM,#^X1B	;Does name begin with an escape?
	BNEQ	10$		;No
	SUBL	#4,TTYLEN	;Yes, drop first four characters
	ADDL	#4,TTYADDR
10$:	$ASSIGN_S DEVNAM=TTYDESC,CHAN=TTCHAN ;Assign the channel
	$GETCHN_S CHAN=TTCHAN,-	;Get the terminal characteristics
		  PRILEN=SETCHLEN,-	;into buffer of length 16 bytes
		  PRIBUF=SET_CHAR_BUFF ;located at this address
	CMPB	#DC$_TERM,SETCHBF+DVI$_DEVCLASS ;Is this really a terminal?
	BEQL	15$
	JMP	TRMERR		;No - give him the message and exit
15$:	MOVZBL	SETCHBF+5,TERMTYPE ;Save the terminal type code
	MOVQ	SETCHBF+4,SAVE_TTY_BITS ;Save the old characteristics
;For now, don't disable TTSYNC, so VT100's will work either way
INITT2:	BICL	#TT$M_HOSTSYNC!- ;Want ^S and ^Q disabled
		 TT$M_READSYNC!- ;...
		 TT$M_TTSYNC!-	 ;...
		 TT$M_WRAP!-	 ;and no wrap-around
		 TT$M_NOTYPEAHD,- ;and allowing typeahead
		 SETCHBF+8	 ;Clear all these bits in the buffer
	BSBW	CHECK_DEBUG_MODE ;Set up the debug mode flag
	TSTB	DEBUG_FLAG	;Should we run in debug mode?
	BNEQ	40$		;Yes, don't use passall mode
;	BISL	#TT$M_PASSALL!-	;Set passall mode
;		 TT$M_NOECHO,-	;and no echo
;		 SETCHBF+8
	BISL	#TT$M_PASSALL,-	;Set passall mode
		 SETCHBF+8

40$:	$QIOW_S	FUNC=#IO$_SETMODE,-
		CHAN=TTCHAN,-
		P1=SETCHBF+4,-	;Set up the correct parameters
		P2=#8		;Length of buffer
	PUSHAL	OLD_CTRL_MASK	;Disable ^T
	PUSHAL	#LIB$M_CLI_CTRLT
	CALLS	#2,G^LIB$DISABLE_CTRL
	BLBS	R0,20$
	HALT
20$:	BITL	#LIB$M_CLI_CTRLY,OLD_CTRL_MASK ;Is ^Y disabled?
	BNEQ	30$		;No - no need to enable it
	PUSHAL	#LIB$M_CLI_CTRLY ;Yes - enable it
	CALLS	#1,G^LIB$ENABLE_CTRL
	BLBS	R0,30$
	HALT
30$:	RSB
INITT1::$SETEXV_S VECTOR=#1,-	;Enable the condition handler
		  ADDRES=GETAK	;for the secondary conditions
	$DCLEXH_S DESBLK=EXITBLOCK ;Set up the exit handler
	RSB			;Then return

;Exit handler to restore the terminal settings to their original state
RESTORE_TTY::	.WORD	^M<>	;Don't use any registers in this routine
	$QIOW_S	FUNC=#IO$_SETMODE,- ;Restore the terminal mode
		CHAN=TTCHAN,-
		P1=SAVE_TTY_BITS
	BITL	#LIB$M_CLI_CTRLT,OLD_CTRL_MASK ;Was ^T enabled?
	BEQL	10$		;No
	PUSHAL	#LIB$M_CLI_CTRLT;Yes - re-enable it
	CALLS	#1,G^LIB$ENABLE_CTRL
10$:	BITL	#LIB$M_CLI_CTRLY,OLD_CTRL_MASK ;Was ^Y enabled?
	BNEQ	20$		;Yes - don't disable it
	PUSHAL	#LIB$M_CLI_CTRLY
	CALLS	#1,G^LIB$DISABLE_CTRL
20$:	RET			;Then return

;Subroutine to check for the existence of the logical name "SED_TERMINAL"
;and set up the terminal type according to the translation of that logical
;name.  If the name does not exist, or does not translate to a known terminal
;type, just returns without modifying anything

CHECK_TERM_LOGICAL:		;Get the logical name translation
	MOVL	#^A"    ",RESCAN_LINE	;Pre-clear the receiving buffer
	MOVL	#^A"    ",RESCAN_LINE+4	;  to spaces
	$TRNLOG_S LOGNAM=SEDTERM,RSLBUF=RESCAN_DESC,RSLLEN=RESCAN_LENGTH
	BLBS	R0,20$		;Any logical name found?
10$:	RSB			;No
20$:	CMPW	#8,RESCAN_LENGTH ;Is the length greater than 8?
	BLSS	10$		;Yes - it couldn't be a valid terminal type then
	PUSHR	#^M<R5,R6>	;Save some registers
	MOVL	#NAMLEN,R6	;Get the number of entries
	DIVL	#4,R6
30$:	MOVAQ	TRMNAM[R6],R4	;Point to the name
	CMPC3	#8,RESCAN_LINE,(R4) ;Is this the one?
	TSTL	R0
	BEQL	40$		;Yes
	SOBGEQ	R6,30$		;No - loop through the table
	POPR	#^M<R5,R6>	;Not found - just return
	RSB
40$:	MOVL	NAMTAB[R6],TERMTYPE ;Save the terminal type code
	POPR	#^M<R5,R6>
	RSB			;and return
;Subroutine to translate the logical name 'SED$DEBUG'.  If this translates
;to 'YES', then SED is to run in debug mode, and the debug flag is set.

CHECK_DEBUG_MODE:
	CLRB	DEBUG_FLAG	;Assume not running in debug mode
	$TRNLOG_S LOGNAM=DBG_NAME, RSLBUF=RESCAN_DESC,-
		  RSLLEN=RESCAN_LENGTH	;Translate the name
	BLBC	R0,10$		;If name not found, just return
	CMPB	#3,RESCAN_LENGTH ;Is the length correct?
	BNEQ	10$		;No - it couldn't be 'YES'
	CMPW	#^A"YE",RESCAN_LINE ;Are the first two chars correct?
	BNEQ	10$		;No
	CMPB	#^A"S",RESCAN_LINE+2 ;Yes - is the last char correct?
	BNEQ	10$		;No
	MOVB	#-1,DEBUG_FLAG	;Yes - set the debug flag
10$:	RSB			;Then return
DBG_NAME:	.ASCID	/SED$DEBUG/	;Logical name to be translated
MBX_NAME:	.ASCID	/SED_MBX/	;Logical name for broadcast mailbox

GLOB			;Define external symbols from other modules

.END	START