;
;THE TXT-2 TEXT EDITOR STARTS HERE BUT ENTRY IS AT TXT2 (FA0B)
;
;ROUTINE TO CREATE A ONE LINE FILE NECESSARY FOR THE
;EDITOR WHEN STARTING A NEW (E.G. NULL OR EMPTY) FILE
;
LFA00:	MVI	M,2		;LENGTH BYTE
	INX	H		;POINT TO NEXT BYTE
	MVI	M,0DH		;CARRIAGE RETURN
	INX	H		;POINT TO NEXT
	MVI	M,1		;END OF FILE MARK
	SHLD	EOFP		;NOW WE HAVE A NON-EMPTY FILE
;
;THIS IS THE EDITOR ENTRY POINT
;
TXT2:	LXI	SP,SMODE	;SET STACK POINTER
	LHLD	BOFP		;GET BEG OF FILE POINTER
	LXI	D,EOFP		;AND POINT TO END OF FILE PTR
	CALL	LFD42		;COMPARE THEM
	JZ	LFA00		;CREATE ONE LINE FILE IF EMPTY
	JC	WHAT		;ERROR IF BOFP > EOFP
	PUSH	H		;SAVE BEG. OF FILE POINTER
	CALL	LFD4E		;CLEAR SCREEN & INITIALIZE VARS
	SUB	A		;GET A ZERO
	MOV	B,A		;MAKE IT ROW
	CALL	LFF1A		;CALC CUR ADDR & TURN IT ON
	POP	H		;RESTORE BEG OF FILE PNTR
LFA27:	SHLD	LD19A		;
	CALL	LFAD9
;
;THIS IS THE BEGINNING OF THE MAIN EDITOR COMMAND LOOP
;
LFA2D:	CALL	LFA33		;GET AND EXECUTE A COMMAND
	JMP	LFA2D		;DO IT AGAIN
;
;AND THAT WAS THE END OF IT
;
LFA33:	CALL	LFF13		;CALC CUR ADDR & TURN CURSR ON
	CALL	IN8		;GET A CHAR OF COMMAND
LFA39:	CPI	' '		;CONTROL CHAR ?
	JNC	LFC04		;PROCESS PRINTING CHAR IF NOT
	CPI	'A'-40H		;CURSOR LEFT COMMAND ?
	JZ	LFB57		;PROCESS IF SO
	CPI	'S'-40H		;CURSOR RIGHT COMMAND ?
	JZ	LFC10		;PROCESS IF SO
	PUSH	PSW		;SAVE COMMAND
	CALL	LFCA4
	POP	B		;RESTORE COMMAND TO B
	LXI	H,LFA65		;EDITOR COMMAND TABLE
LFA50:	MOV	A,M		;GET TABLE COMMAND
	ORA	A		;END OF TABLE ?
	RZ			;YES
	CMP	B		;NO - SAME AS COMMAND ?
	INX	H		;POINT TO COMMAND ADDR
	JZ	LFA60		;DISPATCH TO IT ON MATCH
	INX	H		;NO MATCH - POINT PAST COMMAND
	INX	H		;TO NEXT COMMAND
	JMP	LFA50		;AND TEST NEXT COMMAND
;
;ROUTINE TO DISPATCH TO COMMAND IN TABLE
;
LFA5D:	LXI	H,LD1A1		;POINT TO UNDEFINED COMMAND
LFA60:	MOV	A,M		;COMMAND LOW BYTE TO A
	INX	H		;POINT TO HIGH BYTE
	MOV	H,M		;HIGH BYTE TO H
	MOV	L,A		;H,L NOW HAS COMPLETE ADDR
	PCHL			;DISPATCH TO COMMAND ROUTINE
;
;HERE IS THE COMMAND TABLE FOR THE EDITOR COMMANDS
;
LFA65:	DB	'W'-40H		;UP
	DW	LFACC
	DB	'Z'-40H		;DOWN
	DW	LFB62
	DB	'E'-40H		;SCROLL UP ONE LINE
	DW	LFB8E
	DB	'X'-40H		;SCROLL DOWN ONE LINE
	DW	LFAC6
	DB	'R'-40H		;SCROLL UP 1 PAGE
	DW	LFB12
	DB	'C'-40H		;SCROLL DOWN 1 PAGE
	DW	LFB21
	DB	'J'-40H		;ERASE EOF & SCROLL UP (L/F)
	DW	LFB7B
	DB	'B'-40H		;INSERT LINE
	DW	LFBC8
	DB	'M'-40H		;SCROLL UP & INSERT LINE (C/R)
	DW	LFB9D
	DB	'T'-40H		;TOGGLE INSERT MODE SW
	DW	LFB72
	DB	'P'-40H		;DELETE LINE
	DW	LFBD2
	DB	'H'-40H		;DELETE CHAR
	DW	LFC2E
	DB	'F'-40H		;EXIT TO ALS-8
	DW	LFAA5
	DB	'O'-40H		;EDITOR SEARCH
	DW	LFF58
	DB	'I'-40H		;CONTINUE SEARCH
	DW	LFF64
	DB	'Y'-40H		;REPEAT COMMAND
	DW	LFAAE
	DB	'Q'-40H		;HOME COMMAND
	DW	LFA9C
	DB	'U'-40H		;UNDEFINED COMMAND
	DW	LFA5D
	DB	0
