	.TITLE    MCE - CLI-Commandline-Editor
;
	.IDENT    -V4.22-	; this identcode appears in MCE messages
;
	.ENABLE    LC
;
;	Copyright (c) 1988
;
; 	J.H. Hamakers,
;	Asea Brown Boveri Industie b.v.
;	P.O.Box 301
;	3000 AH  Rotterdam
;	The Netherlands
;	Phone : +31 - 10 - 4078631
;
;	All rights reserved
;
;	This software may be copied and distributed ONLY
;	on a non profit basis and with the inclusion of
;	the above copyright statement.
;
;	PLEASE CONTACT ME FOR PROBLEMS OR SUGGESTIONS
;
;       +---------------------------------------------------+
;	| See MCEREL.DOC for information about this release |
;       +---------------------------------------------------+
;
; Test the ident of MCEPRE.MAC .....
;
	.IF NDF	IDNPRE
.ERROR ;MCE -- MCEPRE.MAC not compatible with this version of MCE.
.ERROR ;       Please build again.
	.IFF
	.IF NE IDNPRE-4.
.ERROR ;MCE -- MCEPRE.MAC not compatible with this version of MCE.
.ERROR ;       Please build again.
	.ENDC
	.ENDC
;
	.SBTTL	MCE ----------- *** Macros, Constants, Variables etc. ***

;
; Psects used .....
;
	.PSECT	CODE ,I,RO
	.PSECT	IDATA,D,RW
	.PSECT	PDATA,D,RO
	.PSECT

;
; Macro calls .....
;
	.MCALL	DIR$	,EXIT$S	,MRKT$S	,QIO$	,SDIR$S
	.MCALL	SPWN$	,SREX$S	,STSE$	,STSE$S	,WTSE$

	.IF DF	FILE

	.MCALL	CSI$	,CSI$1	,CSI$2
	.MCALL	GET$S	,CLOSE$	,GMCR$	,NMBLK$	,OPEN$R
	.MCALL	FDBDF$	,FDRC$A	,FDOP$A	,FSRSZ$

	.ENDC	;FILE

	.IIF DF	CLISUP!FILE		.MCALL	GCII$

	.IIF DF	RTMESS!RTEXIT!TMOTIM	.MCALL	GLUN$S

	.IIF DF	TMOTIM			.MCALL	ASTX$S

	.IIF DF	STATUS&TMOTIM		.MCALL	QIOW$S


;
; Local symbol definitions .....
;

CMDSIZ	= 78.
;
BELL	= 7
BKSP	= 10
LF	= 12
CR	= 15
ESC	= 33
BLNK	= 40
DEL	= 177
;
TI	= 1			; TI: LUN
INILUN	= 2			; MCEINI.xxx LUN
EFN	= 1			; Eventflag

	.IF DF	STATUS&TMOTIM

EFNAST	= 2			; Eventflag in TIMAST

	.ENDC	;STATUS&TMOTIM

	.IIF NDF INSDEF	   INSDEF = 0
	.IIF NDF INTDEF	   INTDEF = 1
	.IIF NDF MAXFIF    MAXFIF = 22.
	.IIF NDF MINCHR    MINCHR = 1
	.IIF NDF OLDDEF	   OLDDEF = 1
	.IIF NDF OVSDEF	   OVSDEF = 0

	.IIF DF	EDT 	.IIF NDF EDTDEF	   EDTDEF = 0
	.IIF DF	EXTNPR	.IIF NDF PRMDEF	   PRMDEF = 1
	.IIF DF	STATUS	.IIF NDF STADEF	   STADEF = 1

	.NLIST	BEX

	.MACRO	NEWLIN  Z
	.IF B Z
	.ASCII	<CR><LF>
	.IFF
	.ASCIZ	<CR><LF>
	.ENDC
	.ENDM	NEWLIN

;
; Stopfor/Waitfor I/O DPBs .....
;
; Normally we STOP for I/O. When MCE is aborted we WAIT for I/O.
; We use the WTSE$ directive here to copy the DIC-code to STOPIO.
; (See  EXAST:)
;
	.PSECT	PDATA

WAITIO:	WTSE$

	.PSECT	IDATA

STOPIO:	STSE$	EFN

;
; DBPs .....
;
	.IF DF	COMPND

SPAWN:	SPWN$	,,,,,,,EXSTAT

	.IFF	;COMPND

SPAWN:	SPWN$	

	.ENDC	;COMPND
;
	TASK	= SPAWN+S.PWTN		; Taskname
	WAITFL	= SPAWN+S.PWEF		; Event flag
$$$=.
.=TASK

	.IF DF	CLISUP

	.RAD50	\CLI...\ 	; Current CLI

	.IFF	;CLISUP

	.RAD50	\MCR...\ 	; Task for Systems without alternate CLI-Supp.

	.ENDC	;CLISUP

.=$$$

;
QIODIR:	QIO$	,TI,EFN,,IOSTAT
;
	ADR	= QIODIR+Q.IOPL		; I/O Bufferaddress
	CODE	= QIODIR+Q.IOFN		; I/O Functioncode
	LEN	= QIODIR+Q.IOPL+2	; I/O length
					; ( Also used for Spawn )
;
; File stuff .....
;

	.IF DF	FILE

	FSRSZ$	1		; File storage region

	.PSECT	IDATA

;
; FDB for MCEINI files .....
;
FDBIN:	FDBDF$
	FDRC$A	,CMDBUF	,CMDSIZ
	FDOP$A	 INILUN	,FDSPT	,NAMBLK	,FO.RD

;
; Descriptor dispatch table .....
;
FDSPT:	DEVL	,DEV		; Device string
FDIR:	DIRL	,DIR		; Directory string at startup
	0   	,0		; No File name ( NAMBLK will be used )

;
; Descriptors .....
;
; Device descriptor in RW data section for it can be overwritten
;
DEV:	.ASCII    /LB:/        	; Device Name
DEVL = .-DEV
	.EVEN

	.PSECT	PDATA

	.IF DF	A$SV

DIR:	.ASCII	/[2,2]/

	.IFF	;A$SV

DIR:	.ASCII	/[1,2]/

	.ENDC	;A$SV

DIRL = .-DIR
	.EVEN

	.PSECT	IDATA

;
; Default startup filename block .....
;
; Default filename ( if no alternate CLI support ) is 'MCEINI.CMD'.
; Default device is SY: ( but superimposed by LB: in FDSPT ).
; SY: in the NAMBLK will be effective for files specified in the
; invoking MCR/DCL commandline. Specifying 'MCE XXX' thus results in
; file name 'SY0:XXX.CMD'.
; Note, that the filetype in NAMBLK will be overwritten by the CLI name.
; ( See GETCLI )
;
NAMBLK:	NMBLK$	MCEINI ,CMD ,0 ,SY ,0
;
	FILTYP = NAMBLK+N.FTYP	; Address of RAD-50 filetype

;
; CSI$ Control block .....
;
CSIBLK:	CSI$			; Define CSI control block offsets
	.BLKB	C.SIZE
	.EVEN

	.ENDC	;FILE

;
; Variable textstrings .....
;
; These textstrings are in RW Psects for they are dynamicly changed.
;

;
; - Pool information ...
;
POOLTX: .ASCII	/MCE -- Pool:/
POOLDT:	.BLKB	18.

;
; - Startup text ...
;

	.IF DF	CLISUP

STRTXT:	.ASCII	\MCE -- CLI-Commandline-Editor \

	.IFF	;CLISUP

STRTXT:	.ASCII	\MCE -- MCR-Commandline-Editor \

	.ENDC	;CLISUP

IDENT:	.ASCII	\      \	; Ident will be placed here

	.IIF DF	A$SV	.ASCII \/ASV\

	.IIF DF VT2XX	.ASCII \/VT2\

	.IIF DF TDV2XX	.ASCII \/TDV\

	NEWLIN	Z

;
; - Help spawn string ...
;
HLPTXT:	.ASCII	\HELP \

        .IIF DF HLPNEW	.ASCII	\/\

        .IIF DF A$SV	.ASCII	\ASV \

	.ASCII	\MCE\

HPAG0:	.ASCII	<0>\MCE\
HPAGE:	.ASCIZ	\ \

	.IF DF	COMPND

;
; - Terminating a compound commandline ...
;
EXSTMS:	NEWLIN
	.ASCII	\MCE -- Terminated Compound Commandline, Exit status :\
EXSTDA:	.ASCII	\     \
	NEWLIN
	.ASCII	\       --->\
EXSTML=.-EXSTMS

	.ENDC	;COMPND

	.IF DF	STATUS

;
; - Statusline ...
;
STATX1:	.ASCII	<ESC>"D"
	.ASCII	<ESC>"M"
STATX2:	.ASCII	<ESC>"7"
	.ASCII	<ESC>"[1;23r"
	.ASCII	<ESC>"[24;1H"
	.ASCII	<ESC>"[7m"
STATX3:	.ASCII	"MCE-"
IDENT2:	.ASCII	"        FIFO:"
STALIR:	.ASCII	"list/"
	.ASCII	"xx/"
	.ASCII	"xx/"
	.ASCII	"xx CMSZ:"
STACMD:	.ASCII	"xx KEYP:"
STAKEY:	.ASCII	"no  SVINT:"
STASVI:	.ASCII	"xxx SVOLD:"
STASVR:	.ASCII	"xxx TMO:"
STATMO:	.ASCII	"no "
STALN3=.-STATX3
	.ASCII	<ESC>"[K"
	.ASCII	<ESC>"[m"
	.ASCII	<ESC>"8"
STALN2=.-STATX2
STALN1=.-STATX1

;
; - Statusline clear ..
;
STACLR:	.ASCII	<ESC>"7"
	.ASCII	<ESC>"[1;24r"
	.ASCII	<ESC>"8"
	.ASCII	<ESC>"[J"
STACLN=.-STACLR

	.ENDC	;STATUS

	.EVEN

	.PSECT	PDATA
;
; Permanent strings .....
;
BS:	.REPT	CMDSIZ		; Backspace buffer for
 	.ASCII	<BKSP>		;   cursor positioning
 	.ENDR			;
;
SCRCLR:	.ASCII	<ESC>"[H"	; Clear
	.ASCII	<ESC>"[J"	;     screen
SCRCLL=.-SCRCLR			;

;
; - Various messages ...
;
BYETXT: .ASCIZ /BYE/
ENDTXT: NEWLIN			; Exit
EXITXT: .ASCIZ /MCE -- Exit/	;   message
ERRTXT: NEWLIN
	.ASCIZ /MCE -- Internal command error/<BELL>
CRET:				; Only <CR><LF>
NOPOOL: NEWLIN
	.ASCIZ /MCE -- Pool exhausted - Install MCE with INC/<BELL>
TOOLON: NEWLIN
	.ASCIZ /MCE -- Command too long/<BELL>


	.IF DF	EDT

APLTXT:	.ASCII	<ESC>/=/
EDTTXT:	.ASCII	\HELP \

        .IIF DF HLPNEW	.ASCII	\/\

        .IIF DF A$SV	.ASCII	\ASV \

	.ASCIZ	\MCE KEYPAD\

