Google
 

Trailing-Edge - PDP-10 Archives - steco_19840320_1er_E35 - 10,5676/teco/newsrc/teccin.mac
There are 3 other files named teccin.mac in the archive. Click here to see a list.
	SUBTTL	Introduction

; Copyright (c) 1982 Stevens Institute of Technology, Hoboken, New Jersey
; 07030.

; This software may be used and copied provided that this copyright notice
;is included, and provided that copies of all modifications are sent to:
;
;	TECO Project
;	Computer Center
;	Stevens Institute of Technology
;	Castle Point Station
;	Hoboken, New Jersey    07030
;
;
; The information in this software is subject to change without notice
; and should not be construed as a commitment by Stevens Institute of
; Technology.

  ; Search needed universals

	SEARCH	TECUNV		; TECO universal file

  ; Generate the prologue


	TECVER==200		; Major version number
	TECMIN==1		; Minor version number
	TECEDT==1157		; Edit level
	TECWHO==0		; Last editor


	PROLOGUE(CIN,<TECO Command input routines>)	; Generate the TITLE and other stuff

	$CODE			; Put things into code PSECT
	SUBTTL	Table of Contents


	SUBTTL	Revision History
COMMENT	|


1145	By: Nick Bush		On: 8-Febuary-1982
	Re-write command input routines to implement FI command. As part of this
	allow user to set prompt by storing the prompt text for normal commands in
	the Q-register 'COMMAND-PROMPT'.
	Modules: TECUNV,TECPRS,TECCIN,TECFCM,TECVID,TECUPD

1157	By: Nick Bush		On: 28-April-1982
	Fix command input to work correctly with a ^U after an escape on the
	first line of a command.
	
	Put in yet another check in an attempt to avoid PTD stopcodes for the command
	buffer.
	Modules: TECCIN,TECUPD
|
	SUBTTL	Special flags

; The following are special flags are stored in the saved character
;to indicate special processing that needs to be done when the
;character is read.

	INTFLG	C,LH.ALF,$$
	FLAG	ECH		; Character needs to be echoed if video mode
	SUBTTL	C$CINI - Initialize command input

;+
;.hl1 C$CINI
; This routine is used to initialize the command input routines.
;It will set the QRG where text is to be stored, and where the prompt
;is to come from.
;.lit
;
; Usage:
;	T1/ Address of QRG
;	T2/ Length of prompt
;	PUSHJ	P,C$CINI
;	 (return here always)
;
;.end lit
;-

C$CINI:	MOVEM	T1,CINQRG	; Save the QRG address
	MOVEM	T2,PMTLEN	; And the length of the prompt
	POPJ	P,		; And return
	SUBTTL	C$INPT - Command input processing.

;+
;.HL1 C$INPT
;This routine will input a command into a text buffer associated with
;a QRG block.
;It will not do any immdediate command processing.
;.literal
;
; Usage:
;	T1/ Address of the QRG to use for inputting the command into
;	T2/ Length of prompt (text already in QRG)
;	CH/ 0 or first character of command (not yet echoed)
;	PUSHJ	P,C$INPT
;	(Return)
;
; On return:
;	- Text of the command stored.
;
;.end literal
;-

C$INPT:	JUMPE	CH,CINP.0	; Any first character?
	TXO	CH,C$$ECH	; Flag it will need echoing in video mode
	PUSHJ	P,C$RCHR	; Yes, set up to fetch it
	JRST	CINP.4		; And go get a character

; Here if we need to prompt

CINP.0:	PUSHJ	P,C$PRMT	; Prompt (or update screen)
; Here to get the input

CINP.4:	PUSHJ	P,C$ICHS	; Input a character with all processing

; Check if anything left of input.  If not, then we should return so
;special first character things can be done.

	MOVE	T1,CINQRG	; Get the QRG address
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; And get the address of the buffer
	CFMG.	T2,BLKPT,(T1),PMTLEN ; Anything left?
	 POPJ	P,		; No, let caller figure it out
	JUMPL	CH,CINP.4	; If we just edited something forget this
	PUSHJ	P,C$CEND	; Check if done
	 JRST	CINP.5		; All done
	JRST	CINP.4		; Need more, keep going

; Here when done with the command

CINP.5:	JMPS	.POPJ1		; Done if screen mode
	AOS	(P)		; Give skip return
	PJRST	.TCRLF		; Otherwise type a CRLF
	SUBTTL	C$PRMT - Prompt the user

;+
;.hl1 C$PRMT
; This routine will output the prompt (or update the screen) for the
;current QRG.
;-

C$PRMT:	JMPS	CPRM.V		; Skip this if video mode
	SKIPN	T2,PMTLEN	; Any prompt to type?
	 JRST	CPRM.3		; No, just force out the buffer

CPRM.1:	MOVE	T1,CINQRG	; Get the QRG address
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
	ADDX	T1,<POINT 7,.BKTLN> ; Set up the byte pointer

CPRM.2:	SOJL	T2,CPRM.3	; Done yet?
	ILDB	CH,T1		; Get a character
	PUSHJ	P,T$OCHR	; Type it
	JRST	CPRM.2		; And loop

CPRM.3:	TXNE	F,F.TYOF	; Any typeout left to force out?
	 PUSHJ	P,TTYOUT	; Yes, force it
	POPJ	P,		; And return

; Here in video mode to update the screen

CPRM.V:	SKIPL	OUTFLG		; Check if any output was done
	 JRST	CPRM.W		; No, just set up the input routine
	SETZM	OUTFLG		; Flag no output now
	MOVEI	T1,[ASCIZ |--Cont--|] ; Yes, get the prompt
	PUSHJ	P,V$ASK		; And ask him if he is done
CPRM.W:	MOVE	T1,CINQRG	; Get the QRG address
	ZERO.	,QRGVAL,(T1)	; Clear out the fixed position value
	BITOFF	T2,QR$FIX!QR$SHF,$QRFLG(P1) ; Flag section should be updated to show current position
	XMOVEI	T1,$QRPDB(T1)	; Point to the old buffer pointer
	SKIPE	$TPADR(T1)	; Is there one?
	 PUSHJ	P,M$RELB	; Yes, release it so that things are updated ok
	MOVX	T1,.TRUE	; Get the flag
	PUSHJ	P,SC$UPD	; And update the screen
	PJRST	V$CINI		; Initialize the input routines
	SUBTTL	C$CEND - Check for end of command.

;+
;.hl1 C$CEND
;This routine will check for the end of the current command processing.
;It will give a non-skip return if the end of the command is encountered and
;a skip return if it is not.
;.literal
;
; Usage:
;	CH/ Current character
;	PUSHJ	P,C$CEND
;	(Non-skip return)
;	(Skip Return)
;
; On a non-skip return:
;	- End of command
;
; On a skip return:
;	- Not end of the command
;
;.end literal
;-