;
;HOME CURSOR
;
LFA9C:	XRA	A		;GET A ZERO
	STA	NCHAR		;MAKE IT THE COLUMN
	MVI	A,6		;HOME=LINE 7 (START W/0 AT TOP)
	JMP	LFAD6		;PUT THE CURSOR THERE
;
;EXIT EDITOR TO ALS-8
;
LFAA5:	CALL	LFD4E		;CLEAR VDM-1 SCREEN
	CALL	FCHK		;FCHK FILE
	JMP	EORMS		;GO BACK TO ALS-8
;
;REPEAT COMMAND
;
LFAAE:	CALL	IN8		;GET COMMAND TO REPEAT
	STA	BBUF		;SAVE COMMAND
	CALL	IN8		;GET REPEAT COUNT
	SUI	30H		;CONVERT TO BINARY
LFAB9:	PUSH	PSW		;SAVE COUNT
	LDA	BBUF		;GET COMMAND
	CALL	LFA39		;EXECUTE IT ONE TIME
	POP	PSW		;RESTORE COUNT
	DCR	A		;DECREMENT COUNT
	RZ			;DONE IF COUNT=0
	JMP	LFAB9		;ELSE DO IT AGAIN
;
;SCROLL DOWN 1 LINE
;
LFAC6:	CALL	LFC72
	JNZ	LFAD9
;
;CURSOR UP
;
LFACC:	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	DCR	A
	JP	LFAD6
	LDA	LD199
LFAD6:	STA	SLINE
LFAD9:	LHLD	LD19A
	SHLD	LD19C
	XRA	A
	STA	LD198		;CLEAR INSERT MODE
	PUSH	PSW
LFAE4:	STA	LD199
	XCHG
	LXI	H,SLINE
	CMP	M
	XCHG
	JNZ	LFAF3
	SHLD	LD19E
LFAF3:	CALL	LFE07
LFAF6:	POP	PSW
	INR	A
	CPI	16
	RZ
	MOV	B,A
	CALL	LFC5F
	XCHG
	MOV	A,B
	PUSH	PSW
	JNZ	LFAE4
	MVI	B,0
	MVI	C,'#'
	LXI	H,4001H
	CALL	LFE4E
	JMP	LFAF6
;
;SCROLL UP 1 PAGE (16 LINES)
;
LFB12:	MVI	A,16
LFB14:	PUSH	PSW
	CALL	LFC5F
	CNZ	LFB94
	POP	PSW
	DCR	A
	JNZ	LFB14
	RET
;
;SCROLL DOWN 1 PAGE (16 LINES)
;
LFB21:	MVI	A,16
LFB23:	PUSH	PSW
	CALL	LFC72
	CNZ	LFAD9
	POP	PSW
	DCR	A
	JNZ	LFB23
	RET
;
;ROUTINE TO GIVE WARNING WHEN TEXT BUFFER GETS FULL
;
LFB30:	LXI	D,LFB46		;POINT TO WARNING MESSAGE
	MVI	C,17		;LENGTH OF MESSAGE
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	LFE0C		;PRINT MESSAGE
LFB3B:	CALL	IN8		;GET CHAR FROM CONSOLE
	CPI	'Q'-40H		;CONTROL-Q ?
	JNZ	LFB3B		;NO - WAIT INDEFINATELY
	JMP	TXT2		;YES - RESTART EDITOR
;
LFB46:	DB	'FULL--TYPE CTRL Q'
;
;CURSOR LEFT COMMAND
;
LFB57:	CALL	LFF2D		;CURSOR OFF
	MOV	A,B		;COLUMN TO A
	DCR	A		;DECREMENT IT
LFB5C:	ANI	3FH		;KEEP IT TO 0-63
	MOV	M,A		;PUT IT BACK AS NEW COLUMN
	JMP	LFF16		;TURN CURSOR ON & RET
;
;CURSOR DOWN
;
LFB62:	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	LXI	H,LD199
	CMP	M
	JNZ	LFB6E
	MVI	A,0FFH
