	.title	k11cmd	command level for kermit-11
	.ident	/8.0.01/


	baselev	==	2		; baseline level
	edit	==	7		; edit (independent of base_level)
	release	==	'T&137		; T for test, V for release
	
	

;	Brian Nelson  01-Dec-83  13:19:14
;
;	Change Software, Toledo, Ohio
;	University of Toledo, Toledo, Ohio
;
;	Copyright (C) 1983   Change Software, Inc.
;
;
;	edits:
;
;	01 08-Jan-84  K11CMD	BDN	fix SET PARITY
;	01 08-Jan-84  K11PAK	BDN	Change  timeout to  MYTIME from MAXTIME
;					if remote's SINIT packet had a value of
;					zero for the timeout (CMS kermit?)
;	01 08-Jan-84  K11CMD	BDN	Added  call to XINIT for initialization
;					based on the operating system.
;	01 08-Jan-84  K11PAK	BDN	Fix .asicz for ERROR: SPACK
;	02 11-Jan-84  K11RMS	BDN	Added RMS rename
;	02 11-Jan-84  K11CMD	BDN	Added RENAME command
;	02 12-Jan-84  K11PAK	BDN	Fix checking for X , Z in ACK for Sdata
;	02 13-Jan-84  K11CMD	BDN	Added TAKE and @ commands
;	02 13-Jan-84  K11CMD	BDN	Added showing speed for SHOW LINE
;	02 13-Jan-84  K11M41	BDN	More rsxm/m+ code added
;	02 13-Jan-84  K11CMD	BDN	Moved C$HELP to module K11HLP
;	02 16-Jan-84  K11CMD	BDN	Add Set Block-Check-Type and SHOW BLOCK
;	02 16-Jan-84  K11PAK	BDN	Redo  checksum processing to accomadate
;					12 bit and CRC types.
;	02 16-Jan-84  K11CMD	BDN	Allow  underscore and digits in command
;					names.
;	02 17-Jan-84  K11PAK	BDN	Allow 12 bit and CRC-CCITT Checksums
;					The user should always set the checksum
;					type for both KERMITS.
;	02 17-Jan-84  K11CMD	BDN	Allow open for KERMIT.INI
;	02 17-Jan-84  K11CMD	BDN	Added  commands  NOTE and  COMMENT  for
;					echoing text from indirect files.
;	02 18-Jan-84  K11CMD	BDN	Added  REMOTE,  SPACE and  REMOTE SPACE
;					commands.  Support  added to K11E80 and
;					K11SER for generic U command.
;	03 20-Jan-84  K11M41	BDN	Test and fix TTSPEED, SETSPD and BINREA
;					for RSX11M/M+
;	03 22-Jan-84  K11M41	BDN	Fixed  BINREAD(lun,tmo)  to work with a
;					passed timout of '-1' to effect a  read
;					without wait (no stalling if no data).
;	03 23-Jan-84  K11E80	BDN	Rewrote NOECHO(line)  and ECHO(line) to
;					set noecho when the remote  link is set
;					via SET LIN  and open in K11CON.  Added
;					calls in K11CMD and K11CON to NOECHO.
;	03 23-Jan-84  K11M41	BDN	Modified CANTYP(lun) to force LUN 5  if
;					a value of zero (0) is passed for a lun
;					to  make it  compatible  with  the RSTS
;					version of CANTYP.
;	03 23-Jan-84  K11SER	BDN	Finished  prototype version of extended
;					replies and added the  remote DIRECTORY
;					command (generic D) to test it for RSTS
;	03 25-Jan-84  K11HLP	BDN	Finished subtopics for HELP command
;	03 25-Jan-84  K11CMD	BDN	Added SET RECORD-FORMAT STREAM and
;					and   SET RECORD-FORMAT VARIABLE
;	03 25-jan-84  K11RMS	BDN	Added support for stream ascii
;
; Version 2
;
;
; I decided that I would like to have the normal TED timestamp on the edit.
;
;
; 04 27-Jan-84  18:30:07  K11PAK  BDN	Redo support for extended server replies
; 04 27-Jan-84  18:45:08  K11SER  BDN	Redo support for remote commands
; 04 27-Jan-84  18:55:44  K11PAK  BDN	If datafield.len < 0 then reset checksum
;					type to type '1' in RPACK$
; 04 27-Jan-84  20:02:34  K11HLP  BDN	Fix keyword match to  match @ position 1
; 04 27-Jan-84  21:33:21  K11CMD  BDN	Added REM ERASE,  also add synonyms  for
;					SET LOGFILE as LOG_FILE and LOG-FILE.
; 05 30-Jan-84  12:01:41  K11CMD  BDN	Add ERASE, DELETE
; 05 30-Jan-84  13:44:28  K11RMS  BDN	Added  RMS $ERASE  code and disk logging
;					of files deleted.
; 05 30-Jan-84  16:38:01  K11SER  BDN	Consolidated remote  server command pac-
;					ket sending and creation.
; 05 30-Jan-84  20:10:28  K11HLP  BDN	Found out  that K11HLP  needs temp privs
;					to get at the help file (K11HLP.HLP). If
;					the sys  manager installs  the  optional
;					patch to FIP for UU.LOK then a <234>  is
;					needed.
; 05 31-Jan-84  08:41:03  K11CMD  BDN	Moved SHOW command to  K11SHO.MAC,  also
;					moved $NAME and COMMAND macros to K11CDF
; 05 31-Jan-84  09:36:56  K11RMS  BDN	Fixed  help file access  problem at  the
;					source, ie, insure FB$GET is set only if
;					the file is opened for reading.
; 06 01-Feb-84  10:21:19  K11CMD  BDN	Moved type and rename commands to K11SHO
;					to space space in the root.
; 06 01-Feb-84  10:22:17  K11SER  BDN	Insure KERMIT.TMP has the default device
;					string inserted in it for create.
; 06 01-Feb-84  10:36:27  K11CMD  BDN	Add  'REMOTE TYPE' and added 'DISK to be
;					same as 'SPACE'
; 06 01-Feb-84  10:37:49  K11SER  BDN	Support remote type in server
; 06 01-Feb-84  13:06:36  K1180S  BDN	New module, do a partial SYSTAT for RSTS
; 06 01-Feb-84  13:07:10  K11SER  BDN	Add support for remote WHO command
; 06 01-Feb-84  13:07:26  K11CMD  BDN	Local and remote WHO commands.
; 06 01-Feb-84  14:25:46  K11RMS  BDN	Insure FB$FID in the FOP is cleared  for
;					the $ERASE call.
; 06 02-Feb-84  17:24:19  K11E80  BDN	Fix  CANTYP and  change parameter  list.
;					Mods required to K11SER, K11PAK,  K11CMD
;					and K11M41.
; 06 03-Feb-84  10:06:23  K11RMS  BDN	Rewrote  the default  directory to  work
;					the way  it should by using  $PARSE  and
;					the DNS and DNA fields in the FAB.  Also
;					added FPARSE to return an expanded name.
;					Changes to K11CMD, K11SER and K11PAK.
; 06 04-Feb-84  11:53:32  K11CPY	New module, do file copies using RMS i/o
;					This could be dependent on new  versions
;					of  RMS11 as I access  the IFABS to copy
;					the correct file attributes,
; 06 04-Feb-84  11:54:59  K11SER	Added remote copy and rename support.
; 06 04-Feb-84  11:55:22  K11CMD	Added local copy and remote copy, rename
; 06 06-Feb-84  10:34:04  K11PAK	Added SETTMO to decide what receive time
;					out to use based on server timeout,  the
;					other  kermit's desired  timeout and any
;					timeout set via SET TIMEOUT value.
; 07 08-Feb-84  15:19:58  K11SER	Force mode to be remote if we are to run
;					as a server. Not really needed, but what
;					about doing a SET LINE and then SERVER ?
; 07 09-Feb-84  09:20:34  K11E80	Try to anticipate the DHV11 q bus inter-
;					face for  showing and setting speed.  No
;					changes needed to K11M41 for rsx.
; 08 09-Feb-84  21:33:55  K11RSX.ODL	Overlayed CSI1, CSI2 and PARSE which are
;					used to get the simple filename.ext from
;					the RMS11 expanded name string.
; 09 10-Feb-84  12:25:27  K11M41	Add HANGUP via IO.HNG qio, added code to
;					spawn  MCR SET /SPEED=TTnn:xxxx:xxxx  if
;					the SF.SMC  call to  change speed  fails
;					with  an IE.PRI error,  also changed the
;					cli for SPWN$S to CLI... from MCR...



	.sbttl	define macros and things we want for KERMIT-11

	.include	/IN:K11MAC.MAC/
	.include	/IN:K11CDF.MAC/
	.iif ndf, k11inc, .error ; INCLUDE for IN:K11MAC.MAC failed

	.psect	$code

	cc$max	==	2

	.enabl	gbl








	.sbttl	the main program
	code


