PROCEDURE	<COMND - Runoff command parser>,010000
;+
; Copyright (c) 1976
; Digital Equipment Corporation, Maynard, Mass.
;
; This software is furnished under  a license for use only  on  a
; single computer system and may be  copied only with  the inclu-
; sion of  the  above  copyright notice.  This software,  or  any
; other copies thereof, may not be  provided  or  otherwise  made
; available to any other person except  for  use  on  such system
; and to  one who agrees  to  these license  terms.  Title to and
; ownership of the software shall at all times remain in DEC.
;
; The information in this software  is  subject to change without
; notice and should not be construed  as  a commitment by Digital
; Equipment Corporation.
;
; DEC assumes no responsibility for the use or reliability of its
; software on equipment which is not supplied by DEC.
;
; Abstract:	This module performs the command parsing for
;		Runoff. At the moment, it is extremely crude.
;
; Written: 1-Jun-72, -0.0.0-, L. Wade
;
; Modified: 16-Jan-80, -1.0.0-, Henry R. Tumblin
;	Produced Duke supported version
;
; Verified: 16-Jan-80, -1.0.0-, Henry R. Tumblin
;-

	.SBTTL	MCALLS AND RUNOFF DEFINITIONS

;	runoff defined globals

	.GLOBL	CCIN		; Read character from input file
				; Or secondary buffer
	.GLOBL	CMADR		; Special processing command pointer
	.GLOBL	CMBF		; Command buffer header
	.GLOBL	CMTAB		; Command table starting address
	.GLOBL	COMNT		; Comment processing subroutine
	.GLOBL	ECTAB		; End of command table pointer
	.GLOBL	ENDF		; End command seen
	.GLOBL	GCI		; Get character from input file
	.GLOBL	GCSCH		; Saved character for re-processing
	.GLOBL	HFIN		; Input buffer descriptor
	.GLOBL	LF		; Line feed
	.GLOBL	LITFG		; Literal active flag
	.GLOBL	LOOKUP		; Command lookup table
	.GLOBL	SDBUF		; Secondary input buffer
	.GLOBL	SEMI		; Semi-colon
	.GLOBL	SPECF		; Special command processing flag
	.GLOBL	TEXT		; Text processing subroutine
	.GLOBL	T1		; Temp #1
	.GLOBL	WCI		; Write character to output buffer
	.GLOBL	$SDISW		; Secondary buffer flag

;	Globals defined here
 
	.GLOBL	CMN		; Command handler entry point

	.SBTTL	CMN -- mainline

	CODE	COMND

;	Note:
;	R1 - Period character
;	R5 - Address of flag word 'F.1'

	.ENABL	LSB
;
;	Initialize command and secondary buffer descriptors
;
;	A copy of the input command is placed in
;	CMBF as well as SDBUF. SDBUF will still contain the
;	period, where CMBF will not.
;

CMN::	MOV	CMBF+BF.ADR,CMBF+BF.PTR	  ; Command buffer
	CLR	CMBF+BF.LEN		; Init length of command line
	MOV	SDBUF+BF.ADR,SDBUF+BF.PTR ; Initialise descriptor
	CLR	SDBUF+BF.LEN		; Init length of command line
	CALL	CMDCHS			; Write period into secondary buffer
	CALL	CMCIN			; Get first character of command
	CMPNE	#SEMI,R1,5$		; Not a comment?
	JMP	COMNT			; Process comment
;
;	Obtain index into command lookup table
;
5$:	BITB	#CHAUC!CHALC,CHATBL(R1) ; Is it alphabetic?
	BEQ	ILCM1			; EQ - no
	MOV	R1,R3			; Get character
	SUB	#'A,R3			; make it an offset
	ASL	R3			; Make it a byte offset
	MOV	LOOKUP(R3),R3		; Get index into command table
	BEQ	ILCM1			; Eq - then command doesn't exist

CM2:	MOV	2(R3),R2		; prepare to read defined command
	MOV	CMBF+BF.ADR,T1+BF.ADR 	; Prepare pointer to read user's cmd
	MOV	CMBF+BF.ADR,T1+BF.PTR 	; Set pointer
	MOV	CMBF+BF.PTR,T1+BF.END 	; set end
	MOV	CMBF+BF.LEN,T1+BF.LEN 	; Set current string length in buffer
