	.TITLE	SET
	.IDENT	"V1.8"
	.NLIST	BEX,CND
;
;   Author:	D. Mischler	26-OCT-87
;
;   This module implements the SET command.
;
	.MCALL	CSI$,CSI$1,CSI$2
	.MCALL	CLOSE$,OPEN$
	CSI$
	.PAGE
	.SBTTL	Top-level dispatch
	.PSECT	CODE,I,RO
;
;   Dispatch on SET keyword.
;
SET::	CALL	U$FNXT		; Find primary keyword, OK?
	BCS	MISARG		; No, complain.
	MOV	#SETTBL,R1	; Point to SET keyword table.
	CALL	U$DCOD		; Decode keyword, OK?
	BCS	ERRXIT		; No, complain.
	CALLR	(R2)		; Process keyword.

;   SET command keyword is missing.
MISARG:	MOV	#E.RAMS,R1	; Point to error message.
ERRXIT:	CALLR	ERROR		; Display error message.
	.PAGE
	.SBTTL	Set HISTORY buffer size
;
;   Set HISTORY buffer size.
;
SETHST:	CALL	U$FNXT		; Point to buffer size expression, OK?
	BCS	MISARG		; No, complain.
	CALL	XPRESS		; Evaluate size expression, all right?
	BCS	ERRXIT		; No, forget it.
	CALL	FREHST		; Deallocate current history buffer (if any).
	MOV	R1,R5		; Save history buffer size in entries, zero?
	BEQ	20$		; Yes, no buffer is desired.
	MUL	#18.,R1		; Multiply by entry size.
	MOV	R1,R0		; Copy buffer size into place, is it OK?
	BMI	30$		; No, fail it (claim memory is full).
	CALL	U$RQCB		; Attempt history buffer allocation, OK?
	BCS	30$		; No, complain.
	MOV	R0,HSTBUF	; Save history buffer address.
	MOV	R0,HSTPTR	; Save history buffer pointer.
	ADD	R0,R1		; Produce history buffer end address.
	MOV	R1,HSTEND	; Save it.
	MOV	R5,HSTSIZ	; Save history buffer size in entries.
10$:	CLR	(R0)+		; Zero a word.
	CMP	R0,R1		; Entire buffer zeroed?
	BNE	10$		; No, keep going.
20$:	RETURN
;   Here if memory fills up.
30$:	MOV	#E.MFUL,R1	; Point to error message.
	BR	ERRXIT		; Exit with complaint.

;
;   Routine to deallocate an existing history buffer.
;
FREHST:	JSR	R5,.SAVR1	; Preserve R1 - R5.
	MOV	HSTSIZ,R1	; Get current history buffer size, zero?
	BEQ	10$		; Yes, none of this is necessary.
	MUL	#18.,R1		; Get size of buffer in bytes.
	MOV	HSTBUF,R2	; Get history buffer address.
	MOV	#FREMEM,R0	; Point to free memory list header.
	CALL	$RLCB		; Release memory back to pool.
10$:	CLR	HSTBUF		; No history buffer exists.
	CLR	HSTPTR		; There is no current entry.
	CLR	HSTSIZ		; Zap history size word.
	RETURN
	.PAGE
	.SBTTL	Set LOG file
;
;   Set LOG file name.
;
SETLOG:	CALL	U$FNXT			; Point to file name, OK?
	BCS	MISARG			; No, complain.
	MOV	R0,-(SP)		; Save filename string base address.
	CALL	U$FTRM			; Find filename terminator.
	SUB	(SP),R0			; Get filename string length.
	MOV	R0,LOGCSI+C.CMLD	; Save length in CSI block.
	MOV	(SP)+,R2		; Get source buffer address.
	MOV	#LOGNAM,R1		; Point to destination buffer.
5$:	MOVB	(R2)+,(R1)+		; Save filename for later use.
	SOB	R0,5$
	MOV	#LOGCSI,R0		; Point to CSI control block.
	MOV	#LOGNAM,C.CMLD+2(R0)	; Save filename string address.
	CSI$1				; Perform syntax analysis, OK?
	BCS	10$			; No, complain.
	CSI$2	,OUTPUT			; Build data-set descriptor, OK?
	BCS	10$			; No, complain.
	TST	LOGOPN			; Is the log file open?
	BEQ	20$			; No, it's OK.
	CLOSE$	#LOGFDB			; Close log file.
	OPEN$	#LOGFDB			; Attempt to open log file, OK?
	BCC	20$			; Yes, exit quietly.
10$:	MOV	#E.LOPN,R1		; Point to error message.
	CALL	ERROR			; Complain.
	CLR	LOGENB			; Disable logging.
20$:	RETURN