kermit::calls	setcc	,<#cctrap>	; enable control C trapping ?
	call	drpprv			; drop temp privs (for RSTS)
	clr	cccnt			; clear control C count
	mov	#stack	,sp		; initialize a large stack
	call	init			; clear out r/w things
	call	kerini			; try to open SY:KERMIT.INI
	call	sho$ve			; print version and edit number

10$:	calls	setcc	,<#cctrap>	; command loop reading
	call	drpprv			; insure no privs are up now
	call	fixchk			; restore setted crc type
	clr	cccnt			; no control C's
	call	getcmd			; read and parse the command
	tst	r0			; but did it work out ?
	blt	70$			; no
	jsr	pc	,@cmdadr	; dispatch to the command
	br	90$			; and drop to bottom of the loop

70$:	cmp	r0	,#cmd$ex	; control Z typed
	bne	80$			; no
	jmp	c$exit			; yes, exit normally

80$:	cmp	r0	,#cmd$ba	; invalid command ?
	bne	90$			; no
	print	#200$			; yes, print out an error message
	br	90$			; and go back for more


90$:	br	10$			; back to the command loop


200$:	.asciz	/Unrecognized command/<cr><lf>
	.even

	global	<drpprv	,fixchk	,stack>


	.sbttl	commands

c$rec::	$name	<REC>
	call	opentt			; initialize the link line
	tst	outopn			; is an output file already open?
	beq	10$			; no
	calls	close	,<#lun.ou>	; yes, close it up please