LFB6E:	INR	A
	JMP	LFAD6
;
;TOGGLE CHAR INSERT MODE
;
LFB72:	LDA	LD198		;GET INSERT MODE SWITCH
	XRI	1		;TOGGLE LOW ORDER BIT
	STA	LD198		;PUT IT BACK
	RET			;DONE
;
;ERASE TO THE END OF LINE AND SCROLL UP
;
LFB7B:	CALL	LFDED		;CALC CURSOR ADDR
LFB7E:	MVI	M,' '		;MOVE SPACE TO LINE
	INR	L		;INR LINE POINTER
	MOV	A,L		;MOVE IT TO A
	ANI	3FH		;END OF LINE YET ?
	JNZ	LFB7E		;MORE SPACES IF NOT
	CALL	LFCA4		;YES - NOW UPDATE FILE
	SUB	A		;GET A ZERO
	STA	NCHAR		;AND MAKE IT NEW COLUMN
;
;SCROLL UP 1 LINE
;
LFB8E:	CALL	LFC5F
	JZ	LFB62
LFB94:	LXI	H,LD19A
	CALL	LFC62
	JMP	LFAD9
;
;SCROLL UP AND INSERT 1 LINE
;
LFB9D:	LXI	H,LD19E
	CALL	LFC62
	JNZ	LFBAC
	LHLD	EOFP
	SHLD	LD19E
LFBAC:	CALL	LFC51
	XRA	A
	STA	NCHAR
	LDA	LD199
	CPI	0FH
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	JNZ	LFB6E
	LXI	H,LD19A
	CALL	LFC62
	JMP	LFAD9
;
	DB	01H		;THIS IS A FOOL'S BYTE
;
;INSERT LINE COMMAND
;
LFBC8:	CALL	LFC51
	XRA	A
	STA	NCHAR
	JMP	LFAD9
;
;DELETE LINE COMMAND
;
LFBD2:	SUB	A		;GET A ZERO
	STA	LD198		;USE IT TO CLEAR INSERT MODE
	LHLD	BOFP
	MOV	A,M
	CALL	LFD32
	MOV	A,M
	CPI	1
	RZ
	CALL	LFC5F
	JNZ	LFBEA
	CALL	LFC72
LFBEA:	PUSH	PSW
	LHLD	LD19E
	MOV	A,M
	CMA
	INR	A
	CALL	LFCD1
	POP	PSW
	JNZ	LFAD9
	LHLD	LD19E
	MOV	A,M
	CPI	1
	JZ	LFACC
	JMP	LFAD9
;
;
;
LFC04:	MOV	C,A
	LDA	LD198		;GET INSERT MODE FLAG
	ORA	A		;SET CPU FLAGS
	JNZ	LFC18		;JUMP IF IN INSERT MODE
	CALL	LFDED
	MOV	M,C
;
;CURSOR RIGHT COMMAND
;
LFC10:	CALL	LFF2D		;TURN CURSOR OFF
	MOV	A,B		;COLUMN TO A
	INR	A		;INCREMENT IT
	JMP	LFB5C		;CURSOR BACK ON & RET
;
;
;
LFC18:	CALL	LFDED
	MOV	A,C
	ORI	80H
	MOV	C,A
LFC1F:	MOV	A,M
	ANI	7FH
	MOV	M,C
	MOV	C,A
	INR	L
	MOV	A,L
	ANI	3FH
	JNZ	LFC1F
	JMP	LFC10
;
;DELETE CHARACTER
;
LFC2E:	CALL	LFDED		;CALC CURSOR POSITION
	LDA	NCHAR		;GET CURRENT COLUMN
	CPI	3FH		;COLUMN 63 (LAST) ?
	JC	LFC3C		;NO - DELETE CHAR
	MVI	M,' '+80H	;MAKE LAST COL SPACE W/CURSOR
	RET			;DONE
;
;ROUTINE TO DELETE A CHAR FROM MIDDLE OF LINE
;
LFC3C:	MOV	A,L		;GET LINE POINTER
	MOV	E,A		;SAVE IT
	ORI	3FH		;MAKE IT POINT TO LAST COL
	MOV	L,A		;PUT IT BACK
	MOV	A,E		;RESTORE ORIG PTR TO A
	MVI	C,' '		;SPACE TO C
LFC44:	MOV	B,M		;GET CHAR FROM LINE
	MOV	M,C		;REPL WITH CHAR ON IT'S RIGHT
	MOV	C,B		;AND MAKE IT NXT CHAR ON RIGHT
	DCR	L		;DECR COLUMN POINTER
	CMP	L		;AND COMPARE TO INITIAL COL
	JNZ	LFC44		;AND KEEP UP IF NOT DONE
	MOV	A,B		;GET LAST CHAR TO STORE IN A