INV:	.ASCII	<ESC>/[7m/
INVL	=.-INV
NOR:	.ASCII	<ESC>/[m/
NORL	=.-NOR
NUMTXT:	.ASCII	<ESC>/>/

	.ENDC	;EDT

	.IF DF  FILE

FLSTXT: NEWLIN
	.ASCIZ /MCE -- Filespecification syntax error/<BELL>
FILTXT: NEWLIN
	.ASCIZ /MCE -- File open error/<BELL>

	.ENDC	;FILE

	.IF LT	MAXHLP-'A

;
; - This text is needed when MCE is not build together with a HELP-file ...
;
NOHTXT: NEWLIN
	.ASCII /MCE -- No information about number of HELP pages, /
	.ASCII /so cannot use NXT and PRV keys/
	NEWLIN
	.ASCII /       Generate MCE.HLP and MCE.TSK together with /
	.ASCII /MCEBLD.CMD/<BELL>
NOHLEN=.-NOHTXT

	.ENDC	;MAXHLP-'A

;
; - RT: Messages ...
;
	.IF DF	RTEXIT

RTTXT:  NEWLIN
	.ASCII /MCE -- Started on a remote terminal (RT:) Exiting ...../<BELL>
	NEWLIN
RTTXTL=.-RTTXT

	.ENDC	;RTEXIT

	.IF DF	RTMESS

RTTXT:  NEWLIN
	.ASCII /MCE -- ** WARNING ** Started on a remote terminal (RT:)/
	NEWLIN
	.ASCII /       If your local system is VMS with its commandline editor/
	NEWLIN
	.ASCII /       enabled please type "MCE EXIT"/<BELL>
	NEWLIN
RTTXTL=.-RTTXT

	.ENDC	;RTMESS

	.IF DF	VT2XX

VT2ESQ:	.ASCII	/[23~/		; VT2XX <ESC> Picture
VT2ESL = .-VT2ESQ		;

	.ENDC	;VT2XX

	.EVEN

;
; Internal MCE command dispatch table .....
; ( See subroutine INTERN )
;
INTCMD:
	.ASCII	/CLEA/          ; Clear FIFO
	ICCLEA
	.ASCII	/CMSZ/          ; Minimum cmd size
	ICCMSZ
	.ASCII	/ECHO/		; Echo commandline
	ICECHO
	.ASCII	/EXIT/		; Task exit
	EXIT
	.ASCII	/FISZ/          ; FIFO maximum
	ICFISZ
	.ASCII	/FREE/          ; Free poolspace
	ICFREE
	.ASCII	/INSE/          ; Auto insert mode
	ICINSE
	.ASCII	/LIST/          ; FIFO is a list
	ICLIST
	.ASCII	/OVER/          ; Auto overstrike  mode
	ICOVER
	.ASCII	/PURG/		; Delete all command translations
	ICPURG
	.ASCII	/RING/          ; FIFO is a ringbuffer
	ICRING
	.ASCII	/SVIN/          ; Save Internal commands on/off
	ICSVIN
	.ASCII	/SVOL/          ; Save Old commands on/off
	ICSVOL
	.ASCII	/VERS/          ; Version
	ICVERS

	.IF DF	EDT

	.ASCII	/KEYP/
	ICKEYP

	.ENDC	;EDT

	.IF DF	EXTNPR

	.ASCII	/PROM/
	ICPROM

	.ENDC	;EXTNPR

	.IF DF 	FILE

	.ASCII	/CHAI/		; Chain to other file (= READ)
	ICREAD
	.ASCII	/READ/		; Read definition file 'MCE READ filespc'
	ICREAD
	.ASCII	/REPL/          ; Replace translations by new file
	ICREPL

	.ENDC	;FILE

	.IF DF 	STATUS

	.ASCII	/STAT/          ; Status line on/off
	ICSTAT

	.ENDC	;STATUS

	0			; End of table marker

	.PSECT	IDATA
;
; Various variables and buffers .....
;
FREE:   .BLKW	2		; Free memory listhead
IOSTAT:	.BLKW 	2		; I/O Statusblock
MAXF:	MAXFIF			; FIFO size
MINC:	MINCHR			; Commandlength to be saved
POOL:	.BLKW	3		; Pool information
PROMLF:	DEFPR			; Point to default prompt with <LF><CR>
PROMPT:	DEFPR+1			; Point to default prompt with <CR>

	.IF DF	COMPND

EXSTAT:	.BLKW	8.		; Exit status block

	.ENDC	;COMPND

	.IF DF	EDT

SELSTR:	0			; Address of select start

	.ENDC	;EDT

	.IF DF  TMOTIM!RTMESS!RTEXIT

GLUNB:	.BLKW	6.

	.ENDC	;TMOTIM!RTMESS!RTEXIT

;
; Flags, buffers and other bytes .....
;
CHAR:	.BYTE	0		; Input-character
ECHFLG:	.BYTE	0		; If ne : Echo commandline
INSFLG:	.BYTE	INSDEF		; If ne : Auto insert
				;	  - change with MCE INSErt on/off
LEAFLG:	.BYTE	0		; If ne : Leave FIFO pointer     ( CTRL/X )
NEXFLG:	.BYTE	0		; If ne : Don't execute Command  ( CTRL/N )
NLOFLG:	.BYTE	0		; If ne : Don't load Command in Commandbuffer
OLDFLG:	.BYTE	0		; If ne : Old command , not edited
OVSFLG:	.BYTE	OVSDEF		; If ne : Auto overstike
				;	  - change with MCE OVERstrike on/off
MODFLG:	.BYTE	OVSDEF		; If odd: Overstrike mode
				;	  - change with ^A
PRIFLG:	.BYTE	0		; If ne : Commandbuffer being printout
RNGFLG:	.BYTE	0		; If ne : FIFO is a ringbuffer
				;	  - change with MCE LIST/RING
SINFLG:	.BYTE	INTDEF		; If ne : Internal commands are saved
				;	  - change with MCE SVINtern on/off
SOLFLG:	.BYTE	OLDDEF		; If ne : Old commands are saved
				;	  - change with MCE SVOLd on/off

	.IF DF	EDT

EDTFLG:	.BYTE	EDTDEF		; If ne : EDT Mode active
				;	  - change with MCE KEYPad on/off
GOLDFL:	.BYTE	0		; If ne : "GOLD" pushed
PSTBUF:	.BLKB	CMDSIZ		; Paste buffer
PSTLEN:	.BYTE	0		; Length of string in Paste buffer
SELFLG:	.BYTE	0		; if ne : Ansi-selective range active

	.ENDC	;EDT

	.IF DF	EXTNPR

PRMFLG:	.BYTE	PRMDEF		; if ne : extended prompt

	.ENDC	;EXTNPR

	.IF DF	FILE

FILINI:	.BYTE	0		; If ne : Startup file being processed
FILINP:	.BYTE	0		; If ne : File Input
FILREX:	.BYTE	0		; If ne : MCE Read or MCE Replace being
				;         processed
	.ENDC	;FILE

	.IF DF	STATUS

STAFLG:	.BYTE	STADEF		; If ne : Status line is displayed
				;	  - change with MCE STATus on/off

	.ENDC	;STATUS

	.IF DF	TMOTIM

TMOCNT:	.BYTE	TMOTIM		; Counter for timeout
TT0FLG:	.BYTE	0		; If ne : TI: = TT0:

	.ENDC	;TMOTIM

 	.EVEN

;
; FIFO Buffer descriptors .....
;
FIFO:	0, FIFO			; Header FIFO Buffer
;
	F.1ST	= 0		; Pointer to first entry
	F.LAST	= 2		; Pointer to last entry
;
	FI.NXT	= 0		; Pointer to next Entry
	FI.LEN	= 2		; Length of entry
	FI.TXT	= 4		; Text, terminated by binary 0
;
FIFCNT:	.BYTE	0		; Number of entries in FIFO
FIFPOI:	.BYTE	0		; Entry number
FIFPTR:	0			; Ptr to current Entry (for UP, DOWN keys)

;
; Translation buffer .....
; ( same entries as in FIFO )
;
TRNB:    0, TRNB       		; Header command definitions

;
; Terminal characteristics buffer .....
;
SFGMCB:
ANI:	.BYTE	TC.ANI,0	; ANSI Terminal
HLD:	.BYTE	TC.HLD,0	; Hold screen mode

	.IF DF	VT2XX!TDV2XX

TTP:	.BYTE	TC.TTP,0	; Get terminal type

	.ENDC	;VT2XX!TDV2XX

SFGMCL = .-SFGMCB

;
; Prompt area .....
;
	.BLKB	24.		; Prompt buffer
	.EVEN
DEFPR:	.ASCII	<LF>		;
	.ASCII	<CR>		;
CMDBUF:	.BLKB	CMDSIZ		; Current buffer
CMDEND:
	.EVEN
SAVBUF:	.BLKB	CMDSIZ		; Save Buffer
RCLBUF:	.BLKB	CMDSIZ		; Recall Buffer
	.EVEN

	.IF DF 	FILE

;
; MCR command line directive and buffer .....
;
GMCR:	GMCR$
;
	MCRLIN = GMCR+G.MCRB

	.ENDC	;FILE

	.IF DF	CLISUP!FILE

;
; Buffer to receive CLI information .....
;
; Things taken from cli information are :
;
;  - CLI name to test if DCL	CLISUP
;  - CLI name as filetype	CLISUP&FILE
;  - Prompt			CLISUP
;  - Current Directory		FILE
;  
;
	CLIBSZ	= 50.
;
GCLI:	GCII$	CLIBUF,CLIBSZ
CLIBUF:	.BLKB	CLIBSZ		; Information buffer
;

	.ENDC	;CLISUP!FILE

	.IF DF	CLISUP

	CLIPRM = CLIBUF+G.CIDP	; CLI prompt
	CLINAM = CLIBUF+G.CICL	; CLI name

	.ENDC	;CLISUP

	.IF DF	FILE

	CLIUIC = CLIBUF+G.CICU	; Current UIC
;
; Current directory string .....
;
CURDIR:	.BLKB	40.

	.ENDC	;FILE

; -------------------------------------------------------------------
; Command check buffers and flags ....
; The whole area is cleared so do not split.
;
CDSC:	0, 0			; Descriptor of whole remainder
PDSC:				; Descriptor of P0 .. P8
	.REPT    9.
 	0, 0
	.ENDR
;
	PX.LEN	= 0		; Bytecount
	PX.ADR	= 2		; Address
	PX.SIZ	= 4		; Length of an entry
;
CFETCH:	.BYTE	0		; Flag if Paramter fetched
OVMSG:	.BYTE	0		; Send Overflow Message
CTSTAR:	.BYTE	0		; Find command with "*" enabled (ne 0)
TMPFLG:	.BYTE	0		; Temporary Flag: "*" encountered in compare
 	.EVEN
CLL = .-CDSC            	; Region to be cleared from CDSC
; -------------------------------------------------------------------

	.SBTTL	MCE - DSPTAB -- Jumptable

	.PSECT	PDATA
;
; JUMP TABLE
;
; This is the dispatch table for control characters.
; The table contains the addresses of the action routines for the
; different codes.
; When bit 0 of an address is set, the corresponding ctrl-key
; may not be superimposed by a definition.
;
DSPTAB:
	INSERT+1	; SINGLE CHR.
	CHOVER		; CTRL/A
	UP		; CTRL/B
	CLRLIN		; CTRL/C
	LEFT		; CTRL/D
	ENDLIN		; CTRL/E
	RIGHT		; CTRL/F
	loop		; CTRL/G
	BEGLIN		; BS (CTRL/H)
	MOVWRD		; HT (CTRL/I)
	DELEW		; LF (CTRL/J)
	DELRL		; CTRL/K
	loop		; CTRL/L
	EXEC+1		; CR (CTRL/M)
	SAVE		; CTRL/N
	ESCAP+1		; CTRL/O = SS3 8-bit ctrl. char. in 7-bit mode
			;  See note in release notes
			;
	loop		; CTRL/P
	loop+1		; CTRL/Q (XON)
	RETYPE		; CTRL/R
	loop+1		; CTRL/S (XOFF)
	DELAY		; CTRL/T
	DELEL		; CTRL/U
	DELRC		; CTRL/V
	DELRW		; CTRL/W
	EXELEA		; CTRL/X
	EXIT		; CTRL/Y
	loop		; CTRL/Z
	ESCAP+1		; ESC		(CTRL/[)
	loop		; CTRL/\	(CTRL/|)
	loop		; CTRL/]	(CTRL/})
	loop		; CTRL/^	(CTRL/~)
	HELP		; CTRL/?

	.IF DF	EDT

	.SBTTL	MCE - EDTTAB -- EDT-Key Jumptable
;
EDTTAB:
;
;       normal  gold	 esc. sequ	key  EDT	GOLD EDT

	DELRC,  DELRC	; ESC O l	,   DELCHR	/ UNDLCHR
	DELRW,  DELRW	; ESC O m	-   DELWRD	/ UNDLWRD
	SELECT, RESET	; ESC O n	.   SELECT	/ RESET
	loop,	loop	; ESC O o
	BEGLIN,	CLRLIN	; ESC O p	0   BLINE	/ OPENLINE
	MOVWRD,	MOVWRD	; ESC O q	1   WORD	/ CHNGCAS
	ENDLIN,	DELRL	; ESC O r	2   EOL		/ DELEOL
	loop,	loop	; ESC O s	3   CHAR	/ SPECIN
	loop,	loop	; ESC O t	4   ADVANCE	/ BOTTOM
	loop,	loop	; ESC O u	5   BACKUP	/ TOP
	CUT,	PASTE	; ESC O v	6   CUT		/ PASTE
	TRANSL,	TRANSL	; ESC O w	7   PAGE	/ COMMAND
	PRINTC,	SHVERS	; ESC O x	8   SECTION	/ FILL
	PRINTF,	SHFREE	; ESC O y	9   APPEND	/ REPLACE
	GOLD,	GOLD	; ESC O P      PF1  GOLD	/ GOLD
	EDTHLP, EDTHLP	; ESC O Q      PF2  HELP	/ HELP
	RECALL,	RECALL	; ESC O R      PF3  FINDNXT	/ FIND
	DELRL,	DELRL	; ESC O S      PF4  DELLIN	/ UNDLIN

	.ENDC	;EDT

	.IF DF TDV2XX

	.SBTTL	MCE - TDVTAB -- TDV2230 Key table
;
TDVTAB:
;	Action routine	  Key
;
	loop		; F1
	loop		; F2
	loop		; F3
	loop		; F4
	loop		; F5
	loop		; F6
	loop		; F7

	.ENDC	;TDV2XX

	.IF	DF	VT2XX

	.SBTTL	MCE - VT2TAB -- VT2XX Key table
;
; Entry:
;
;		Word 1 :   2 Ascii char. from esc-seq.
;		Word 2 :   Action routine address
;		Word 3 :   2 Ascii char. from key
;
	.MACRO	KEYVT2,ESC,ACT,KEY
	.ASCII	/ESC/
	.IF NB ACT
	ACT
	.IFF
	LOOP
	.ENDC
	.ASCII	/KEY/
	.ENDM
;
VT2TAB:
	KEYVT2	<1 >	,RECALL	,<$F>	; Find
	KEYVT2	<2 >	,PASTE	,<$I>	; Insert here
	KEYVT2	<3 >	,CUT	,<$R>	; Remove
	KEYVT2	<4 >	,SELECT	,<$S>	; Select
	KEYVT2	<5 >	,PRVHLP	,<$P>	; Prev. Screen
	KEYVT2	<6 >	,NXTHLP	,<$N>	; Next Screen
;
	KEYVT2	<17>	,	,<6 >	; F6
	KEYVT2	<18>	,	,<7 >	; F7
	KEYVT2	<19>	,	,<8 >	; F8
	KEYVT2	<20>	,	,<9 >	; F9
	KEYVT2	<21>	,	,<10>	; F10
	KEYVT2	<23>	,VT2ESC	,<11>	; F11	ESC
	KEYVT2	<24>	,BEGLIN	,<12>	; F12	BS
	KEYVT2	<25>	,DELEW	,<13>	; F13	LF
	KEYVT2	<26>	,	,<14>	; F14
	KEYVT2	<28>	,HELP	,<15>	; F15	HELP
	KEYVT2	<29>	,EXECNW	,<16>	; F16	DO
	KEYVT2	<31>	,	,<17>	; F17
	KEYVT2	<32>	,	,<18>	; F18
	KEYVT2	<33>	,	,<19>	; F19
	KEYVT2	<34>	,	,<20>	; F20
;
VT2LEN	=.-VT2TAB

	.ENDC	;VT2XX

	.SBTTL
	.SBTTL	MCE ----------- *** Start of Code ***
	.SBTTL	MCE - START  -- INIT-Code
;
; Register usage
;
; R0    Scratch Pointer
; R1    Cursor in CMDBUF
; R2    First free byte in CMDBUF (End of Text)
; R3    Scratch
; R4    Scratch
; R5    Scratch Counter
;
	.PSECT CODE
;
START:
;
; TKB puts in R3 and R4 the Task identcode in RAD50 format from the
; .IDENT directive  or from the IDENT option in the TKB-CMD file.
; We use this to put in MCE's prompts ( See Multi-Tasker july 85 )
;
	MOV	#IDENT,R0	; R0 => Version field address
	MOV	R3,R1		; 1st 3 RAD50 char.
	CALL	$C5TA		; Convert
	MOV	R4,R1		; 2nd 3 RAD50 char.
	CALL	$C5TA		; Convert

	.IF DF	STATUS

	MOV	#IDENT,R0	; R0 => Version field address
	MOV	#IDENT2,R1	; R1 => Version field address statusline
	MOV	#6,R2		; R2 =  Counter
10$:
	MOVB	(R0)+,(R1)+	; Copy
	SOB	R2,10$		;   ident.

	.ENDC	;STATUS

	SREX$S	#EXAST		; Specify exit ast
	MOV	#FREE,R0	; R0 => Free memory listhead
	CALL	$INIDM		; Initialize Free Memory
	CALL	TERM		; Get terminal info
	CALL	CLRBUF		; Initialize CMDBUF buffer

	.IF NDF SILENT

	MOV	#STRTXT,R0	; Print
	CALL	IOMSG		;   Startup message

	.ENDC	;SILENT

	.IF DF  TMOTIM!RTMESS!RTEXIT

	MOV	#GLUNB,R0	; Buffer
	GLUN$S	#TI,R0        	; Get terminal information

	.IF DF  RTMESS!RTEXIT

	CMP	(R0),#"RT	; Remote terminal ?
	BNE	20$		;  No : => 20$
	MOV	#RTTXT,ADR	; Print
	MOV	#RTTXTL,LEN	; Print
	CALL	IOW		;   RT message

	.IF DF  RTEXIT

	JMP	EXIT		;

	.ENDC	;RTEXIT

20$:

	.ENDC	;RTMESS!RTEXIT

	.IF DF  TMOTIM

	CMP	(R0),#"TT	; Normal terminal ?
	BNE	30$		;  No : => 30$
  	TSTB	2(R0)		; TT0 ?
	BNE	30$		;  No : => 30$
	INCB	TT0FLG		; Set TT0: flag
30$:
	CALL	MARK		; Marktime for timeout

	.ENDC	;TMOTIM

	.ENDC	;TMOTIM!RTMESS!RTEXIT

	.IF DF  FILE

	CALL    FILOP		; Open MCEINI file

	.ENDC	;FILE

	.SBTTL	MCE - RESTAR -- Get next Line,  Main-Loop
;
RESTAR:
	CLRB	NEXFLG		; +
	CLRB	LEAFLG		;  Clear flags
	CLRB	OLDFLG		; -

	.IF DF	EDT

	CLR	SELSTR		; Clear start of select
	CLRB	SELFLG		; Clear ANSI-select flag
	CLRB	GOLDFL		; Clear "GOLD"

	.ENDC	;EDT

	CALL	TERM		; Get terminal info

	.IF DF	FILE

	TSTB	FILINP		; File Input ?
	BEQ	10$		;  No  : => 10$
	CALL	FILREA		; Goto EXEC1 if something read
10$:				;  then come back to RESTAR

	.ENDC	;FILE

	MOV	#IO.ATT,CODE    ; Attach
	CALL	IO		;    the terminal

	.IF DF	EDT

	TSTB	EDTFLG		; EDT Keys enabled ?
	BEQ	20$		;  No : => 20$
	MOV	#APLTXT,ADR	; Aplication keypad
	MOV	#2,LEN		; Length
	CALL	IOW		; Write
20$:

	.ENDC	;EDT

;
; Set our task default directory string to that of the terminal. We
; need to do that since the last command could have been a SET /DEF
; RSX11M does nothing with this directive so it doesn't have to be
; conditionalized
;
	SDIR$S	#SD.TI		; Set task DDS to terminal DDS

	.IF DF	STATUS

	CALL	PRISTA		; Print status line

	.ENDC	;STATUS

	.SBTTL	MCE - PRIPRM -- Print the prompt
;
PRIPRM:
	MOV	#IO.CCO,CODE	; Cancel <CTRL/O>
	MOV	PROMLF,ADR      ; Start of prompt buffer
	MOV	#CMDBUF+2,R3	; Point behind prompt buffer ( Room for ESC[ )
	MOVB	#'[,-(R3)	; Insert '[' ( Hold screen mode )
	MOVB	#ESC,-(R3)	; Insert ESC ( Hold screen mode )

	.IF DF  CLISUP!FILE

	CALL	GETCLI		; Get CLI information

	.ENDC	;CLISUP!FILE

	.IF DF  CLISUP

	BCC	10$		;  Success : => 10$
	MOV	#^RMCR,TASK	; MCR... only
	BR	40$		; Continue with default prompt
;
10$:
;
; Copy CLI prompt
;
	MOV	#CLIPRM,R0	; R0 => CLI Prompt information
	MOVB	(R0)+,R4	; Get length, advance to prompt string
	ADD	R4,R0		; Point behind CLI prompt
	CLR	-(SP)		; Reserve space
20$:
	MOVB	-(R0),(SP)	; Save character
	CMPB	(SP),#CR	; <CR> ?
	BEQ	30$		;  Yes : => 30$
	CMPB	(SP),#LF	; <LF> ?
	BEQ	30$		;  Yes : => 30$
	MOVB	(SP),-(R3)	; Copy character
30$:
	SOB	R4,20$          ; Next character
	TST	(SP)+		; Flush space
	BR	50$		; => 50$
40$:

	.ENDC	;CLISUP

	MOVB	#'>,-(R3)	; Default prompt
50$:
	BICB	INSFLG,MODFLG	; Clear overstrike mode if Auto Insert
	BISB	OVSFLG,MODFLG	; Set   overstrike mode if Auto Overstrike

	.IF DF	EXTNPR

	TSTB	PRMFLG		; Extended prompt ?
	BEQ	70$		;  No : => 70$

	.IF DF	EDT

	TSTB	EDTFLG		; EDT mode active ?
	BEQ	60$		;  No : => 60$

	.IF DF	STATUS

	TSTB	STAFLG		; Status line ?
	BNE	60$		;  Yes : => 60$

	.ENDC	;STATUS

	MOVB	#':,-(R3)	; Display EDT mode active
60$:

	.ENDC	;EDT

	MOVB	#'+,-(R3)	; Assume insert mode
	BITB	#1,MODFLG	; Overstrike ?
	BEQ	70$		;  No : => 70$
	MOVB	#'-,(R3)	; Overstrike
70$:

	.ENDC	;EXTNPR

	MOVB	#CR,-(R3)	; Insert <CR>
	MOVB	#LF,-(R3)	; Insert <LF>
	MOVB	#'/,-1(R3)	; Insert '/' ( hold screen mode )
	MOVB	#ESC,-2(R3)	; Insert <ESC> ( hold screen mode )
	MOV	#CMDBUF,LEN	; Point behind prompt buffer
	SUB	R3,LEN		; Length
	MOV	R3,PROMPT	; +
	MOV	R3,PROMLF	;  Adjust
	INC	PROMPT		;     Pointers
	MOV	PROMLF,ADR	; -
80$:
	TSTB	HLD+1		; Hold screen mode ?
	BEQ	90$		;  No : => 90$
	ADD	#4,LEN		; Adjust length for Hold screen escseq.
	SUB	#2,ADR		; Adjust address
90$:
	CALL	IO		; Output prompt
;
; Clear edit buffer and setup R1 and R2 as pointers
;
	CALL	CLRBUF		; Clear edit buffer

	.SBTTL	MCE - LOOP   -- Accept next Char. for input and dispatch it
;
LOOP:
	MOV	#IO.RST!TF.RNE,CODE
				; Accept one chr.
	MOV	#CHAR,ADR	; 1 Character buffer
	MOV	#1,LEN		; Length
	CALL	IO		; Read 1 char
LOOP00:

	.IF DF  TMOTIM

	CMPB	IOSTAT,#IE.ABO	; IO killed ? (time-out)
	BNE	30$		;  No : => 30$
	MOV	#BYETXT,R0 	; Assume "BYE"
	TSTB	TT0FLG		; Are we on TT0: ?
	BNE	10$		;  Yes : => 10$
	MOV	#^RMCR,TASK	; MCR...
	BR	20$		; => 20$
10$:
	MOV	#EXITXT,R0	; "MCE EXIT"
20$:
	CALL	GETBUF		; Copy in CMDBUF
	CALL	DISPLY		; Display
	JMP	EXEC		; Execute "BYE" or "MCE EXIT" command
30$:

	.ENDC	;TMOTIM

	MOVB    IOSTAT+1,R4     ; Test for branch table
	BIC     #177600,R4      ; Make 7-Bit ASCII
				; ( See note in release notes )
40$:
	CMPB	R4,#DEL		; Delete ?
	BNE	50$		;  No : => 50$
	JMP	DELEC		; => Delete char.
50$:
	BIC     #177740,R4      ; IO.RST:  all ctrl-char in iostat
	MOV	R4,R3		; Copy in R3
        ASL     R3		; Word offset
	BIT	#1,DSPTAB(R3)	; May be translated ?
	BEQ	60$		;  Yes : => 60$
	MOV	DSPTAB(R3),R3	; Take address
	BIC	#1,R3		; Clear bit 0
	JMP	(R3)		; Do action routine
60$:
;
; Check if to be translated
;
	MOVB	#'^,SAVBUF	; Insert
	MOVB	R4,SAVBUF+1	;   key
	BISB	#100,SAVBUF+1	; Make ASCII
	CMPB	SAVBUF+1,#'_	; "_" ?
	BNE	70$		;  No : => 70$
	MOVB	#'?,SAVBUF+1	; Make "?"
70$:
        ASL     R4		; Word offset
	ADD	#DSPTAB,R4	; Add table address
	MOV	#2,PDSC+PX.LEN	; P0 Length = 2
PROCESS:
	MOV	#SAVBUF,PDSC+PX.ADR
				; P0 Address
	MOV	R2,-(SP)	; Save R2
	CALL	FNDCMD		; Find cmd
	MOV	(SP)+,R2	; Restore R2
	BCS	10$		;  No entry found : => 10$
	JMP	FUNC		; Proccess it
10$:
        JMP     @(R4)     	; <== Dispatch

	.SBTTL
	.SBTTL    MCE ----------- *** Key actions ***
	.SBTTL    MCE - BEGLIN -- Begin of line
;
BEGLIN:

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	10$		;  No :=> 10$
	MOV	#CMDBUF,R1	; Cursor at pos 1
	CALL	DISPLY		; Rewrite line
	JMP	LOOP		; => LOOP

	.ENDC	;EDT

10$:
	CALL	SPBACK		; Back space one position
	BCC	10$		; If CC not yet at the begin
	JMP	LOOP		; => LOOP
;
;
	.SBTTL    MCE - CHOVER -- Flip between insert and overstrike mode
;
CHOVER:
	INCB	MODFLG		; Change mode

	.IF DF	EXTNPR

	TSTB	PRMFLG		; Extended prompt ?
	BEQ	20$		;  No : => 20$
	MOV	PROMPT,R4	; R4 => Prompt
	TSTB	(R4)+		; R4 => Mode character
	MOVB	#'+,(R4)	; Insert "+"
	BITB	#1,MODFLG	; Overstrike ?
	BEQ	10$		;  No : => 10$
	MOVB	#'-,(R4)	; Insert "-"
10$:
	CALL	DISPLY		; Rewrite line
20$:

	.ENDC	;EXTNPR

	BR	LOOP1		; => LOOP
;
;
	.SBTTL    MCE - DELEC  -- Delete left single char
;
DELEC:
	CALL	SPBACK		; Back space one position
	BCS	LOOP1		;  Error : => LOOP
	BR	DELCHR		; => DELCHR
;
;
	.SBTTL    MCE - DELEL  -- Delete from start of line to cursor
;
DELEL:
	CMP	R1,#CMDBUF	; At begin of buffer ?
	BLOS	60$		;  Yes : => 60$
	MOV	#CMDBUF,R0	; R0 => CMDBUF

	.IF DF	EDT

	TST	SELSTR		; Selective range active ?
	BEQ	10$		;  No : => 10$
	CMP	R1,SELSTR	; Compare cursor with start of range
	BLO	10$		;  Left of start : => 10$
	MOV	R1,SELSTR	; Backup range

	.ENDC	;EDT

10$:
	CMP	R1,R2		; EOL ?
	BEQ	20$		;  Yes : => 20$
	MOVB	(R1)+,(R0)+	; Shift string left

	.IF DF	EDT

	TST	SELSTR		; Selective range active ?
	BEQ	10$		;  No : => 10$
	DEC	SELSTR		; Backup range

	.ENDC	;EDT

	BR	10$		; => 10$
20$:
	MOV	R0,R2		; End of text
30$:
	CMP	R0,#CMDEND	; End of buffer ?
	BHIS	40$		;  Yes : => 40$
	MOVB	#BLNK,(R0)+	; Fill with blank
	BR	30$		; => 30$
40$:
	CLRB	OLDFLG		; No old command
	TSTB	ANI+1		; Ansi Screen ?
	BNE	50$		;  Yes : => 50$

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BNE	50$		;  Yes : => 50$

	.ENDC	;EDT

	MOV	PROMPT,ADR      ; +
	MOV	R1,LEN          ;  Rewrite line
	SUB	PROMPT,LEN      ;
	CALL	IOW    		; -
	MOV	#CMDBUF,LEN	; +
	SUB	PROMPT,LEN	;  Reposition cursor
	CALL	IO              ;
	MOV	#CMDBUF,R1      ; -
	BR	60$		; => 60$
50$:
	MOV	#CMDBUF,R1      ; Reposition cursor
	CALL	DISPLY		; Rewrite line
60$:
	BR	LOOP1		; => LOOP
;
;
	.SBTTL    MCE - DELEW  -- Delete left single word
;
DELEW:
	CMP	R1,#CMDBUF	; At begin of buffer ?
	BLOS	LOOP1		;  Yes : => LOOP
	MOV	R1,-(SP)	; Save cursor position
10$:
	DEC	R1		; Cursor left
	CMP	R1,#CMDBUF	; At begin of buffer ?
	BLOS	30$		;  Yes : => 30$
	MOVB	-1(R1),R0	; Get previous char
	CMPB	R0,#BLNK	; Space ?
	BNE	20$		;  No  : => 20$
	CMPB	R0,(R1)		; Was previous one a space ?
	BEQ	10$		;  Yes : => 10$, delete it
20$:
	CALL	SRWORD		; Search word
	BCC	10$		;
30$:
	MOV	(SP)+,R0	; R0 = Initial cursor position
	MOV	R1,-(SP)	; Save new cursor position
	BR	DELWRD		; => Delwrd
;
;
	.SBTTL    MCE - DELRC  -- Delete right single char
;
DELRC:
	CMP	R1,R2		; At EOL ?
	BHIS	LOOP1		;  Yes : => LOOP
DELCHR:

	.IF DF	EDT

	TST	SELSTR		; Selective range active ?
	BEQ	10$		;  No : => 10$
	CMP	R1,SELSTR	; Compare cursor with start of range
	BHI	10$		;  Right of start
	DEC	SELSTR		; Backup range
10$:

	.ENDC	;EDT

	MOV	R1,R0		; R0 => Cursor
20$:
	MOVB	1(R0),(R0)+	; Shift string left
	CMP	R0,R2		; At EOL ?
	BLOS	20$		;  No : => 20$

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	30$		;  No : => 30$
	DEC	R2		; End of text
	CALL	DISPLY		; Rewrite line
	BR	40$		;
30$:

	.ENDC	;EDT

	CALL	UPDATE		; Rewrite line
	DEC	R2		; End of text
40$:
	CLRB	OLDFLG		; No old command
;
LOOP1:	JMP	LOOP		; => LOOP
;
	.SBTTL    MCE - DELRL  -- Delete from cursor to eol
;
DELRL:
	MOV	R1,R0		; R0 => Cursor
10$:
	CMP	R0,R2		; EOL ?
	BHIS	20$		;  Yes : => 20$
	CLRB	OLDFLG		; No old command
	MOVB	#BLNK,(R0)+	; Space
	BR	10$		;
20$:

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	30$		;  No : => 30$
	MOV	R1,R2		; Cursor at EOL
	CALL	DISPLY		; Rewrite line
	BR	40$		;
30$:

	.ENDC	;EDT

	CALL	UPDATE		; Rewrite line
	MOV	R1,R2		; Cursor at EOL
40$:
	BR	LOOP1		; => LOOP
;
;
	.SBTTL    MCE - DELRW  -- Delete right single word
;
DELRW:
	CMP	R1,R2		; At EOL ?
	BHIS	LOOP1		;  Yes : => LOOP
	MOV	R1,-(SP)	; Save cursor position
10$:
	MOVB	(R1)+,R0	; Get char
	CMPB	R0,#BLNK	; Space ?
	BNE	20$		;  No  : => 20$
	CMPB	R0,(R1)		; Is next one a space ?
	BEQ	30$		;  Yes : => 30$, delete it
20$:
	CALL	SRWORD		; Search word
	BCS	40$		;
30$:
	CMP	R1,R2		; At EOL ?
	BLO	10$		;  No : => 10$
40$:
	MOV	R1,R0		; R0 = Current cursor position
	MOV	(SP),R1		; R1 = Initial cursor position

;
DELWRD:

	.IF DF	EDT

	TST	SELSTR		; Selective range active ?
	BEQ	20$		;  No : => 20$
	CMP	R0,SELSTR	; Compare cursor with start of range
	BHI	10$		;  Right of start : => 10$
	SUB	R0,SELSTR	; Backup
	ADD	R1,SELSTR	;     range
	BR	20$		; => 20$
10$:
	CMP	R1,SELSTR	; New cursor left of start range ?
	BHIS	20$		;  No : => 20$
	MOV	R1,SELSTR	; Update start of range
20$:

	.ENDC	;EDT

	CMP	R0,R2		; EOL ?
	BHIS	30$		;  No  : => 30$
	MOVB	(R0),(R1)+	; Shift down
	MOVB	#BLNK,(R0)+	; Must be replaced by space
	BR	DELWRD		; => DELWRD
30$:
	MOV	R1,R2		; New end ptr
	MOV	(SP)+,R1	; Restore cursor
	CLRB	OLDFLG		; No old command
;
;
	.SBTTL    MCE - RETYPE -- Retype line
;
RETYPE:
	CALL	DISPLY		; Write buffer
	BR	LOOP1		; => LOOP
;
;
	.SBTTL    MCE - ENDLIN -- Jump to end of text
;
ENDLIN:

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	10$		;  No : => 10$
	MOV	R2,R1        	; End of text
	CALL	DISPLY		; Rewrite line
	BR	20$		;
10$:

	.ENDC	;EDT

	MOV	R1,ADR		; +
	MOV	R2,LEN		;  Write from cursor to end
	SUB	R1,LEN		;
	BEQ	20$		;
	CALL	IOW		; -
	MOV	R2,R1        	; End of text
20$:
	BR	LOOP1		; => LOOP
;
;
	.SBTTL    MCE - INSERT -- Insert one character
;
INSERT:
	CMP	R2,#CMDEND	; Still Room ?
	BHIS	LOOP1		;  No : => LOOP
	MOV	#CHAR,ADR	; +
	MOV	#1,LEN		;  Echo character
	CALL	IOW		; -
	CLRB	OLDFLG		; No old command
	BITB	#1,MODFLG	; Overstrike ?
	BEQ	10$		;  No : => 10$
	MOVB	CHAR,(R1)+	; Overstrike
	CMP	R1,R2		; At end ?
	BLOS	LOOP1		;  No : => LOOP
	MOV	R1,R2		; Increment end ptr
	BR	LOOP1		; => LOOP
10$:
	INC	R2		; No overstrike - shift
	MOV	R2,R0		; R0 => EOL
20$:
	MOVB	-(R0),1(R0)	; Shift string right
	CMP	R0,R1		; At cursor ?
	BHI	20$		;  No : => 20$
	MOVB	CHAR,(R1)+	; Insert new character

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	30$		;  No : => 30$
	CALL	DISPLY		; Rewrite line
	BR	40$		;
30$:

	.ENDC	;EDT

	CALL	UPDATE		; Rewrite line
40$:
	BR	LOOP1		; => LOOP
;
;
	.SBTTL    MCE - MOVWRD -- Move word
;
MOVWRD:
	CMP	R1,R2		; At EOL ?
	BLO	10$		;  No => 10$
	MOV	#CMDBUF,R1	; Set at begin
	BR	40$		; => 40$
10$:
	MOVB	(R1)+,R0	; Get char
	CMPB	R0,#BLNK	; Space ?
	BNE	20$		;  No  : => 20$
	CMPB	R0,(R1)		; Is next one a space ?
	BEQ	30$		;  Yes : => 30$
20$:
	CALL	SRWORD		; Search word
	BCS	40$		;
30$:
	CMP	R1,R2		; At EOL ?
	BLO	10$		;  No : => 10$
40$:
	CALL	DISPLY		;
	JMP	LOOP		; => LOOP

	.SBTTL
	.SBTTL	MCE ----------- *** Escape Sequences ***
	.SBTTL	MCE - ESCAP  -- Filter out Escape Sequences
;
ESCAP:
	.ENABL	LSB
;
	CALL	IO		; Read next char
	MOVB	CHAR,R0		; R0 = Character
	CMPB	R0,#'[		; <ESC>[  ?
	BEQ	ESCAP		;  Yes : => ESCAP
	CMPB	R0,#'O		; <ESC>O  ?
	BEQ	ESCAP		;  Yes : => ESCAP
	CMPB	R0,#'?		; <ESC>?  ?
	BEQ	ESCAP		;  Yes : => ESCAP
	CMPB	IOSTAT+1,#ESC	; <ESC><ESC> ?
	BNE	10$		;  No  : => 10$
	JMP	EXECNW		; Execute no-wait
10$:
	CMPB	R0,#'A		; <UP-ARROW> ?
	BNE	60$		;  No  : => 60$
;
; UP-ARROW .....
;
	.SBTTL    MCE - UP     -- Older command
UP:
	MOV	FIFPTR,R5	; Get Ptr of buffer
	BNE	20$		;  Defined : => 20$
	TST	FIFO+F.1ST	; Any entry ?
	BEQ	80$		;  No  : => 80$
	MOV	FIFO+F.LAST,FIFPTR
				; Take
	MOVB	FIFCNT,FIFPOI	;     newest entry
	BR	80$		; => 80$
20$:
	MOV	#FIFO+F.1ST,R5	; Find previous entry
30$:
	MOV	FI.NXT(R5),R5	; Next
	BNE	40$		;  Got one : => 40$
	TSTB	RNGFLG		; Ringbuffer ?
	BEQ	80$		;  No : => 80$
	CLRB	FIFPOI		; None
	BR	50$		; => 50$
40$:
	CMP	FI.NXT(R5),FIFPTR
				; Does this point to me ?
	BNE	30$		;  No  : => 30$
	DECB	FIFPOI		; One older
50$:
	MOV	R5,FIFPTR	; Found - load
	BR	80$		;            and display
;
60$:
	CMPB	R0,#'B		; <DOWN-ARROW> ?
	BNE	110$		;  No : => 110$
;
; DOWN-ARROW .....
;
	.SBTTL    MCE - DOWN   -- Newer command
;
DOWN:
	MOV	FIFPTR,R5	; Get Ptr of buffer
	BNE	70$		;  Defined : => 70$
	TST	FIFO+F.1ST	; Any entry at all ?
	BEQ	80$		;  No  : => 80$
	TSTB	RNGFLG		; Ringbuffer ?
	BEQ	90$		;  No : => 90$
	MOV	FIFO+F.1ST,FIFPTR
				; Take oldest
	MOVB	#1,FIFPOI	; Oldest
	BR	80$		; => 80$
70$:
	TST	FI.NXT(R5)	; Goto next buffer if any
	BEQ	CLRLIN		;  No more : => CLRLIN
	MOV	FI.NXT(R5),FIFPTR
				; Next
	INCB	FIFPOI		; One newer
80$:

	.IF DF	EDT

	CLR	SELSTR		; Clear start of select
	CLRB	SELFLG		; Clear ANSI-select flag

	.ENDC	;EDT

	CALL	GETFIF		; Load CMDBUF from FIFO
	BR	100$		; => 100$
;
; CLEAR LINE .....
;
	.SBTTL    MCE - CLRLIN -- Clear line
CLRLIN:
	CLRB	OLDFLG		; Clear flag
	CALL	CLEAR		; Clear FIFO pointers
90$:

	.IF DF	EDT

	CLR	SELSTR		; Clear start of select
	CLRB	SELFLG		; Clear ANSI-select flag

	.ENDC	;EDT

	CALL	CLRBUF		; Clear edit buffer
	CALL	DISPLY		;   and display prompt
100$:

	.IF DF	STATUS

	CALL	PRIST1		; Print status line

	.ENDC	;STATUS

	BR	LOOP2		; => LOOP
;
110$:
	CMPB	R0,#'C		; <RIGHT-ARROW> ?
	BNE	130$		;  No  : => 130$
;
; RIGHT-ARROW .....
;
	.SBTTL    MCE - RIGHT  -- Cursor right
;
RIGHT:
	CMP	R1,R2		; End of text ?
	BHIS	LOOP2		;  Yes : => LOOP
	MOV	R1,ADR		; Rewrite
	MOV	#1,LEN		;    Character
	CALL	IOW		;     at Cursor position
	INC	R1		; Shift cursor right

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	120$		;  No : => 120$
	CALL	DISPLY		; Rewrite line
120$:

	.ENDC	;EDT

	BR	LOOP2		; => LOOP
;
130$:
	CMPB	R0,#'D		; <LEFT-ARROW> ?
	BNE	150$		;  No : => 150$
;
; LEFT-ARROW .....
;
	.SBTTL    MCE - LEFT   -- Cursor left
;
LEFT:
	CALL	SPBACK		; Cursor left one space

	.IF DF	EDT

	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	140$		;  No : => 140$
	CALL	DISPLY		; Rewrite line
140$:

	.ENDC	;EDT

	BR	LOOP2		; => LOOP
;
150$:

	.IF DF	EDT

;
; EDT-KEYS .....
;
	TSTB	EDTFLG		; EDT Keys enabled ?
	BEQ	200$		;  No : => 200$
	CMPB	R0,#'M		; <ENTER> ?
	BNE	160$		;  No  : => 160$
	JMP	EXEC		; Execute
160$:
	CMPB	R0,#'P		; +
	BLO	170$		;  PFx range ?
	CMPB	R0,#'S		;   No : => 170$
	BHI	170$		; -
	ADD 	#<'z-'l-'P>,R0	; Relocate to table offset
	BR	180$		; => 180$
170$:
	CMPB	R0,#'l		; +
	BLO	200$		;  Within Keypad range ?
	CMPB	R0,#'y		;   No  : => 200$
	BHI	200$		; -
	SUB	#'l,R0		; Make
180$:
	ASL	R0		;  dispatchtable
	ASL	R0		;       offset
	TSTB	GOLDFL		; Gold ?
	BEQ	190$		;  No  : => 190$
	TST	(R0)+		; Point to "GOLD" entry
	CLRB	GOLDFL		; Clear "GOLD"
190$:
	JMP	@EDTTAB(R0)	; Do EDT function
200$:

	.ENDC	;EDT

;
; PF-KEYS .....
;
	SUB	#'P,R0		; Any PFn key ?
	BLO	210$		;  No : => VT2KEY
	CMP	R0,#'S-'P	; > PF4 ?
	BLOS	220$		;  Yes : => VT2KEY
210$:
	JMP	VT2KEY		;
220$:
	MOV	R0,-(SP)	; Save 0..3 for <PF1>..<PF4>
	MOV	#"PF,SAVBUF	; "PF' in SAVBUF
	ADD	#'1,R0		; Make ascii from PR-number
	MOV	R0,SAVBUF+2	; Insert in SAVBUF
	MOV	#3,PDSC+PX.LEN	; P0 Length
	MOV	#SAVBUF,PDSC+PX.ADR
				; P0 Address
	MOV	R2,-(SP)	; Save R2
	CALL	FNDCMD		; Find cmd
	MOV	(SP)+,R2	; Restore R2
	MOV	(SP)+,R0	; Restore R0
	BCC	FUNC		;  Entry found : => FUNC
;
	MOV	R2,R1		; Point to end of buffer
	ASL	R0		; Word offset
	ADD	R0,PC		; Branch
	BR	TRANSL		; <PF1>
	BR	RECALL		; <PF2>
	BR	PRINTC		; <PF3>
;                               ; <PF4>
;	Fall through to PRINTF, adjacency assumed
;
	.DSABL	LSB

	.SBTTL    MCE - PRINTF -- <PF4> Print FIFO buffer
;
PRINTF:
;
; <PF4> Print FIFO .....
;
	CALL	PRIFIF		; <PF4> Print whole FIFO
	BR	LOOP2		; => LOOP
;
;
LOOP2:	JMP	LOOP		; => LOOP
;
;
	.SBTTL    MCE - PRINTC -- <PF3> Print command buffer
;
PRINTC:
;
; <PF3> Print CMD Buffer
;
	CALL	PRICMD		; Print command buffer
	BR	LOOP2		; => LOOP
;
;
	.SBTTL    MCE - RECALL -- <PF2> Recall a command
;
RECALL:
;
; <PF2> - RECALL
;
	CALL	RECCMD		; Recall Command

	.IF DF	STATUS

	CALL	PRIST1		; Dispay status line

	.ENDC	;STATUS

	BR	LOOP2		; => LOOP
;
;
	.SBTTL    MCE - TRANSL -- <PF1> Translate a command
;
TRANSL:
;
; <PF1> Translate
;
	MOV	#CMDBUF,R0	; R0 => CMDBUF
	CMP	R2,R0		; Something in buffer ?
	BEQ	LOOP2		;  No : => LOOP
	INCB	NLOFLG		; Disable command load
	SUB	R0,R2		; Calculate Length
	MOV	R2,LEN		; Make length
	CALL	CMDCHK		; Command Translation
	MOV	LEN,R2		; Restore R2
	ADD	#CMDBUF,R2	; Point
	MOV	R2,R1		;   to end
	CALL	DISPLY		; Write line
	CLRB	NLOFLG		; Enable command load
	BR	LOOP2		; => LOOP
;
;
	.SBTTL    MCE - FUNC   -- Exectute function key commands
;
FUNC:
	MOV	R1,R0		; Find start of text
FUNCEX:
;
; Execute command in (R0)
;
	CALL	IOCR		; Clear current line
	CALL	GETBUF		; Load CMDBUF buffer
	MOV	#CMDBUF,R0	; R0 => CMDBUF
	SUB	R0,R2		; Calculate length
	MOV	R2,LEN		; Save it
	CALL	DETACH		; Detach terminal
	JMP	EXEC3		; Execute without display

	.IF DF  VT2XX

	.IF LT	MAXHLP-'A

	.SBTTL    MCE - PRVHLP -- Previous screen
	.SBTTL    MCE - NXTHLP -- Next screen

PRVHLP:
NXTHLP:
	MOV	#NOHTXT,ADR	; No help page
	MOV	#NOHLEN,LEN	;
	CALL	IOW		;   information
	JMP	RESTAR		;

	.IFF	;MAXHLP-'A
;
;
	.SBTTL    MCE - PRVHLP -- Previous screen
;
; Spawn "HELP MCE<page-1>"
;
PRVHLP:

	DECB	HPAGE		; Previous screen
	CMPB	HPAGE,#'A	; Low limit ?
	BHIS	10$		;  No => 10$
	MOVB	#' ,HPAGE	; Take
	CLRB	HPAG0		;    main help
10$:
	BR	HELPGO		; =>
;
;
	.SBTTL    MCE - NXTHLP -- Next screen
;
; Spawn "HELP MCE<page+1>"
;
NXTHLP:
;
	TSTB	HPAG0		; Was main help last ?
	BNE	10$		;  No : => 10$
	MOVB	#' ,HPAG0	; Sub topics
	MOVB	#'A-1,HPAGE	; Init for first subtopic
10$:
	INCB	HPAGE		; Next screen
	CMPB	HPAGE,#MAXHLP	; High limit ?
	BLOS	20$		;  No => 20$
	MOVB	#MAXHLP,HPAGE	; Take last help
20$:
	BR	HELPGO		; =>

	.ENDC	;MAXHLP-'A

	.ENDC	;VT2XX
;
;
	.SBTTL    MCE - HELP   -- Help key
;
; <HELP> or <CTRL/?>  Spawn "HELP MCE "
;
HELP:
	MOVB	#' ,HPAGE	; Take
	CLRB	HPAG0		;    main help
HELPGO:
	CALL	CLRSCR		; Clear screen
	MOV	#HLPTXT,R0	; Move HELP MCE into Buffer
	BR	FUNCEX		; => FUNCEX

	.IF DF	EDT

	.SBTTL    MCE - GOLD   -- "GOLD" Key
;
GOLD:
	INCB	GOLDFL		; Set "GOLD" flag
	BR	LOOP2		; => LOOP
;
;
	.SBTTL    MCE - SHVERS -- Version
;
SHVERS:
	MOV	#RESTAR,-(SP)	; RESTAR as return address
	CALLR	ICVERS		; Display Version
;
;
	.SBTTL    MCE - SHFREE -- Free pool
;
SHFREE:
	MOV	#RESTAR,-(SP)	; RESTAR as return address
	CALLR	ICFREE		; Display Free pool
;
;
	.SBTTL    MCE - EDTHLP -- Keypad Help
;
EDTHLP:
	TSTB	ANI+1		; Ansi Screen ?
	BEQ	10$		;  No : => 10$
	MOV	#SCRCLR,ADR	; Clear
	MOV	#SCRCLL,LEN	;    screen
	CALL	IOW		;
10$:
	MOV	#EDTTXT,R0	; EDT helptext
	BR	FUNCEX		; => FUNCEX
;
;
	.SBTTL    MCE - SELECT -- Select key
;
SELECT:
	MOV	R1,SELSTR	; Save of select address
	MOVB	ANI+1,SELFLG	; Set Ansi-select flag
	BEQ	10$		;  No Ansi : => 10$
	CALL	DISPLY		;
10$:
	BR	LOOP3		; => LOOP
;
;
	.SBTTL    MCE - RESET  -- Reset key
;
RESET:
	CLR	SELSTR		; Clear start of select
	CLRB	SELFLG		; Clear Ansi-select flag
	TSTB	ANI+1		; Test Ansi-flag
	BEQ	10$		;  No Ansi : => 10$
	CALL	DISPLY		;
10$:
	BR	LOOP3		; => LOOP
;
;
	.SBTTL    MCE - CUT    -- Put selective range in Paste buffer
;
CUT:
	TST	SELSTR		; Range active ?
	BEQ	40$		;  No : => 40$
	CMP	R1,SELSTR	; Compare cursor with start of range
	BEQ	40$		; - Equal => 40$
	BHI	10$		; - Right => 10$
	MOV	R1,R4		; R4 = Start
	MOV	SELSTR,R0	; R0 = End
	BR	20$		; => 20$
10$:
	MOV	SELSTR,R4	; R4 = Start
	MOV	R1,R0		; R0 = End
20$:
	MOV	R4,R1		; R1 => Start
	MOV	#PSTBUF,R3	; R3 => Save buffer
	CLRB	PSTLEN		; Clear length
	MOV	R4,-(SP)	; Save new cursor pos.
30$:
	MOVB	(R4)+,(R3)+	; Copy character
	INCB	PSTLEN		; Update length
	CMP	R4,R0		; At the end ?
	BLO	30$		;  No : => 30$
	CLR	SELSTR		; Range not active
	CLRB	SELFLG		; Clear Ansi-select flag
	JMP	DELWRD		; Delete range
40$:
	BR	LOOP3		; => LOOP
;
;
	.SBTTL    MCE - PASTE  -- Put Paste buffer in at cursor position
;
PASTE:
	CLR	R4		; R4 = Counter
	BISB	PSTLEN,R4	; R4 := length of PASTE string
	BEQ	60$		;  Zero : => 60$
	MOV	#PSTBUF,R5	; R5 => PSTBUF
	CLRB	OLDFLG		; No old command
;
10$:
	CMP	R2,#CMDEND	; Still Room ?
	BHIS	60$		;  No : => 60$
	MOV	R5,ADR		; +
	MOV	#1,LEN		;  Echo character
	CALL	IOW		; -
	BITB	#1,MODFLG	; Overstrike ?
	BEQ	20$		;  No : => 10$
;
	MOVB	(R5)+,(R1)+	; Overstrike
	CMP	R1,R2		; At end ?
	BLOS	40$		;  No : => Loop
	MOV	R1,R2		; Increment end ptr
	BR	40$		; => Loop
20$:
	INC	R2		; No overstrike - shift
	MOV	R2,R0		; R0 => EOL
30$:
	MOVB	-(R0),1(R0)	; Shift string right
	CMP	R0,R1		; At cursor ?
	BHI	30$		;  No : => 30$
	MOVB	(R5)+,(R1)+	; Insert new character
40$:
	SOB	R4,10$		;
;
	TSTB	SELFLG		; ANSI-Select active ?
	BEQ	50$		;  No : => 50$
	CALL	DISPLY		; Rewrite line
	BR	60$		;
50$:
	CALL	UPDATE		; Rewrite line
60$:
;
LOOP3:	JMP	LOOP		; => LOOP

	.ENDC	;EDT

	.SBTTL	MCE - VT2KEY -- VT2xx Functionkeys
;
VT2KEY:

	.IF DF VT2XX

	CMPB	TTP+1,#T.V2XX	; VT2xx ?
	BEQ	10$		;  Yes : => 10$
	JMP	TDVKEY		; => TDVKEY
10$:
;
; Check if function key  :
;
;		<ESC>[n~    	n   1..6
;		  or
;		<ESC>[nn~	nn  17..34
;

	MOVB	CHAR,R0		; R0 = character
	BIC	#177600,R0	;
	CMPB	R0,#'1		; +
	BLO	50$		;  1..6 ?
	CMPB	R0,#'6		;
	BHI	50$		; -
	SWAB	R0		; Char in highbyte
	BISB	#BLNK,R0	; Lowbyte = space
	MOV	R0,-(SP)	; Save it
	CALL	IO		; Next char.
	MOVB	CHAR,R0		; Take char.
	CMPB	R0,#'~		; Tilde ?
	BEQ	20$		;  Yes: => 20$
	CMPB	R0,#'0		; +
	BLO	40$		;  0..9 ?
	CMPB	R0,#'9		;
	BHI	40$		; -
	CLRB	(SP)		; Clear byte
	BISB	R0,(SP)		; Insert in word
	CALL	IO		; Next char.
	CMPB	CHAR,#'~	; Tilde ?
	BNE	40$		;  No: => 40$
20$:
	MOV	(SP)+,R0	; Retrieve word
	SWAB	R0		; Adjust
	MOV	#VT2TAB,R4	; R4 => VT2XX table
	MOV	#VT2LEN/6,R5	; R5 =  Table length
30$:
	CMP	R0,(R4)+	; Look for table entry
	BEQ	VT2FN		;  Found : => VT2FN
	CMP	(R4)+,(R4)+	; Next entry
	SOB	R5,30$		; Try next
	JMP	LOOP		;  Not found : => LOOP
40$:
	TST	(SP)+		; Flush word
50$:
	JMP	LOOP00		; => LOOP00
;
;
	.SBTTL	MCE - VT2FN  -- Check if VT2xx key to be translated
;
VT2FN:
;
; Check if to be translated
;
	MOVB	#'F,SAVBUF	; Insert
	MOVB	2(R4),SAVBUF+1	;   key
	MOVB	3(R4),SAVBUF+2	;     ident
	MOV	#3,PDSC+PX.LEN	; Assume P0 Length = 3
	CMPB	SAVBUF+2,#BLNK	; Blank ?
	BNE	10$		;  No : => 10$
	DEC	PDSC+PX.LEN	; P0 Length = 2
10$:
	JMP	PROCESS		; Go via table
;
;
	.SBTTL	MCE - VT2ESC -- Check for VT2XX <ESC><ESC>
;
; Typed VT2xx F11 (<ESC>) key; look for a second one
;
VT2ESC:
	CALL	IO		; Next char
	CMPB	IOSTAT+1,#ESC	; <ESC> ?
	BNE	20$		;  No : => 20$
	MOV	#VT2ESQ,R4	; R4 -> VT2XX ESC-SEQ.
	MOV	#VT2ESL,R5	; R5 = Length
10$:
	CALL	IO		; Next char.
	CMPB	CHAR,(R4)+	; Match ?
	BNE	20$		;  No : => 20$
	SOB	R5,10$		; Next
	JMP	EXECNW		; <ESC><ESC>
20$:
	JMP	LOOP		;

	.ENDC	;VT2XX

	.SBTTL	MCE - TDVTST -- TDV2230 Key support
;
TDVKEY:

	.IF DF TDV2XX

	CMPB	TTP+1,#200	; TDV2XX ?
	BNE	10$		;  No: => 10$
;
;	<ESC> O ...
;
; Test character is in the range of "T" - "Z" for F1..F7
;
	MOVB	CHAR,R4		; R4 = Character
	BIC	#177600,R4	;
	SUB	#'T,R4		; Normalize
	BLT	10$		;  Less then : => 10$
	CMPB	R4,#'Z-'T	; In range ?
	BGT	10$		;  No : => 10$
;
; Function ok: convert to string
;
	MOVB	#'F,SAVBUF	; Insert
	MOVB	R4,R0		;
	ADD	#'1,R0		;     key  code
	MOVB	R0,SAVBUF+1	;
;
	MOV	#2,PDSC+PX.LEN	; P0 Length
	ASL	R4		; Make word offset
	ADD	#TDVTAB,R4	; Add table address
	JMP	PROCES		;
10$:

	.ENDC	;TDV2XX

	JMP	LOOP		; => LOOP

    	.SBTTL
    	.SBTTL    MCE ----------- *** Command execution ***
    	.SBTTL    MCE - DELAY  -- Detach and delay
;
DELAY:
	CALL	IOCRLF		; Print <CR><LF>
	CALL	DETACH		; Detach terminal
	MRKT$S	#EFN,#10.,#2	; Wait
	DIR$	#STOPIO		;     10 seconds
	JMP	RESTAR		; => RESTAR
;
;
    .SBTTL    MCE - SAVE   -- Save command without execution
;
SAVE:
	INCB	NEXFLG		; Don't execute
	BR	EXEC1		; => EXEC1
;
    .SBTTL    MCE - EXELEA -- Execute and leave pointer
;
EXELEA:
	INCB	LEAFLG		; Don't clear pointers
	BR	EXEC1		; => EXEC1
;
;
    .SBTTL    MCE - EXECNW -- Execute command no-wait
;
EXECNW:
	CLR	WAITFL		; Clear EVF
	BR	EXEC1		; => EXEC1
;
;
    .SBTTL    MCE - EXEC   -- Execute command
;
EXEC:
	.ENABL	LSB

	MOV	#1,WAITFL	; EVF = 1
EXEC1:
	CALL	IOCR		; Print <CR>
	CALL	DETACH		; Detach terminal
	SUB	#CMDBUF,R2	; Calculate Length
	MOV	R2,LEN		; Store
	CALL	SUPRES		; Ignore leading blanks
	BCS	50$		;  Empty ? => 50$
10$:
	TSTB	SOLFLG		; Save old commands ?
	BNE	20$		;  Yes : => 20$
	TSTB	OLDFLG		; Old command ?
	BNE	30$		;  Yes : => 30$
20$:
	CALL	LDFIF		; Load into FIFO
30$:
	TSTB	LEAFLG		; Leave pointers ?
	BNE	EXEC2		;  Yes : => EXEC2
	CALL	CLEAR		; Clear pointers
	TSTB	NEXFLG		; Execute ?
	BNE	50$		;  No : => 50$
EXEC2:
	CALL	CMDCHK		; Check for command Translation
	BCS	50$		; Nothing to execute
EXEC3:

	.IF DF	TMOTIM

	CLRB	TMOCNT		; Disable timeouts (until next IO)

	.ENDC	;TMOTIM

	CALL	SUPRR0		; Ignore leading blanks ( Start at R0 )
	BCS	50$		; If C set : Empty command
;
; R0  => First non blank character
; LEN =  Length of command
;
	CALL	INTERN		; Internal command , BYE or LOG ?
	BCC	50$		; If C clear: no command for CLI
	CALL	DOEXEC		; Excute command in buffer CMDBUF
	TST	WAITFL		; Wait ?
	BNE	40$		;  Yes : => 40$
	INC	WAITFL		; Make flag #1
	MRKT$S	WAITFL,#20.,#1	; Allow task to run
40$:
	STSE$S	WAITFL		; Stop until done
50$:
	JMP	RESTAR		; => RESTAR

	.DSABL	LSB
;
;
	.SBTTL	MCE - EXAST  -- Task exit ast
;
EXAST:
;
; Change STOP to WAIT
;
	MOV	#IO.KIL,CODE	;; Kill
	CALL	IO		;;    pending read
	MOV	WAITIO,STOPIO	;; Change DIC-code
	DIR$	#STOPIO		;; Wait for I/O
;
;
	.SBTTL	MCE - EXIT   -- Task exit
;
EXIT:

	.IF NDF SILENT

	MOV	#ENDTXT,R0	; Exit
	CALL	IOMSG		;   message

	.ENDC	;SILENT

;
	.SBTTL	MCE - EXITI  -- Immediate Task exit
;
EXITI:

	.IF DF	STATUS

	TSTB	ANI+1		; Ansi Screen ?
	BEQ	10$		;  No : => 10$
	MOV	#STACLR,ADR	; Clear 
	MOV	#STACLN,LEN	;  Statusline
	CALL	IOW		;
10$:

	.ENDC	;STATUS

	CALL	DETACH		; Detach terminal
	EXIT$S			; Exit

	.SBTTL
	.SBTTL  MCE ----------- *** Internal Command Handling ***
	.SBTTL	MCE - INTERN -- Check for internal commands

; Check if the command (AFTER translation) is BYE, LOG[out] or an
; internal command starting with the verb 'MCE '.
; To check for the special commands after translation offers the
; possibility to define any other string for exit/bye.
; (E.g.: LOGOF*F := BYE, BYE := LOGOUT )
; INTERN returns C set, if no internal command, i.e. the buffer R0 =>
; with length LEN has to be submitted to the CLI.
; C clear on return, if internal command found, no CLI submit.
;
.MACRO	CMPBNE	Source,Char,Labl
	MovB	Source,R3
	BicB	#40,R3
	CmpB	R3,#''Char
	Bne	Labl
.ENDM	CMPBNE
;
.MACRO	CMPBEQ	Source,Char,Labl
	MovB	Source,R3
	BicB	#40,R3
	CmpB	R3,#''Char
	Beq	Labl
.ENDM	CMPBEQ
;
INTERN:
;
; To be recognised as an internal command, at least 3 characters
; must be present.
; Internal commands trapped are:
; BYE        : the MCR RSX logout command
; LOG[OUT]   : the DCL RSX logout command
; MCE action : MCE internal actions
;
	CMP	LEN,#3		; Length in range ?
	BLT	40$		;  No : => 40$

	.IF DF	CLISUP

	CMP	CLINAM,#^RDCL	; In DCL ?
	BNE	10$		;  No : => 10$
	CMPBNE	 (R0),L,10$	; +
	CMPBNE	1(R0),O,10$	;  LOG ?
	CMPBEQ	2(R0),G,20$	; -
10$:

	.ENDC	;CLISUP

	CMPBNE	 (R0),B,30$	; +
	CMPBNE	1(R0),Y,30$	;  BYE ?
	CMPBNE	2(R0),E,30$	; -
20$:
	MOV	#^RMCR,TASK	; Force MCR...
	MOV	#BYETXT,R0	; Command to spawn is "BYE"
	CALL	GETBUF		; Copy in CMDBUF
	MOV	#CMDBUF,R0	; R0 => CMDBUF
	MOV	#3,LEN		; "BYE" = 3 char.
	CLR	WAITFL		; Do not wait
	CALL	DOEXEC		; Submit "BYE" to MCR...
	CALLR	EXITI		; Immediate task exit
30$:
	CMPBNE	 (R0),M,40$	; +
	CMPBNE	1(R0),C,40$	;  MCE ?
	CMPBEQ	2(R0),E,50$	; -
40$:
	SEC			; No internal command trapped
	RETURN			;
;
; Internal command strings must not be less than 8 characters in length
; Ignore anything else
;
50$:
	MOV	#INTCMD,R1	; Point to internal command table
	ADD	#3,R0		; Point
	SUB	#3,LEN		;    behind "MCE"
	CALL	SUPRR0		; Suppress spaces
	BCS	150$		; Empty => 150$
	CMP	LEN,#4		; At least 4 characters left ?
	BLT	150$		;  No : => 150$
	CLR	R3		; +
	BISB	(R0)+,R3	;
	SWAB	R3		;
	BISB	(R0)+,R3	;   R3 := Upcased 1st 2 characters
	SWAB	R3		;
	BIC	#"  ,R3		; -
	CLR	R4		; +
	BISB	(R0)+,R4	;
	SWAB	R4		;
	BISB	(R0)+,R4	;   R4 := Upcased 2nd 2 characters
	SWAB	R4		;
	BIC	#"  ,R4		; -
	SUB	#4,LEN		;    behind "MCE XXXX"
60$:
;
; Look for Verb in Table .....
;
	TST	(R1)		; End of table reached ?
	BEQ	150$		;  Yes : => 150$
	CMP	R3,(R1)+	; First 2 characters match ?
	BEQ	70$		;  Yes : => 70$
	ADD	#4,R1		; Point to next table entry
	BR	60$		; Look ahead
70$:
	CMP	R4,(R1)+	; Second 2 characters match ?
	BEQ	80$		; If eq Yes: action verb match
	TST	(R1)+		; Point to next table entry
	BR	60$		; Look ahead
80$:
	CALL	@(R1)		; EXECute internal command
;
	BCS	150$		;  Not OK ? => 150$
	TSTB	SINFLG		; Save internal command ?
	BNE	140$		;  Yes : => 140$

	.IF DF	FILE

	TSTB	FILREX		; Read or Replace being processed ?
	BNE	90$		;  Yes : => 90$
	TSTB	FILINP		; File input ?
	BNE	140$		;  Yes : => 140$
90$:
	CLRB	FILREX		; Clear flag

	.ENDC	;FILE

	MOV	FIFO+F.1ST,R0	; R0 => First entry
	BEQ	140$		; No entries : => 140$
	MOV	FIFO+F.LAST,R2	; R2 => Last entry
	CMP	R0,R2		; 1st = last ?
	BEQ	120$		;  Yes : => 120$
100$:
	CMP	FI.NXT(R0),R2	; Next = Last ?
	BEQ	110$		;  Yes : Delete this one
	MOV	FI.NXT(R0),R0	; Next
	BR	100$		; => 100$
110$:
	MOV	R0,FIFO+F.LAST	; New last
	CLR	(R0)		; Last
	MOV	#FREE,R0	; R0 => Free listhead
	MOV	FI.LEN(R2),R1	; R1 = Length
	CALL	$RLCB		; Release block
	BR	130$		; => 130$
120$:
	MOV	#FIFO+F.1ST,R0	; R0 => Header
	CALL	FRENT		; Free entry
130$:
	DECB	FIFCNT		; One less
140$:
	CLC			; Success
	RETURN			;
150$:
	MOV	#ERRTXT,R0	; Error
	CALLR	IOMSG		;   Message

	.SBTTL	MCE - ICCLEA -- Clear
;
; Clear FIFO
;
ICCLEA:
;
	MOV	MAXF,-(SP)	; Save maxFIFO
	CLR	MAXF		; Clear
	CALL	CLEFIF		;    FIFO
	MOV	(SP)+,MAXF	; Restore maxFIFO
	RETURN			;
;
;
	.SBTTL	MCE - ICCMSZ -- Cmsz x
;
; CMD Size
;
ICCMSZ:
;
	MOV	#MINC,R5	; R5 => Destination
	CALLR	VALUE		;
;
;
	.SBTTL	MCE - ICECHO -- Echo on/off
;
; Echo On/Off
;
ICECHO:
;
	MOV	#ECHFLG,R3	; R3 => Flag
	CALLR	ONOFF		; => On / Off
;
;
	.SBTTL	MCE - ICFISZ -- Fisz x
;
; FIFO size
;
ICFISZ:
;
	MOV	#MAXF,R5	; R5 => Destination
	CALL	VALUE		; Get value
	BCC	10$		;
	RETURN			;
10$:
	CALLR	CLEFIF		; Clear fifo
;
;
	.SBTTL	MCE - ICFREE -- Free
;
; Free poolspace
;
ICFREE:
	MOV	#POOL,R5	; Point to pool raw data buffer
	CLR	(R5)+		; Clear number of fragments
	CLR	(R5)+		; Clear total pool
	CLR	(R5)		; Clear biggest hole
	MOV	FREE,R4		; Get address of pool listhead
	BEQ	30$		;  No blocks : => 30$
10$:
	TST	(R4)+		; R4 => Size
	CMP	(R5),(R4)	; This size > stored ?
	BHIS	20$		;  No : => 20$
	MOV	(R4),(R5)	; Set new max
20$:
	ADD	(R4),-(R5)	; Add this space to total
	INC	-(R5)		; Increment number of pool fragments
	CMP	(R5)+,(R5)+	; Point R5 to end of raw data buffer
	MOV	-(R4),R4	; Get addr of next block
	BNE	10$		; If ne more to examine
30$:
	MOV	#POOLDT,R0	; POOL message
	MOV	#3,R4		; 3 words to convert
40$:
	MOV	(R5),R1		; Binary value
	MOV	#20012,R2	; Parms.
	CALL	$CBTA		; Convert
	MOVB	#'.,(R0)+	; Decimal
	MOVB	#':,(R0)+	; Terminate
	TST	-(R5)		; Next
	SOB 	R4,40$		;   word
;
	CLRB	-(R0)		; ASCIZ
	MOV	#POOLTX,R0	; R0 => Message
	CALLR	IOMSG		; Write and return
;
;
	.SBTTL	MCE - ICINSE -- Auto Insert on/off
;
; Auto insert On/Off
;
ICINSE:
;
	MOV	#INSFLG,R3	; R3 => Flag
	CALL	ONOFF		; => On / Off
	BCS	10$		;  Error : => 10$
	TSTB	(R3)		; Set ?
	BEQ	10$		;  No : => 10$
	CLRB	OVSFLG		; Clear auto overstrike
10$:
	RETURN			;
;
	.IF DF	EDT

;
	.SBTTL	MCE - ICKEYP -- Keypad on/off
;
; Keypad On/Off
;
ICKEYP:
;
	MOV	#EDTFLG,R3	; R3 => Flag
	CALLR	ONOFF		; => On / Off

	.ENDC	;EDT

;
	.SBTTL	MCE - ICLIST -- LIST
;
; FIFO is LIST
;
ICLIST:
;
	CLRB	RNGFLG		; Indicate LIST
	RETURN			;
;
;
	.SBTTL	MCE - ICOVER -- Auto Overstrike on/off
;
; Auto overstrike On/Off
;
ICOVER:
;
	MOV	#OVSFLG,R3	; R3 => Flag
	CALL	ONOFF		; => On / Off
	BCS	10$		;  Error : => 10$
	TSTB	(R3)		; Set ?
	BEQ	10$		;  No : => 10$
	CLRB	INSFLG		; Clear auto insert
10$:
	RETURN			;

	.IF DF	EXTNPR

	.SBTTL	MCE - ICPROM -- Prompt on/off
;
; Prompt On/Off
;
ICPROM:
;
	MOV	#PRMFLG,R3	; R3 => Flag
	CALLR	ONOFF		; => On / Off

	.ENDC	;PRMFLG

;
	.SBTTL	MCE - ICPURG -- Purge
;
; Delete current translation table
;
ICPURG:
;
	MOV	#TRNB+F.1ST,R0	; Queue header for Transtation table
	CALL	FRENT		; Delete table entry
	BCS	ICPURG		; More entries ? : => ICPURG
	RETURN			;
;

	.IF DF 	FILE

	.SBTTL	MCE - ICREAD -- Read
;
; read commands from file specified
;
ICREAD:
;
	MOV	R0,-(SP)	; Save pointer
	TSTB	FILINP		; Is a file open ?
	BEQ	10$		; If eq no: just open new
;
; Close a file currently open, i.e. 'MCE READ' issued from
; inside a definition is equivalent to a 'MCE CHAIN' command
;
	CALL	FILCLO		; Close current file
10$:
	MOV	(SP)+,R1	; Point behind 'MCE XXXX'
	MOV	LEN,R2		; Length of command
	CALL	GETFIL		; Get new file name
	BCS	20$		; Error => 20$
	CALL	FILOP1		; Read file(s)
	INCB	FILREX		; Read or Replace being processed
20$:
	CALLR	SUCCES		; Always success

	.SBTTL	MCE - ICREPL -- Replace
;
ICREPL:
	MOV	R0,-(SP)	; Save pointer
	CALL	ICPURG		; Delete current translation table
	MOV	(SP)+,R0	; Restore pointer
	BR	ICREAD		;

	.ENDC	;FILE

;
	.SBTTL	MCE - ICRING -- Ring
;
; FIFO is RING buffer
;
ICRING:
	MOVB	#1,RNGFLG	; Indicate RING
	CALLR	SUCCES		;
;

	.IF DF	STATUS

	.SBTTL	MCE - ICSTAT -- Status [ on/off ]
;
; Status
;
ICSTAT:
;
	CALL	DELSEA		; Search for delimitor
	TST	LEN		; Left ?
	BNE	30$		;  Yes : => 30$
	CALL	STAFIL		; Fill statusline
	MOV	#STATX3,ADR	; Address
	MOV	#STALN3,LEN	; Length
	CALLR	IOW		;
30$:
	TSTB	ANI+1		; ANSI Terminal ?
	BEQ	20$		;  No : => 20$
	MOV	#STAFLG,R3	; R3 => Flag
	MOVB	(R3),R2		; Old status
	MOV	R2,-(SP)	; Save it
	CALL	ONOFF		; => On / Off
	MOV	(SP)+,R2	; Restore
	BCS	20$		;
	TSTB	STAFLG		; Off ?
	BNE	20$		;  No : => 20$
	TSTB	R2		; Was it on ?
	BEQ	20$		;  no : => 20$
	MOV	#STACLR,ADR	; Address
	MOV	#STACLN,LEN	; Length
	CALLR	IOW		; Clear status line
20$:
	RETURN			;

	.ENDC	;STATUS

;
	.SBTTL	MCE - ICSVIN -- Intern on/off
;
; Save internal commands On/Off
;
ICSVIN:
;
	MOV	#SINFLG,R3	; R3 => Flag
	CALLR	ONOFF		; => On / Off
;
;
	.SBTTL	MCE - ICSVOL -- Old commands on/off
;
; Save old commands On/Off
;
ICSVOL:
;
	MOV	#SOLFLG,R3	; R3 => Flag
	CALLR	ONOFF		; => On / Off
;
;
	.SBTTL	MCE - ICVERS -- Version
;
; Show version
;
ICVERS:
;
	MOV	#STRTXT,R0	; Print
	CALLR	IOMSG		;   Startup message

	.SBTTL	MCE - CLEFIF -- Clear Fifo
;
CLEFIF:
	CMPB	FIFCNT,MAXF	; Maximum reached ?
	BLOS	10$		;  No : => 10$
	CALL	CLFIFI		; Release first entry
	BCS	CLEFIF		; More ? : => CLEFIF
10$:
	CALLR	SUCCES		;
;
;
	.SBTTL	MCE - DELSEA -- Delimitter search
;
DELSEA:
	TST	LEN		; Length
	BEQ	20$		; Zero : => 20$
10$:
	CMPB	(R0),#BLNK	; Start with a Space ?
	BEQ	20$		;  Yes : => 20$
	INC	R0		; Next := First
	DEC	LEN		; One less
	BNE	10$		; Not empty : => 10$
20$:
	RETURN			;


	.SBTTL	MCE - ONOFF  -- Check for ON or OFF in command
;
; ON/OFF
;
;  R3 => Byte flag
;
ONOFF:
	CALL	DELSEA		; Search for delimitor
	CALL	SUPRR0		; Suppress
	BCS	NOSUCC		;  Empty : => NOSUCC
	BICB	#40,(R0)	; Upcase
	CMPB	(R0)+,#'O	; 'O ?
	BNE 	NOSUCC		;  No : => NOSUCC
	BICB	#40,(R0)	; Upcase
	CMPB	(R0),#'N	; 'N ?
	BNE 	30$		;  No : => 30$
	INCB	(R3)		; Set flag
	BR	SUCCES		;
30$:
	CMPB	(R0)+,#'F	; 'F ?
	BNE 	NOSUCC		;  No : => NOSUCC
	BICB	#40,(R0)	; Upcase
	CMPB	(R0),#'F	; 'F ?
	BNE 	NOSUCC		;  No : => NOSUCC
	CLRB	(R3)		; Reset flag
;
SUCCES:
	CLC			; Succes
	RETURN			;
NOSUCC:
	SEC			; Not Succes
	RETURN			;
;
;
	.SBTTL	MCE - VALUE  -- Convert value of MCE XXXX nnn command
;
VALUE:
	CALL	DELSEA		; Search for delimitor
	CALL	SUPRR0		; Suppress
	BCS	NOSUCC		;  Empty : => NOSUCC
	CALL	$CDTB		; Convert
	TST	R1		; Empty ?
	BEQ	NOSUCC		;  Yes : => NOSUCC
	CMP	R1,#99.		; Too large ?
	BHI	NOSUCC		;  Yes : => NOSUCC
	MOV	R1,(R5)		; Insert value
	BR	SUCCES		;

	.SBTTL
	.SBTTL    MCE ----------- *** Subroutines ****
	.SBTTL    MCE - CLEAR  -- Clear flags and pointers
;
CLEAR:
;
	CLR	FIFPTR 		; Clear
	CLRB	FIFPOI		;   pointers
	RETURN			;
;
;
	.SBTTL    MCE - CLFIFI -- Clear first entry of FIFO buffer
;
CLFIFI:
	MOV	#FIFO+F.1ST,R0	; This header
	CALL	FRENT		; Free entry from queue
	BCC	10$		;  Empty : => 10$
	DECB	FIFCNT		; Adjust count
10$:
	RETURN			;
;
;
	.SBTTL	MCE - CLRBUF -- Clear Buffer CMDBUF
;
CLRBUF:
	MOV	#CMDBUF,R1	; R1 => CMDBUF
	MOV	R1,R2		; R2 => CMDBUF
	MOV	#CMDSIZ,R5	; R5 =  CMDSIZ
10$:
	MOVB	#BLNK,(R1)+	; Reset CMDBUF to blank
	SOB	R5,10$		; Go back if not the end
	MOV	R2,R1		; R1 => CMDBUF
	RETURN			;
;
;
	.SBTTL	MCE - CLRSCR -- Clear Screen
;
CLRSCR:
	TSTB	ANI+1		; Ansi Screen ?
	BEQ	10$		;  No : => 10$
	MOV	#SCRCLR,ADR	; Clear
	MOV	#SCRCLL,LEN	;   screen
	CALLR	IOW		;
10$:
	SEC			; Not cleared
	RETURN			;

	.SBTTL	MCE - CMDCHK -- Check for Command definition
;
; Check for Command definition
; or replace first command word by stuff defined in command buffer
; P1..P8 may also be replaced
;
;   R0  => Buffer
;   LEN =  Length
;
;
;
CMDCHK:
	MOV	R0,-(SP)	; Save pointer in CMDBUF
	MOV	LEN,-(SP)	; Save initial length
;
	MOV	#CDSC,R1	; +
	MOV	#CLL/2,R2	;
10$:				; Clear scratch buffer
	CLR	(R1)+		;
	SOB	R2,10$		; -
;
	MOV	R0,R1		; R1 => Source Buffer
	MOV	LEN,R2		; R2 =  Length
	MOV	#SAVBUF,R3	; R3 => Destination Buffer
	MOV	#PDSC,R5	; R5 => Current Parameter Descriptor
	MOV	R3,PX.ADR(R5)	; Start of P0
20$:
;
; Store single char
;
	MOVB	(R1)+,R0	; R0 = char
	CALL	CNVUPC		; Convert and check for delimiter
	MOVB	R0,(R3)+	; Store char in SAVBUF
	BCC	60$		;  No delimiter found : => 60$
30$:
	CMPB	(R1),#BLNK	; Another Space ?
	BNE	40$		;  No : => 40$
	INC	R1		; Next
	SOB	R2,30$		;   Character
;
	BR	80$		; End : => 80$
40$:
;
; To next Pn
;
	CMP	R5,#PDSC	; Is this P0 ?
	BNE	50$		;  No  : => 50$
	MOV	R3,CDSC+PX.ADR	; Load start Address of remainder
	DEC	CDSC+PX.ADR	; Point to space
50$:
	CMP	R5,#8.*PX.SIZ+PDSC
				; Already on P8 ?
	BHIS	60$		;  Yes : => 60$, put it all there
	ADD	#PX.SIZ,R5	; Next Parameter
	MOV	R3,PX.ADR(R5)	; Start address
	BR	70$		; Do not count
60$:
;
; No delimiter found
;
	INC	PX.LEN(R5)	; Count char
70$:
	SOB	R2,20$		; Next character
80$:
;
	MOV	R3,LEN		; Calculate
	SUB	#SAVBUF,LEN	;  Compressed length
	MOV	CDSC+PX.ADR,R2	; Remainder Descriptor defined ?
	BEQ	90$		;  No => 90$
	SUB	R2,R3		; Calculate length
	MOV	R3,CDSC+PX.LEN	; Store length
;
; Now everything is moved into SAVBUF
; Check if we define a new command ":=" in P1
;
90$:
	MOV	#PDSC+PX.SIZ,R2	; R2 => P1 descr
	CMP	(R2)+,#2	; Correct length ?
	BNE	100$		;  No => 100$
	MOV	(R2),R2		; R2 => string
	CMPB	(R2)+,#':	; +
	BNE	100$		;
	CMPB	(R2)+,#'=	;   ":="
	BNE	100$		; -
	CALL	NEWCMD		; Match found
	SEC			; Nothing to execute
	BR	110$		; =>
;
; Try find an entry in the commandbuffer with key P0
;
100$:
	CALL    FNDCMA		; Check in table
	BCC	120$		;  Entry found => 120$
	CLC			; Indicate success
110$:
	MOV	(SP)+,LEN	; Restore initial length
	MOV	(SP)+,R0	; Restore pointer in CMDBUF
	RETURN			;
120$:
;
; Entry found, R1 points to Text
;
	MOV	#CMDBUF,R2	; R2 => Destination
130$:
;
; Assemble buffer CMDBUF
;
	MOVB	(R1)+,R0	; Next char
	BEQ	150$		;  All done : => 150$
	CMPB	R0,#''		; Could it be 'Pn' ?
	BNE	140$		;  No  : => 140$
	CALL	SUBST		; Check it and substitute if necessary
	BCS	130$		; Already substituted : => 130$
140$:
	MOVB	R0,(R2)+	; Store character in CMDBUF
	BR	130$		; Next char from CMD Buf
150$:
;
; Whole buffer moved to CMDBUF
;
	TSTB	CFETCH		; Buffer already feched ?
	BLT	160$		;  Yes : => 160$
	MOV	#CDSC,R1	; This descriptor to append
	CALL	STORE		; Store
160$:
;
; All done, execute new command
;
	MOV	#CMDBUF,R0	; R0 => CMDBUF
	SUB	R0,R2		; Calculate new length
	MOV	R2,LEN		;  and store
	CMP	(SP)+,(SP)+	; Flush pointer and length
	TSTB	OVMSG		; Buffer overflow ?
	BEQ	170$		;  No : => 170$
	MOV	#TOOLON,R0	; Give
	CALL	IOMSG		;   message
	SEC			; Not success
170$:
	RETURN			;

	.SBTTL	MCE - CNVUPC -- Convert to uppercase
;
; Convert to upper case, CC-C set if delimiter
;
CNVUPC:
	CMPB	R0,#'A+40	; Convert to upper case
	BLO	10$		;
	CMPB	R0,#'Z+40	;
	BHI	10$		;
	BICB	#40,R0		; Convert to upper
10$:
	CMPB	R0,#BLNK	; Delimter ?
	SEC			;
	BEQ	30$		; Its a delimiter
20$:
	CLC			; Character within string
30$:
	RETURN			;

	.IF DF	STATUS

;
	.SBTTL	MCE - CONV   -- Convert 2 characters -> ASCII
;
CONV:
	MOV	#11012,R2	; Convert 2 chars
	CALLR	$CBTA		; Convert

	.ENDC	;STATUS
;
;
	.SBTTL	MCE - DETACH -- Detach terminal
;
DETACH:

	.IF DF	EDT

	TSTB	EDTFLG		; EDT Keys enabled ?
	BEQ	10$		;  No : => 10$
	MOV	LEN,-(SP)	; Save length
	MOV	#NUMTXT,ADR	; Numeric keypad
	MOV	#2,LEN		; Length
	CALL	IOW		; Write
	MOV	(SP)+,LEN	; Restore length
10$:

	.ENDC	;EDT

	MOV	#IO.DET,CODE	; Detach
	CALLR	IO		;     the terminal
;
;
	.SBTTL	MCE - DISPLY -- Rewrite whole Line
;
DISPLY:
	TSTB	ANI+1		; Ansi Screen ?
	BNE	20$		;  Yes : => 20$
	CMP	ADR,PROMLF     	; Just new Line written ?
	BNE	10$		;  No  : => 10$
	CMP	LEN,#2		; Something written ?
	BLE	20$		;  No  : => 20$
10$:
	MOV	PROMLF,ADR	; Line with <LF><CR>
	BR	30$		; => 30$
20$:
	MOV	PROMPT,ADR      ; Line with <CR>
30$:
	MOV	R2,LEN		; Calculate
	SUB	ADR,LEN		;       length
	MOV	R0,-(SP)	; Save R0
	MOV	R2,R0		; R0 => EOL
	MOVB	#ESC,(R0)+	; Append
	MOVB	#'[,(R0)+	;   Clear till EOL
	MOVB	#'K,(R0)+	;       Esc sequence
	TSTB	ANI+1		; Ansi Screen ?
	BEQ	40$        	;  No  : => 40$
	ADD	#3,LEN		; Make Escseq visible
40$:

	.IF DF	EDT

	TST	SELSTR		; Select active ?
	BEQ	70$		;  No : => 70$
	CMP	R1,SELSTR	; Compare cursor to start of sel range
	BEQ	70$		;  - Equal => 70$
	MOV	R3,-(SP)	; Save R3
	MOV	R4,-(SP)	; Save R4
	BLO	50$		;  - Cursor left of start
	MOV	SELSTR,R3	; Start
	MOV	R1,R4		; End
	BR	60$		; => 60$
50$:
	MOV	R1,R3		; Start
	MOV	SELSTR,R4	; End
60$:
	CALL	WRISEL		; Write selective range
	MOV	(SP)+,R4	; Restore R4
	MOV	(SP)+,R3	; Restore R3
70$:

	.ENDC	;EDT

	CALL	IOW		; Write
	MOVB	#BLNK,-(R0)	; +
	MOVB	#BLNK,-(R0)	;  Flush Escseq
	MOVB	#BLNK,-(R0)	; -
	MOV	(SP)+,R0	; Restore R0
	MOV	#BS,ADR		; +
	MOV	R2,LEN		;
	SUB	R1,LEN		;  Restore Cursor
	BEQ	80$		;
	CALLR	IO		; -
80$:
	RETURN			;

	.SBTTL	MCE - DOEXEC -- Submit command to CLI
;
DOEXEC:
;
; R0  => First non blank character
; LEN =  Length of command
;

	.IF DF	COMPND

	MOV	R0,R3		; R0 => start of command
	MOV	LEN,R4		; R4 =  Length
	INC	WAITFL		; Always wait
10$:
	MOV	R4,R1		; R1 =  Length
	BEQ	60$		; Empty : => 60$
	CLR	R2		; Compute length here
20$:
	CMPB	(R3)+,#'&	; Ampersand here ?
	BNE	30$		;  No : => 30$
	CMPB	-2(R3),#BLNK	; Preceeded by a space ?
	BEQ	40$		;  Yes : => 40$
30$:
	INC	R2		; Count command length
	SOB	R1,20$		; End of story ?
;
	MOV	R2,LEN		; Load new length
	DEC	WAITFL		; Restore wait condition
	CALLR	DOEXE1		; Process last or only command
40$:
	MOV	R2,LEN		; Load new length
	INC	R2		; Account for &-sign
	SUB	R2,R4		; Compute unused string length
	BEQ	50$		;  Empty ? Yes : => 50$
;
; Execute .....
;
	CALL	DOEXE1		; Go execute it
	STSE$S	WAITFL		; Stop for execution
	CMP	EXSTAT,#EX$SUC	; Successfull ?
	BEQ	50$		;  Yes : => 50$
;
; Message with exit status .....
;
	MOV	R0,-(SP)	; Save R0
	MOV	LEN,-(SP)	; Save Length
	MOV	#EXSTDA,R0	; R0 => ASCII buffer
	MOV	EXSTAT,R1	; R1 =  Value
	MOV	#27012,R2	; R2 =  Parameters
	CALL	$CBTA		; Convert to ASCII
	MOV	#EXSTMS,ADR	;
	MOV	#EXSTML,LEN	;
	CALL	IOW
	MOV	(SP)+,LEN	; Restore Command length
	MOV	(SP)+,ADR	; Restore Command pointer
	CALLR	IOW
50$:
	MOV	R3,R0		; Set to unused string
	BR	10$		; Go for next part
60$:
	RETURN			;

	.ENDC	;COMPND

DOEXE1:
;
	.IF DF	COMPND

	CALL	SUPRR0		; Suppress Leading spaces

	.ENDC	;COMPND

	TSTB	ECHFLG		; Echo ?
	BEQ	10$		;  No : => 10$
	MOV	LEN,-(SP)	; Save length
	CALL	IOCRLF		; New line
	MOV	(SP),LEN	; Get length
	MOV	R0,ADR		; Address of command
	CALL	IOW		; Write command
	CALL	IOCR		; New line
	MOV	(SP)+,LEN	; Restore length
10$:
;
; ***  EXECUTE COMMAND ***
;
	MOV	R0    ,SPAWN+S.PWCA
	MOV	LEN   ,SPAWN+S.PWCL
	DIR$	#SPAWN		;
	RETURN			;

	.IF DF	FILE

;
	.SBTTL	MCE - FILCLO -- Close current MCEINI file
;
FILCLO:
	CLRB	FILINP		; No file input
	CLOSE$	#FDBIN		; Close inputfile
	TST	FDIR		; Was it first default file ?
	BEQ	10$		;  No : => 10$
	CALL	FILOP3		; Open next file
	BCS	10$		;
	CALLR	FILREA		; If opened : => FILREA
10$:
	RETURN			;
;
;
	.SBTTL	MCE - FILOP  -- Open MCEINI file from MCR line
;
FILOP:	INCB	FILINI		; Startup file
	CALL	GETMCR		; Get MCR commandline (startup file)
	BCC	FILOP2		;  OK : => FILOP2
	RETURN			;
;
;
	.SBTTL	MCE - FILOP1 -- Open MCEINI file
;
FILOP1:
	CLRB	FILINI		; No startup
FILOP2:
	CALL	GETCLI		; Get CLI info
	CALL   	FILOP4		; Open File LB:[1,2]xxx.CLI
	BCC	FILRET		; Success
	TST	FDIR		; Was it first default file ?
	BEQ	10$		;  No : => 10$
	CALL	FILOP3		; Open 'SY:xxx.CLI'
	BCC	FILRET		;  Ok : => FILRET
	TSTB	FILINI		; Startup ?
	BNE	FILRET		;  Yes : => FILRET
10$:
	MOV	#FILTXT,R0	; Error
	CALLR	IOMSG		;   Message
;
FILOP3:
	CLR	FDIR		; No directory descriptor
	MOV	#"SY,DEV	; Try file 'SY:xxx.CLI'
FILOP4:
	CLRB	FILINP		; Assume file can not be opened
	OPEN$R	#FDBIN		; Open input file
	BCS	FILRET		;  Not OK : => FILRET
	INCB	FILINP		; Enable File Input
FILRET:
	RETURN			; Return
;
	.SBTTL	MCE - FILREA -- Read from MCEINI file
;
FILREA:
	GET$S	#FDBIN		; Get a record
	BCC	10$		;
	CALLR	FILCLO		;  No more records : => Close file
10$:
	MOV	F.NRBD(R0),LEN	; Length
	CALL	REPLHT		; Replace TABs
	CALL	SUPRES		; Ignore leading blanks
	BCS	FILREA		;  Empty line : => FILREA
	TST	(SP)+		; Do not return
	MOV	#1,WAITFL	; Wait for execution of commands
	CALLR	EXEC2		;   but execute directly

	.ENDC	;FILE

	.SBTTL	MCE - FNDCMA -- Find entry in command table with "*"
	.SBTTL	MCE - FNDCMD -- Find entry in command table
;
;
;    Input    - PDSC of P0 defined
;             - CTSTAR .ne.0 to allow abreviated command if command
;               definition contains "*" (a la VMS)
;    Output   - CC-C set - no entry found
;               CC-C clr - entry found
;               R0 - to entry
;               R1 - to point to string after ":="
;               R2 - to previous entry (for remove and inserts)
;
FNDCMA:
	.ENABL	LSB

	MOVB	#1,CTSTAR	; Enable abbrivations
	BR	10$		;
FNDCMD:
	CLRB	CTSTAR		; Ignore "*" in translation buffer
10$:
	MOV	#TRNB+F.1ST,R0	; R0 => Translationbuffer
	MOV	R3,-(SP)	; Save R3
	MOV	R1,-(SP)	; Save R1
	CLR	-(SP)		; For previous entry
20$:
	MOV	R0,(SP)		; Save previous entry
	TST	FI.NXT(R0)	; Any next entry ?
	BEQ	100$		;  No : => 100$, end of list
	MOV	FI.NXT(R0),R0	; Take next entry
	MOV	R0,R1		; R1 => Entry
	ADD	#FI.TXT,R1	; R1 => Text
	MOV	PDSC+PX.LEN,R3	; Length to be compared
	BLE	100$		;  Zero : => 100$
	MOV	PDSC+PX.ADR,R2	; Start addr of P0
	TSTB	CTSTAR		; Without abbreviation ?
	BEQ	80$		;  Yes : => 80$
;
; Check for match, accepting any "*" in command defintion
;
	CLRB	TMPFLG		; Reset Flag: "*" found in Cmd Translation
30$:
	CMPB	(R1),#'*	; Check for "*" in translation buffer
	BNE	40$		;  Not yet found : => 40$
	INCB	TMPFLG		; Found, remember it
	INC	R1		; Next char
40$:
	CMPB	(R1),#BLNK	; End of translation buffer ?
	BEQ	60$		;  Yes : => 60$, terminate compare
	CMPB	(R2)+,(R1)+	; Equal ?
	BEQ	50$		;  Yes : => 50$
	BGT	20$		; NE and must come further down in list
	TSTB	TMPFLG		; Passed entry - any "*" seen ?
	BNE	20$		;  Yes : => 20$, continue search
	BR	100$		; We passed alphabetical order : => 100$
50$:
	SOB	R3,30$		; Next char
;
	CMPB	(R1),#BLNK	; End of input string ?
	BEQ	70$		;  Yes : => 70$
	CMPB	(R1),#'*	; Next byte end ?
	BEQ	70$		;  Yes : => 70$
60$:
	TSTB	TMPFLG		; Abbreviation possible ?
	BEQ	20$		;  No  : => 20$
70$:
	CMPB	(R1)+,#BLNK	; End of string (or binary 0???) ?
	BHI	70$		;  Not yet found : => 70$
	BR	90$		; Point past key
;
; Check for match, ignoring any "*" in command defintion
;
80$:
	CMPB	(R2)+,(R1)+	; Compare
	BGT	20$		; NE and must come further down in list
	BLT	100$		; Already passed alphabetical order
	SOB	R3,80$		; Next
;
	CMPB	(R1)+,#BLNK	; Followed by space ?
	BNE	100$		;  No  : => 100$
90$:
	ADD	#3,R1		; Skip ":= "
	CLC			; Successful
	MOV	(SP)+,R2	; R2 => Previous entry
	TST	(SP)+		; Flush old R1
	BR	110$		;
100$:
	SEC			; Not found
	MOV	(SP)+,R2	; R2 => Previous entry
	MOV	(SP)+,R1	; Old R1
110$:
	MOV	(SP)+,R3	; Restore R3
	RETURN			;

	.DSABL	LSB

    	.SBTTL    MCE - FRENT  -- Free entry from queue
;
;  Header in R0.   CC-C clear if it was empty
;
FRENT:
	JSR	R5,.SAVR1	; Save Regs
	MOV	F.1ST(R0),R2	; Get entry if any
	CLC			; Assume empty
	BEQ	20$		;  None : => 20$
	MOV	FI.NXT(R2),FI.NXT(R0)
				; Remove from head of queue
	BNE	10$		; More entries
	MOV	R0,F.LAST(R0)	; This was last one
10$:
	MOV	FI.LEN(R2),R1	; R1 =  Length of entry
	MOV	#FREE,R0	; R0 => Free memory list head
	CALL	$RLCB		; Release memory block
	SEC			; Success
20$:
	RETURN			;
;
;
	.SBTTL	MCE - GETBUF -- Load Buffer into CMDBUF
;
; R0 points to source
;
GETBUF:
	MOV	#CMDBUF,R1	; R1 => CMDBUF
	MOV	R1,R2		; R1 => CMDBUF
	MOV	#CMDSIZ,R5	; R5 =  CMDSIZ
10$:
	TSTB	PRIFLG		; Print commandbuffer ?
	BEQ	30$		;  No : => 30$
	CMPB	(R0),#':	; Command definition ?
	BNE	30$		;  No : => 30$
	CMPB	-1(R0),#BLNK	; Space in front ?
	BNE	30$		;  No : => 30$
	CMPB	1(R0),#'=	; Equal sign behind ?
	BNE	30$		;  No : => 30$
20$:
	MOVB	#BLNK,(R1)+	; Insert spaces
	CMP	R1,#CMDBUF+12.	;  At posision ?
	BLO	20$		; No : => 20$
30$:
	MOVB	(R0)+,(R1)+	; (R0) --> CMDBUF
	BEQ	50$		;  Zero : => 50$
	CMPB	-1(R1),#BLNK	; Blank ?
	BEQ	40$		;  Yes : => 40$
	MOV	R1,R2		; R2 => Behind last
40$:
	SOB	R5,10$		; Go back if not the end
	BR	60$		; => 60$
50$:
	MOVB	#BLNK,-1(R1)	; Overprint 000 (.ASCIZ)
60$:
	MOV	R2,R1		; Both at the end
	RETURN			;

	.IF DF	CLISUP!FILE
;
;
	.SBTTL	MCE - GETCLI -- Get CLI information
;
GETCLI:
	DIR$	#GCLI		; Get CLI information
	BCS	10$		; Error is C set

	.IF DF	CLISUP&FILE

	MOV	CLINAM,FILTYP	; Use CLI name for file type

	.ENDC	;CLISUP&FILE

	.IF DF	FILE

	CALL	$SAVAL		; Save all registers
	MOV	#CURDIR,R2	; R2 => Ascii Current directory
	MOV	CLIUIC,R3	; Binary value from GCLI
	CLR	R4		; Parameters ( No lea. zeroes, add separ. )	
	CALL	.PPASC		; Convert to ASCII
	MOV	R2,R1		; Calculate
	MOV	#CURDIR,R2	;    length
	SUB	R2,R1		;       and point to Ascii
	CALL	.WDFDR		; Write default UIC

	.ENDC	;FILE

10$:
	RETURN			;

	.ENDC	;CLISUP!FILE
;
;
	.SBTTL    MCE - GETFIF -- Get FIFO Buffer, pointed to by FIFPTR
;
GETFIF:
	CLRB	OLDFLG		; No old command
	MOV	FIFPTR,R0	; Get Ptr
	BNE	10$		;  Defined : => 10$
	MOV	#FIFPTR,R0	; Null String
	BR	20$		; => 20$
10$:
	INCB	OLDFLG		; Old command
	ADD	#FI.TXT,R0	; Get start of text
20$:
	CALL	GETBUF		; Load buffer
	CALLR	DISPLY		;  and display
;
;
	.IF DF 	FILE		;

	.SBTTL	MCE - GETFIL -- Get filespecification
	.SBTTL	MCE - GETMCR -- Get filespecification from MCR command
;
; This subroutine dequeues the command which invokes MCE (if any),
; and overrides the default startup file name (MCEINI.xxx) by
; file specified in the commandline.
; Command line syntax is : 'MCE file_specification'
;
	.ENABL LSB
GETMCR:
	DIR$	#GMCR		; Get commandline
	BCS	20$		;  Problem => 20$
	MOV	#MCRLIN,R1	; Point to commandline
	MOV	$DSW,R2		; Length of line
GETFIL:
;
; reset FDB file-name pointers
;
	MOV	#"LB,DEV	; Reset default file volume
	MOV	#DIRL,FDIR	; Restore pointer to default directory
	MOV	#FDSPT,FDBIN+F.DSPT
				; Reset DSPT pointer in FDB
	TST	R2		; Any length ?
	BEQ	20$		;  No : => 20$
10$:
	CMPB	#BLNK,(R1)+	; Mnemonic delimiter ?
	BEQ	30$
	DEC	R2		; Count remaining char
	BNE	10$		; If eq: empty command
20$:
	CLC			; Success
	BR	50$		;
30$:
	DEC	R2		; Flush space
	CSI$1	#CSIBLK,R1,R2	; Syntax check
	BCS	40$		; Syntax error: ignore it
	CSI$2	R0,OUTPUT	; Parse line into its com
	BCS	40$		; No file: ignore it
;
; Now we have a file descriptor table inside the CSI parser block
; override the default DSPT pointing to MCEINI.CMD:
;
	MOV	#CSIBLK+C.DSDS,FDBIN+F.DSPT
				; New DSPT pointer
	CLR	FDIR		; Indicate 'No more files'
	BR	50$		; => 50$
40$:
	MOV	#FLSTXT,R0	; Filespec
	CALL	IOMSG		;     syntax error
	SEC			; Indicate error
50$:
	RETURN			;
	.DSABL	LSB

	.ENDC	;FILE

	.SBTTL	MCE - IO     -- General I/O Routine
;
IO:

	.IF DF	TMOTIM

	MOVB	#TMOTIM,TMOCNT	; Set new timeoutcount

	.ENDC	;TMOTIM

	DIR$	#QIODIR		; Do I/O
	DIR$	#STOPIO		; Stop for I/O (or wait when aborted)
	RETURN			;
;
;
	.SBTTL	MCE - IOCR   -- Print <CR>
;
IOCR:
	MOV	#1,LEN		; Length
	BR	IOCL		; => IOCL
;
	.SBTTL	MCE - IOCRLF -- Print <CR><LF>
;
IOCRLF:
	MOV	#2,LEN		; Length
IOCL:
	MOV	#IO.CCO,CODE    ; Cancel <CTRL/O>
	MOV	#CRET,ADR      	; Print <CR> ( <LF> )
	BR	IO		; Go to IO
;
;
	.SBTTL	MCE - IOMSG  -- Print Message
;
; Print a Msg in (R0)
;
IOMSG:
	CALL	IOCRLF		; Print <CR><LF>
	CALL	GETBUF		; (R0) --> CMDBUF
	CALL	DISPLY		; Write line
	CALLR	CLRBUF		;
;
;
	.SBTTL	MCE - IOW    -- Write routine
;
IOW:
	MOV	#IO.WVB,CODE    ; write
	BR	IO		; Go to IO
;
;
    .SBTTL    MCE - LDFIF  -- Load CMDBUF into FIFO Buffer
;
; R0  => First non blank character
; LEN =  Length of command
;
LDFIF:
	CALL	$SAVAL		; Save Regs
	MOV	LEN,R5		; R5 =  Length
	BEQ	40$		;  Zero : => 40$
	CMP	R5,MINC		; Save it ?
	BLO	40$		;  No : => 40$
	MOV	R0,R4		; R4 => Command
	MOV	R5,R1		; R1 =  Length
	ADD	#FI.TXT+1,R1	; Increment for header and 0 byte
	CMPB	FIFCNT,MAXF	; Maximum reached ?
	BLO	20$		;  No : => 20$
10$:
	CALL	CLFIFI		; Release first entry
	BCC	40$		; Nothing to release
20$:
	MOV	#FREE,R0	; R0 => Free memory listhead
	CALL	$RQCB		; Request core block
	BCS	10$		; Nothing received yet - release more
	CLR	FI.NXT(R0)	; No next entry
	MOV	R0,@FIFO+F.LAST	; Link to previous
	MOV	R0,FIFO+F.LAST	; New last entry
	MOV	R1,FI.LEN(R0)	; Total length
	ADD	#FI.TXT,R0	; Point to text field
	MOV	R4,R1 		; Source text
30$:
	MOVB	(R1)+,(R0)+	; Load
	SOB	R5,30$		;   string
	CLRB	(R0)		; End of string
	INCB	FIFCNT		; Count
40$:
	RETURN			;

	.IF DF	TMOTIM

;
	.SBTTL	MCE - MARK   -- Next Marktime
MARK:
	MRKT$S	,#60.,#2,#TIMAST;(;)
	RETURN			;(;)

	.ENDC	;TMOTIM

	.SBTTL	MCE - NEWCMD -- Define new command or delete command
;
; Define new command in command buffer, or delete it
;
NEWCMD:
	TSTB	NLOFLG		; Skip processing ?
	BNE	50$		;  Yes : => 50$
	CALL	FNDCMD		; Check if in table
	BCC	60$		;  Yes : => 60$, release old entry
	TST	2*PX.SIZ+PDSC	; P2 defined ?
	BNE	10$		;  Yes : => 10$, must load
	TST	3*PX.SIZ+PDSC+PX.ADR
				; P3 with addr ?
	BEQ	50$		;  No  : => 50$, delete only
10$:
;
; Insert new command
;
	MOV	R2,R3		; R3 => Entry after which to insert
	MOV	LEN,R1		; length of string
	BEQ	50$		;   Zero : => 50$
	ADD	#FI.TXT+1,R1	; With overhead and 0 byte
	MOV	#FREE,R0	; R0 => Free memory listhead
	CALL	$RQCB		; Request core block
	BCC	20$		;  Ok : => 20$
	MOV	#NOPOOL,R0	; No more Pool
	CALL	IOMSG		; Give the message
	BR	50$		; => 50$
20$:
	MOV	FI.NXT(R3),FI.NXT(R0)
				; Link to previous entry
	BNE	30$		;
	MOV	R0,TRNB+F.LAST	; We will be last one
30$:
	MOV	R0,FI.NXT(R3)	;
	MOV	R1,FI.LEN(R0)	; Total length
	ADD	#FI.TXT,R0	; R0 => Start of text
	MOV	#SAVBUF,R1	; R1 => Source
	MOV	LEN,R2		; R2 =  Length
40$:
	MOVB	(R1)+,(R0)+	; Copy
	SOB	R2,40$		;  text
	CLRB	(R0)		; Write delimiter
50$:
	RETURN			;
60$:
;
; Release old entry
;
	MOV	FI.NXT(R0),FI.NXT(R2)
				; Link remainder
	BNE	70$		;  More entries : => 70$
	MOV	R2,TRNB+F.LAST	; This was last one
70$:
	MOV	FI.LEN(R0),R1	; R1 = Length
	MOV	R0,R2		;
	MOV	#FREE,R0	; R0 => Free memory listhead
	CALL	$RLCB		; Release it
	BR	NEWCMD		; Find more to release

	.IF DF	STATUS

;
	.SBTTL	MCE - OFFON  -- Depending on flag in R1 : Fill with ON or OFF
;
OFFON:
;
	MOVB	#'o,(R0)+	; +
	TSTB	(R1)		;
	BEQ	10$		;
	MOVB	#'n,(R0)+	;
	MOVB	#' ,(R0)+	;
	RETURN
10$:
	MOVB	#'f,(R0)+	;
	MOVB	#'f,(R0)+	;
	RETURN			; -

	.ENDC	;STATUS

    .SBTTL    MCE - PRICMD -- Print Cmd buffer and put pointer to end of queue
;
PRICMD:
	MOV	#TRNB+F.1ST, FIFPTR
				; Point to Translationbuffer
	INCB	PRIFLG		; Flag Tarnslationbuffer print-out
	BR	PRIXXX		; => PRIXXX
;
;
    .SBTTL    MCE - PRIFIF -- Print FIFO and put pointer to end of queue
;
PRIFIF:
	MOV	#FIFO+F.1ST,FIFPTR
				; Point to FIFO
PRIXXX:
	CALL	CLRSCR		; Clear screen
	BCC	20$		;  Cleared : => 20$
10$:
	CALL	IOCRLF		; Blank line
20$:
	MOV	@FIFPTR,FIFPTR	; Next PTR
	BEQ	30$		;  Done : => 30$
	CALL	GETFIF		; Display
	BR	10$		; => 10$
30$:
	CLRB	PRIFLG		; Flag commandbuffer print-out
	CALL	IOCRLF		; Blank line
	CALL	CLRBUF		; Clear edit buffer (FIFPTR already cleared)

	.IF DF	STATUS

	CALL	DISPLY		;  and display prompt
	CALLR	PRISTA		; Print status line

	.IFF	;STATUS

	CALLR	DISPLY		;  and display prompt

	.IFT	;STATUS

	.SBTTL	MCE - PRISTA -- Print the status line
;
PRISTA:
	MOV	#STATX1,ADR	; Print
	MOV	#STALN1,LEN	;   The
	BR	PRIST2		; Statusline
PRIST1:
	MOV	#STATX2,ADR	; Print
	MOV	#STALN2,LEN	;   The
	BR	PRIST2		;     status line
PRIST2:
	CALL	STAFIL		; Fill status record
	TSTB	STAFLG		; Statusline wanted ?
	BEQ	10$		;  No : => 10$
	CALLR	IOW		;     Statusline
10$:
	RETURN			;

	.ENDC	;STATUS

	.SBTTL	MCE - RECCMD -- Recall command from FIFO
;
; Recall Command from FIFO by key
;
RECCMD:
	CLR	-(SP)		; Room for Pointer to FIFO entry
	MOVB	FIFPOI,R5	; R5 = FIFO entry number
	MOV	FIFO+F.1ST,R4	; R4 => Oldest Entry in FIFO
	BEQ	50$		;  Empty : => 50$
	MOVB	#1,R5		; Start above oldest
	TST	FIFPTR		; Old pointer ?
	BNE	20$		;  Defined : => 20$
	MOV	#CMDBUF,R1	; R1 => Source Buffer
	MOV	#RCLBUF,R3	; R3 => Destination Buffer
	SUB	R1,R2		; R2 =  Length
	BLE	20$		;  Zero : => 20$
10$:
;
; Store single char into Recall buffer
;
	MOVB	(R1)+,R0	; R0 = next char
	CALL	CNVUPC		; Convert
	MOVB	R0,(R3)+	; Store char
	SOB	R2,10$		; Next
	CLRB	(R3)		; EOL
20$:
;
; Check next entry in FIFO
;
	MOV	#RCLBUF,R1	; R1 => Source to Compare
	TSTB	(R1)		; Search mask defined ?
	BEQ	50$		;  No : => 50$
	MOV	R4,R3		; R3 => Entry
	ADD	#FI.TXT,R3	; R3 => Text of entry
30$:
	MOVB	(R3)+,R0	; R0 = Next char
	BEQ	40$		;  EOL : => 40$
	CALL	CNVUPC		; Convert to uppercase
	CMPB	R0,(R1)+	; Compare with source
	BNE	40$		;  No match : => 40$
	TSTB	(R1)		; EOL ?
	BNE	30$		;  No : => 30$, Try next char
	MOV	R4,(SP)		; Source exhausted - match found
	MOVB	R5,FIFPOI	; Store FIFO entry number
40$:
	INCB	R5		; One newer
	MOV	FI.NXT(R4),R4	; R4 => Next entry
	BEQ	50$		;  No more : => 50$
	CMP	R4,FIFPTR	; Continue search ?
	BNE	20$		;  Yes : => 20$
50$:
	MOV	(SP)+,FIFPTR	; Pop Pointer to entry if any
	BNE	60$		; Any pointer ? => 60$
	CLRB	FIFPOI		;
60$:
	CALL	GETFIF		; Load from FIFO (or delete CMDBUF buffer)
	RETURN			;

	.SBTTL	MCE - REPLHT -- Replace TABs
;
REPLHT:
;
	MOV	#CMDBUF,R0	; R0 => CMDBUF
	MOV	LEN,R2		; Length
	BEQ	30$		;  Empty ? Yes : => 30$
10$:
	CMPB	(R0)+,#HT	; TAB ?
	BNE	20$		;  No : => 20$
	MOVB	#BLNK,-1(R0)	; Replace by space
20$:
	SOB	R2,10$		;
30$:
	RETURN			;
;
;
	.SBTTL    MCE - SPBACK -- Backspace 1 char.
;
SPBACK:
	CMP	R1,#CMDBUF	; At begin of buffer ?
	BLOS	10$		;  Yes : => 10$
	MOV	#BS,ADR		; Write
	MOV	#1,LEN		;    a
	CALL	IOW		;       backspace
	DEC	R1		; Shift cursor
	RETURN			;
10$:
	SEC			; Indicate cursur error
	RETURN			;
;
;
	.SBTTL    MCE - SRWORD -- Search for word
;
SRWORD:
	CMPB	R0,#'0		; Digit ?
	BLO	10$		;  No  : => 10$
	CMPB	R0,#'9		; Digit ?
	BLO	20$		;  Yes : => 20$
	CMPB	R0,#'_		; Special char ?
	BEQ	20$		;  Yes : => 20$
	BIC	#40,R0		; Convert to uppercase
	CMPB	R0,#'A		; Alphabetical ?
	BLO	10$		;  No  : => 10$
	CMPB	R0,#'Z		; Alphabetical ?
	BLOS	20$		;  Yes : => 20$
10$:
	SEC			;
	RETURN
20$:
	CLC			;
	RETURN

	.IF DF	STATUS

;
	.SBTTL	MCE - STAFIL -- Fill status line
;
STAFIL:
;
	MOV	R1,-(SP)	; Save R1
	MOV	R2,-(SP)	; Save R2
	MOV	#STALIR,R0	; +
	TSTB	RNGFLG		;
	BEQ	10$		;
	MOVB	#'r,(R0)+	;
	MOVB	#'i,(R0)+	;
	MOVB	#'n,(R0)+	;
	MOVB	#'g,(R0)+	;   Ring or List
	BR	20$		;
10$:
	MOVB	#'l,(R0)+	;
	MOVB	#'i,(R0)+	;
	MOVB	#'s,(R0)+	;
	MOVB	#'t,(R0)+	; -
20$:
	TSTB	(R0)+		; +
	MOV	MAXF,R1		;   Maxfif
	CALL	CONV		; -
	TSTB	(R0)+		; +
	MOVB	FIFCNT,R1	;   Fifcnt
	CALL	CONV		; -
	TSTB	(R0)+		; +
	MOVB	FIFPOI,R1	;   Fifpoi
	CALL	CONV		; -
	MOV	#STACMD,R0	; +
	MOV	MINC,R1		;   Minchr
	CALL	CONV		; -

	.IF DF	EDT

	MOV	#STAKEY,R0	; +
	MOV	#EDTFLG,R1	;   Keypad
	CALL	OFFON		; -

	.ENDC	;EDT

	MOV	#STASVI,R0	; +
	MOV	#SINFLG,R1	;   Save internals
	CALL	OFFON		; -
	MOV	#STASVR,R0	; +
	MOV	#SOLFLG,R1	;   Save old
	CALL	OFFON		; -

	.IF DF	TMOTIM

	MOV	#STATMO,R0	; +
	MOVB	TMOCNT,R1	;    Time-out count
	MOV	#15012,R2	;
	CALL	$CBTA		; -

	.ENDC	;TMOTIM

	MOV	(SP)+,R2	; Restore R2
	MOV	(SP)+,R1	; Restore R1
	RETURN			;

	.ENDC	;STATUS

;
	.SBTTL	MCE - STORE  -- Append string with descriptor (R1) to CMDBUF
;
STORE:
;
;
	MOV	PX.LEN(R1),R5	; R5 = Length
	BEQ	30$		;  Empty : => 30$
	MOV	PX.ADR(R1),R1	; R1 = Source Addr
10$:
	CMP	R2,#CMDEND	; In range ?
	BLO	20$		;  Yes : => 160
	DECB	OVMSG		; Mark for Ovflw
	RETURN			;
20$:
	MOVB	(R1)+,(R2)+	; Copy
	SOB	R5,10$		;  characters
30$:
	RETURN
;
;
	.SBTTL	MCE - SUBST  -- Check and substitute if necessary
SUBST:
;
; Substitute Pn's
;
	JSR	R5,.SAVR1	; Save Regs
	CMPB	(R1)+,#'P	; Check next symbol
	BNE	10$		;  No match : => 10$
	MOVB	(R1)+,R3	; Get Parameter number
	SUB	#'0,R3		; Decode
	BLE	10$		;  Illegal : => 10$
	CMP	R3,#8.		; In range ?
	BHI	10$		;  No : => 10$
	CMPB	(R1)+,R0	; Endmark ?
	BEQ	20$		;  Yes : => 20$
10$:
	CLC			; Tell no substitution
	RETURN			;
20$:
;
; Substitution string found
;
	MOV	R1,2(SP)	; Set up R1 after return
	ASL	R3		; Param num
	ASL	R3		;        times 4
	ADD	#PDSC,R3	; R3 => Descriptor
	MOV	R3,R1		;
	CALL	STORE		; Load it
	MOV	R2,2*2(SP)	; Load R2 after return
	DECB	CFETCH		; Mark that parameter fetched
	SEC			; Tell substituted
	RETURN			;
;
;
	.SBTTL	MCE - SUPRES -- Suppress leading blanks
;
SUPRES:
;
	MOV	#CMDBUF,R0	; R0 => CMDBUF
;
	.SBTTL	MCE - SUPRR0 -- Suppress leading blanks ( Start at R0 )
;
SUPRR0:
;
	TST	LEN		; Empty ?
	BEQ	20$		;  Yes : => 20$
10$:
	CMPB	(R0),#BLNK	; Start with a Space ?
	BNE	30$		;  No : => 30$
	INC	R0		; Next := First
	DEC	LEN		; One less
	BNE	10$		; Not Empty : => 10$
20$:
	SEC			; Return
	RETURN			;
30$:
	CLC			; Success
	RETURN			;
;
;
	.SBTTL	MCE - TERM   -- Get terminal information
;
TERM:
	MOV	#SFGMCB,ADR    	; GMC Buffer
	MOV	#SFGMCL,LEN    	; GMC Bufferlength
	MOV     #SF.GMC,CODE   	; GMC Code

	.IF DF	STATUS

	CALL	IO              ; Do it
        TSTB	ANI+1		; ANSI Terminal
	BNE	10$		;  Yes : => 10$
	CLRB	STAFLG		; No statusline possible
10$:
	RETURN			;

	.IFF	;STATUS

	CALLR	IO		; Do it

	.ENDC	;STATUS

	.IF DF	TMOTIM

	.SBTTL	MCE - TIMAST -- TI: Time-out AST
;
; On timeout - log off (TT0: just exit)
;
TIMAST:
	TST	(SP)+		;; Restore stack
	DECB	TMOCNT		;; Timeout ?
	BLT	10$		;; Should not have decremented
	BNE	20$		;; Not yet
;
; Timed out - kill pending read
;
	MOV	#IO.KIL,CODE	;; Kill
	CALL	IO		;;    pending read
10$:
	CLRB	TMOCNT		;;
20$:

	.IF DF	STATUS

	CALL	STAFIL		;; Fill statusline
	TSTB	STAFLG		;; Statusline wanted ?
	BEQ	30$		;;  No : => 30$
	QIOW$S	#IO.WVB,#TI,#EFNAST,,,,<#STATX2,#STALN2,#0>
30$:

	.ENDC	;STATUS

	CALL	MARK		;; Mark time
	ASTX$S			;; Exit ast

	.ENDC	;TMOTIM

;
;
	.SBTTL	MCE - UPDATE -- Update commandline
;
; Write from current Position to End of Line and reposition Cursor
;
UPDATE:
	MOV	R1,ADR		; Address of Cursor
	MOV	R2,LEN		; R2 => EOL
	SUB	R1,LEN		; Length
	BEQ	10$		;  Zero : => 10$
	CALL	IOW		; Write rest of line
	MOV	#BS,ADR		; Address backspaces
	CALLR	IO		; Reposition Cursor
10$:
	RETURN			;

	.IF DF	EDT
;
	.SBTTL	MCE - WRISEL -- Write selective range
;
WRISEL:
;
;    | B U F F E R . . . . . . . . . . |clrlin|
;    ^                 ^      ^         ^      ^
;   ADR               R3     R4        R2     R0
;                    start   end
;                                      |      |
; LEN = length of buffer --------------+------+
;
	TSTB	ANI+1		; Ansi Screen ?
	BEQ	10$		;  No : => 10$
	MOV	LEN,-(SP)	; Save length
	MOV	R3,LEN		; Calculate
	SUB	ADR,LEN		;    length to start of range
	SUB	LEN,(SP)	; Update restlength
	CALL	IOW		; Write
;
	MOV	#INV,ADR	; Addres of inv esc seq.
	MOV	#INVL,LEN	; Length
	CALL	IOW		;
;
	MOV	R3,ADR		; Address of range
	MOV	R4,LEN		; Calculate
	SUB	R3,LEN		;  length of range
	SUB	LEN,(SP)	; Update restlength
	CALL	IOW		;
;
	MOV	#NOR,ADR	; Addres of inv esc seq.
	MOV	#NORL,LEN	; Length
	CALL	IOW		;
;
	MOV	R4,ADR		; Address of rest
	MOV	(SP)+,LEN	; Rest length
10$:
	RETURN			;

	.ENDC	;EDT

	.END    START