;
;   Set TYPE for the EXAMINE command.
;
SETTYP:	CALL	U$FNXT		; Point to keyword, OK?
	BCS	MISARG		; No, complain.
	MOV	#TYPTBL,R1	; Point to type table.
	CALL	U$DCOD		; Decode type keyword, OK?
	BCS	ERRXIT		; No, complain.
	MOV	R2,DSPTYP	; Set up default display type.
	RETURN
	.PAGE
	.SBTTL	Set break, trace and watchpoints
;
;   Set breakpoint.
;
SETBRK:	MOV	#BRKLST,-(SP)	; Push breakpoint list head address.
	BR	.STPNT		; Enter common code.
;
;   Set tracepoint.
;
SETTRC:	MOV	#TRCLST,-(SP)	; Push tracepoint list head address.
	BR	.STPNT		; Enter common code.
;
;   Set watchpoint.
;
SETWCH:	MOV	#WCHLST,-(SP)	; Push watchpoint list head address.
.STPNT:	CALL	U$FNXT		; Find address expression, OK?
	BCS	60$		; No, required argument is missing.
10$:	CALL	XPRESS		; Evaluate address expression, all right?
	BCS	80$		; Nope, defecate on the user.
	MOV	R0,R3		; Save command line pointer.
	MOV	#P.LEN,R0	; Get length of required memory area.
	CALL	U$RQCB		; Attempt allocation, OK?
	BCS	70$		; No, complain.
	MOV	R1,P.ADDR(R0)	; Save address in halt point block.
	MOV	(SP),R5		; Point to list head.
;   Insert halt point block in the list by address.
20$:	MOV	(R5),R4		; Get address of next block, zero?
	BEQ	30$		; Yes, append to end of list.
	CMP	R1,P.ADDR(R4)	; Does new block go here?
	BLO	30$		; Yes, do it. Is specified point a duplicate?
	BEQ	40$		; Yes, deallocate block.
	MOV	R4,R5		; Cycle for next block.
	BR	20$		; Check next.
;   Link newly allocated halt point block into the list.
30$:	MOV	R0,(R5)		; Link previous block to new one.
	MOV	R4,(R0)		; Set up link to next.
	BR	50$		; See if there's another address expression.
;   Specified point is a duplicate: deallocate descriptor block.
40$:	MOV	R0,R2		; Copy block address.
	MOV	#FREMEM,R0	; Point to free memory list header.
	MOV	#P.LEN,R1	; Get block length.
	CALL	$RLCB		; Release memory.
;   Allow another address expression, separated by a comma.
50$:	MOV	R3,R0		; Restore command line pointer.
	CMPB	#',,(R0)+	; Is a comma next?
	BEQ	10$		; Yes, handle next block.
	TST	(SP)+		; Clean up stack and exit.
	RETURN
;   Missing argument.
60$:	MOV	#E.RAMS,R1	; Pick up error code.
	BR	80$
;   Allocation failure.
70$:	MOV	#E.MFUL,R1	; Pick up error code.
80$:	TST	(SP)+		; Clean up stack.
	CALLR	ERROR		; Display error message and return.
	.PAGE
	.SBTTL	Set profile range
;
;   Set profile range. No overlap with existing ranges is allowed.
;
SETPRO:	CALL	U$FNXT		; Find address expression, OK?
	BCS	100$		; No, complain about missing arguments.
	CALL	XPRESS		; Evaluate base of range, OK?
	BCS	199$		; No, complain.
	BIC	#1,R1		; Make sure address is even.
	MOV	R1,R5		; Save base address.
	CMPB	#':,(R0)+	; Is a delimiter present?
	BNE	100$		; No, complain about missing arguments.
	CALL	XPRESS		; Evaluate top of range, OK?
	BCS	199$		; No, complain.
	ADD	#2,R1		; Round up to next word address.
	BIC	#1,R1		; Make sure address is even.
	CMP	R1,R5		; Is top of range higher than base?
	BLOS	110$		; No, complain.
	MOV	R1,R4		; Save top of range.
;   Make sure new range does not overlap any existing ranges.
	MOV	#PROLST,R1	; Get profile range list header address.
10$:	MOV	(R1),R1		; Point to next profile range block, zero?
	BEQ	20$		; Yes, range is OK.
	MOV	PR.BAS(R1),R2	; Get range base address.
	CMP	R2,R4		; Is existing range base >= new top?
	BHIS	10$		; Yes, check next range.
	ADD	PR.RNG(R1),R2	; Get range top address.
	CMP	R2,R5		; Is existing range top <= new base?
	BLOS	10$		; Yes, check next range.
	BR	120$		; Address range overlaps an existing range.