;
;TURN ON THE CURSOR
;
LFC4D:	ORI	80H		;MAKE CURSOR BIT HIGH
	MOV	M,A		;PUT CHAR W/CURSOR ON SCREEN
	RET			;DONE, CURSOR ON
;
;
;
LFC51:	MVI	A,2
	CALL	LFCD1
	LHLD	LD19E
	MVI	M,2
	INX	H
	MVI	M,0DH
	RET
;
;
;
LFC5F:	LXI	H,LD19C
LFC62:	MOV	E,M
	INX	H
	MOV	D,M
	LDAX	D
	XCHG
	CALL	LFD32
	XCHG
	LDAX	D
	DCR	A
	RZ
	MOV	M,D
	DCX	H
	MOV	M,E
	RET
;
;
;
LFC72:	LHLD	LD19A
	CALL	LFC95
	RZ
	DCX	H
LFC7A:	DCX	H
	CALL	LFC95
	JZ	LFC90
	MOV	A,M
	CPI	0DH
	JNZ	LFC7A
	DCX	H
	MOV	A,M
	CPI	0DH
	JZ	LFC8F
	INX	H
LFC8F:	INX	H
LFC90:	INR	A
	SHLD	LD19A
	RET
;
;
;
LFC95:	LDA	BOFP
	SUB	L
	LDA	BOFP+1
	SBB	H
	RNZ
	LDA	BOFP
	SUB	L
	ORA	A
	RET
;
;
;
LFCA4:	CALL	LFF2D		;TURN ON THE CURSOR
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	LFE33		;BACK UP TO LAST NON BLANK CHAR
	INR	C
	INR	C
	MOV	A,C
	CPI	6
	JNC	LFCB8
	MVI	A,6
	MOV	C,A
LFCB8:	LHLD	LD19E
	SUB	M
	CALL	LFCD1
	LHLD	LD19E
	MOV	M,C
	DCR	C
	DCR	C
	INX	H
	XCHG
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	LFE24
	XCHG
	MVI	M,0DH
	RET
;
;
;
LFCD1:	MOV	B,A
	ORA	A
	RZ
	JM	LFD1A
	LHLD	EOFP
	CALL	LFD32
	LXI	D,LD191		;POINT TO ESET BUFFER LIMIT
	CALL	LFD42
	JC	LFB30
	XCHG
	LHLD	LD19E
	DCX	H
	MVI	M,81H
	LHLD	EOFP
LFCF0:	MOV	A,M
	CPI	81H
	JZ	LFCFC
	STAX	D
	DCX	H
	DCX	D
	JMP	LFCF0
;
;
;
LFCFC:	MVI	M,0DH
LFCFE:	LHLD	EOFP
	MOV	A,B
	CALL	LFD32
	SHLD	EOFP
	LHLD	LD19C
	LXI	D,LD19E
	CALL	LFD42
	RZ
	MOV	A,B
	CALL	LFD32
	SHLD	LD19C
	RET
;
;
;
LFD1A:	CMA
	INR	A
	LHLD	LD19E
	CALL	LFD32
	XCHG
	LHLD	LD19E
LFD26:	LDAX	D
	MOV	M,A
	CPI	01H
	JZ	LFCFE
	INX	H
	INX	D
	JMP	LFD26
;
;
;
LFD32:	ORA	A
	JM	LFD3B
	ADD	L
	MOV	L,A
	RNC
	INR	H
	RET
;
;
;
LFD3B:	ADD	L
	MOV	L,A
	MVI	A,0FFH
	ADC	H
	MOV	H,A
	RET
;
;
;
LFD42:	LDAX	D
	SUB	L
	INX	D
	LDAX	D
	SBB	H
	DCX	D
	RC
	RNZ
	LDAX	D
	SUB	L
	ORA	A
	RET
;
;ROUTINE TO CLEAR ALL OR PART OF VDM-1 DISPLAY SCREEN
;
LFD4E:	LXI	H,VDM1		;ENTER HERE TO CLR WHOLE SCREEN
LFD51:	MVI	M,' '		;FILL WITH SPACES
	INX	H		;POINT TO NEXT CHAR POSITION
	MOV	A,H		;GET HIGH ORDER BYTE
	CPI	0D0H		;PAST END OF SCREEN ?
	JC	LFD51		;CONTINUE IF NOT
	XRA	A		;ELSE GET A ZERO TO CLEAR:
	STA	BOSL		;BEGINNING OF SCREEN LINE (0-F)
	STA	BOTL		;BEGINNING OF TEXT LINE (0-F)
	STA	NCHAR		;CURRENT COLUMN POSITION
	MVI	A,0FH		;THEN GET A 15
	STA	SLINE		;TO PUT US ON THE BOTTOM LINE