10$:	calls	recsw	,<#'R>		; get the file
	tst	r0			; did it work
	bne	20$			; no
	calls	printm	,<#1,#200$>	; yes, say so if we are local
	br	100$			; bye
20$:	calls	printm	,<#1,#210$>	; it failed, say so iff local
100$:	call	clostt			; release the terminal
	return

	.enabl	lc
200$:	.asciz	/Receive complete/<cr><lf>
210$:	.asciz	/Receive failed/<cr><lf>
	.even



	.sbttl	send a file to pc
	.enabl	lsb
	.enabl	lc


c$send::$name	<SEN>
	clr	index			; initialize for directory i/o
	tst	inopn			; is an input file currently open
	beq	5$			; no
	calls	close	,<#lun.in>	; yes, pelase close old file up
5$:	call	opentt			; open and initialize the terminal
	mov	#argbuf	,r1		; address of command line buffer
	tstb	@r1
	bne	10$			; yes
	message	<?Syntax   SEND Filename.type>,cr
	br	100$
10$:	tst	sermode			; are we a server now ?
	bne	15$			; yes, don't delay sending it.
	tst	remote
	beq	15$
	calls	suspend	,<sendly>	; give them a moment to type REC
15$:	copyz	r1,#srcnam,#60
	call	getnxt			; get the first filename please
	tst	r0			; did it work ?
	bne	100$			; no. Getnxt will send the error pak
	calls	sendsw	,<#'S>		; now send the file
	tst	r0			; did it work ?
	bne	20$			; no
	calls	printm	,<#1,#200$>	; yes
	br	100$			; bye
20$:	calls	printm	,<#1,#210$>	; no
100$:	call	clostt			; exit
	return
	
	.dsabl	lsb

	global	<cmdbuf	,index	,inopn	,sermod	,srcnam	,sendly>
	
200$:	.asciz	/Send complete/<cr><lf>
210$:	.asciz	/Send failed/<cr><lf>
	.even




	.sbttl	call the server


c$serv::$name	<SER>
	print	#200$			; dump a message out please
	call	opentt			; get the line open please
	direrr	r0			; print any errors out
	calls	cantyp	,<#ttname,#lun.ti>; dump garbage perhaps
	call	server			; and do it
	call	clostt			; we came back ?
	return				; ok

	global	<lun.ti	,server>

200$:
.ascii #Kermit Server running on PDP-11 host. Please type your escape sequence#
.byte  cr,lf
.ascii #to return  to your local machine.  Shut down the server by  typing the#
.byte  cr,lf
.asciz #Kermit BYE command on your local machine.#<cr><lf>
.even




	.sbttl	initialize ourselves