C$CEND:	CAXE	CH,.CHESC	; Yes, second escape?
	 PJRST	.POPJ1		; And give skip return
	TXZ	F,F.ECHO	; Clear echoing for one char
	PUSHJ	P,C$ICHR	; Get a character with editing
	CAXE	CH,.CHESC	; Second consecutive escape?
	 JRST	CEND.1		; No, echo the character
	JMPNS	CEND.E		; No echo needed for EVOFF
	MOVX	CH,"$"		; Yes, get a dollar sign
	PUSHJ	P,V$ECHO	; Echo it
	MOVX	CH,.CHESC	; And get the escape back
CEND.E:	MOVE	T1,CINQRG	; Get the QRG to append to
	PJRST	M$ACHR		; And append the character

; Here if it is not the end of the command.  Echo the character and
;give skip return

CEND.1:	AOS	(P)		; Give skip return when done
	TXO	CH,C$$ECH	; Flag character needs to be echoed
	PUSHJ	P,C$RCHR	; Remember the character
	POPJ	P,		; Or just return if EVOFF$
	SUBTTL	C$ICHS - Input a character with special character processing.

;+
;.HL1 C$ICHS
;This routine will input a character.  It will do any special character
;processing that is required.  That is it will handle the control G and
;control R processing.
;.literal
;
; Usage:
;	PUSHJ	P,C$ICHS
;	(Return)
;
; On return:
;	CH/ Next non-special character
;
;.end literal
;-

	BITMSK(SPCMSK,.CH,<CNG,CNR>) ; Define mask of interesting chars

C$ICHS:	PUSHJ	P,C$ICHE	; Get a character (with editing)
	JUMPL	CH,.POPJ	; If editing character, try again
	MOVX	T1,SPCMSK	; Get the mask of special characters
	LSH	T1,(CH)		; Shift it over
	JUMPGE	T1,.POPJ	; If not a special character, just return
	XMOVEI	T1,SPCTBL	; Get the table
	PUSHJ	P,DISP1		; Do the function
	 POPJ	P,		; Wasn't one, just return
	POPJ	P,		; Otherwise just return

SPCTBL:	XWD	C$CCNG,.CHBEL	; Control-G (bell)
	XWD	C$CCNR,$CHQOT	; Quoting character (^R)
	XWD	0,0		; End of table
	SUBTTL	C$CCNG - Process the control G special character

;+
;.HL1 C$CCNG
;This routine will handle the control G processing.  It will cause the
;next character to be read.  If the next character is a control G, space
;or period it will do some special processing.
;.literal
;
; Usage:
;	PUSHJ	P,C$CCNG
;	(Return)
;
; On return:
;	- Finished the processing.
;
;.end literal
;-

C$CCNG:	PUSHJ	P,C$ICHE	; Get the next character (with editing)
	JUMPL	CH,.POPJ	; Just return if it was edited away
	$SAVE	<P1>		; Save  P1
	MOVE	P1,CH		; Copy the char
	MOVEI	T1,BELDSP	; Get the dispatch table address
	SKPNS			; Screen mode?
	 MOVEI	T1,VBELDS	; Yes, get correct table pointer
	PUSHJ	P,NDISPT	; Dispatch
	MOVE	CH,P1		; Get the character back again
	POPJ	P,		; And return

; Dispatch table for ^G in non-video mode

BELDSP:	XWD CNG.SP," "		; ^G<space>
	XWD CNG.PR,"."		; ^G.
	XWD CNG.BL,.CHBEL	; ^G^G
	XWD 0,0

; Routines for ^G commands in non-video mode

CNG.SP:	PUSHJ	P,C$DLCH	; Delete a character
	 JFCL			; Never happens
	PUSHJ	P,C$DLCH	; Delete the second
	 JFCL			; Forget the error
	MOVE	T1,CINQRG	; Get the QRG address
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the buffer address
	CFMG.	T2,BLKPT,(T1),PMTLEN ; Anything other than the prompt?
	 JRST	CCNU.F		; No, go delete that
	PUSHJ	P,C$RPRT	; Reprint the line
	SETO	CH,		; Flag no character left
	POPJ	P,		; And return

CNG.PR:	PUSHJ	P,C$DLCH	; Delete a character
	 JFCL			; Never happens
	PUSHJ	P,C$DLCH	; Delete the second
	 JFCL			; Ignore this
	MOVE	T1,CINQRG	; Get the QRG address
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the buffer address
	CFMG.	T2,BLKPT,(T1),PMTLEN ; Anything other than the prompt?
	 JRST	CCNU.F		; No, go delete that
	PUSHJ	P,CRPR.A	; ^G. reprints entire command
	SETO	CH,		; Flag nothing left
	POPJ	P,		; And return

CNG.BL:	MOVE	T1,PMTLEN	; Delete back to the prompt
	PUSHJ	P,C$DLTX	;  .  .  .
	PUSHJ	P,.TCRLF	; Type a CRLF
	SETO	CH,		; Flag nothing left
	POPJ	P,		; And return

; Table for ^G in video mode

VBELDS:	XWD CNG.VS," "		; ^G<space>
	XWD CNG.VS,"."		; ^G. (same as ^G<space>)
	XWD CNG.VB,.CHBEL	; ^G^G
	XWD 0,0

; Here on ^G<space> or ^G.

CNG.VS:	PUSHJ	P,C$DLCH	; Delete the character
	 JFCL			; Ignore it
	PUSHJ	P,C$DLCH	; And the second
	 JFCL			; Shouldn't happen
	MOVE	T1,CINQRG	; Get the Q-reg we are using
	LOAD.	T2,TPTADR,+$QRTPT(T1) ; Get the text buffer address
	CFMG.	T3,BLKPT,(T2),PMTLEN ; More than just the prompt?
	 JRST	CCNU.E		; No, just refresh things
	PJRST	V$CTRG		; Yes, fix things up

; Here one ^G^G

CNG.VB:	PUSHJ	P,CCNU.E	; Just delete the world and refresh things
	SETO	CH,		; Flag nothing left
	POPJ	P,		; And return
	SUBTTL	C$CCNR - Process the control R special character


;+
;.HL1 C$CCNR
;This routine will hanlde the control R quoting character processing.
;It will quote any character except a delete, control U or a control W.
;.literal
;
; Usage:
;	PUSHJ	P,C$CCNR
;	(Return)
;
; On return:
;	CH/ Quoted character.
;	or -1 if ^R was edited away
;
;.end literal
;-