;   New address range is OK.
20$:	SUB	R5,R4		; Get range size.
	MOV	#1,R3		; Get default compression factor.
	CALL	U$FNXT		; Has a compression factor been specified?
	BCS	30$		; No, use the default.
	CALL	XPRESS		; Evaluate compression factor, OK?
	BCS	199$		; No, complain.
	MOV	R1,R3		; Save compression factor, zero?
	BEQ	130$		; Yes, complain about it.
30$:	MOV	R4,R1		; Copy range size.
	CLR	R0		; Zero extend address range size.
	DIV	R3,R0		; Get number of words needed for counters, OK?
	BVS	140$		; No, complain.
	ASL	R0		; Make it number of bytes needed, OK?
	BCS	140$		; No, complain. Will result confuse U$RQCB?
	BMI	140$		; Yes, call it illegal.
	ADD	#PR.CNT+4,R0	; Adjust size for overhead and safety.
	MOV	R0,R2		; Copy block size.
	CALL	U$RQCB		; Attempt to allocate enough memory, OK?
	BCS	150$		; No, complain that memory is full.
	.PAGE
;
;   Fill in the profile range block and insert it in the list.
;
	MOV	R0,R1		; Copy block address.
	MOV	R2,-(SP)	; Save block size in bytes.
	ROR	R2		; Get block size in words.
40$:	CLR	(R0)+		; Zero the whole block.
	SOB	R2,40$
	MOV	(SP)+,PR.SIZ(R1); Save size of profile range block.
	MOV	R5,PR.BAS(R1)	; Save base address of range.
	MOV	R4,PR.RNG(R1)	; Save address range size.
	MOV	R3,PR.CMP(R1)	; Save compression factor.
	MOV	#PROLST,R5	; Point to profile range list header.
50$:	MOV	(R5),R4		; Get address of next range, zero?
	BEQ	60$		; Yes, insert new range here.
	CMP	PR.BAS(R1),PR.BAS(R4) ; Is new base less than existing base?
	BLO	60$		; Yes, insert new range here.
	MOV	R4,R5		; Set up new backwards pointer.
	BR	50$		; Try next block.
;   Insert new range in list.
60$:	MOV	R4,(R1)		; Set up link to next.
	MOV	R1,(R5)		; Link previous to new entry.
	RETURN
;   At least one argument is missing.
100$:	MOV	#E.RAMS,R1	; Required argument missing.
	BR	199$
;   Top of range must be higher than base.
110$:	MOV	#E.BAR,R1	; Bad address range.
	BR	199$
;   Range must not overlap another profile range.
120$:	MOV	#E.AROV,R1	; Address range overlap.
	BR	199$
;   Illegal compression factor.
130$:	MOV	#E.BCF,R1	; Bad compression factor.
	BR	199$
;   Range is too large for compression factor.
140$:	MOV	#E.RMBC,R1	; Range must be compressed.
	BR	199$
;   Memory full.
150$:	MOV	#E.MFUL,R1	; Memory full.
199$:	CALLR	ERROR		; Complain and exit.
	.PAGE
	.SBTTL	Set parameters
;
;   Set parameters. R1 must point to parameters keyword table.
;
SETPRM:	MOV	R1,-(SP)	; Save keyword table address.
	CALL	U$FNXT		; Find keyword start, OK?
	BCS	20$		; No, complain about missing argument.
10$:	MOV	(SP),R1		; Point to keyword table.
	CALL	U$DCOD		; Find keyword entry, OK?
	BCS	30$		; No, complain.
	MOV	R0,-(SP)	; Save command line pointer.
	CLR	R1		; Make a zero.
	CALL	(R2)		; Process keyword.
	MOV	(SP)+,R0	; Pop command line pointer.
	CALL	U$FNXT		; Is there another keyword?
	BCC	10$		; Yes, take care of it too.
	TST	(SP)+		; Remove keyword table address from stack.
	RETURN

;   Complain about missing argument.
20$:	MOV	#E.RAMS,R1	; Point to error message.
30$:	TST	(SP)+		; Pop keyword table address.
	CALLR	ERROR
	.PAGE
	.SBTTL	Set MODE parameters
;
;   Set MODE parameters.
;
SETMOD:	MOV	#MODTBL,R1	; Point to SET MODE keyword table.
	CALLR	SETPRM		; Set mode parameters.

;
;   Routines to set default radix.
;
SETBIN::MOV	BINFMT,R1	; Get binary format word.
	BR	SETRDX
SETDEC::MOV	DECFMT,R1	; Get decimal format word.
	BR	SETRDX
SETHEX::MOV	HEXFMT,R1	; Get hexadecimal format word.
	BR	SETRDX
