	ALWAYS	1FEB84	SUM	<SUM VIRTUAL MEMORY>
	.MCALL	DIR$,CALLR
;************************************************************************
;*									*
;*	MODULE: SUM and CSUM						*
;*									*
;*	FUNCTION: COMPUTE A 16-BIT BYTE-WISE SUM OVER A RANGE		*
;*									*
;*	INPUT PARAMETERS:						*
;*									*
;*	R0 POINTS TO THE COMMAND LINE IN PROCESS			*
;*									*
;*	OUTPUT PARAMETERS:						*
;*									*
;*	R0 POINTS JUST BEYOND COMMAND LINE				*
;*									*
;*	DESTROYS: R1,R2,R3,R4,R5					*
;*									*
;*	AUTHOR: KEVIN ANGLEY						*
;*									*
;*	DATE: 27-JUL-82							*
;*									*
;*	REVISED BY: CHRIS DORAN, SIRA LTD.				*
;*									*
;*	DATE: JAN-FEB 84						*
;*									*
;*	MODIFICATIONS:							*
;*		Support STEP option.					*
;*		Add CSUM command:					*
;*		Put BYTE and WORD keys, only used here, into this	*
;*		  module, for overlaid code.				*
;*		Return cs on error, cc if all OK.			*
;*									*
;************************************************************************

CSUM::	PUSH	(PC)+		; Set flag for CSUM entry
SUM::	PUSH			; Clear it for SUM
	CALL	FROMTH		; GET FROM ADDR IN R1, THRU ADDR IN R2,
				;  COUNT IN R3, and step in STEP
	BCS	250$		;  CS: NOT SUCCESSFUL, TAKE ERROR EXIT
	PUSH	R0		; SAVE COMMAND LINE POINTER
	CLR	R0		; CLEAR INITIAL SUM
	MOV	R1,R2		; SAVE FROM ADDRESS IN R2 - DON'T NEED THRU
30$:
	CLR	%1		; Clear whole word
	BISB	MEMORY(R2),R1	; Get byte to add, w/o sign extend
	ADD	R1,R0		; ADD TO ACCUMULATED SUM
	ADD	STEP,R2		; MOVE TO NEXT VIRTUAL MEMORY LOCATION
	SOB	R3,30$		; USE COUNT TO COUNT LOCATIONS TO SUM
	MOV	R0,R1		; PREPARE FOR CONVERSION
	MOV	R0,R5		; SAVE IN R5 FOR POSSIBLE OUTPUT TO LOCATION
	MOV	#SMO+SMOLEN-4,R0 ; PUT INTO MESSAGE
	CALL	PUTHX4		; CONVERT TO HEX - PUT IN MESSAGE
	OUTPUT	SMO
	POP	R0		; RESTORE COMMAND LINE POINTER
	TST	@SP		; CSUM?
	BNE	47$		; Yes, go store at THRU+1
	TSTB	(R0)		; "TO" SPECIFIED?
	BEQ	255$		;  EQ: NO - TAKE NO ACTION
	GETKEY	TO		; GET KEYWORD "TO"
	BEQ	40$		;  EQ: GOT IT
	OUTPUT	MSK		; MISSING KEYWORD
	BR	255$		; TAKE ERROR EXIT
40$:
	CMPB	#'%,(R0)	; PSEUDO-REGISTER DESTINATION FOR SUM?
	BNE	45$		;  NE: NO - GET 6-DIGIT HEX ADDRESS
	INC	R0		; POINT TO REGISTER NUMBER
	CLR	R1		; CLEAR HIGH BYTE OF REGISTER NUMBER
	CALL	GETHX2		; GET TWO DIGIT HEX NUMBER
	BCS	255$		;  CS: FAILURE
	MOVB	R5,REGISTER(R1)	; PUT IN LOW BYTE
	INCB	R1		; INCREMENT REGISTER NUMBER WITH WRAP
	SWAB	R5		; PREPARE TO PUT OUT HIGH BYTE
	MOVB	R5,REGISTER(R1)	; PUT IN HIGH BYTE
	BR	255$		; ALL DONE (CC from SWAB)
45$:
	CALL	GETHXL		; GET TARGET ADDRESS
	BCS	255$		;  CS: FAILED
	MOV	R1,R3		; PUT REAL ADDRESS WHERE IT BELONGS
	MOV	R2,R4
	BR	50$		; SUM just stores %5

47$:	MOV	%5,@SP		; Save sum for CSUM
	MOV	FROM,%2		; First store FROM address
	CALL	UNOFFSET	; Un-offsetted
	MOV	%3,%5		; (Lo word only -- only defined for 16-bit machines)
	MOV	THRU,%2		; Store at THRU
	INC	%2		;	       +1
	CALL	UNOFFSET	; Un-offsetted
	CALL	STOWRD		; Store word
	BCS	255$		;  CS: invalid
	MOV	@SP,%5		; Follow with checksum
50$:	CALL	STOWRD

250$:				; ERROR EXIT
255$:				; NORMAL EXIT
	POP			; Purge stack of SUM/CSUM flag
	CALLR	EXTRA		; PURGE COMMAND LINE OF SUPERFLUOUS JUNK
				;  AND RETURN FROM THERE

; Store word in %5 in two bytes addressed by %3/%4. Return cs from VALID if
; can't be done, else cc.
STOWRD:	CALL	300$		; Store lo byte
	BCS	355$		;  CS: INVALID
	SWAB	R5		; Swap to hi
300$:	CALL	VALID		; VALIDATE AND OFFSET LOC
	BCS	355$		;  CS: INVALID
	MOVB	R5,MEMORY(R2)	; PUT IN HIGH BYTE
	INCR34			; INCREMENT REAL ADDRESS
355$:	RETURN

	.END