C$CCNR:	PUSHJ	P,C$ICHE	; Get the next character
	JUMPL	CH,.POPJ	; Just return if edited away
	PJRST	C$ICHE		; Otherwise, try again
	SUBTTL	C$ICHE - Input a character with editing


;+
;.HL1 C$ICHE
;.literal
;
; Usage:
;	CINQRG/ QRG to append the character to
;	PMTLEN/ Length of text that is the prompt (already in QRG)
;	PUSHJ	P,C$ICHE
;	(Return)
;
; On return:
;	CH/ Character that was input (=-1 if editing character)
;	Character appended to buffer (or characters deleted)
;
;.end literal
;-

	BITMSK(EDCMSK,.CH,<CNH,CNW,CNU>) ; Define mask for interesting chars

C$ICHE:	PUSHJ	P,C$ICHR	; Get a character
	MOVX	T1,EDCMSK	; Get the mask of editing characters
	LSH	T1,(CH)		; Check if special character
	CAXE	CH,.CHDEL	; Delete?
	 JUMPGE	T1,ICHE.1	; No, other special character?

; Here if the character is an editing character.
;Call the correct routine for handling it

	XMOVEI	T1,EDCTBL	; Get the table address
	TXNE	CRT,CR$TTY	; Want backspace editing?
	 XMOVEI	T1,EDCTB1	; No, leave that out
	PUSHJ	P,DISP1		; Dispatch on the character
	 JRST	ICHE.1		; Not in table, just append it in
	SETO	CH,		; Flag some editing was done
	POPJ	P,		; And return

; Here if the character should be appended to the buffer.

ICHE.1:	MOVE	T1,CINQRG	; Get the QRG address
	PUSHJ	P,M$ACHR	; Append the character
	MOVE	T1,CINQRG	; Get the QRG address
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
	LOAD.	T3,BLKEND,(T1)	; Get the final address
	MOVE	T2,T3		; And get a copy
	SOJ	T2,		; Plus one
	PJRST	UPDBND		; Update the bounds

; Dispatch table for editing characters

EDCTBL:	XWD	C$CCNH,.CHCNH	; Backspace (control-H)
EDCTB1:	XWD	C$DELE,.CHDEL	; Delete
	XWD	C$CCNW,.CHCNW	; Control-W
	XWD	C$CCNU,.CHCNU	; Control-U
	XWD	0,0		; End of table
	SUBTTL	C$CCNW - Process a control W editing character


;+
;.HL1 C$CCNW
; This routine will handle control-W editing characters.  This will
;delete the previous word, or the previous delimeter if the previous item
;is not a word.
;.literal
;
; Usage:
;	PUSHJ	P,C$CCNW
;	(Return)
;
; On return:
;
;.end literal
;-

C$CCNW:	MOVE	T1,CINQRG	; Get the QRG we are using
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
	PUSHJ	P,C$DWRD	; Find the start of the word
	CAMGE	T1,PMTLEN	; Hit the prompt?
	 JRST	CCNU.0		; Yes, act like control-U
	JMPNS	CCNW.1		; Video mode works different
	CAMG	T1,PMTLEN	; Deleting back to the prompt?
	 JRST	CCNU.E		; Yes, just update or reprompt
	PUSHJ	P,C$DLTX	; Delete the text
	MOVX	T1,.TRUE	; Put cursor and end of command
	PJRST	V$UPCM		; Update the command display

; Check how many characters being deleted.  Just ignore 0 characters,
;and handle 1 character like a delete.

CCNW.1:	TXNN	CRT,CR$RUB	; Old style rubouts?
	 CAMLE	T1,PMTLEN	; No, anything left other than the prompt?
	  JRST	.+2		; Keep going
	   JRST	CCNU.F		; Get rid of everything
	$SAVE	<P1,P2,P3,P4>	; Save some ac's
	MOVE	P4,CINQRG	; Get the QRG address
	LOAD.	P4,TPTADR,+$QRTPT(P4) ; Get the address of the buffer
	MOVE	P1,T1		; Put into safer place
	LOAD.	T1,BLKEND,(P4)	; Get the final address
	SUB	T1,P1		; See how many are being deleted
	TXNE	CRT,CR$RUB	; Old rubout treatment?
	 JRST	CCNW.R		; Yes, go handle it
	CAMGE	P1,PMTLEN	; Only the prompt?
	 JRST	[PUSHJ	P,CCNW.B	; Delete the ^W
		JRST	CDEL.0]		; And delete the character
	CAMG	P1,PMTLEN	; Anything left past the prompt?
	 JRST	CCNW.B		; Back up over two characters (^W)
	JRST	CCNW.2		; Fancy rubout, go handle it

; Here for old rubout style treatment of ^W.  We will just type out the
;characters backwards.

CCNW.R:	MOVE	P1,T1		; Get the number of characters to delete

CCNW.O:	PUSHJ	P,C$DLCH	; Kill the character
	 STOPCD	PWD,<Part of word disappeared>
	PUSHJ	P,T$OCHR	; Type the character out
	SOJG	P1,CCNW.O	; And keep deleting
	POPJ	P,		; And return


; To properly handle words which wrap around line boundaries, we
;will determine the position of the final character which will be left,
;and then determine how many (if any) line boundaries the word being
;deleted crosses.

CCNW.2:	PUSHJ	P,C$BLIN	; Find the start of this line
	CAMN	T1,P1		; If start of line and start of word are
	 JRST	CCNU.0		; the same, just act line an ^U
	MOVE	P2,T1		; Otherwise, get the current position
	SUBM	P1,P2		; Get the number of characters to skip
	BLDBPT	(T1,(P4))	; Set up the byte pointer
	MOVE	P3,T1		; Get the byte pointer
	SETZ	T2,		; Clear the line position
CCNW.3:	ILDB	CH,P3		; Get a character
	PUSHJ	P,C$CLEN	; And get the position
	CAMLE	T2,TRMWID	; Need to wrap yet?
	 JRST	[SUB	T2,TRMWID	; Correct for wrap-around
		SOJA	T2,.+1]		;  .  .  .
	SOJG	P2,CCNW.3	; Keep getting the width until we hit the spot

; Save the horizontal position, and see whether the word wraps

	PUSH	P,T2		; Save the current position
	LOAD.	P2,BLKEND,(P4)	; Get the end address of the buffer
	SUB	P2,P1		; And determine how many characters are being deleted
	SETZ	P4,		; Initialize a counter for times the word wraps

CCNW.4:	ILDB	CH,P3		; Get a character
	PUSHJ	P,C$CLEN	; Get the character length
	CAMG	T2,TRMWID	; Need to wrap now?
	 JRST	CCNW.5		; No, skip this
	SUB	T2,TRMWID	; Correct for the wrap-around
	SOJ	T2,		;  .  .  .
	AOJ	P4,		; Count the line