init:	mov	#rwdata	,r0		; first of all, clear all read/write
	mov	#rwsize/2,r1		; data out please
10$:	clr	(r0)+			; for i := 1 to rwdata_size
	sob	r1	,10$		;  do data[i] := 0 ;
	mov	sp	,remote		; assume remote
	call	rparini			; default remotes sinit parameters
	call	sparini			; initialize my sinit parameters
	mov	#mx$try	,maxtry		; initialize retry limit
	mov	#defchk	,chktyp		; set the default checksum type
	mov	#defdly	,sendly		; init the delay for send command
	mov	#1	,chksiz		; and the default checksum size
	call	xinit
	return				; end



kerini::nop				; can always patch this with a 207
	calls	open	,<#200$,#lun.ta,#text>
	tst	r0			; did the open work ?
	bne	100$			; no, just ignore it
	mov	#lun.ta	,cmdlun		; yes, setup for reading from INIT
100$:	return

200$:	.asciz	/SY:KERMIT.INI/
	.even

	global	<xinit	,cmdlun	,lun.ta	,defchk	,defdly	,chktyp	,sendly>
	global	<chksiz>




	.sbttl	open and close a link




opentt::tst	linksts			; already open ?
	bne	100$			; yes, ignore it then
	tst	remote			; if remote
	beq	10$			;  then ttname := ourname
	calls	gttnam	,<#ttname>	; get the terminal name here
10$:	calls	ttyini	,<#ttname,#lun.ti,#ter$xo>
	tst	r0
	bne	100$
	calls	ttysav	,<#ttname>	; save terminal settings
	calls	ttyset	,<#ttname>	; set some things now
	mov	sp	,linksts	; flag it as being open
100$:	return


clostt::calls	ttyfin	,<#ttname,#lun.ti>
	call	ttyrst
	clr	linksts
	return
	
	global	<linksts,remote	,rwdata	,rwsize	,ttname>
	global	<gttnam	,ttyini	,ttyrst	,ttysav	,ttyset>
	global	<chksiz	,chktyp	,defchk	,mx$try	,maxtry>



	.sbttl	exit kermit-11

c$exit::call	sd$off
10$:	tst	outopn
	beq	20$
	calls	close	,<#lun.ou>
20$:
	jmp	exit

	global	<exit>



c$nop::	return				; a NO-OP command ???







	.sbttl	connect, bye, finish and get

c$conn::$name	<CON>
	message	<Connecting to >	; say we are trying to connect
	print	#ttdial
	message				; a crlf
	tst	conesc			; an escape character set ?
	bne	10$			; yes
	movb	#con$esc,conesc		; no, set the default in
10$:	copyz	#ttdial	,#ttname	; insure correct name
	clr	remote			; insure remote flag set
	call	doconn			; do it
	return				; back to command parser



rm$bye:
c$bye::	$name	<BYE>
	call	ckremote		; must not be remote for this
	bcs	100$			; we are remote, abort this
	call	rembye			; tell a server to logout
100$:	return				; back to command loop


rm$fin:
c$fin::	$name	<FIN>
	call	ckremote		; must not be remote for this
	bcs	100$			; we are remote, abort this
	call	remfin			; tell a server to exit
100$:	return				; back to command loop


rm$get:
c$get::	$name	<GET>
	call	ckremote		; must not be remote for this
	bcs	100$			; we are remote, abort this
	calls	remget	,<#argbuf>	; tell a server to get a file
100$:	return				; back to command loop


rm$spa:	$name	<SPA>
	call	remspa			; issue a space ('U') generic command
100$:	return


rm$hlp:	$name	<HEL>
	call	remhlp			; issue a space ('U') generic command
100$:	return


rm$dir:	$name	<DIR>
	calls	remdir	,<#argbuf>	; issue a dir ('D') generic command
100$:	return


rm$typ:	$name	<TYP>
	calls	remtyp	,<#argbuf>	; issue a typ ('T') generic command
100$:	return


rm$who:	$name	<WHO>
	calls	remwho	,<#argbuf>	; issue a who ('W') generic command
100$:	return


rm$del:	$name	<DEL>
	calls	remera	,<#argbuf>	; issue a erase ('E') generic command
100$:	return


