;	c/	1/		1/
	.TITLE	EDI00
	.IDENT	/X01/
									;**-1
	.NLIST	BEX
	.ENABL	LC
mutask=1
;
; EDITOR (TEMP FILE VERSION)
;
; VERSION X01
;
; DAVID G. CONROY	16-DEC-77
;
;
; as modified by Eric Levy
;
			.if df mutask
				.macro pure
                                .psect pur,ro
				.endm

				.macro impure
                                .psect ipur,rw
				.endm
			
			.iff
			
				.macro pure
				.endm
				.macro impure
				.endm
			
			.endc
	.GLOBL	ERROR
	.GLOBL  tabmsk
        .GLOBL  protec
	.GLOBL	WDONE
	.GLOBL	COMMND
	.GLOBL	ADR1
	.GLOBL	ADR2
	.globl padr1,padr2
	.GLOBL	ZERO
	.GLOBL	DOT
	.GLOBL	DOL
	.GLOBL	TOP
	.GLOBL	SPS
	.GLOBL	EXECM
	.GLOBL	LBUF1
	.GLOBL	LBUF2
	.GLOBL	LBUF3
	.GLOBL	GUBUF
	.GLOBL	FN
	.GLOBL	OV
	.GLOBL	OS
	.GLOBL	OE
        .GLOBL  OL
        .GLOBL  OB
        .GLOBL  Oa
        .GLOBL  pflg

	.GLOBL	ONUM							;JUL06EL
	.GLOBL	SAVEQ							;JUL06EL
	.GLOBL	OLDCMD
	.GLOBL	SFN
	.GLOBL	GUPTR
	.GLOBL	PEEK
	.GLOBL	macflg

	.MCALL	CALL
	.MCALL	close$
	.MCALL	CALLR
	.MCALL	RETURN
	.MCALL	dir$

;
; GLOBAL EQUIVALENCES
;

EOF	==	0		;TEXT END OF FILE
NL	==	12		;ASCII NEWLINE
CR	==	15		;ASCII CARRIAGE RETURN
ESC	==	33		;ASCII ESCAPE
FF	==	14		;ASCII FORMFEED
PSIZE	==	22.		;PAGE SIZE (IN LINES)
LBS     ==      250.            ;LINE BUFFER SIZE (see edi11 - must match)
GUBS	==	160.		;GLOBAL/UNTIL BUFFER SIZE
FNS	==	40.		;FILE NAME SIZE
maccmd	==	177		;special macro command processor code

;
; GLOBAL DATA
;


protec: .word   160000          ;protection of input file (init with def)
pflg:   .word   0               ;0=normal write, <>0 = write aprotection attr
WDONE:	.WORD	0		;FOR THOSE WHO FORGET TO "W".
OV:	.WORD	1		;OPTION VERBOSE FLAG
OS:	.WORD	0		;OPTION SENSITIVE FLAG
OE:	.WORD   0		;OPTION USE EDI-LIKE SYNTAX 0=NO, -1=YES
ol:     .WORD   -1               ;automatic on and off of centerline in lmode
ob:     .WORD   0               ;don't replace leading spaces with tabs
oa:     .WORD   0               ;automatic indenting 1/2 tab moves tag
ONUM:	.WORD	-1		;OPTION FOR LIST WITH LINE NUMBERS	;JUL06EL
tabmsk: .word   177770          ;half tab initially
GUPTR:	.WORD	0		;GLOBAL/UNTIL POINTER
PEEK:	.WORD	-1		;PEEK CHARACTER
OLDCMD:	.BLKW	1		;COMMAND ON THE LINE FLAG
pADR1:	.word 0			;ADDRESS 1 previous
pADR2:	.word 0			;ADDRESS 2 previous
ADR1:	.BLKW	1		;ADDRESS 1
ADR2:	.BLKW	1		;ADDRESS 2
ZERO:	.BLKW	1		;ADDRESS OF LINE 0
DOT:	.BLKW	1		;ADDRESS OF CURRENT LINE
DOL:	.BLKW	1		;ADDRESS OF LAST LINE
TOP:	.BLKW	1		;POINTER TO TOP OF MEMORY
SPS:	.BLKW	1		;SAVE FOR SP
EXECM:	.BLKW	1		;NON ZERO DURING COMMAND EXECUTION
macflg:	.BLKW	1		;NON ZERO DURING macro EXECUTION
SAVEQ:	.BLKW	1		;SAVE LAST = LINE NUMBER		;JUL06EL
	.word	0		;need place before lbuf1 to clobber