CCNW.5:	SOJG	P2,CCNW.4	; And loop for all characters

	ADDI	T2,2		; Account for the echo of the ^W
	CAMLE	T2,TRMWID	; Need to wrap because of that?
	 JRST	[SUB	T2,TRMWID	; Yes, do it
		AOJ	P4,		; Count the line
		SOJA	T2,.+1]		;  .  .  .
	POP	P,T1		; Get the old width back
	JUMPN	P4,CCNW.6	; If the word is on more than one line, go handle

	SUB	T2,T1		; No, get the number of characters to delete
	MOVE	P2,T2		; Get into safe place
	TXNE	CRT,CR$CTU	; Terminal have a delete to EOL?
	 JRST	CCNW.7		; Yes, do it that way
CCNW.C:	MOVE	T1,$CRBCK(CRT)	; Get the backspace sequence
	PUSHJ	P,SC$MES	; Output it
	PUSHJ	P,C$ERS1	; Kill the character
	SOJG	P2,CCNW.C	;  .  .  .

	MOVE	T1,P1		; Get the number to delete
	PJRST	C$DLTX		; Delete the characters

; Here if the word is on one line and the terminal has a DEL function.

CCNW.7:	MOVE	T1,$CRBCK(CRT)	; Get the back cursor sequence
	PUSHJ	P,SC$MES	; Output the sequence
	SOJG	P2,CCNW.7	; Back up enough
	XCT	$CRDEL(CRT)	; Delete the end of the line

	MOVE	T1,P1		; Get the number to delete
	PJRST	C$DLTX		; Delete the characters

; Here if the word spans lines.  This is a real problem on terminals
;without a delete to end of line since it can be very expensive to delete
;all those characters.
; On terminals which have a DEL and DLF functions, we will use them
;to go up the page to the line with the word.  On terminals without,
;we will leave the ^W there and reprint the start of the line that
;is left.

CCNW.6:	TXNN	CRT,CR$NCR	; Allowed to have free CR's?
	 TXNN	CRT,CR$CTU	; And have a DEL function?
	  JRST	CCNW.8		; No, must do strange way
	XCT	$CRCTU(CRT)	; Delete this line
CCNW.9:	XCT	$CRDLF(CRT)	; No, go up one line
	XCT	$CRDEL(CRT)	; And delete it
	SOJG	P4,CCNW.9	; Keep trying
	MOVE	T1,P1		; Get the deletion point
	PUSHJ	P,C$DLTX	; Delete the text
	MOVEI	CH,.CHCRT	; Keep the monitor informed of where we are
	PUSHJ	P,T$OCHR	; Type it
	PUSHJ	P,T$OCHR	; (second one to make sure everyone is happy)
	JRST	CRPR.0		; And go type the line back out

; Here if the terminal is stupid.

CCNW.8:	MOVE	T1,P1		; Get the amount to delete
	PUSHJ	P,C$DLTX	; Do it
	PJRST	C$RPRT		; And type the start of the line out


; Here to delete the ^W from the screen and back up over the previous
;character

CCNW.B:	MOVE	T1,$CRBCK(CRT)	; Get the backspace seequnce
	PUSHJ	P,SC$MES	; Back up one
	PUSHJ	P,C$ERS2	; Eat two chars
	MOVE	T1,$CRBCK(CRT)	; And back up one more
	PJRST	SC$MES		; and return
	SUBTTL	C$CCNU - Process a control U editing character


;+
;.HL1 C$CCNU
; This routine will handle the control-U editing character.  This
;will delete back to the beginning of the current line, or, if the
;last character was an end-of-line, and we are in video mode, it will
;delete the previous line.
;.literal
;
; Usage:
;	PUSHJ	P,C$CCNU
;	(Return)
;
; On return:
;
;.end literal
;-

C$CCNU:	JMPS	CCNU.1		; Process the video one
	CAXN	CH,.CHCNU	; Was this on a ^U character?
	 PUSHJ	P,T$OCHR	; Yes, we must echo it
CCNU.0:	SKPS			; Skip this in screen mode
	 XCT	$CRCTU(CRT)	; Do the function

CCNU.1:	PUSHJ	P,C$BLIN	; Find the start of this line
	CAMG	T1,PMTLEN	; Are we hitting the prompt?
	 JRST	CCNU.E		; Yes, delete everything back to it

	MOVE	T2,CINQRG	; Get the QRG address
	LOAD.	T2,TPTADR,+$QRTPT(T2) ; Get the address of the buffer
	CFMN.	,BLKEND,(T2),T1	; Were we already at the start of a line?
	 JMPNS	CCNU.2		; Yes, need to check for previous line in screen mode
	PUSHJ	P,C$DLCH	; Delete the previous character (EOL)
	 JRST	CCNU.E		; If nothing left, all done
	CAXE	CH,.CHLFD	; Need to check for CRLF?
	 JRST	CCNU.3		; No, skip the check
	MOVE	T1,CINQRG	; Get the QRG we are reading into
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Yes, get the address of the buffer
	LOAD.	T2,BLKEND,(T1)	; And the last character address
	SOJ	T2,		; Minus one to fetch last character
	IDIVI	T2,5		; Convert to byte pointer
	TDO	T2,BTAB(T3)	;  .  .  .
	ADD	T2,T1		;  .  .  .
	ADDX	T2,.BKTLN	;  .  .  .
	LDB	CH,T2		; Get the character before what we just deleted
	CAXN	CH,.CHCRT	; Carriage return?
	 PUSHJ	P,C$DLCH	; Yes, delete it
	  JRST	CCNU.E		; If nothing left, all done
CCNU.3:	PUSHJ	P,C$BLIN	; Find the start of the line
	CAMG	T1,PMTLEN	; Deleting into the prompt?
	 JRST	CCNU.E		; Yes, just go try again

CCNU.2:	PUSHJ	P,C$DLTX	; Delete the text
	JMPNS	.POPJ		; If not screen more, we are all done
	MOVX	T1,.TRUE	; Put cursor at end of command
	PJRST	V$UPCM		; Otherwise, do the screen update

; Here if the entire buffer is being deleted.  Delete the text from
;the buffer and either re-prompt (non-video), or update the whole screen.

CCNU.F:	XCT	$CRCTU(CRT)	; Kill whatever is there
CCNU.E:	MOVE	T1,PMTLEN	; Get where to delete to
	PUSHJ	P,C$DLTX	; Delete the text
	JMPS	[SETO	CH,		; Flag editing was done
		POPJ	P,]		; And return
	TXNN	CRT,CR$NCR	; Allowed to have free CR's?
	 TXNN	CRT,CR$CTU	; Have a control-U string?
	  JRST	[PUSHJ P,.TCRLF		; No, print a CRLF
		SETO	CH,		; Flag editing character
		POPJ	P,]		; And return
	MOVX	T1,<BYTE(7).CHCRT,.CHCRT> ; Send a couple CR's first
	PUSHJ	P,SC$MES	; Output the CR's
	SETO	CH,		; Flag editing character
	POPJ	P,		; And return
	SUBTTL	C$CCNH - Process a control H editing character