rm$ren:	$name	<REN>			; do a remote rename please
	call	gettwo			; insure both arguments are here
	tst	r0			; but did that work out ok ?
	bne	100$			; no, just exit then please
	calls	remren	,<#cmdbuf,#argbuf>; send a generic 'r' please
100$:	return				; bye


rm$cop:	$name	<COP>			; do a remote Kopy please
	call	gettwo			; insure both arguments are here
	tst	r0			; but did that work out ok ?
	bne	100$			; no, just exit then please
	calls	remcop	,<#cmdbuf,#argbuf>; send a generic 'K' please
100$:	return				; bye



ckremo:	tst	remote			; are we local or remote
	bne	100$			; local, ok
	clc				; ok
	return				; bye
100$:	message	<KERMIT is not running as a LOCAL Kermit>,cr
	sec
	return

	global	<rembye	,remdir	,remera	,remfin	,remget	,remhlp>
	global	<remspa	,conesc	,remote	,doconn	,ttdial	,ttname>
	global	<remcop	,remren>






	.sbttl	the local directory and type commands
	.enabl	lsb

c$dir::	$name	<DIR>
	tstb	defdir
	beq	10$
	message	<Current default is >
	print	#defdir
	message
10$:	calls	dodir	,<#argbuf,#0>	; get the passed filespec for dir
	tst	r0			; do the directoty. did it work ?
	beq	100$			; yes
	direrr	r0			; no, print the error
100$:	return				; bye

	.dsabl	lsb


c$who::	calls	systat	,<#0>
	return




	.sbttl	the take command
	.enabl	lsb


c$take::$name	<TAKE>
	tst	cmdlun			; indirect file already open ?
	beq	10$			; no
	message	<Previous TAKE file closed>,cr
	calls	close	,<#lun.ta>	; yes, please close it now
	clr	cmdlun			; assume the next open will fail?
10$:	calls	open	,<#argbuf,#lun.ta>
	tst	r0			; did the open for command file work?
	bne	20$			; no, print error and exit
	mov	#lun.ta	,cmdlun		; yes, stuff the unit number in
	return				; bye

20$:	direrr	r0			; print a error message and exit
	clr	cmdlun			; force input from KB:
	return				; bye


;	R E A D C M D
;
;	input:	@r5	buffer address
;		2(r5)	prompt address
;	output:	r0	error
;		r1	byte count


readcmd:tst	cmdlun			; reading from indirect file
	beq	50$			; no, do a read on the terminal
	calls	getrec	,<@r5,#lun.ta>	; yes, try to read a record
	tst	r0			; did it work ?
	bne	30$			; yes

	tst	tkecho			; should we echo the prompt and
	beq	100$			; the command string read ?
	print	2(r5)			; yes, print the passed prompt
	print	@r5	,r1		; and also echo the command.z
	message				; crlf
	br	100$			; and exit with a success read

30$:	cmp	r0	,#ER$EOF	; hopefully, it's end of file
	beq	40$			; yes
	message	<Read error on TAKE file: >
	direrr	r0			; no, print the RMS error number
40$:	message	<Current TAKE file closed>,cr
	calls	close	,<#lun.ta>	; close the file on any errors
	clr	cmdlun			; and read a command from TI:

50$:	print	2(r5)			; print the prompt
	calls	echo	,<#0>		; ensure the local terminal echoes
	calls	kbread	,<@r5>		; read a record from the terminal
100$:	return				; bye


tkecho::.word	-1			; if <> then echo the take file

	global	<cmdlun	,argbuf	,cmdbuf	,er$eof	,lun.ta>

	.dsabl	lsb





	.sbttl	the SYSTEM command
	.enabl	lsb

c$sys::	$name	<SYS>
	tstb	argbuf			; need something in ARGBUF
	bne	10$			; oops
	message	<The SYSTEM command requires a command to execute>,cr
	return
10$:	strlen	#argbuf			; get the current length so we
	add	#argbuf	,r0		; can stuff a carriage return
	movb	#cr	,(r0)+		; and a null in
	clrb	@r0			; all set now
	mov	#200$	,r5		; call the PK driver
	call	runjob			; simple
	tst	r0			; did it work ?
	beq	100$			; yes
	message	<Error from spawning command >
	decout	r0
	message
100$:	return



;	ierr = runjob(buffer,mode,10,timout)
;
;	 All parameters for  RSTS are  used so we can use the
;	generalized PK code used also in MINITAB (C) and TED.
;	For RSX11M/M+, only the first argument is needed.