SETOCT::MOV	OCTFMT,R1	; Get octal format word.
SETRDX:	BIC	#NC.LDZ,R1	; Disable leading zeroes.
	MOV	NCFLGS,R0	; Get current numeric conversion flags.
	BIC	#^C<NC.LDZ!NC.SGN>,R0 ; Mask to leading and signed bits.
	BIS	R0,R1		; Set flag bits appropriately.
	MOV	R1,NCFLGS	; Set up default conversion flags.
	RETURN

;   Enable leading zeroes.
LDZON::	BIS	#NC.LDZ,NCFLGS	; Enable leading zeroes.
	RETURN
;   Disable leading zeroes.
LDZOFF::BIC	#NC.LDZ,NCFLGS	; Disable leading zeroes.
	RETURN

;   Enable signed output.
SGNON::	BIS	#NC.SGN,NCFLGS	; Enable signed output.
	RETURN
;   Disable signed output.
SGNOFF::BIC	#NC.SGN,NCFLGS	; Disable signed output.
	RETURN

;   Enable instruction simulation.
SIMON::	MOV	#-1,SIMENB	; Enable instruction simulation mode.
	RETURN
;   Disable instruction simulation.
SIMOFF::CLR	SIMENB		; Disable instruction simulation mode.
	RETURN

;   Enable single mode (one value per line).
SINGON::MOV	#-1,SINGLE	; Enable single output mode.
	RETURN
;   Disable single mode (multiple values per line).
SINGOF::CLR	SINGLE		; Disable single output mode.
	RETURN

;   Enable symbolic output.
SYMBON::MOV	#C$SYMB,CNMODE	; Enable symbolic output.
	RETURN
;   Disable symbolic output.
SYMBOF::MOV	#C$NUM,CNMODE	; Disable symbolic output.
	RETURN
	.PAGE
	.SBTTL	Set OUTPUT parameters
;
;   Set OUTPUT parameters.
;
SETOUT:	MOV	#OUTTBL,R1	; Point to SET OUTPUT keyword table.
	CALLR	SETPRM		; Set output parameters.

;
;   Enable/disable terminal attachment during output.
;
ATTON:	MOV	#1,ATTENB	; Enable terminal attachment.
	RETURN
;   Disable terminal attachment during output.
ATTOFF:	CLR	ATTENB		; Disable terminal attachment.
	RETURN

;
;   Turn on logging.
;
LOGON:	TST	LOGENB		; Is logging already enabled?
	BNE	10$		; Yes, skip out.
	TST	LOGOPN		; Is log file open?
	BNE	10$		; Yes, just enable logging.
	OPEN$	#LOGFDB		; Open the log file, OK?
	BCS	20$		; No, complain.
10$:	MOV	#1,LOGENB	; Enable logging.
	RETURN
;   File open error prevents logging.
20$:	MOV	#E.LOPN,R1
	CALL	ERROR
;
;   Turn off logging.
;
LOGOFF:	CLR	LOGENB		; Disable logging.
	RETURN

;
;   Enable/disable terminal output.
;
TRMON:	MOV	#1,TRMENB	; Enable terminal output.
	RETURN
;   Disable terminal output.
TRMOFF:	CLR	TRMENB		; Disable terminal output.
	RETURN

;
;   Enable/disable command line verification.
;
VFYON:	MOV	#1,VFYENB	; Enable command line verification.
	RETURN
;   Disable command line verification.
VFYOFF:	CLR	VFYENB		; Disable command line verification.
	RETURN
	.PAGE
	.SBTTL	Keyword dispatch tables
	.PSECT	RODATA,D,RO
;
;   Top-level SET keyword table.
;
SETTBL:	KEYWRD	BREAK,SETBRK	; Breakpoint.
	KEYWRD	LOG,SETLOG	; Log file name.
 .IF DF	I$MTPS
	KEYWRD	HISTORY,SETHST	; History.
 .ENDC
	KEYWRD	MODE,SETMOD	; Mode parameters.
	KEYWRD	OUTPUT,SETOUT	; Output parameters.
	KEYWRD	PROFILE,SETPRO	; Profile range.
	KEYWRD	TRACE,SETTRC	; Tracepoint.
	KEYWRD	TYPE,SETTYP	; Display type.
	KEYWRD	WATCH,SETWCH	; Watchpoint.
	.WORD	0

;
;   SET OUTPUT keyword table.
;
OUTTBL:	KEYWRD	ATTACH,ATTON
	KEYWRD	LOG,LOGON
	KEYWRD	NOATTACH,ATTOFF
	KEYWRD	NOLOG,LOGOFF
	KEYWRD	NOTERM,TRMOFF
	KEYWRD	TERM,TRMON
	KEYWRD	NOVERIFY,VFYOFF
	KEYWRD	VERIFY,VFYON
	.WORD	0

	.END