;+
;.HL1 C$CCNH
;.literal
;
; Usage:
;	PUSHJ	P,C$CCNH
;	(Return)
;
; On return:
;
;.end literal
;-

C$CCNH:	JMPS	CDEL.V		; If video mode, go handle it
	MOVE	T1,$CRCBS(CRT)	; Get the string to cancel the backspace
	PUSHJ	P,SC$MES	; Do it
	JRST	CDEL.0		; And delete the character
	SUBTTL	C$DELE - Process a delete editing character

;+
;.HL1 C$DELE
;This rutine will handle deleting a character with the rubout
;character (177).  It will cause the screen to update, or the text to be
;typed on the terminal, etc.
;.literal
;
; Usage:
;	T1/ QRG text is being deleted from
;	PUSHJ	P,C$DELE
;	(Return)
;
; On return:
;	- Proper handling finished.
;
;.end literal
;-

C$DELE:	TXNN	CRT,CR$RUB	; Check if old type of rubout processing wanted?
	 JRST	CDEL.1		; No, do fancy stuff
C$RUBO:	PUSHJ	P,C$DLCH	; Kill the character
	 JRST	CCNU.F		; Empty?
	TXO	S,S.OLOG	; Suppress one character to the log file
	PUSHJ	P,T$OCHR	; Type the character out
	POPJ	P,		; Return

; Here if we want special processing of rubouts.

CDEL.1:	JMPS	CDEL.V		; Video mode?
	MOVE	T1,CINQRG	; Get the QRG address
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; And determine the address of the buffer
	CFMG.	T2,BLKPT,(T1),PMTLEN ; Just the prompt left?
	 JRST	CCNU.F		; And exit through common routine

	MOVE	T1,$CRCRB(CRT)	; Get the string to cancel the rubout
	PUSHJ	P,SC$MES	; Type the string

; Here to delete the previous character because of either a delete or
;backspace being typed.

CDEL.0:	PUSHJ	P,C$HPOS	; Get the position
	$SAVE	<P1,P2,P3,P4>	; Save some ac's
	DMOVE	P3,T1		; Copy the informaion
	PUSHJ	P,C$DLCH	; Delete the character from the buffer
	 POPJ	P,		; Nothing left, all done
	PUSH	P,CH		; Save the character
	PUSHJ	P,C$HPOS	; Go gigure out the horizontal position
	DMOVE	P1,T1		; Get the position information
	POP	P,T1		; Get the character back
	PUSHJ	P,CDEL.2	; Delete the character from the screen
	MOVE	T1,CINQRG	; Get the address of the QRG
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
	CFMG.	T2,BLKPT,(T1),PMTLEN ; Anything more than the prompt?
	 JRST	CCNU.F		; Yes, wipe it out
	POPJ	P,		; No, just return

; Check for special characters

CDEL.2:	CAXG	T1,.CHBEL	; Control G or less ?
	 JRST	C$DCH2		; Delete the two char wide character
	CAXN	T1,.CHCNH	; Is this a backspace ?
	 JRST	C$DCM1		; Delete a backspace
	CAXN	T1,.CHTAB	; Is this a tab ?
	 JRST	C$DCTB		; Delete an end of line
	CAXN	T1,.CHLFD	; Line feed?
	 JRST	C$DCEL		; Yes, delete it
	CAXG	T1,.CHFFD	; EOL? (LF, VT1, FF)
	 JMPNS	C$DCEL		; Delete an end of line
	CAXN	T1,.CHCRT	; Carriage return ?
	 JRST	C$DCCR		; Yes - Delete it
	CAXE	T1,.CHESC	; Is this an altmode ?
	 CAXL	T1," "		; or .GE. a blank ?
	  JRST	C$DCH1		; Yes - Delete a single character
	PJRST	C$DCH2		; No, it is two characters wide

; Here in video mode to delete one character


CDEL.V:	PUSHJ	P,V$DELC	; Delete one character
	 POPJ	P,		; Return
	JRST	CCNU.E		; Nothing left
	SUBTTL	C$DLCH - Routine to delete one character from the buffer

;+
;.HL1 C$DLCH
; This routine will delete the last character in the text buffer.
;.lit
;
; Usage:
;	PUSHJ	P,C$DLCH
;	 (Return, buffer empty)
;	(Return, character deleted)

; On skip return:
;	CH/ Character which was deleted
;
;.end lit
;-

BACKUP::
C$DLCH:	MOVE	T3,CINQRG	; Get the Q-reg we are using
	LOAD.	T3,TPTADR,+$QRTPT(T3) ; Get the text buffer address
	LOAD.	T1,BLKPT,(T3)	; Get the address of PT
	SOJ	T1,		; Decrement the position
	CAMGE	T1,PMTLEN	; Anything left past the prompt?
	 POPJ	P,		; No, can't delete the prompt
	STOR.	T1,BLKPT,(T3)	; Decrement the pointer
	MOVE	T1,T3		; Get the address of the buffer
	LOAD.	T2,BLKEND,(T1)	; And the final character
	MOVE	T3,T2		; Get a copy
	SOJ	T2,		; Fix up to indicate last character being killed
	PUSHJ	P,UPDBND	; And update the bounds
	MOVE	T3,T1		; Get the buffer address back
	LOAD.	T1,BLKPT,(T3)	; Get the pointer back
	DECR.	T4,BLKEND,(T3)	; Adjust Z
	INCR.	T4,BLKFRE,(T3)	; Adjust the number free
	IDIVI	T1,5		; Build a byte pointer
	ADDI	T1,.BKTLN(T3)	; Point to the correct word
	HLL	T1,BTAB(T2)	; Fill in the rest of the byte pointer
	LDB	CH,T1		; Get the character
	JRST	.POPJ1		; Give a skip return
	SUBTTL	C$DLTX - Routine to delete some text from the buffer

;+
;.hl1 C$DLTX
; This routine will delete back to a given point in the buffer.
;.lit
;
; Usage:
;	T1/ Desired final address
;	PUSHJ	P,C$DLTX
;	(Return, text deleted)
;
;.end lit
;-