200$:	.word	4,argbuf,220$,230$,240$	; parameter list
220$:	.word	100305			; internal mode for running on the PK
230$:	.word	9.			; first free logical unit number
240$:	.word	10.			; ten minutes and i kill the PK's job
	.dsabl	lsb

	global	<argbuf	,runjob>




c$spac::$name	<SPA>
	sub	#120	,sp		; allocate space for a buffer
	mov	sp	,r1		; point to it
	calls	dskuse	,<r1>		; get the usage string
	print	r1			; print it
	message				; a crlf
	add	#120	,sp		; pop the local buffer
	return				; and exit




	.sbttl	the LOCAL command (basically, a NOP)


c$loc::	$name	<LOC>
	calls	getcm0	,<#argbuf,#cmdlst>
	tst	r0
	bmi	110$
	calls	getcm1	,<#argbuf,#cmdlst,r0>
	tst	r0
	bmi	110$
	jsr	pc	,@r1
110$:	return


	global	<argbuf>




	.sbttl	the REMOTE command
	.enabl	lsb

c$rem::	$name	<REM>
	call	ckremo			; insure that we are remote
	bcs	120$			; no, exit then
	calls	getcm0	,<#argbuf,#remlst>
	tst	r0			; did we find the remote command
	bmi	110$			; no
	calls	getcm1	,<#argbuf,#remlst,r0>
	tst	r0			; now could we get command arguements?
	bmi	120$			; no
	jsr	pc	,@r1		; dispatch on it now please
	return
110$:	message	<Unrecogized REMOTE command>,cr
120$:	return

	.dsabl	lsb


	command	remlst	,BYE	,3	,rm$bye
	command	remlst	,COPY	,3	,rm$cop	,<From: >,string
	command	remlst	,DELETE	,3	,rm$del	,<Filepsec: >,string
	command	remlst	,DIRECTORY,3	,rm$dir	,<Of what: >,string
	command	remlst	,DISK	,3	,rm$spa
	command	remlst	,ERASE	,3	,rm$del	,<Filepsec: >,string
	command	remlst	,FINISH	,3	,rm$fin
	command	remlst	,GET	,3	,rm$get	,<Filespec: >,string
	command	remlst	,HELP	,3	,rm$hlp
	command	remlst	,RENAME	,3	,rm$ren	,<From: >,string
	command	remlst	,SPACE	,3	,rm$spa
	command	remlst	,TYPE	,3	,rm$typ	,<What: >,string
	command	remlst	,WHO	,3	,rm$who
	command	remlst








	.sbttl	define the allowable commands

	$cmglob	=	1		; globalize

	command	cmdlst	,@	,1	,c$take	,<Command file ? >,string
	command	cmdlst	,BYE	,3	,c$bye
	command	cmdlst	,COMMENT,4	,c$nop
	command	cmdlst	,CONNECT,3	,c$conn
	command	cmdlst	,COPY	,3	,c$copy	,<From: >,string
	command	cmdlst	,DELETE	,3	,c$del	,<What: >,string
	command	cmdlst	,DIRECT	,3	,c$dir
	command	cmdlst	,DISCONNECT,4	,c$disc
	command	cmdlst	,DISK	,4	,c$spac
	command	cmdlst	,ERASE	,3	,c$del	,<What: >,string
	command	cmdlst	,EXIT	,3	,c$exit
	command	cmdlst	,FINISH	,3	,c$fin
	command	cmdlst	,GET	,3	,c$get	,<File ? >,string
	command	cmdlst	,HANGUP	,3	,c$hang
	command	cmdlst	,HELP	,3	,c$help
	command	cmdlst	,LOCAL	,3	,c$loc	,<Local command ? >,string
	command	cmdlst	,LOGOUT	,3	,c$bye
	command	cmdlst	,NOTE	,3	,c$nop
	command	cmdlst	,QUIT	,3	,c$exit
	command	cmdlst	,RECEIVE,3	,c$rec
	command	cmdlst	,REMOTE	,3	,c$rem	,<Remote Kermit cmd ? >,string
	command	cmdlst	,RENAME	,3	,c$rena	,<From: >,string
	command	cmdlst	,SEND	,3	,c$send	,<File ? >,string
	command	cmdlst	,SERVER	,3	,c$serv
	command	cmdlst	,SET	,3	,c$set	,<What: >,string
	command	cmdlst	,SHOW	,3	,c$show	,<What: >,string
	command	cmdlst	,SPACE	,3	,c$spac
	command	cmdlst	,SYSTEM	,3	,c$sys	,<Command: >,string
	command	cmdlst	,TAKE	,3	,c$take	,<Command file ? >,string
	command	cmdlst	,TYPE	,3	,c$type	,<File ? >,string
	command	cmdlst	,WHO	,3	,c$who
	command	cmdlst

	.psect	$code


	.sbttl	get command from the attached terminal