;
;THIS ROUTINE OUTPUTS A PROPER COMMAND BYTE TO THE VDM-1/SOL-20
;VIDEO DISPLAY GENERATOR BASED ON SCREEN PARAMTETERS
;
LFD69:	LDA	BOSL		;BEGINNING OF SCREEN LINE (0-F)
	RLC			;SHIFT LEFT TO HIGH NIBBLE
	RLC			;
	RLC			;
	RLC			;
	LXI	H,BOTL		;BEGINNING OF TEXT LINE (0-F)
	ORA	M		;A NOW HAS VDM CONTROL BYTE
	OUT	0C8H		;FOR VDM-1
	OUT	0FEH		;FOR SOL'S
	RET			;DONE
;
;
;
LFD79:	INR	L
	MOV	A,L
	ANI	3FH
	RNZ
	MOV	A,L
	ADI	0C0H
	MOV	L,A
	RET
;
;THIS ROUTINE IS PART OF THE VDM-1 DRIVER USED TO DISPLAY
;NORMAL CHARS AFTER CHECKING FOR SPEED CNTL HAS BEEN DONE
;
LFD83:	ANI	7FH		;CLEAR PARITY BIT
	MOV	C,A		;SAVE IN C
	LXI	H,NCHAR		;CURRENT COLUMN
	MOV	B,M		;COL IN B
	CPI	0DH		;IS CHAR A C/R ?
	JZ	LFDB1		;PROCESS IT SEPERATELY
	CPI	5FH		;BACKSPACE ?
	JZ	LFEED		;IT GET'S SPECIAL TREATMENT TOO
	CPI	'A'-40H		;CURSOR ON-OFF TOGGLE ?
	JZ	LFF06		;ANOTHER SPECIAL
	CPI	'Z'-40H		;CLEAR SCREEN ?
	JZ	LFD4E		;LAST SPECIAL CHAR
	CPI	20H		;TESTING FOR CONTROL CHAR
	RC			;SKIP THEM IF FOUND
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	VDAD		;AND CALCULATE CHAR ADDRESS
	MOV	M,C		;PUT CHAR ON SCREEN
	LDA	NCHAR		;NOW GET COLUMN
	INR	A		;AND INCREMENT IT
	CPI	64		;GONE OFF END OF LINE ?
	JNZ	LFDBD		;NO - OK THEN
;
;COME HERE TO PROCESS CARRIAGE RETURN
;
LFDB1:	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	LFE46		;TURN CURSOR OFF
	MVI	A,1
	CALL	LFDCD		;CLEAR TO END OF LINE & SCROLL
	SUB	A		;GET A ZERO
LFDBD:	STA	NCHAR		;PUT UPDATED COL. POSITION BACK
	MOV	B,A		;AND MOVE IT TO B
	LDA	LD197		;GET CURSOR ON-OFF FLAG
	CPI	0		;SET FLAGS
	RZ			;DONE IF CURSOR OFF
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	JMP	LFF1A		;TURN CURSOR ON & RETURN
;
;
;
LFDCD:	LXI	H,BOTL		;BEGINNING OF TEXT LINE (0-F)
	ORA	A
	JZ	LFDD9
	MOV	A,M
	INR	M
	JMP	LFDDD
LFDD9:	DCR	M
	MOV	A,M
	ANI	0FH
LFDDD:	SUB	M
	MVI	C,0
	CALL	LFE0C
	LXI	H,BOTL		;BEGINNING OF TEXT LINE (0-F)
	MOV	A,M
	ANI	0FH
	MOV	M,A
	JMP	LFD69
;
;
;
LFDED:	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	LXI	H,NCHAR		;GET COLUMN POSITION
	MOV	B,M		;TO B
;
;FOLLOWING ROUTINE CALCULATES ADDR OF CHAR AT LINE
;IN "A" AND COL "B"
;
VDAD:	MOV	L,A		;LINE NO. (0-F) TO L
	LDA	BOTL		;BEGINNING OF TEXT LINE (0-F)
	ADD	L		;ADD OFFSET TO LINE
	RRC			;DIVIDE BY TWO
	RRC			;AGAIN, NOW /4
	MOV	L,A		;SAVE # PAGES (256) OFFSET
	ANI	3		;MAKE IT 0-3 ONLY
	ADI	(VDM1 SHR 8) AND 0FFH
	MOV	H,A		;H NOW HI SCREEN ADDR
	MOV	A,L		;RESTORE # 256 BYTE PGS. OFFSET
	ANI	0C0H		;CHG TO # LINES FROM PG BOUNDRY
	ADD	B		;ADD IN COL ON LINE
	MOV	L,A		;H,L NOW COMPLETE ADDR
	RET			;DONE