C$DLTX:	MOVE	T3,T1		; Get the offset
	MOVE	T1,CINQRG	; Get the Q-reg
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the text buffer address
	LOAD.	T2,BLKEND,(T1)	; Get the end pointer
	SUB	T2,T3		; And get the number of characters we are deleting
	JUMPE	T2,.POPJ	; If none being deleted, skip this
	LOAD.	T4,BLKPT,(T1)	; Get the pointer address
	SUB	T4,T2		; Decrement the pointer
	JUMPGE	T4,.+2		; Don't let it get negative
	 SETZ	T4,		;  .  .  .
	STOR.	T4,BLKPT,(T1)	; Update the pointer
	MOVE	T2,T3		; Get the first character killed
	LOAD.	T3,BLKEND,(T1)	; And the last
	PUSH	P,T2		; Save T2
	PUSH	P,T3		; And T3
	PUSHJ	P,UPDBND	; Update the bounds
	POP	P,T3		; And restore the info
	POP	P,T2		; To actually delete the characters
	EXCH	T2,T3		; Fix up for shrinking buffer
	SUB	T2,T3		; And get the amount being killed
	PUSHJ	P,M$SRNK	; Shrink the buffer
	POPJ	P,		; And return
	SUBTTL	C$DCxx - Routines to delete characters from the screen

;+
;.HL1 C$DCxx
; These routines are used to rubout characters on the screen of a CRT when
;we are not in video mode (EVOFF).
;.lit
;
; Usage:
;	CH/ Character being deleted
;	P1/ Length of last character before being deleted
;	P2/ Column that current text runs to
;	P3/ Length of character being deleted
;	P4/ Column after character being deleted
;	PUSHJ	P,C$DCxx
;	 (return)
;
;.end lit
;.hl2 C$DCH1
; This routine will delete a one character wide character field.
;-

C$DCH1:	PUSHJ	P,C$ERS1	; Delete one character
	PJRST	C$DCFN		; And finish up

;+
;.hl2 C$DCH2
; This routine will rubout a two character wide character from the
;terminal.
;-

C$DCH2:	PUSHJ	P,C$ERS2	; Rubout the characters
	FALL	C$DCFN		; And finish up

;+
;.hl2 C$DCFN
; This routine will finish up from deleting a character.
;-

C$DCFN:	CAMG	P2,P4		; Finished ?
	 POPJ	P,		; All done
	FALL	C$DCRW		; Line was wrapped and now is not, retype things

;+
;.HL2 C$DCRW
; This routine will reprint the current command.  It is used when
;a character is deleted which terminated the line on the screen.
;-

C$DCRW:	XCT	$CRDLF(CRT)	; Delete a line
	TXNN	CRT,CR$NWP	; Terminal wrap around backwards?
	 XCT	$CRDLF(CRT)	; No, delete another line feed
	TXNE	CRT,CR$NCR	; Allowed the free CR's?
	 JRST	C$RPRT		; Reprint the line
	MOVEI	CH,.CHCRT	; Get a carriage return
	PUSHJ	P,T$OCHR	; And output it
	PUSHJ	P,T$OCHR	; Make sure it really gets out
				; (problem in DM1520A loses the first one)
	JRST	CRPR.0		; Reprint the line (minus the CRLF)

;+
;.HL2 C$DCM1
; Here to delete a character which is minus one columns wide (backspace).
;Just send the string to blank a character.
;-

C$DCM1:	MOVE	T1,$CRSPC(CRT)	; Get the text to blank out the character
	PJRST	SC$MES		; Send it to the terminal

;+
;.HL2 C$DCTB
; Here to delete a tab.  To do this we must figure out what column the tab
;started in and then delete back to that pointer
;-

C$DCTB:	JUMPE	P4,C$DCFN	; If at the beginning of the line go retype if needed
	SUB	P4,P2		; Determine how much to back up
	SOJLE	P4,.POPJ	; If nothing to type, don't bother

CDCT.0:	MOVE	T1,$CRBCK(CRT)	; Get the string address
	PUSHJ	P,SC$MES	; Back up
	SOJG	P4,CDCT.0	; Loop
	POPJ	P,		; And return

;+
;.HL2 C$DCCR
; This routine will delete a carriage return.
;-

C$DCCR:	MOVE	T1,$CRSPC(CRT)	; Get the forward cursor
	TXNE	CRT,CR$WAP	; Wrap around forward work?
	 TXNN	CRT,CR$NWP	; Yes, also wrap around backwards?
	  JRST	.+2		; One or the other doesn't work
	PUSHJ	P,SC$STR	; Both work, put back at column 0
	SKIPE	T1,$CRDCR(CRT)	; Get the address of the text to output
	 PUSHJ	P,SC$STR	; Output it
	PJRST	CRPR.0		; Act like a ^G<space>

;+
;.HL2 C$DCEL
; This routine will delete a end of line character
;-

C$DCEL:	ADDI	T1,(CRT)	; Get the block address plus the character
	MOVE	T3,$CRDLF-.CHLFD(T1) ; Get the proper string
	MOVE	T1,$CRSPC(CRT)	; Undo the backspace
	TXNE	CRT,CR$NWP	; Does this terminal wrap around backwards?
	 SKIPE	P2		; Yes, are we at column 0?
	  JRST	.+2		; Don't need to kill the backspace
DCEL.1:	PUSHJ	P,SC$MES	; kill the effect of a backspace
	JUMPE	T3,C$DCFN	; Have something to do?
	XCT	T3		; Yes, do it
	JRST	C$DCFN		; And continue on
	SUBTTL	C$ERS1 and C$ERS2 - Routines to erase characters from screen

;+
;.HL2 C$ERS1 and C$ERS2
; These routines will erase characters from the CRT.  C$ERS1 will handle
;a single character position, and C$ERS2 will do two character positions.
;-

C$ERS2::PUSHJ	P,C$ERS1	; Get the first character
	MOVE	T1,$CRBCK(CRT)	; Get the back cursor sequence
	PUSHJ	P,SC$MES	; Do it
	FALL	C$ERS1		; And fall into routine to erase second character

C$ERS1::MOVE	T1,$CRDBS(CRT)	; Get the string
	PJRST	SC$MES		; And output it
	SUBTTL	C$RPRT - Reprint the last line

;+
;.HL1 C$RPRT
; This routine will reprint some text from the current command buffer.
;.lit
;
; Usage:
;	PUSHJ	P,C$RPRT	; Type a CRLF and current line
;
;	PUSHJ	P,CRPR.0	; Just type current line
;
;	PUSHJ	P,CRPR.A	; Print CRLF and entire command
;
;.end lit
;-