;	G E T C M D
;
;	input:	nothing
;	output:	r0	command index in dispatch table
;		r0	-1 (CMD$BAD) for invalid command
;			-2 (CMD$EX)  for exit
;	side effects:	cmdbuf written into

	cvtarg	=	4 + 10 + 20 + 40 + 200

	.name	=	0
	.minle	=	2
	.cmdad	=	4
	.cmdar	=	6
	.cmdat	=	10

	cmd$ab	==	-3
	cmd$ex	==	-2
	cmd$bad	==	-1

getcmd::clrb	argbuf
10$:	clr	cmdnum
	mov	#cmdbuf	,r4		; point to the command buffer
	calls	readcmd	,<r4,#prompt>	; get from current input stream
	tst	r0			; and exit if it failed for whatever
	bne	120$			; oops
	tst	cccnt			; time to exit on control C ?
	bne	120$			; yep
	calls	cvt$$	,<r4,r1,#cvtarg>; remove junk, convert to upcase
	tst	r0			; anything left ?
	beq	10$			; no, reprompt and try again
	clrb	cmdbuf(r0)		; insure .asciz please
	calls	getcm0	,<r4,#cmdlst>	; search for the command
	mov	r1	,cmdadr		; store address of routine away
	mov	r0	,cmdnum		; store index of command away
	mov	r0	,r3		; did we actually find a command ?
	bmi	110$			; no
	calls	getcm1	,<r4,#cmdlst,r3>; now get the rest of the commandline
	tst	r0			; or prompt for extra. Did it work
	bmi	110$			; no
100$:	mov	cmdnum	,r0
110$:	return

120$:	mov	#cmd$ex	,r0
	return


	.psect	$pdata

prompt:	.asciz	/Kermit-11>/
	.psect	$code




	.sbttl	getcm1	check for additional input needed

;	G E T C M 1
;
;	input:	@r5	current command buffer
;		2(r5)	command table address
;		4(r5)	index of the current command
;
;	output:	r0	index of current command or < 0 for error
;		argbuf	any additional input or rest of the command line



getcm1:	save	<r1,r2,r3>
	mov	@r5	,r1
	scan	#40	,r1		; look for a space that might delimit
	tst	r0			; the command name from an argument
	beq	30$			; nothing there
	add	r1	,r0		; point to the string after the space
	copyz	r0,#argbuf,#200		; copy the command arg over please
	br	100$			; and exit

30$:	mov	4(r5)	,r3		; get the command index
	mul	#$listl*2,r3		; if no arg given, see if one is needed
	add	2(r5)	,r3		; add in base address of command table
	mov	.cmdar(r3),r3		; get the argument prompt now
	tstb	@r3			; anything there that is required ?
	beq	100$			; no
40$:	.print	r3			; yes, prompt for it and read it now
	calls	kbread	,<#argbuf>	; read a command from the keyboard
	tst	r0			; and exit if it failed for whatever
	bne	90$			; oops
	tst	cccnt
	bne	90$
	calls	cvt$$	,<#argbuf,r1,#cvtarg>; remove junk, convert to upcase
	tst	r0			; anything left ?
	beq	40$			; no, reprompt and try again
	clrb	argbuf(r0)		; insure .asciz
	br	100$


90$:	mov	#cmd$ab	,r0
	br	110$
100$:	mov	4(r5)	,r0
110$:	unsave	<r3,r2,r1>
	return


	global	<argbuf	,cmdadr	,cmdbuf	,cmdnum>




	.sbttl	getcm0	find the command in the table


;	input:	@r5	command buffer
;		2(r5)	first command descriptor block
;	output:	r0	command index
;		r1	dispatch address
;
;	errors:	r0	-1 (CMD$BAD)	unrecognized command
;
;
;	descriptor block:
;
;		.word	commandname text
;		.word	minimum length
;		.word	address of command itself
;		.word	required argument prompt or a null for nothing
;		.word	type of argument