CM4:	MOV	#T1,R4			; Get user's command character
	CALL	GCI			;  ..
	.WORD	CM5			; Need more from file
6$:	MOVB	(R2)+,R0		; Get next command character
	BMI	CM6			; If mi end of command
	CMPEQ	R1,R0,CM4		; characters match?

10$:	CMP	(R3)+,(R3)+		; Move up to next entry
	CMP	R3,#ECTAB		; At end of table ?
	BHIS	ILCM1			; Eq - then quit
	BR	CM2			; And check this command

CM5:	CALL	CMCIN			; Read user's command from file
	CMPEQ	R1,#LF,40$		; End of line?
	INC	T1+BF.END		; Reset end of temporary buffer
	INC	T1+BF.PTR		; Update pointer
	BR	6$			; Go check new character

CM6:	BITB	#CHAUC!CHALC,CHATBL(R1) ; Alphabetic?
	BNE	10$			; IF EQ yes
	TSTB	-(R2)			; Point to terminal byte
	BITEQ	#SPECF,(R5),23$		; No special processing active?
	CMPEQ	(R3),CMADR,30$		; Command address match?
	BITNE	#LITFG,(R5),50$		; Literal processing active?

23$:	BITNEB	#ENDF,(R2),ILCM1 	; Unexpected end directive?

27$:	BITNEB	(R2),(R5),ILCM1		; Command not legal in current context

30$:	MOV	#T1,R4			; Point to command buffer
	TST	BF.LEN(R4)		; Anything left there ?
	BNE	140$			; NE - yes
	MOVB	R1,GCSCH		; Save terminal byte
	BR	60$
140$:	MOV	T1+BF.PTR,R0		; Get current pointer
	SUB	T1+BF.ADR,R0		; Get length so far
	MOV	SDBUF+BF.ADR,SDBUF+BF.PTR ; Reset pointer
	ADD	R0,SDBUF+BF.PTR		; Point to remaining characters
	SUB	R0,SDBUF+BF.LEN		; Set length remaining
	CLRB	GCSCH			; Say nothing from saved char. buffer
	MOVB	#1,$SDISW		; Say input is coming from SDBUF

60$:	RETURN				; 

	.SBTTL	CMCIN - COMMAND CHARACTER INPUT

;	This routine will read a command character, convert
;	it to upper case if necessary, and store it in 
;	the secondary buffer.
 
;	R1 - the command character read

CMCIN:	CALL	CCIN		; read from input file
	CALL	CMDCHS		; write character into secondary buffer
	BITB	#CHALC,CHATBL(R1) ; Is it a lower case letter?
	BEQ	CMDCHC		; EQ - no
	BIC	#40,R1		; Make it lower case.
 
;	set pointer to command descriptor, then
;	go insert character in buffer

CMDCHC:	MOV	#CMBF,R4	; point to command descriptor
	CALL	WCI		; Write character into command buffer
	RETURN

;	set pointer to secondary input buffer and write
;	character out there

CMDCHS:	MOV	#SDBUF,R4	; point to secondary input descriptor
	CALL	WCI		; write character in command buffer
	RETURN

	.SBTTL	ILLEGAL COMMAND PROCESSING
 
;	At this point, the command is invalid. 
;	flush the remainder of the input line
;	print an error message, and return.

ILCM1:	CALL	CMCIN		; now add rest of line
	CMPNE	R1,#LF,ILCM1	; not end of line?, loop until there

40$:	BITNE	#LITFG,(R5),50$	; literal processing active?, then no error
	MOVB	R1,GCSCH	; save line feed character
	CLR	R1		; convert string to asciz
	CALL	CMDCHC		; store null character in buffer
	DIAG	ILCMM		; illegal command
	JMP	LCR		; And go back to main loop
 
;	Literal processing active, clear stack, say
;	input is coming from another source, and let
;	'text' handle it.

50$:	TST	(SP)+		; clean stack
	COMB	$SDISW		; set secondary input flag
	JMP	TEXT		; process text
	.DSABL	LSB

	.END
