	.TITLE	AUXSPN - Spawn A Command
	.IDENT	/1.0/
	.ENABL	LC
;+
;
;			  Free software BY
;		Project Software & Development, Inc.
;
; This  software  is  furnished  for  free and may be used and copied as
; desired.  This software or any other copies thereof may be provided or
; otherwise  made  available  to  any  other  person.  No  title  to and
; ownership of the software is hereby transferred or allowed. 
;
; The  information  in this software is subject to change without notice
; and  should  not  be  construed  as  a commitment  by PROJECT SOFTWARE
; AND DEVELOPMENT, INC.
;
; PROJECT SOFTWARE assumes no responsibility for the use or  reliability  
; of this software on any equipment whatsoever.
;
;	Project Software & Development, Inc.
;	14 Story St.
;	Cambridge, Ma. 02138
;	617-661-1444
;
;
; Title:	AUXSPN.MAC
; Author:	Robin Miller
; Date:		July 23, 1985
;
; Description:
;
;	This module contains the routines neccessary to spawn a command
; to the Monitor Console Routine (MCR).
;
; Modification History:
;
; April 17, 1986 modified to work with Reese IAS system, F. Borger
;-

	.ENABL	AMA
	.NLIST	BEX
	.psect	rwdata,rw,d,lcl,rel,con

	.MCALL	DIR$, SPWN$S, STSE$S
;
;	local definitions
;
ut.ac=20				;define terminal activity byte
;
;	Local storage:
;
DEFCLI::.BLKW	2			; The default CLI name.
TSKNAM:	.RAD50	%...XXX%		; Name of requested task
RUNNAM:	.RAD50	%RUN%			; Rad50 for run
MCRNAM:	.RAD50	%...MAS%		; Spawn command to Massage task
MFTNAM:	.RAD50	%...MFT%		; Multi function task name
MFTTAB:	.RAD50	/ABOALTCANDISENAFIXRESUNF/
UICBUF:	.WORD	0			; Buffer for saving current uic
SPNEST::.BLKW	8.			; Spawn exit status block .

	.psect	code,ro,i,lcl,rel,con
	.SBTTL	SPNCMD - Spawn A Command.
;+
;
; SPNCMD - Spawn a command.
;
; This routine is called to spawn a command from the table parser.  It
; detaches the terminal before spawning and then reattaches the terminal
; afterwards. (Modified to not do detach/reattach)
;
; Inputs:
;	R3 = The remaining string byte count.
;	R4 = The string buffer address.
;
; Outputs:
;	R3 = The string byte count is set to 0.
;	R4 = Points to end of the string buffer.
;
;	Registers R0 and R1 are destroyed.
;
;	All other registers are preserved.
;
;-
SPNCMD::CALL	PRESPN			; Write the pre-spawn sequence.
;*	CALL	SEWRAP			; Reenable automatic wrap-around.
;	DIR$	#DETACH			; Detach the terminal.
	MOV	#FMTBUF,R0		; Copy command to spawn here.
	MOV	R0,R1			; Copy the output address.
;
;	handle any @ command
;
	cmpb	(R4),#'@		; indirect ?
	bne	10$			; no
	movb	#'I,(R1)+
	movb	#'N,(R1)+
	movb	#'D,(R1)+
	movb	#' ,(R1)+
;
;	Copy the command line buffer.
;
10$:	MOVB	(R4)+,(R1)		; Copy the command line.
	cmpb	(R1)+,#140		; Lower case command ?
	blt	101$			; no, no problem
	bicb	#40,-1(R1)		; yes, make it upper case
101$:	SOB	R3,10$			; Loop until done.
	CLRB	(R1)			; Terminate the command line.
	SUB	R0,R1			; Calculate the byte count.

;	Setup the CLI to spawn to.

;	MOV	#DEFCLI,R2		; Set address of default CLI.
;	BIT	#S.MCR,KEYSTA		; Spawn this command to MCR ?
;	BEQ	20$			; If EQ, no.
	MOV	#MCRNAM,R2		; Yes, spawn command to MCR.

;20$:	BITB	#S.DCL,KEYSTA		; Spawn this command to DCL ?
;	BEQ	30$			; If EQ, no (use the MCR).
;	MOV	#DCLNAM,R2		; Yes, spawn command to DCL.

30$:	CALL	SPAWN			; Spawn the command line.
;	DIR$	#ATTACH			; Reattach the terminal.
	CALL	CHKERR			; Check/report any errors.
;*	CALL	CLWRAP			; Disable automatic wrap-around.
	JMP	AFTSPN			; Write the after spawn sequence.

	.SBTTL	SPAWN - Spawn an MCR command line.