getcm0::save	<r2,r3,r4>
	mov	@r5	,r1		; the passed command buffer
	strlen	r1			; get the command length
	mov	r0	,r3		; error if nothing is there
	beq	110$			; oops
	clr	r2			; length := 0
10$:	scan	(r1)+	,#cmdch		; is this character ok in name?
	tst	r0			; find it in the list ?
	beq	20$			; no, we have found enough
	inc	r2			; command name len and pointer
	sob	r3	,10$		; next

20$:	tst	r2			; anything useful in cmd line
	ble	110$			; No leading letters ????
	mov	2(r5)	,r4		; the list of edit commands
	clr	r3			; R3 will have the command #

30$:	tst	.name(r4)		; anything left in the command list
	beq	110$			; no
	cmpb	r2	,.minle(r4)	; check if command length is ok
	blo	40$			; no, not enough for the command
	 strlen	.name(r4)		; get the length of the command name
	 calls	instr, <.name(r4),r0,@r5,r2> ; the next command?
	 dec	r0			; if match = position 1 we have it
	 beq	100$			;  then 'found the command'
40$:	inc	r3			; commandnum := commandnum + 1
	add	#$listl*2,r4		; cmdsaddr   := succ( cmdsaddr)
	br	30$


100$:	mov	r3	,r0		; return command index and exit
	mov	.cmdad(r4),r1		; return the command address also
	br	200$

110$:	mov	#cmd$ba	,r0		; bad command
	br	200$

200$:	unsave	<r4,r3,r2>
	return

cmdch:	.asciz	/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-@_/
	.even




	.sbttl	cctrap	the control C trap


cctrap::cmp	cccnt	,#cc$max
	bhi	100$
	calls	setcc	,<#cctrap>
	inc	cccnt
	rti

100$:	jmp	c$exit

	global	<cccnt	,exit>




;	D I R E R $
;
;	called from DIRERR value    macro

	.enabl	lsb


direr$::mov	r0	,-(sp)		; direrr will select whether or not
	mov	4(sp)	,r0		; to call rms error or FIP (or DIR)
	beq	10$			; error based on whether the error
	calls	syserr	,<r0,#errtxt>	; code is < 0 (implies RMS) or > 0
	print	#errtxt			; which  implies either FIP  (RSTS)
	message				; or a DIRECTIVE error (RSX).  Thus
10$:	mov	(sp)+	,r0		; for RSX all error codes should be
	mov	@sp	,2(sp)		; made > 0 for non RMS errors.
	tst	(sp)+			; error 0 is a no-op.
	return

	.dsabl	lsb


	.sbttl	get/and or read second command argument

;	input:	argbuf	command args
;	output:	cmdbuf	first arg
;		argbuf	second arg
;		r0	error code from read if done, else zero


gettwo::save	<r1,r2>			; save temps please
	mov	#argbuf	,r2		; point to the arguement buffer
	tstb	@r2			; anything there (should be) ?
	beq	100$			; no
	dec	r2
10$:	inc	r2			; next byte
	tstb	@r2			; We have to finish parsing this
	beq	20$			; end of it, prompt for 'To:'
	cmpb	@r2	,#40		; find a space yet ?
	bne	10$			; no
	clrb	(r2)+			; yes, make it .asciz
	copyz	#argbuf	,#cmdbuf	; save the first part of the arg
	br	30$			; got old and new so we are all set

20$:	mov	#argbuf	,r2		; point to the 'to:' part to read
	copyz	r2	,#cmdbuf	; save the from part
	print	#200$			; and read the rest of it
	calls	echo	,<#0>		; ensure terminal can echo
	calls	kbread	,<r2>		; do it
	tst	r0			; did it work ?
	bne	100$			; no
	calls	cvt$$	,<r2,r1,#377>	; yes, remove all junk
	tst	r0			; anything left ?
	beq	20$			; no
	add	r2	,r0		; yes, make it .asciz
	clrb	@r0			; simple

30$:	copyz	r2	,#argbuf	; return arg number two in argbuf
	clr	r0			; no errors please
100$:	unsave	<r2,r1>			; pop temps and exit
	return

200$:	.asciz	/To:   /
	.even



	
	.end	kermit