C$RPRT:	PUSHJ	P,.TCRLF	; Output a CRLF
CRPR.0:	MOVE	T1,CINQRG	; Get the address of the QRG we are inputting
	PUSHJ	P,C$BLIN	; Find the start of the line
	$SAVE	<P1,P2,P3>	; Save some ac's
	MOVE	P1,CINQRG	; Get the QRG address
	LOAD.	P1,TPTADR,+$QRTPT(P1) ; Get the address of the buffer
	LOAD.	P2,BLKPT,(P1)	; Get the current position
	SUB	P2,T1		; And get the amount to type
	JRST	CRPR.1		; Join common routine

; Here to print entire buffer

CRPR.A:	PUSHJ	P,.TCRLF	; Type a CRLF
CRPR.B:	$SAVE	<P1,P2,P3>	; Save P1 and P2
	MOVE	P1,CINQRG	; Get the QRG address
	LOAD.	P1,TPTADR,+$QRTPT(P1) ; Get the address of the text
	LOAD.	P2,BLKPT,(P1)	; And the amount to type
	SETZ	T1,		; Type from start of buffer

; Common code for printing from given position

CRPR.1:	IDIVI	T1,5		; Make the byte pointer
	TDO	T1,BTAB-1(T2)	;  .  .  .
	ADDX	T1,.BKTLN	; And point to the text
	ADD	T1,P1		;  .  .  .
	MOVE	P3,T1		; Get the pointer into a safe place

; Here to loop typing characters

CRPR.2:	SOJL	P2,.POPJ	; Done?
	ILDB	CH,P3		; Get a character
	PUSHJ	P,T$OCHR	; Type it
	JRST	CRPR.2		; Get the next character
	SUBTTL	C$HPOS - Determine horizontal position

;+
;.HL2 C$HPOS
;This routine will determine the horizonntal position of the current character
;in the command string.
;.literal
;
; Usage:
;	PUSHJ	P,C$HPOS
;	(Return)
;
; Returns:
;	T1 - The length of the last character
;	T2 - The character position
;.end literal
;-

C$HPOS:	PUSHJ	P,C$BLIN	; Back to the beginning of the line
	$SAVE	<P1,P2>		; Save P1/P2
	MOVE	P1,CINQRG	; Get the QRG address
	LOAD.	P1,TPTADR,+$QRTPT(P1) ; Get the command buffer address
	MOVE	P2,T1		; Copy the character address
	IDIVI	T1,5		; Make a byte pointer
	HLL	T1,BTAB-1(T2)	; . . .
	ADDI	T1,.BKTLN(P1)	; Get the address of the text in the block
	LOAD.	T2,BLKPT,(P1)	; Get the character address of point
	SUB	T2,P2		; Compute the length
	MOVE	P1,T1		; Copy both items over
	EXCH	T2,P2		; And switch the others
	SETZ	T1,		; Assume we start counting from zero
	MOVE	T2,T1		; Copy the address of the first character

CHPO.0:	SOJL	P2,.POPJ	; Return if at it
	ILDB	CH,P1		; Get the first character
	PUSHJ	P,C$CLEN	; Determine the length of the character
	CAMLE	T2,TRMWID	; Wider then allowed ?
	 SETZ	T2,		; Yes - Set the width to zero
	JRST	CHPO.0		; Loop until done
	SUBTTL	C$CLEN - Determine length of character

;+
;.HL2 C$CLEN
;This routine will return the length of the character that is given it.
;It will also update the character position on the line of the character,
;this is mainly for tabs.
;.literal
;
; Usage:
;	MOVE	CH,Character
;	MOVE	T2,Line.position
;	PUSHJ	P,C$CLEN
;	(Return)
;
; Returns:
;	T1 - Length of the character
;	T2 - Updated line position.
;.end literal
;-

C$CLEN:	SETZ	T1,		; Clear the lenght
	CAXE	CH,.CHESC	; Is this an altmode ?
	 CAXL	CH," "		; Or anything " " or over ?
	  AOJA	T1,CLEN.1	; Yes - It has a width of one
	CAXN	CH,.CHCRT	; Is this a carriage return?
	 JRST	[SETZB	T1,T2		; Yes, that puts us at column 0
		POPJ	P,]		; Return the zeros
	CAXN	CH,.CHCNH	; Is this a backspace ?
	 SOJA	T1,.POPJ	; Yes - Width of minus one
	CAXN	CH,.CHLFD	; A linefeed is zero
	 JRST	CLEN.1		; Return to the caller
	CAXN	CH,.CHVTB	; A vertical tab may be special
	  JRST	[JMPS	CLEN.3		; If screen processing then 2
		ADD	T1,$CRWVT(CRT)	; Else use the value in theblock
		JRST CLEN.1]
	CAXN	CH,.CHFFD		; A form feed might also
	  JRST	[JMPS	CLEN.3		; If screen processing then 2
		ADD	T1,$CRWFF(CRT)	; Else use the value in the block
		JRST CLEN.1]
	CAXE	CH,.CHTAB	; A tab ?
	  JRST	CLEN.3		; No - Use the width of 2
	TXO	T2,7		; Make it at the tab stop
	AOJ	T2,		; Bump so we go to the next
	MOVEI	T1,^D8		; Get the length
	POPJ	P,		; Return

; Here for control characters.  The width is two

CLEN.3:	MOVEI	T1,2		; Add in the width
CLEN.1:	ADD	T2,T1		; This is the new length
	POPJ	P,		; Return
	SUBTTL	C$BLIN - Determine start of line

;+
;.HL2 C$BLIN
;This routine will determine the beginning of the line of the command.
;It will set up the registers for calling NLINE and then call it.
;.literal
;
; Usage:
;	PUSHJ	P,C$BLIN
;	(Return -- T1 contains the character address)
;.end literal
;-

C$BLIN:	MOVE	T1,CINQRG	; Get the address of the QRG
	LOAD.	T1,TPTADR,+$QRTPT(T1) ; Get the text buffer address
	JMPS	C$BL.Z		; If video mode, different break set
	LOAD.	T1,BLKPT,(T1)	; And save PT
	PUSH	P,T1		;  .  .  .
C$BL.0:	SETZ	A1,		; Back to the beginning of the line
	PUSHJ	P,GETCMD	; Do the argument processing
	MOVE	T1,A2		; Return it in T1
	SOJL	T1,C$BL.2	; If we hit the beginning of the buffer return this value
	SOJL	T1,C$BL.2	; If only one character from start of buffer return zero
	IDIVI	T1,5		; Make the word offset
	HLL	T1,BTAB(T2)	; And make the byte pointer
	MOVE	T2,CINQRG	; Get the QRG to use
	LOAD.	T2,TPTADR,+$QRTPT(T2) ; Get the command buffer address again
	ADDI	T1,.BKTLN(T2)	; And make the byte pointer absolute
	LDB	T3,T1		; Get the character before the pointer
	CAXE	T3,.CHFFD	; Is this a form feed ?
	 CAXN	T3,.CHVTB	; Or a vertical tab ?
	  JRST	C$BL.3		; Yes, end of the line
	CAXE	T3,.CHCRT	; Is it a carriage return?
	 JRST	C$BL.1		; No, back up some more
	ILDB	T3,T1		; Yes, get the next character
	CAXE	T3,.CHLFD	; Is it a line feed?
	 JRST	C$BL.1		; No, need to go back some more