;
;
;
LFE07:	MOV	C,M
	DCR	C
	DCR	C
	INX	H
	XCHG
LFE0C:	MVI	B,0
	CALL	VDAD
	MVI	B,64
LFE13:	XRA	A
	CMP	C
	MVI	A,' '
	JZ	LFE1D
	LDAX	D
	INX	D
	DCR	C
LFE1D:	MOV	M,A
	INR	L
	DCR	B
	JNZ	LFE13
	RET
;
;
;
LFE24:	MVI	B,0
	CALL	VDAD
	INR	C
LFE2A:	DCR	C
	RZ
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	JMP	LFE2A
;
;
;
LFE33:	MVI	B,3FH
	CALL	VDAD
	MVI	C,40H
LFE3A:	MOV	A,M
	ANI	7FH
	CPI	20H
	RNZ
	DCX	H
	DCR	C
	JNZ	LFE3A
	RET
;
;ROUTINE TO TURN CURSOR OFF
;
LFE46:	CALL	VDAD		;CALCULATE SCREEN ADDR
	MOV	A,M		;GET CHAR UNDER CURSOR
	ANI	7FH		;TURN CURSOR BIT OFF
	MOV	M,A		;PUT IT BACK
	RET			;DONE, CURSOR OFF
;
;
;
LFE4E:	XCHG
LFE4F:	PUSH	PSW
	PUSH	D
	CALL	VDAD
LFE54:	MOV	M,C
	CALL	LFD79
	DCR	D
	JNZ	LFE54
	POP	D
	POP	PSW
	DCR	E
	RZ
	INR	A
	JMP	LFE4F
;
;
;
LFE64:	CPI	1BH		;ESCAPE CHAR ?
	JZ	EORMS		;BACK TO ALS-8 THEN
	CPI	20H		;SPACE BAR ?
	JNZ	LFEC1		;NO - CLEAR CHRR AND RETURN
LFE6E:	CALL	STAT		;YES - CHAR TYPED ?
	JZ	LFE6E		;NO - WAIT FOREVER IF NECESSARY
	JMP	LFEC2		;THEN SAVE THAT CHAR AS CHRR
;
;VDM-1 DRIVER STARTS HERE
;
LFE77:	MOV	A,B		;GET CHAR TO A
	CPI	7FH		;DELETE CHAR ?
	RZ			;RETURN IF SO
	PUSH	H		;ELSE SAVE REGISTERS
	PUSH	D		;
	PUSH	B		;
	LDA	SPEED		;GET SPEED CONTROL BYTE
	MOV	H,A		;TO H
	MVI	L,80H		;COUNTER NOW SET
	CALL	LFE9D		;SEE IF CHAR WAITING
	XRA	A		;MAKE ACC. ZERO
LFE88:	DCX	H		;DCR TIMER COUNTER
	CMP	H		;H = 0 YET ?
	JNZ	LFE88		;NO - THEN DELAY SOME MORE
	POP	B		;RESTORE CHAR TO B
	PUSH	B		;AND RE-SAVE B,C
	MOV	A,B		;GET CHAR AGAIN
	CPI	'S'-40H		;CONTROL-S ?
	CZ	LFEC6		;CALL SPEED SET ROUTINE
	CALL	LFD83		;PUT CHAR ON SCREEN
	POP	B		;RESTORE REGS
	POP	D		;
	POP	H		;
	MOV	A,B		;PUT CHAR IN ACC ON EXIT
	RET			;DONE
;
;ROUTINE TO CHECK FOR KEYBOARD INPUT & SCREEN CONTROL VALUE
;
LFE9D:	LDA	CHRR		;DEFAULT SPEED
	MOV	B,A		;SAVE IT IN B
	CALL	STAT		;KEYBOARD CHAR WAITING ?
	CNZ	IN8		;YES - THEN GET IT
	MOV	A,B		;DEFAULT SPEED OR CHAR TO A
LFEA8:	ORA	A		;SET FLAGS
	RZ			;NO CHG IF CHR/DEFAULT=0
	CPI	'9'+1		;NUMERIC ?
	JNC	LFE64		;NO, NOT NUMERIC
	CPI	'1'		;NUMERIC ?
	JC	LFE64		;NO, NOT NUMERIC
	ANI	0FH		;CONVERT TO BINARY
	MOV	C,A		;SAVE IN C
	XRA	A		;CLEAR ACC & FLAGS
	STC			;SET CARRY