;+
;
; SPAWN  - Spawn a MCR command line and wait until it's done.
;
; This subroutine spawns a command to the MCR dispatcher.
;
; Inputs:
;	R0 = Command line to spawn (<ESC> or <CR> appended.)
;	R1 = The command line byte count.
;	R2 = Address of CLI to spawn to.
;
; Outputs:
;	C bit clear/set = Success/failure.
;
;	All registers are preserved.
;
;-
SPAWN::	call	chkcmd			;check for user defined commands
	CALL	$SAVAL			; Save all registers.
;
;	CHECK FOR MFT NAMES
;
	mov	r1,-(sp)		;save used regs
	mov	r0,-(sp)
	mov	r2,-(sp)
	call	$cat5			;convert name to rad-50
	mov	(sp)+,r2
	mov	r1,TSKNAM+2		;save name for later spawn
	mov	#8.,R5			;set to check for 8. mft names
	mov	#MFTTAB,R4		;set to start of mft name table
6$:	cmp	r1,(r4)+		;compare req'd task with mft task
	bne	7$			;br if no match
	mov	#MFTNAM,R2		;change requested name
7$:	sob	R5,6$
;
;	do privilege check
;
	mov	.crtsk,r0		;get my atl again
	mov	a.ti(r0),r0		;now have pud pointer
	mov	u.pc(r0),uicbuf		;save current uic for later spawn
					;set activity bit in privileges byte
	bisb	#ut.ac,u.pr(r0)		;for automatic log-out option
	mov	u.lbn(r0),r0		;now have privilege word in r0
					;requested name (not mft or mas) in r1
	jsr	pc,prichk		;check users privileges
	tst	r0			;can he do this
	bpl	77$			;yes he can
	mov	(sp)+,r0		;no he can't
	mov	(sp)+,r1		;fix the stack
	jmp	PRIERR			;and do error thing

;
;	spawn first to task directly, then to massage
;
77$:	mov	(sp)+,r0		;restore used regs
	mov	(sp)+,r1
	MOV	R2,R3			; Copy the CLI to spawn to.
	cmp	r3,#mftnam		; is it multi function task ?
	beq	78$			; yes, dont try for task directly
	mov	#tsknam,r3		; no try for task first
78$:	MOV	R0,R2			; Copy the buffer address.
	ADD	R1,R2			; Point to the last byte.
	MOVB	#15,(R2)+		; Append a carret as terminator.
	cmp	tsknam+2,runnam		; Is this a run command?
	bne	780$			; br if not
	MOVB	#ESC,-1(R2)		; Append an escape as terminator.
					;  to prevent an MCR prompt.
780$:
;	INC	R1			; Adjust the byte count.
	movb	uicbuf,r2		; set up member uic
	bic	#177400,r2		; clear sign extend
	movb	uicbuf+1,r5		; set up group uic
	bic	#177400,r5		; clear sign extend
781$:	SPWN$S	R3,,,r5,r2,#SPNEFN,,#SPNEST,R0,R1 ; Spawn the command.
	cmp	tsknam+2,runnam		; is this a run command ?
	bne	782$			; br if not
	jmp	exit			; else leave now
782$:	cmp	$dsw,#-2		; task not installed ?
	bne	79$			; br if not
	cmp	R3,#tsknam		; only if we tried the task directly
	bne	79$			; should we retry with spawn
	mov	#mcrnam,r3
	br	781$
;79$:	CALL	CHKDIR			; Check the directive status.
;	BCS	100$			; If CS, the directive failed.
79$:	cmp	$dsw,#-7		; Is task already active ?
	bne	791$			; br if not
	jmp	acterr			; else do error thing
791$:	cmp	$dsw,#1			; did spawn go ?
	beq	792$			; br if it did
	jmp	otherr			; else do error thing
792$:	STSE$S	#SPNEFN			; Stop for spawned command.
	mov	@#.crtsk,r5		;get my atl again
	mov	a.ti(r5),r5		;now have pud pointer
	bitb	#ut.lg,u.pr(r5)		; is terminal logged on ?
	bne	100$			; br if it is
	jmp	exit			; user did a bye, so go away
100$:	RETURN

	.sbttl	Handler Errors
;
;	handle privilege error
;
PRIERR:	mov	#primes,r1		;set for call
	mov	#prilen,r2
	call	outmsg			;output privilege error message
	return
;
;	handle task already active error
;
ACTERR:	mov	#actmes,r1
	mov	#actlen,r2
	call	outmsg
	return
;
;	handler other error
;
OTHERR:	MOV	#othmes,r1
	mov	#othlen,r2
	call	outmsg
	return
	.psect	rwdata,rw,d,lcl,rel,con
;
;	error messages
;
PRIMES:	.ascii	/You do not have the privilege to issue that command./
PRILEN=.-PRIMES
	.even
ACTMES:	.ascii	/Task is already active at another terminal./
ACTLEN=.-ACTMES
	.even
OTHMES:	.ascii	/Unable to run task due to other error./
OTHLEN=.-OTHMES
	.even
	.END