C$BL.3:	SKIPA	T1,A2		; Found the place, return the character address
C$BL.2:	 SETZ	T1,		; Hit beginning of buffer first
	MOVE	T2,CINQRG	; Get the QRG address
	LOAD.	T2,TPTADR,+$QRTPT(T2) ; Make sure PT is still correct
	POP	P,T3		;  .  .  .
	STOR.	T3,BLKPT,(T2)	; Store the old pointer back
	POPJ	P,		; Return to the caller

C$BL.1:	SUBI	A2,1		; Back up one character
	STOR.	A2,BLKPT,(T2)	; To find the previous end of line
	JRST	C$BL.0		; And try again

; Here if screen mode

C$BL.Z:	PUSHJ	P,GETVID	; Get the address of the beginning of the line
	MOVE	T1,A2		; Copy the results
	POPJ	P,		; Return to the caller
	SUBTTL	C$DWRD - Find previous word boundary

;+
;.HL2 C$DWRD
; This routine will determine how much should be deleted on a ^W.
;It will determine the amount to delete the same way as the monitor
;does, with the exception that in video mode, it will also delete EOL's.
;.literal
;
; Usage:
;	T1/ Address of text buffer
;	PUSHJ	P,C$DWRD
;	 (return, T1= new END address)
;
;.end lit
;-

C$DWRD:	$SAVE	<P1,P2>		; Save some ac's
	MOVE	P1,T1		; Get the buffer address
	LOAD.	T1,BLKEND,(P1)	; Get the final character address
	SETZ	P2,		; Nothing deleted so far

CDWR.1:	SOJL	T1,.RET0	; If nothing left, just return

	MOVE	T2,T1		; Get the address
	IDIVX	T2,5		; Convert to a byte pointer
	ADD	T2,P1		;  .  .  .
	ADDX	T2,.BKTLN	;  .  .  .
	TDO	T2,BTAB(T3)	;  .  .  .
	LDB	T2,T2		; Get the character
	MOVE	T3,CHRFLG(T2)	; Get the flags
	JUMPN	P2,CDWR.2	; If we have already deleted something, check this char
	TXNN	T3,CF.NUM!CF.ALP ; Alphanumeric character?
	 JRST	CDWR.3		; No, check spacing
	MOVE	P2,T2		; Yes, save the character
	JRST	CDWR.1		; And keep going

CDWR.3:	CAXE	T2,.CHTAB	; Is it a tab?
	 CAXN	T2," "		; Or space?
	  JRST	[SETO	P2,		; Yes, flag that
		JRST	CDWR.1]		; And keep going
	JMPS	CDWR.4		; Screen mode?
	CAXE	T2,.CHCRT	; Carriage return?
	 CAXN	T2,.CHLFD	; Or line feed?
	  AOJA	T1,.POPJ	; Yes, don't delete them
	CAXE	T2,.CHVTB	; Or vertical tabs
	 CAXN	T2,.CHFFD	; Or form feeds
	  AOJA	T1,.POPJ	;  .  .  .
	POPJ	P,		; Anything else we just delete the one character
; Here in screen mode when we have a delimeter.  If it is anything
;but a LF, just delete the one character.  If it is a LF, check if it is
;part of a CRLF, and if so, also delete the CR.

CDWR.4:	CAXE	T2,.CHLFD	; Line feed?
	 POPJ	P,		; No, all done
	SOS	T2,T1		; Yes, get the previous character
	IDIVI	T2,5		; Make the byte pointer
	TDO	T2,BTAB(T3)	;  .  .  .
	ADD	T2,P1		;  .  .  .
	ADDX	T2,.BKTLN	;  .  .  .
	LDB	T2,T2		; Get the character
	CAXE	T2,.CHCRT	; Carriage return?
	 AOJ	T1,		; No, this is a lonely LF
	POPJ	P,		; Return

; Here for subsequent characters

CDWR.2:	CAXE	T2,.CHTAB	; Spacing character?
	 CAXN	T2," "		;  .  .  .
	  JRST	[JUMPL	P2,CDWR.1	; Yes, if no alpha yet, keep deleting
		AOJA	T1,.POPJ]	; Otherwise this is the end
	TXNN	T3,CF.NUM!CF.ALP ; Alphanumeric?
	 AOJA	T1,.POPJ	; No, don't delete it
	MOVE	P2,T2		; Yes, save the character
	JRST	CDWR.1		; And keep going
	SUBTTL	C$ICHR - Input a character

;+
;.HL1 C$ICHR
;This routine will input the next character from the user terminal.  It will
;get any saved characters if there is one.
;.literal
;
; Usage:
;	PUSHJ	P,C$ICHR
;	(Return)
;
; On return:
;	CH/ Next character
;
;.end literal
;-

C$ICHR:	SETZ	CH,			; Clear this incase of a saved character
	EXCH	CH,CINSVD		; Get the saved character
	JUMPE	CH,CICH.1		; Return if we have a character
	TXZE	CH,C$$ECH		; Need to be echoed?
	 SKPS				; Maybe, video mode?
	  JRST	.+2			; No echo needed
	 PUSHJ	P,V$ECHO		; Yes, echo it
	POPJ	P,			; Return to the caller

; Here if we need to get another character

CICH.1:	$SAVE	<XCTING>		; Save the execution flag
	SETZM	XCTING			; Flag we are in input wait
	PJRST	@TY.IBY			; Get a character and return
	SUBTTL	C$RCHR - Repeat the current character.

;+
;.HL1 C$RCHR
;This routine is used to repeat the current character that was input from the
;user.  The next call to C$ICHR will input this character again.
;.literal
;
; Usage:
;	PUSHJ	P,C$RCHR
;	(Return)
;
; On return:
;	- Character saved.
;
;.end literal
;-

C$RCHR:	MOVEM	CH,CINSVD		; Save the command charater
	POPJ	P,			; Return to the caller
	SUBTTL	Low segment

	$IMPURE
	LOWVER(CIN,1)

CINQRG:	BLOCK	1		; Address of QRG we are using
PMTLEN:	BLOCK	1		; Length of prompt string within QRG

CINSVD:	BLOCK	1		; Saved character to be parsed again (for C$RCHR/C$ICHR)
	SUBTTL	End of TECCIN

	END			; End of TECCIN