LFEB9:	STA	SPEED		;SPEED CONTROL BYTE
	RAL			;MOVE ACCUM/CARRY 1 BIT LEFT
	DCR	C		;DCR SPEED COUNT
	JNZ	LFEB9		;IF SPEED COUNT <> 0, CONTINUE
LFEC1:	XRA	A		;GET A ZERO
LFEC2:	STA	CHRR		;MAKE IT ZERO FOR NEXT TIME
	RET			;DONE
;
;ROUTINE TO SET SPEED
;
LFEC6:	MVI	B,0		;COLUMN = 0
	CALL	LFDB1		;CLEAR LINE
	LXI	H,LFEE6		;POINT TO "SPEED ?" MESSAGE
LFECE:	MOV	A,M		;GET CHAR FROM MSG
	PUSH	H		;SAVE H,L
	CALL	LFD83		;PRINT MESSAGE
	POP	H		;RESTORE H,L
	INX	H		;POINT TO NEXT CHAR
	MOV	A,M		;GET IT
	ORA	A		;SET FLAGS
	JNZ	LFECE		;PRINT IT IF NOT ZERO
	CALL	IN8		;GET CHAR
	CALL	LFEA8		;TEST NUMERIC & SET SPEED
	CALL	CRLF		;DO CR/LF
	JMP	EORNS		;THEN BACK TO ALS-8
;
LFEE6:	DB	'SPEED?'
	DB	0
;
;
;ROUTINE TO PROCESS BACKSPACE (5FH)
;
LFEED:	LDA	NCHAR		;GET COLUMN
	MOV	B,A		;TO B
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	LFE46		;TURN CURSOR OFF
	DCX	H		;POINT TO PREV CHAR
	MVI	M,' '		;REPLACE IT WITH SPACE
	MOV	A,B		;OLD COLUMN ADDR TO A
	ORA	A		;SET FLAGS
	JZ	LFF00		;DON'T BACK INTO PREV LINE
	DCR	B		;DECREMENT COLUMN
LFF00:	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	JMP	LFF1A		;UPDATE ROW, COL, CUR ON & RET
;
;CURSOR ON-OFF TOGGLE ROUTINES
;
LFF06:	LDA	LD197		;GET CURSOR ON-OFF FLAG
	XRI	01H		;TOGGLE LOW ORDER BIT
	STA	LD197		;PUT IT BACK
	ANI	01H		;MASK LOW ORDER BIT
	JNZ	LFF2A		;JUMP IF CURSOR OFF
LFF13:	LDA	NCHAR		;GET COLUMN
LFF16:	MOV	B,A		;TO A
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
LFF1A:	ANI	0FH		;KEEP IT TO 0-15
	STA	SLINE		;UPDATE IT
	CALL	VDAD		;CALCULATE CURSOR ADDRESS
	MOV	A,B		;COLUMN TO A
	STA	NCHAR		;UPDATE IT
	MOV	A,M		;GET CHAR TO A
	JMP	LFC4D		;TURN ON CURSOR & RETURN
LFF2A:	STA	LD197		;UPDATE CURSOR FLAG
LFF2D:	LXI	H,NCHAR		;POINT TO COLUMN
	MOV	B,M		;GET IT TO B
	LDA	SLINE		;GET CURRENT LINE NO (0-F)
	CALL	LFE46		;TURN CURSOR OFF
	LXI	H,NCHAR		;FOR PROPER EXIT
	RET			;DONE, CURSOR OFF
;
;THIS IS THE ALS-8 (NOT TXT-2) FIND COMMAND
;
FIND2:	CALL	CRLF		;DO CR/LF
	CALL	LFF80		;GET SEARCH STRING
	LHLD	BOFP		;LOAD SEARCH STARTING POINT
LFF44:	CALL	LFFC2		;SEARCH FOR STRING
	CPI	1		;EOF FOUND ?
	RZ			;DONE IF YES
	LHLD	INSP		;ELSE POINT TO LINE W/STRING
	INX	H		;POINT PAST LENGTH BYTE
	CALL	SCRN		;PRINT LINE
	CALL	CRLF		;CAR. RET AT END OF LINE
	INX	H		;INR TO NEXT LINE
	JMP	LFF44		;AND CONTINUE SEARCH
;
;EDITOR STRING SEARCH
;
LFF58:	CALL	LFD4E		;CLEAR SCREEN
	CALL	LFF80		;GET SEARCH STRING
	LHLD	BOFP		;POINT TO BEGINNING OF FILE
	SHLD	LD19C		;SAVE AS SEARCH STARTING POINT