LBUF1:	.BLKB	LBS		;LINE BUFFER 1
LBUF2:	.BLKB	LBS		;LINE BUFFER 2
LBUF3:	.BLKB	LBS		;LINE BUFFER 3
GUBUF:	.BLKB	GUBS		;GLOBAL/UNTIL BUFFER
FN:	.BLKB	FNS		;FILE NAME
SFN:	.BYTE	0		;SAVED FILE NAME
	.BLKB	FNS-1		;

	.EVEN
plist:	.word 1
	.word gubuf		;ihang fort call list

ht	=	9.		;tab char
mend:	.ascii "+i"<ht>"a"<1><nl><maccmd><1>	;macro for mend (") cmd
	.ascii "0;[\\&];\\&;+y"<1><nl>
	.ascii "+d"<nl>"-i"<1>"b"
mendl=.-mend
mend2:	.byte 0			;need to putback another char sometimes
	.even

;
; ERROR MESSAGES USED IN "VERBOSE" MODE.
;

	.MACRO	MSG	TEXT,?LAB
	.IF	NDF,...MSG
...MSG:	.BLKW	0
	.ENDC
LAB:	.BLKW	0
	MSG1	<TEXT>,\<LAB-...MSG>
	.ENDM

	.MACRO	MSG1	TEXT,LAB
	.WORD	.ML'LAB
				.if df mutask
					.PSECT	.TEXT.
				.iff
				        .psect .text.,ro
				.endc
.ML'LAB:.ASCIZ	"TEXT"
				.if df mutask
		                        .PSECT
		                .iff
		                        pure
		                .endc
        .ENDM

VETAB:	MSG	<Line too long>		; 0
	MSG	<Search failure>	; 1
	MSG	<Bad command>		; 2
	MSG	<Bad pattern>		; 3
	MSG	<Bad address>		; 4
	MSG	<Address wraparound>	; 5
	MSG	<Address out of buffer>	; 6
	MSG	<**GOK**>		; 7
	MSG	<Cannot open file>	; 8
	MSG	<Bad command>		; 9
	MSG	<File I/O error>	; 10
	MSG	<Too many lines>	; 11
	MSG	<Tempfile full or I/O error>	; 12
	MSG	<file not WRITTEN>	; 13
	MSG	<Bad number>		; 14						;JUL08EL
	MSG 	<Address tags deleted or not set>	; 15
        MSG     <No tab or ~ before macro>   ; 16


;+
; ** ERROR - ERROR PROCESSOR
;
; ALL ERRORS ARE FUNNELLED THROUGH THIS ROUTINE. TWO TYPES OF ERROR
; MESSAGES ARE GENERATED: TERSE MESSAGES (?N, WHERE N IS THE  ERROR
; CODE) AND VERBOSE MESSAGES (AN EPISTLE IN TASTEFUL DUAL CASE).
;
; THE N IN THE ?N MESSAGE IS OF HISTORICAL INTEREST ONLY.
;
; INPUTS:
;	R1=ERROR CODE
;-

	.if ndf mutask
		.PSECT EDI00							;JUL08EL
	.endc

	pure

error:
	tst f.bdb+fdb
	beq 5$			;is file still open
	close$ #fdb		;close it or we're dead
5$:
	call scner1		;move cursor to the bottom first
	TST	OV		;IN VERBOSE MODE
	BNE	10$		;YES
	MOV	#'?,R0		;NO, OUTPUT '?'
	CALL	TTYC		;
	CALL	TTYNUM		;THE ERROR CODE
	BR	20$		;

10$:	ASL	R1		;ERROR CODE TO WORD INDEX
	MOV	VETAB(R1),R0	;GET MESSAGE
	CALL	TTYSTR		;PUT IT OUT

20$:
	call scner2		;output the newline or move cursor
	CLR	GUPTR		;GET OUT OF GLOBALS
	CLR	OLDCMD		;RESET OLD COMMAND FLAG
	clr macflg		;reset macro in progress flag
	MOV	SPS,SP		;FIX SP

;+
; ** COMMND - COMMAND PROCESSOR
;
; USES:
;	ALL
;-

;;;COMMND:	
;;;	clr execm
;;;	call getc
;;;	cmp r0,#'!
;;;	bne 8$			;not an mcr command
;;;	mov #gubuf,r1		;use for temp buffer
;;;	mov #gubs-2,r2		;max len
;;;6$:	call getc
;;;	cmp r0,#nl		;end of line
;;;	beq 7$			;yes
;;;	movb r0,(r1)+		;transfer line
;;;	sob r2,6$		;don't clobber anything if line 2 long
;;;	clr r1			;or else this error
;;;	jmp error
;;;7$:	clrb (r1)		;asciz it
;;;	mov r5,-(sp)		;save
;;;	mov #plist,r5		;fort call
;;;	dir$ #dtty		;detach terminal
;;;	call ihang		;do it
;;;	dir$ #atty		;re-attach terminal
;;;	mov (sp)+,r5
;;;	jmp commnd
;;;8$:	mov r0,peek	;put back the char
COMMND:	
	clr execm
	call getc
	cmp r0,#'!
	bne 8$			;not an mcr command
	clr r4	;use as flag
	mov #3,r3	;# of bytes to sub off addr for $'s
	mov #"$$,gubuf	;precede with 0,1, or 2 $'s
	mov #gubuf+2,r1		;use for temp buffer
	mov #gubs-4,r2		;max len
6$:	call getc
	cmp r0,#nl		;end of line
	beq 7$			;yes
	tst r4		;still counting (# of chars till space or end)
	bne 65$		;no
	cmp r0,#40	;space?
	bne 62$		;nope
	inc r4		;set flag to stop counting
	br 65$

62$:	dec r3		;one less $ to insert
	bge 65$		;min of zero for r3
	clr r3
65$:	movb r0,(r1)+		;transfer line
	sob r2,6$		;don't clobber anything if line 2 long
	clr r1			;or else this error
	jmp error
7$:	clrb (r1)		;asciz it
	mov r5,-(sp)		;save
	mov #gubuf+2,plist+2	;set addr to user line
	sub r3,plist+2		;insert $,s if necessary
	mov #plist,r5		;fort call
	dir$ #dtty		;detach terminal
	call ihang		;do it
	dir$ #atty		;re-attach terminal
	mov (sp)+,r5
	jmp commnd
8$:	mov r0,peek	;put back the char
cmd2:	clr execm		;into cmd mode
	call getc		;get next char and check if nl
	cmp r0,#nl		;cause if it is, might be from last cmd
	beq 5$			;its a nl
	cmp r0,#40		;else check for space bar (=use last range)
	beq 7$			;its a space
	mov r0,peek		;nope, putback 1 char, process as usual
	br 9$

5$:	tst oldcmd		;is the nl remainder of prev cmd?
	bne 6$			;yes
	mov r0,peek		;nope, putback 1 char, process as usual
	br 9$			;no, must be <cr> cmd (.+1p)

6$:	clr oldcmd		;nl + oldcmd=just throw away cr
	br commnd

7$:	
	call chkadr		;check adr1 and adr2
	call getc		;prime it
	br 40$			;go reuse adr1+2
9$:
	CLR	ADR1		;CLEAR OLD
	CLR	ADR2		;LINE ADDRESSES
	CLR	EXECM		;GET INTO COMMAND MODE

10$:	MOV	ADR2,ADR1	;GET AN
	CALL	ADDRES		;ADDRESS
	TST	R2		;DID I GET ONE
	BEQ	30$		;NO
	MOV	R2,ADR2		;USE IT
	CMP	R0,#';		;DELIMITER A ';'
	BNE	20$		;NO
	MOV	R2,DOT		;YES, RESET '.'
	BR	10$		;
20$:	CMP	R0,#',		;DELIMITER A ','
	BEQ	10$		;YES, GO GET ANOTHER ADDRESS

30$:	TST	ADR1		;IF ONLY 1 ADDRESS
	BNE	40$		;THEN
	MOV	ADR2,ADR1	;SET THEM EQUAL

40$:	CMP	R0,#NL		;NEWLINE COMMAND
	BNE	50$		;NO
	TST	ADR2		;PRINT IF WE HAVE AN ADDRESS
	BNE	44$		;OR
	TST	OLDCMD		;IF THERE IS NOTHING ELSE
	BEQ	42$		;ON THE LINE
	CLR	OLDCMD		;OTHERWISE CLEAR FLAG
	JMP	COMMND		;AND GO FOR MORE
42$:	MOV	DOT,R0		;START AT DOT
	ADD	#2,R0		;MOVE AHEAD 1 LINE
	CMP	R0,DOL		;BUT DON'T GO PAST THE END
	BLOS	43$		;
	MOV	#6,R1		;OR ?6
	JMP	ERROR		;
43$:	MOV	R0,ADR1		;SET ADDRESSES FOR
	MOV	R0,ADR2		;PRINT COMMAND
44$:	CLR	OLDCMD		;CLEAR FLAG
	call svadrs		;save address range
	mov #'p,r0
	br 80$			;fake a p command

50$:	CMP	R0,#EOF		;GLOBAL EOF
	BNE	60$		;NO
	MOV	ZERO,R0		;LOOK FOR NEXT GLOBAL LINE
52$:	TST	(R0)+		;
	CMP	R0,DOL		;AT THE END
	BHI	54$		;YES, NO MORE LINES
	BIT	#1,(R0)		;MARKED
	BEQ	52$		;NO
	DEC	(R0)		;REMOVE THE MARK
	MOV	R0,DOT		;SET DOT
	MOV	#GUBUF,GUPTR	;BACKUP GLOBAL POINTERS
	JMP	COMMND		;GO GET COMMAND
54$:	CLR	GUPTR		;GET OUT OF GLOBAL
	JMP	COMMND		;GO GET COMMAND

60$:	INC	OLDCMD		;SET COMMAND ON THE LINE FLAG
	INC	EXECM		;SET COMMAND IN EXECUTION
	CMP	R0,#'=		;EQUAL COMMAND
	BNE	70$		;NO
	CALL	DEFDOT		;DEFAULT TO .=
	MOV	ADR2,R1		;GET ADDRESS
	MOV 	R1,SAVEQ	;SAVE THIS (EVENTUALLY MAY BE USED)	;JUL06EL
	SUB	ZERO,R1		;
	ASR	R1		;CONVERT TO LINES
	clr smode			;out of screen mode here
	CALL	TTYNUM		;DISPLAY IT
	CALL	TTYNL		;
	JMP	COMMND		;

70$:	CMP	R0,#'&		;PRINT A PAGE
	BNE	80$		;NO
	CALL	DEFDOT		;DEFAULT TO CURRENT LINE
	MOV	ADR2,R0		;GET WHERE TO START
	MOV	R0,ADR1		;MAKE A P COMMAND UP
	ADD	#2*PSIZE,R0	;
	CMP	R0,DOL		;BUT DON'T GO PAST THE END
	BLOS	72$		;
	MOV	DOL,R0		;
72$:	MOV	R0,ADR2		;
	MOV #'P,R0		;SIMULATE A N,MP COMING IN WITH CORRECT ADDRESSES
	tst smode		;in screen mode?
	beq 80$			;eq->not screen mode
	mov adr2,adr1		;else its screen mode, so make it a m,mp
	br 85$			;then continue
80$:	cmp r0,#'%		;is it a % command?
	bne 85$
	tst smode
	beq 85$			;% command only in screen mode
	mov dot,r0
	sub #2*psize,r0
	cmp r0,zero
	bhi 82$			;don't go before line 1
	mov zero,r0
	add #2,r0
82$:
	mov r0,adr1
	mov r0,adr2
	mov #'P,r0		;and make it a p command

85$:	cmp r0,#'"		;" command (mend two lines by a macro)
	bne 95$			;nope
	mov #1,macflg		;set macro in progress flag
	mov #mend,r0
	mov #mendl-1,r1		;macro with out the b command
	tst smode		;in screen mode?
	beq 87$
	call getc
	movb r0,mend2		;got to put this back this way
	mov #mend2,r0
	mov #1,r1
	call putbak		;this putback is retreived at the end
	mov #mend,r0
	mov #mendl,r1		;macro with the b command
	clr smode		;else clear it
	call putbak
	jmp commnd
87$:	call putbak
	jmp commnd
95$:
	cmp r0,#maccmd		;is it the "macro command"
	bne 97$			;nope
	call macrop		;yes, goto the macro processor
	jmp commnd		;then back to the main loop
97$:
	cmp r0,#2               ;is it a control b = breakpoint
	bne 197$                ;not
        cmp #debuga,#1          ; is debugging enabled
        bne 197$                ; no
	mov protec,r0
	mov pios,r1
        iot                     ; yes trap to odt

197$:   BIC     #' ,R0          ;MUST BE ALPHABETIC COMMAND
	SUB	#'A,R0		;
	CMP	R0,#'Z-'A	;LEGAL
	BHI	ERR2		;NO
	call svadrs		;save adr1+2
	ASL	R0		;CALL ROUTINE
	call prescn		;pre screen editor call
	mov r0,-(sp)
	CALL	@CMDTAB(R0)	;
	mov (sp)+,r0
	call postscn		;post screen editor call
	JMP	COMMND		;GO BACK TO COMMAND LOOP

ERR2:	MOV	#2,R1		;ILLEGAL COMMAND
	JMP	ERROR		;

svadrs:
	cmp adr1,adr2
	beq 5$		;don't save unless its a range
	mov adr1,padr1	;save adr1
	mov adr2,padr2	;save adr2
5$:	rts pc
chkadr:	
	mov padr1,adr1	;use previous if not
	mov padr2,adr2	;"    "
	tst adr1	;zero
	beq 10$		;yep
	tst adr2	;test this too
	beq 10$		;same place if zero
	cmp adr1,adr2	;
	bhi 10$		;but something is wrong if hi
	cmp adr2,dol	;out of range
	bhi 10$		;yep

5$:	rts pc

10$:	mov #15.,r1	;no prev=error 15
	jmp error
;
; COMMAND JUMP TABLE
; INDEXED BY ASCII CHARACTERS IN THE RANGE A-Z
;


	impure



CMDTAB:	.WORD	ACOM		;APPEND
	.WORD	bcom		;begin screen	in edi07 screen module
C100::	.WORD	CCOM		;CHANGE
	.WORD	DCOM		;DELETE
	.WORD	ECOM		;EDIT
	.WORD	FCOM		;FACTS
	.WORD	GCOM		;GLOBAL
	.WORD	ERR2		;H
	.WORD	ICOM		;INSERT
	.WORD	JCOM		;JOIN
	.WORD	KCOM		;KOPY
	.WORD	lcom		;L
	.WORD	MCOM		;MOVE
        .WORD   ncom            ;New commands (2 letter variety)
	.WORD	OCOM		;OPTIONS
	.WORD	PCOM		;PRINT
	.WORD	QCOM		;QUIT
	.WORD	RCOM		;READ
S100::	.WORD	SCOM		;SUBSTITUTE
	.WORD	tcom		;T
	.WORD	ucom		;U
	.WORD	VCOM		;EXCLUDE
	.WORD	WCOM		;WRITE
	.WORD	XCOM		;WRITE WITH NEW VERSION
	.WORD	YCOM		;Y
	.WORD	ZCOM		;Z COMMAND				;JUL08EL

	.END