;
;CONTINUE SEARCH
;
LFF64:	LXI	SP,SMODE	;RESET STACK POINTER
	LHLD	LD19C		;GET SEARCH STARTING PT.
	CALL	LFFC2		;SEARCH FROM H,L FOR STRING
	CPI	1		;END OF FILE FOUND ?
	JZ	TXT2		;RESTART EDITOR THEN
	CALL	LFD4E		;
	XRA	A		;GET A ZERO
	MOV	B,A		;MAKE IT THE ROW
	CALL	LFF1A		;TURN CURSOR ON
	LHLD	INSP		;GET POINTER TO LINE W/STRING
	JMP	LFA27		;PUT TEXT ON SCRN & RET
;
;ROUTINE TO FIND STRING
;
LFF80:	MVI	B,':'		;GET PROMPT
	CALL	OUT8		;PRINT IT
	MVI	E,0		;INITIALIZE STRING LENGTH
	LXI	H,IBUF+81	;POINT TO STRING LOCATION
LFF8A:	CALL	IN8		;GET STRING CHAR
	CPI	7FH		;DELETE ?
	JNZ	LFFA1		;NO - MUST BE CHAR
	MOV	A,E		;ELSE MOVE LENGTH TO A
	ORA	A		;ZERO ?
	JZ	LFF8A		;NO ACTION IF ZERO
	DCR	E		;ELSE DCR STRING LENGTH
	DCX	H		;AND STRING POINTER
	MVI	B,5FH		;GET A BACKSPACE CHAR
LFF9B:	CALL	OUT8		;AND PRINT IT
	JMP	LFF8A		;THEN GET THE NEXT CHAR
LFFA1:	CPI	0DH		;CARRIAGE RETURN ?
	JNZ	LFFB6		;NO - MUST BE CHAR
	MOV	A,E		;ELSE GET LENGTH TO A
	ORA	A		;SET FLAGS
	JNZ	LFFB1		;IF NOT ZERO, DONE
	CALL	CRLF		;ELSE PRINT CRLF
	JMP	LFF80		;AND GET STRING (AGAIN)
LFFB1:	MOV	M,B		;MOVE C/R TO STRING BUFFER
	CALL	CRLF		;PRINT CR/LF
	RET			;AND RETURN W/STRING IN BUFFER
LFFB6:	CPI	20H		;IS CHAR A CNTL CHAR ?
	JC	LFF8A		;IGNORE IT THEN
	INR	E		;ELSE INR LENGTH
	MOV	M,B		;PUT CHAR IN STRING
	INX	H		;INR POINTER
	JMP	LFF9B		;AND DO NEXT CHAR
;
;ROUTINE TO SEARCH FOR STRING
;
LFFC1:	INX	H		;POINT PAST LENGTH BYTE
LFFC2:	SHLD	INSP		;AND SAVE AS POINTER
	MVI	C,0		;INITIALIZE COUNTER
LFFC7:	LXI	D,IBUF+81	;GET STRING LENGTH
	MOV	A,M		;GET CHAR FROM LINE
	CPI	1		;END OF FILE ?
	RZ			;IF SO, RETURN
LFFCE:	INX	H		;ELSE INCR LINE POINTER
	INR	C		;AND COUNT OF CHARS TESTED
	LDAX	D		;GET CHAR FROM STRING
	CMP	M		;STRING & LINE AGREE ?
	INX	D		;INR STRING POINTER
	JZ	LFFE7		;AND KEEP TESTING
	CPI	0DH		;WAS NON-MATCH DUE TO C/R ?
	RZ			;YES - STRING MATCHED THEN
	MOV	A,M		;ELSE MOVE LINE CHAR TO A
	CPI	0DH		;AND SEE IF END OF LINE
	JZ	LFFC1		;IT WAS - GO TO NEXT LINE
LFFDF:	DCR	C		;ELSE DCR MATCH COUNT
	JZ	LFFC7		;BACK TO WHERE WE STARTED ?
	DCX	H		;NO - DCR LINE POINTER
	JMP	LFFDF		;AND TEST AGAIN
LFFE7:	CPI	0DH		;MATCH - END OF STRING TOO ?
	RZ			;THAT'S STILL A MATCH
	MOV	A,M		;ELSE GET LINE CHAR
	CPI	0DH		;AND SEE IF END OF LINE
	JZ	LFFC1		;IF SO TEST NEXT LINE
	JMP	LFFCE		;ELSE GO ON WITH TEST
;
;ESET COMMAND TO SET UPPER LIMIT ON EDITOR TEXT BUFFER
;
LFFF3:	LHLD	BBUF		;GET VALUE OF UPPER LIMIT
	SHLD	LD191		;SAVE IT
	JMP	EORMS		;AND GO BACK TO ALS-8
