File: FPEAK.MC of Tape: Various/ETH/eth11-3
(Source file text) 

.TITLE THE PEAK PROCESSING SUBROUTINE(PEAK)
;LABORATORY SUBROUTINES
;DEC-11
;FILENAME FPEAK.MAC
;FILE ID FPEAK.1

.CSECT	FPEAK









;			COPYRIGHT (C) 1976 BY
;	    DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
;COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;
;
;
;LDP SOFTWARE DEVELOPMENT GROUP   SEPTEMBER, 1977.
	.SBTTL CONDITIONALS

	;CONDITIONAL ASSEMBLY PARAMETERS
	;  DEFINE PARAMETERS BY REMOVING FIRST ";" IN LINE WHICH 
	;  PRECEEDS THE APPROPRIATE PARAMETER.

;EIS=1
;EAE=1
;AUTOG$=1
.IFDF	EAE
DIV=177300
AC=DIV+2
MQ=AC+2
MUL=MQ+2
EAESR=MUL+3
.ENDC



	;CONDITIONAL ASSEMBLY PARAMETER DESCRIPTIONS

;EIS	"EIS" SHOULD BE DEFINED IF EIS(KE11-E) HARDWARE IS AVAILABLE
;	ON THE SYSTEM WHERE THIS SOFTWARE IS TO BE USED. IF NOT DEFINED,
;	SUBROUTINES WHICH MIMIC THE REQUIRED FUNCTIONS OF THIS HARDWARE
;	ARE ASSEMBLED AND SUBSTITUTED.
;
;EAE	"EAE" SHOULD BE DEFINED IF EIS HARDWARE IS NOT AVAILABLE BUT
;	THE EAE IS.
;	NOTE: IF EAE HARDWARE IS AVAILABLE AND IS TO BE USED, THE 
;	      DEFAULT ADDRESSES ASSOCIATED WITH THE DEVICE ARE USED.
;	      IF YOUR "EAE" IS NOT INSTALLED AT THE NORMAL LOCATIONS
;	      THE DEFAULT ADDRESSES OF THE STATUS WORDS SHOULD BE
;	      MODIFIED TO REFLECT THIS DESCREPENCY BY REDEFINING "DIV"
;	      BY EDITING THIS FILE AND SETTING IT EQUAL TO THE STARTING
;	      ADDRESS OF THE STATUS WORDS ASSOCIATED WITH THE "EAE".
;		
;AUTOG$	THIS SUBROUTINE IS GREATLY AFFECTED BY THIS CONDITIONAL 
;	ASSEMBLY PARAMETER.
;	IF DEFINED, THE DATA WILL ALWAYS BE HANDLED IN THE PROCESSING
;	PORTION OF THE ROUTINE AS IF THE DATA WAS OBTAINED VIA AUTO-
;	GAINING, THUS HAVING A POSSIBILITY OF EIGHTEEN(18) BIT 
;	SIGNIFICANCE, EVEN THOUGH THE ACTUAL DATA MAY BE EITHER 
;	AUTO-GAINED DATA OR 12-BIT NON-AUTO-GAINED DATA DEPENDING
;	ON THE EIGHTH VALUE IN THE PARAMETER TABLE. SEE OPERATING
;	MANUAL.
;	
	.IF	DF,AUTOG$
	OFSET=4
	.IFF
	OFSET=2
	.ENDC

	.SBTTL MACROS,GLOBALS


	R0=%0
	R1=%1
	R2=%2
	R3=%3
	R4=%4
	R5=%5
	SP=%6
	PC=%7

	;INTERNAL GLOBAL
.GLOBL	PEAK


	;MACROS

.MACRO	$MUL	SRC,RX
	.IFDF	EIS
	MUL	SRC,RX
	.IFF
	.NTYPE .SYM,RX
	.IIF NE .SYM .ERROR ;REGISTER MUST BE R0
	.IF NB SRC
	.IIF DIF SRC,R1	MOV SRC,R1
	.ENDC
	JSR PC,MULR0
	.ENDC
.ENDM


.MACRO	$DIV	SRC,RX
	.IFDF	EIS
	DIV	SRC,RX
	.IFF
	.NTYPE .SYM,RX
	.IIF NE .SYM,.ERROR ;REGISTER MUST BE R0
	.IF NB SRC
	.IIF DIF SRC,-(SP) MOV SRC,-(SP)
	.ENDC
	JSR PC,DIVR0
	.ENDC
.ENDM
	.SBTTL MULR0,DIVR0

.IFNDF EIS
;MULR0 SUBROUTINE TO SERVE $MUL SRC,REG MACRO
;USED TO SIMULATE THE INTEGER MULTIPLY INSTRUCTION WHEN THE USER 
;DOES NOT HAVE THE EXTENDED INSTRUCTION SET (EIS).
;CALLED BY THE FOLLOWING
;	MOV	SRC,R1
;	JSR	PC,MULR0
;	RETURNS HIGH PRODUCT IN R0, LOW IN R1
;ON RETURN ONLY C-BIT OF CONDITION CODES IS MEANINGFUL
;C=1 IMPLIES MORE THAN 16-BIT PRODUCT, C=0 IMPLIES SINGLE PREC. OK

;THE MACRO $MUL SRC,REG WILL ALSO GENERATE THIS CALLING SEQUENCE
;WHEN THE CONDITIONAL ASSEMBLY PARAMETER 'EIS' IS NOT DEFINED.

MULR0:	.IFDF	EAE
	MOV	R1,@#MQ		;PUT 1ST NUMBER IN MQ
	MOV	R0,@#MUL	;MULTIPLY BY SECOND NUMBER
	MOV	@#MQ,R1		;LOW ORDER PRODUCT
	MOV	@#AC,R0		;HIGH ORDER PRODUCT
	CLC
	BITB	#2,@#EAESR	;TEST FOR SINGLE PRECISION
	BNE	1$
	SEC			;C=0 IMPLIES 16-BIT PRODUCT OK
1$:	RTS	PC
	.ENDC
	.IFNDF	EAE
	MOV	R2,-(SP)	;PUSH TWO REGISTERS AND A FLAG
	MOV	R4,-(SP)
	CLR	-(SP)
	TST	R0		;CHECK SIGNS
	BPL	2$
	NEG	R0		;TAKE ABSOLUTE VALUES
	INC	@SP		;AND FLAG NEGATIONS
2$:	TST	R1
	BPL	4$
	NEG	R1
	DEC	@SP		;MINUS*MINUS=PLUS
4$:	MOV	#17.,R2		;COUNT ITERATIONS
	CLR	R4		;HIGH ORDER PRODUCT BUILT HERE
6$:	CLC			;CLEAR CARRY FOR ROTATES
	ROR	R4		;SHIFT MULTIPLIER AND PARTIAL PRODUCT
	ROR	R1
	BCC	8$		;NO ADD NEEDED
	ADD	R0,R4
8$:	DEC	R2		;COUNT ITERATION
	BGT	6$
	TST	R4		;WAS RESULT DOUBLE?
	BNE	10$		;YES
	CMP	R1,#100000	;MAYBE
	BLO	12$		;DEFINITELY NOT
	BHI	10$		;DEFINITELY
	TST	@SP		;SPECIAL CASE -2**15 OK
	BNE	12$		;YES
10$:	COM	R2		;USE THIS AS CARRY FLAG
12$:	TST	(SP)+		;IS RESULT TO BE NEGATED?
	BEQ	14$		;NO
	NEG	R4		;YES
	NEG	R1
	SBC	R4
14$:	MOV	R4,R0
	ASR	R2		;SET CARRY BIT FOR TWO WORD CASE
	MOV	(SP)+,R4	;RST REG
	MOV	(SP)+,R2
	RTS	PC
	.ENDC


;DIVR0	32 BY 16 BIT DIVIDE TO SUPPORT MACRO  $DIV  SRC,R0
;CALLED BY USING THE MACRO	$DIV	SRC,R0
;WHICH EXPANDS TO THE FOLLOWING WHEN EIS IS NOT AVAILABLE:
;		MOV	SRC,-(SP)
;		JSR	PC,DIVR0
;	ON RETURN R0 CONTAINS QUOTIENT, R1 CONTAINS REMAINDER
;	SIGN OF REMAINDER SAME AS SIGN OF DIVIDEND
;	CONDITION CODES N AND V CORRECTLY SET, Z AND C NOT

DIVR0:	.IFDF	EAE
	MOV	R1,@#MQ		;LOW ORDER DIVEND
	MOV	R0,@#AC		;HIGH ORDER DIFIDEND
	MOV	2(SP),@#DIV	;DIVIDE
	MOV	(SP)+,@SP	;PUT RETURN ADDR WHERE NEEDED
	MOV	@#MQ,R0		;QUOTIENT
	MOV	@#AC,R1		;REMAINDER
	ROLB	@#EAESR		;SET N AND V
	RTS	PC
	.ENDC
	.IFNDF	EAE
	MOV	2(SP),-(SP)	;GET SOURCE
	MOV	2(SP),4(SP)	;PUT RETURN WHERE NEEDED
	MOV	R2,2(SP)	;FREE A REGISTER
	MOV	(SP)+,R2	;AND FILL IT WITH SOURCE
	MOV	R3,-(SP)	;SAVE ANOTHER REGISTER
	CLR	-(SP)		;SET UP A SIGN CONTROL WORD
	TST	R0
	BGE	1$
	DECB	1(SP)		;KEEP TRACK OF THE ORIGINAL
	NEG	R0		;SIGN AND NEGATE
	NEG	R1		;THE ORIGINAL NUMBER
	SBC	R0		;  I
1$:	TST	R2
	BEQ	12$		;DIVISION BY ZERO IS A NO-NO
	BGT	2$		;->	CHECK THE SIGN
	INC	@SP		;AND KEEP TRACK AS ABOVE
	NEG	R2		;  I
2$:	MOV	R2,R3		;<-	MOVE THE DIVISOR AND
	NEG	R3		;NEGATE FOR THE ALGORITHM
	ADD	R3,R0		;PREFORM THE INITIAL SUBTRACTION
	BCS	12$		;CARRY SET IS AN OVERFLOW
	MOV	#20,-(SP)	;SET UP A COUNTER
	CLR	-(SP)		;THIS IS A LASTING CARRY BIT
3$:	ROL	R1		;ROTATE ONE LEFT
	ROL	R0
	TST	@SP		;CHECK THE LAST CARRY
	BEQ	4$		;IF ZERO ADD ELSE SUBTRACT
	CLR	@SP		;CLEAR THE CARRY
	ADD	R3,R0		;DO ONE MORE STEP
	BR	5$
4$:	ADD	R2,R0		;-2N+N=N FOR THIS STEP
5$:	ADC	@SP		;KEEP IT A WHILE
	BEQ	6$		;IF ZERO OMIT UPDATE
	INC	R1		;NO CARRY POSSIBLE
6$:	DEC	2(SP)		;DECREMENT COUNTER
	BGT	3$		;BRANCH IF MORE TO DO
	ROR	R1		;SEE ABOUT THE LAST CYCLE
	BCS	7$		;OMIT CORRECTION IF ONE
	ADD	R2,R0		;CORRECT REMAINDER
	CLC
7$:	ROL	R1		;REPLACE THE LAST BIT
	CMP	(SP)+,(SP)+	;POP TWO WORDS
	TST	@SP		;TEST FOR REMAINDER CHANGES
	BGE	8$		;OMIT IF POSITVE
	NEG	R0		;NEGATE REMAINDER
	CLRB	1(SP)		;CLEAR SIGN
	DEC	@SP		;BUT DO A GOOD JOB ON QUOTIENT
8$:	CMP	#100000,R1	;TEST FOR THE BUG IN THE ALGORITHM
	BLO	12$		;EXIT WITH ERROR OF TOO BIG
	BEQ	11$		;CHECK FOR OVERFLOW
9$:	TST	(SP)+		;TEST FOR QUOTIENT ADJUSTMENT
	BEQ	10$		;IF ZERO NONE NEEDED
	NEG	R1
10$:	MOV	R0,R2		;SAVE REMAINDER
	MOV	R1,R0		;GET QUOTIENT
	MOV	R2,R1		;AND REMAINDER WHERE NEEDED
	CLC
	BR	13$		;EXIT WITH NO OVERFLOW
11$:	TST	@SP		;TEST FOR NEGATIVE
	BNE	9$		;IF NEGATIVE, OK
12$:	TST	(SP)+		;REMOVE SIGN WORD
	SEC			;MARK OVERFLOW
13$:	MOV	(SP)+,R3	;THIS CLEARS V-BIT
	MOV	(SP)+,R2
	MOV	R0,R0		;THIS SETS Z,N
	BCC	14$
	SEV
14$:	RTS	PC
	.ENDC
.ENDC




	.SBTTL PARAMETER-VARIABLE TABLE OFFSETS


;	THE FOLLOWING LIST OF OFFSETS INTO THE PARAMETER TABLE - SCRATCH
;	AREA DEFINED BY THE ADDRESS IN REGISTER FIVE(R5) WHEN "PEAK" IS
;	CALLED IS USED BY THE ROUTINE.

SR=0		;ITABLE(1), ORIGINAL POINT DENSITY
WT=2		;ITALBE(2), BASELINE TEST PARAMETER
GT=4		;ITABLE(3), NO. OF PERSIST. CHANGES TO CHANGE DIRECTION
HM=6		;ITABLE(4), MINIMUM CHANGE CONSIDERED AN INCREASE
OUTTYP=HM+2	;ITABLE(5)
		;PARAMETER SPECIFIES FLOATING POINT CONVERT AS FOLLOWS
		; = 0  =>LEAVE RESULTS AS DOUBLE PRECISION INTEGER
		; = 1  =>CONVERT TO SINGLE PRECISION FLOATING POINT
		; = -1 =>CONVERT TO DOUBLE PRECISION FLOATING POINT
ERROR=OUTTYP+2	;ITABLE(6), PARAMETER SPECIFYING CALLING ERROR
		; =  0 => NO ERROR
		; =  N => ITABLE(N) IS IN ERROR(USUALLY NEG.)
		; = -N => THE NTH ARGUMENT IN THE CALL IS 
		;         INCORRECT
		; = -8 => NOT ENOUGH ARGUMENTS IN CALL
FIRSTM=ERROR+2	;ITABLE(7), SET EQUAL ZERO MEANS INITIAL MODULE CALL
.IF	DF,AUTOG$
AUT=FIRSTM+2 	;PPAUTG,SET NON-ZERO FOR AUTO-GAINED INPUT
.ENDC
CNTR1=FIRSTM+OFSET ;NEEDED COUNTER
SC=CNTR1+1	;BASELINE TEST INCREASE COUNTER
BS=SC+1		;BASELINE SWITCH. 0=PEAK STARTED ON BASELINE
		;	          1=LOOK FOR PEAK WIDTH
		;		  2=LOOK FOR END ON BASELINE
S1=BS+1		;SWITCH SET IF DECREASING W/OUT A PREV. INCREASE
S2=S1+1		;SWITCH SET IF INCREASING AFTER A DECRES OR BASELINE
Y1=S2+2		;FIRST POINT OF ARRAY USED FOR SMOOTHING WINDOW
.IF	DF,AUTOG$
Y1H=Y1+2	;HI-ORDER PART OF FIRST POINT OF ARRAY
.ENDC
Y2=Y1+OFSET	;SECOND POINT OF ARRAY
.IF	DF,AUTOG$
Y2H=Y2+2	;HI-ORDER OF 2ND PT
.ENDC
Y3=Y2+OFSET	;THIRD PT
.IF 	DF,AUTOG$
Y3H=Y3+2
.ENDC
Y4=Y3+OFSET	;FOURTH PT
.IF	DF,AUTOG$
Y4H=Y4+2
.ENDC
Y5=Y4+OFSET	;FIFTH PT
.IF	DF,AUTOG$
Y5H=Y5+2
.ENDC
Y6=Y5+OFSET	;SIXTH PT
.IF	DF,AUTOG$
Y6H=Y6+2
.ENDC
Y7=Y6+OFSET	;SEVENTH PT
.IF	DF,AUTOG$
Y7H=Y7+2
.ENDC
WS=Y7+OFSET	;SWITCH TO DOUBLE DN IF RATE DECREASE IS NEEDED
PTR=WS+2	;PTR FOR INITIAL SIX POINTS NEEDED FOR DIGITAL FILTER
CAL=PTR+2	;LO-ORDER PART OF AREA ACCUM. DURING SIGNAL INCREASE
CAH=CAL+2	;HI-ORDER PART
OSL=CAH+2	;LO-ORDER PART OF OLD SLOPE MINIMUM
OSH=OSL+2	;HI-ORDER PART
TML=OSH+2	;LO-ORDER PART OF CURRENT PT COUNTER
TMH=TML+2	;HI-ORDER PART
CNTR2=TMH+2	;COUNTER OF POINTS TO AVERAGE
SAV0=CNTR2+2	;WORD TO STORE R0 WHILE WAITING FOR NEXT INPUT BUFFER
SAV1=SAV0+2	;WORD TO STORE R1
SAV6=SAV1+2	;WORD TO STORE SP
MC=SAV6+2	;TEMPORARY COUNTER FOR # OF MINS FOUND
CC=MC+2		;TEMPORARY COUNTER FOR # OF MAXS FOUND
MX=CC+2		;CURRENT MAXIMUM
.IF	DF,AUTOG$
MXH=MX+2	;HIGH ORDER PART OF CURRENT MAXIMUM
.ENDC
KM=MX+OFSET	;LAST CREST HEIGHT
.IF	DF,AUTOG$
KMH=KM+2	;HIGH ORDER PART
.ENDC
CTL=KM+OFSET	;LO-ORDER PART OF TIME OF LATEST MAXIMUM
CTH=CTL+2	;HI-ORDER PART
KTL=CTH+2	;LO-ORDER PART OF PEAK LEADING MINIMUM TIME
KTH=KTL+2	;HI-ORDER PART
BTL=KTH+2	;LO-ORDER PART OF LEADING BASELINE MINIMUM TIME
BTH=BTL+2	;HI-ORDER PART
BM=BTH+2	;LEADING BASELINE MINIMUM
.IF	DF,AUTOG$
BMH=BM+2	;HI-ORDER PART
.ENDC
SLL=BM+OFSET	;LO-ORDER PART OF NEW OR CURRENT SLOPE*1000
SLH=SLL+2	;HI-ORDER PART
OAL=SLH+2	;LO-ORDER PART
OAH=OAL+2	;HI-ORDER PART OF AREA
PH=OAH+2	;LOW ORDER PART OF PEAK HEIGHT
PHH=PH+2	;PEAK HEIGHT	(SAVED FOR OUTPUT)
PTL=PHH+2	;LO-ORDER PART
PTH=PTL+2	;HI-ORDER PART OF TIME OF PEAK (SAVED FOR OUTPUT)
LMH=PTH+2	;LO-ORDER PART
LMHH=LMH+2	;LEADING MINIMUM HEIGHT(SAVED FOR OUTPUT)
LMTL=LMHH+2	;LO-ORDER PART
LMTH=LMTL+2	;HI-ORDER PART OF TIME OR LEADING MINIMUM 
WDL=LMTH+2	;LO-ORDER PART
WDH=WDL+2	;HI-ORDER PART OF WIDTH(IN SAMPLE CNTS)
MN=WDH+2	;LO-ORDER PART
MNH=MN+2	;TRAILING MINIMUM
MTL=MNH+2	;LO-ORDER PART
MTH=MTL+2	;HI-ORDER PART OF TIME OF TRAILING MINIMUM
TYPE=MTH+2	;OUTPUT PEAK TYPE INDICATOR
		;	=0, IMPLIES PEAK ENDED ON BASELINE
		;	=1, IMPLIES PEAK ENDED ON VALLEY
DN=TYPE+4	;ACTUAL DENSITY OF THE POINTS IN THE PROCESS
INPUT=DN+4	;ADDRESS OF INPUT BUFFER
INSIZ=INPUT+2	;ADDRESS OF INPUT BUFFER SIZE
INPTR=INSIZ+2	;ADDRESS OF INPUT BUFFER POINTER
OUTPUT=INPTR+2	;ADDRESS OF OUTPUT BUFFER
OUTSIZ=OUTPUT+2	;ADDRESS OF OUTPUT BUFFER SIZE IN PEAK SETS
OUTPTR=OUTSIZ+2	;ADDRESS OF OUTPUT BUFFER PEAK SET POINTER
	.SBTTL PEAK CALLING DESCRIPTION

	;FORMAT OF FORTRAN CALL SHOULD BE AS FOLLOWS:

	;CALL PEAK(ITABLE,INPUT,INLAST,INPTR,OUTPUT,IDIMO,NPEAKS)

	;WHERE
	;"ITABLE" IS AN INTEGER*2 ARRAY OF LENGTH 68 IF "AUTOG$" IS NOT
	;   DEFINED OR OF LENGTH 79 IF "AUTOG$" IS DEFINED.
	;   THE FIRST SEVEN, OR EIGHT IF "AUTOG$" IS DEFINED, ELEMENTS OF
	;   THIS ARRAY CONTAIN PARAMETERS WHICH ARE USED TO GIVE FINAL 
	;   DEFINITION TO THE PEAK PROCESSING ALGORITHM. THEY ARE AS
	;   FOLLOWS:
	;	1) ITABLE(1) IS A VALUE INDICATING THE NUMBER OF SAMPLES
	;		     TO AVERAGE TO GET ONE POINT FOR THE SEVEN
	;		     POINT DIGITAL FILTER USED IN THE ALGORITHM.
	;		     AS THE PEAKS GROW IN WIDTH DURING THE RUN,
	;		     THE VALUE ACTUALLY USED BY THE ALGORITHM
   	;		     WILL INCREASE BY "ITABLE(1)".
	;	2) ITABLE(2) IS A VALUE USED FOR THE WIDTH TEST TO FIND
	;		     THE BASELINE.  WHEN VALUES ARE RECEIVED 
	;		     THAT ARE "ITABLE(2)"*WIDTH PAST THE PEAK
	;		     TIME, THE BASELINE IS THEN SOUGHT.
	;	3) ITABLE(3) IS A VALUE USED FOR THE DIRECTIONAL CHANGE
	;		     INDICATOR. IT REPRESENTS THE NUMBER OF 
	;		     CONSECUTIVE MOVEMENTS BY THE DATA IN THE
	;		     OPPOSITE DIRECTION TO CHANGE DIRECTION.
	;	4) ITABLE(4) IS A VALUE REPRESENTING THE MINIMUM CHANGE
  	;		     IN INPUT UNITS TO BE CONSIDERED AN INCREASE.
	;	5) ITABLE(5) THIS ELEMENT RELATES THE "DATA TYPE" OF THE
	;		     OUTPUT ARRAY AS FOLLOWS:
	;		     =  0 => OUTPUT ARRAY IS INTEGER*4
	;		     =  1 => OUTPUT ARRAY IS REAL*4
	;		     = -1 => OUTPUT ARRAY IS REAL*8
	;	6) ITABLE(6) THIS ELEMENT CONTAINS THE ERROR INDICATION
	;		     ON RETURN FROM SUBROUTINE
	;		     =  0 => NO ERROR
	;		     =  N => ITABLE(N) IS IN ERROR(USUALLY NEG.)
	;		     = -N => THE NTH ARGUMENT IN THE CALL IS 
	;			     INCORRECT
	;		     = -8 => NOT ENOUGH ARGUMENTS IN CALL
	;  !!! NOTE !!!
	;	IF ITABLE IS OMITTED, THE SUBROUTINE WILL CAUSE A
	;	FATAL MEMORY TRAP ERROR.
	;
	;	7) ITABLE(7) IS AN ELEMENT WHICH MUST BE ZERO ON THE 
	;		     INITIAL ENTRY TO THE SUBROUTINE.  THIS TELL
	;		     THE ROUTINE TO DO THE INITIALIZATION
	;		     WHICH IS NEEDED ONLY ONCE.  THE ROUTINE THEN
	;		     USES THIS ELEMENT FOR REENTRY PURPOSES AND 
	;		     THUS SHOULD NOT BE USED BY THE USER AFTER
	;		     INITIAL ENTRY IS MADE.
	;   IF "AUTOG$" HAS BEEN DEFINED WHEN THE MODULE WAS ASSEMBLED 
	;   THEN:
	;	8) ITABLE(8) IS AN ELEMENT WHICH INDICATES IF THE INPUT 
	;		     DATA HAS BEEN AUTOGAINED AS IN LA-11.
	;		  	A) 0 INDICATES NO AUTOGAINED INPUT.
	;			B) 1 INDICATES ALL AUTOGAINED INPUT.
	;"INPUT" IS AN INTEGER*2 ARRAY OF LENGTH AT LEAST EQUAL TO
	;   "INLAST".
	;"INLAST" IS AN INTEGER*2 VARIABLE EQUAL TO THE VALUE OF THE 
	;   SUBSCRIPT OF THE LAST ELEMENT IN THE INPUT ARRAY WHICH 
	;   CONTAINS DATA TO BE PROCESSED.
	;"INPTR" IS AN INTEGER*2 VARIABLE EQUAL TO THE VALUE OF THE 
	;   SUBSCRIPT OF THE LAST ELEMEMT IN THE "INPUT" ARRAY PROCESSED
	;   BY THE SUBROUTINE. 
	;	A) WHEN A NEW "INPUT" ARRAY IS BEING PROVIDED THE 
	;	   SUBROUTINE, AS ON ORIGINAL ENTRY, "INPTR" SHOULD
	;          BE ZERO.
	;	B) WHEN A PARTIALLY PROCESSED ARRAY IS BEING PROVIDED
	;	   THE SUBROUTINE, AS ON REENTRY AFTER THE OUTPUT ARRAY
	;          HAD BEEN FILLED BUT ALL PROCESSABLE ELEMENTS OF INPUT
	;          HAD NOT BEEN PROCESSED, "INPTR" SHOULD BE EQUAL TO THE
	;	   SUBSCRIPT OF THE LAST ELEMENT OF "INPUT" WHICH HAS 
	;	   BEEN PROCESSED.  ALTERNATIVELY, "INPTR" EQUALS THE 
	;	   SUBSCRIPT OF THE ELEMENT OF "INPUT" MINUS ONE OF THE
	;	   NEXT ELEMENT TO BE PROCESSED.
	;		NOTE: ON RETURN FROM "PEAK" ONE OF TWO CONDITIONS
	;		      EXISTS, AND "INPTR" WILL HAVE A VALUE
	;		      INDICATING THE CONDITION AS FOLLOWS:
	;			1) IF ALL ELEMENTS IN "INPUT" HAVE BEEN
	;			   PROCESSED, "INPTR" WILL EQUAL "-1" ON
	;			   RETURN.
	;			2) IF SOME ELEMENTS IN "INPUT" HAVE NOT
	;			   BEEN PROCESSED, "INPTR" WILL HAVE THE
	;			   PROPER VALUE FOR REENTRY(SEE (B)).
	;		CAUTION!!!!
	;		NOTE: IF "INPTR" = -1 ON REENTRY TO THE 
	;		      ROUTINE, IT WILL DEFAULT TO A VALUE OF 
	;		      ZERO"0".
	;
	;"OUTPUT" IS A DOUBLE SUBCRIPTED(OR EQUIVALENT SINGLE SUBCRIPTED)
	;   ARRAY OF LENGTH (10,XXX) WHERE "XXX" IS AT LEAST
	;   "IDIMO".  FOR EVERY VALUE OF THE SECOND SUBSCRIPT THERE ARE
	;    10 PEAK DATA DESCRIPTOR ELEMENTS AS FOLLOWS:
	;		NOTE: THE DATA TYPE OF "OUTPUT" IS ASSUMED TO BE
	;		      THAT SPECIFIED BY "ITABLE(5)".
	;	1) OUTPUT(1,N) IS THE AREA OF THE NTH PEAK.
	;	2) OUTPUT(2,N) IS THE HEIGHT OF THE NTH PEAK.
	;	3) OUTPUT(3,N) IS THE TIME OF THE NTH PEAK.  
	;	4) OUTPUT(4,N) IS THE LEADING MINIMUM HEIGHT OF THE NTH
	;		       PEAK.
	;	5) OUTPUT(5,N) IS THE TIME OF THE LEADING MINIMUM.
	;	6) OUTPUT(6,N) IS THE HALF WIDTH AT HALF HEIGHT OF THE
	;		       NTH PEAK.
	;	7) OUTPUT(7,N) IS THE HEIGHT OF THE TRAILING MINIMUM OF
	;		       THE NTH PEAK.
	;	8) OUTPUT(8,N) IS THE TIME OF THE TRAILING MINIMUM OF THE
	;		       NTH PEAK.
	;	9) OUTPUT(9,N) IS THE TYPE INDICATOR OF THE NTH PEAK.
	;		       A) 0 INDICATES PEAK ENDED ON BASELINE.
	;		       B) 1 INDICATES PEAK ENDED ON VALLEY.
	;      10)OUTPUT(10,N) IS THE CURRENT NUMBER OF SAMPLES BEING
	;		       AVERAGED TO OBTAIN A "POINT" FOR THE SEVEN
	;		       POINT DIGITAL FILTER.
	;		NOTE: ALL TIMES AND WIDTHS ARE MEASURED IN 
	;		      SAMPLE PERIODS, AND ALL HEIGHTS ARE 
	;		      MEASURED IN INPUT UNITS.
	;"IDIMO" IS THE NUMBER OF PEAKS THAT CAN BE DETECTED BEFORE THE
	;   "OUTPUT" ARRAY IS FILLED. IT IS AN INTEGER*2 VARIABLE, AND 
	;   SERVES AS THE SECOND DIMENSION OF "OUTPUT".
	;"NPEAKS" IS AN INTEGER*2 VARIABLE EQUAL TO THE LAST VALUE
	;   OF THE SECOND SUBSCRIPT OF "OUTPUT" USED BY THE SUBROUTINE.
	;   ALTERNATIVELY, IT IS THE NUMBER OF SETS OF PEAK DATA STORED
	;   BY THE SUBROUTINE IN THE ARRAY "OUTPUT".
	;	A) WHEN THE "OUTPUT" ARRAY HAS NO PEAK DATA IN IT, OR
	; 	   THE PEAK DATA HAS BEEN COPIED SO THAT DATA CAN BE 
	;	   STORED AT THE START OF THE ARRAY, "NPEAKS" SHOULD
	;	   EQUAL ZERO.
	;	B) WHEN A PARTIALLY FILLED ARRAY IS BEING PROVIDED THE
	;	   SUBROUTINE, AS ON REENTRY AFTER THE INPUT ARRAY HAS
	;	   BEEN COMPLETELY PROCESSED BUT THE OUTPUT ARRAY WAS
	;	   NOT FILLED, "NPEAKS" SHOULD BE SET EQUAL TO THE LAST
	;	   VALUE OF THE SECOND SUBSCRIPT OF THE ARRAY "OUTPUT"
	;	   WHICH POINTS TO PEAK DATA.  ALTERNATIVELY, "NPEAKS"
	;	   SHOULD BE SET EQUAL TO THE VALUE MINUS ONE OF THE
	;	   NEXT VALUE OF THE SECOND SUBSCRIPT OF "OUTPUT" WHERE
	;	   PEAK DATA CAN BE STORED.
	;		NOTE: ON RETURN FROM "PEAK" ONE OF TWO CONDITIONS
	;		      EXISTS, AND "NPEAKS" WILL HAVE A VALUE
	;		      INDICATING THE CONDITION AS FOLLOWS:
	;			1) IF ALL ELEMENTS IN "OUTPUT" HAVE BEEN
	;			   FILLED WITH PEAK DATA, "NPEAKS" WILL
	;			   EQUAL (-1) ON RETURN.
	;			2) IF SOME ELEMENTS IN "OUTPUT" HAVE NOT
	;			   BEEN FILLED, "NPEAKS" WILL HAVE THE 
	;			   PROPER VALUE FOR REENTRY(SEE (B)).
	;		CAUTION!!!!
	;		NOTE: IF "NPEAKS" = -1 ON REENTRY TO THE 
	;		      ROUTINE, IT WILL DEFAULT TO A VALUE OF 
	;		      ZERO"0".

	.SBTTL PEAK ENTRY POINT

PEAK:	MOV	R5,R2		;COPY R5
	MOVB	(R2),R3		;GET NO. OF ENTRIES
	BNE	SOME		;IF NONE,
TRAPER:	MOV	R0,1		;IF FIRST ARGUMENT IS MISSING OR
				; DEFAULTED, CAUSE A M-TRAP THROUGH 4
				; ERROR 61 IN FORTRAN
ERRET:	MOV	R3,ERROR(R5)	;INDICATE ERROR
	RTS 	PC		;AND RETURN
SOME:	TST	(R2)+		;POINT TO FIRST ARG ADDRESS
	MOV	(R2)+,R5	;GET WORK AREA ADDRESS
	CMP	#-1,R5		;TEST FOR "ITABLE" PRESENT
	BEQ	TRAPER		;IF NOT, GO TRAP OUT
	CLR	ERROR(R5)	;CLEAR ERROR INDICATOR
	MOV	R5,R4		;GET COPY OF ADDRESS
	CMP	R3,#7		;MAKE SURE THERE ARE ENOUGH
	BGE	2$		;IF ENOUGH CONTINUE
	MOV	#-8.,R3		;OTHERWISE, INDICATE WRONG NO. OF ARGS.
	BR	ERRET		; AND RETURN
2$:	MOV	#4,R3		;GET NO. OF PARAMETERS TO CHECK
	ADD	#10,R4		;POINT R4 TO 5TH ELEMENT
3$:	TST	-(R4)		;CHECK NEXT PARAMENTER
	BLE	ERRET		;IF NEG, RETURN WITH ERROR
	DEC	R3		;AND MORE PARAMETERS TO CHECK
	BNE	3$		;IF SO BRANCH
	ADD	#INPUT,R4	;GET ADDRESS TO STORE I/O ADDRESSES AT
	COM	R3		;SET R3 TO -1
INLOOP:	DEC	R3
	MOV	(R2),(R4)+	;STORE NEXT QUANTITY
	CMP	#-1,(R2)+	;MAKE SURE THE ARGUMENT IS NOT DEFAULTED
	BEQ	ERRET		;IF DEFAULTED, REPORT ERROR
	CMP	#-7,R3		;CHECK FOR END OF LOOP
	BNE	INLOOP		;COUNT THEM
	MOV	@INPTR(R5),R4	;GET OFFSET
	BGE	3$		;IF POS., IS BEING CONTROLLED BY USER
	CLR	R4		;OTHERWISE, DEFAULT TO START OF ARRAY
3$:	ASL	R4		;IN BYTES
	ADD	R4,INPUT(R5)	;GET INPUT BUFFER POINTING RIGHT
	ASR	R4		;GET POINTER BACK IN WORDS
	NEG	R4		; THEN PREPARE TO FIND COUNT
	MOV	#-3,R3		;SET R3 TO INDICATE POSSIBLE ERROR
	TST	@INSIZ(R5)
	BLE	ERRET		;ERROR RETURN IF ARRAY SIZE IS FAULTY
	DEC	R3		;IF NOT, UPDATE POSSIBLE ERROR INDICATOR
	ADD	@INSIZ(R5),R4	; FIND REMAINING COUNT
	BLE	ERRET		;ERROR RETURN IF ARRAY POINTER IS FAULTY
	SUB	#2,R3		;UPDATE POSSIBLE ERROR INDICATOR
	MOV	@OUTPTR(R5),R2	;GET OUTPUT OFFSET
	BGE	4$		;IF POS., IS BEING CONTROLLED BY USER
	CLR	R2		;OTHERWISE, DEFAULT TO START OF ARRAY
	BR	5$
4$:	MOV	#40.,R1		;GET REG. OUTPUT OFFSETT
	TST	OUTTYP(R5)	;SEE IF DOUBLE PRECISION REAL
	BGE	1$		;IF NOT BRANCH
	ASL	R1		;OTHERWISE, DOUBLE
1$:	MOV	R2,R0		;GET POINTER IN MULTIPLYING REGISTER
	$MUL	R1,R0
	ADD	R1,OUTPUT(R5)	;GET OUTPUT BUFFER POINTING RIGHT
	NEG	R2		;PREPARE TO FIND OUTPUT COUNT
5$:	TST	@OUTSIZ(R5)	;CHECK ARRAY SIZE
	BLE	ERRET		;ERROR RETURN IF ARRAY SIZE IS FAULTY
	DEC	R3		;OTHERWISE, UPDATE POSSIBLE ERROR IND.
	ADD	@OUTSIZ(R5),R2	; FIND REMAINING COUNT
	BLE	ERRET		;ERROR RETURN IF ARRAY POINTER IS FAULTY
	TST	FIRSTM(R5)	;CHECK FOR INITIAL ENTRY
	BEQ	INTIL		;IF SO , BRANCH
	CMP	#IRESUM-INTIL,FIRSTM(R5)	;CHECK FOR CORRECT VALUE
	BEQ	2$		;IF CORRECT , B+C
	CMP	#ORESUM-INTIL,FIRSTM(R5)	;CHECK OTHER POSSIBILITY
	BEQ	2$
	MOV	#7,R3		;IF NONE OF THE ABOVE, ERROR
	BR	ERRET		;INDICATE AND RETUR
2$:	MOV	R2,@OUTPTR(R5)	;SAVE OUTPUT COUNT
	MOV	R4,@INPTR(R5)	;SAVE INPUT COUNT
	ADD	FIRSTM(R5),PC	;GO RESUME - PIC,REENTRANTLY


	;COMES HERE ONLY ONCE AT THE FIRST CALL TO 
	;INITIALIZE VARIABLES AND PROCESSING

INTIL:	MOV	R2,@OUTPTR(R5)	;SAVE OUTPUT COUNT
	MOV	R4,@INPTR(R5)	;SAVE INPUT COUNT
	MOV	#24,R3		;GET COUNT OF LOCS TO CLEAR
	MOV	R5,R4		;GET LOCS
	ADD	#OAL,R4		; START ADDRESS
CLRLOC:	CLR	(R4)+		;CLEAR LOCS
	DEC	R3
	BNE	CLRLOC	; ALL OF THEM
	CLRB	SC(R5)		;CLEAR FLAGS. BASELINE SLOPE CHANGE CNTR
	CLRB	BS(R5)		;BASLINE SWITCH
	CLR	CAL(R5)		;ACC. AREA DURING INCREASE
	CLR	CAH(R5)
	MOV	#77777,OSH(R5)	;SET SLOPE TO LARGE NO.
	MOV	#177777,OSL(R5)	;
	CLR	WS(R5)		;RATE CHANGE SWITCH
	MOV	SR(R5),DN(R5)	;TAKE SAMPLE RATE FROM TABLE
	MOV	DN(R5),TML(R5)	;SET UP CURRENT TIME(IN SAMPLE PERIODS)
	CLR	TMH(R5)		;CLEAR HIGH PART OF TIME
	ASL	TML(R5)		;
	ROL	TMH(R5)
	ADD	DN(R5),TML(R5)
	ADC	TMH(R5)		;TIME=3*DENSITY
	MOV	R5,PTR(R5)	;GET ADDR
	ADD	#Y1,PTR(R5)	; OF FIRST AVERAGED ELEMENT
	MOVB	#6,CNTR1(R5)	;GET CNT OF AVERAGED ELEMENTS NEEDED


	;GET FIRST SIX AVERAGED POINTS FOR DIGITAL FILTER.

FIRST6:	JSR	PC,NEXTPT	;GET NEXT AVERAGED POINT

	MOV	R0,@PTR(R5)	;STORE LOW ORDER RESULT
	ADD	#2,PTR(R5)	;POINT TO NEXT LOC

	.IF	DF,AUTOG$
	MOV	R1,@PTR(R5)	;STORE HIGH ORDER RESULT
	ADD	#2,PTR(R5)	;POINT TO NEXT LOC
	.ENDC

	DECB	CNTR1(R5)	;HAVE THE 1ST 6 AVERAGED POINTS BEEN CAL
	BNE	FIRST6		;IF NOT , B+C


	;START OF NEW PEAK


N247:	MOVB	#1,S1(R5)	;SET DECREASING WITHOUT INCREASE
	CLR	MC(R5)		;CLR MINIMUM COUNTER
	CLR	CC(R5)		;CLR MAXIMUM COUNTER
	CLRB	S2(R5)		;SET NOT INCREASING AFTER A DECREASE
	MOV	#77777,MN(R5)	;SET MINIMUM TO LARGE NO.
	CLR	MX(R5)		;SET MAXIMUM LOW

	.IF	DF,AUTOG$
	MOV	#77777,MNH(R5)	;FINISH SETTING MINIMUM
	CLR	MXH(R5)		;FINISH SETTING MAXIMUM
	.ENDC

	;GETTING NEXT POINT

N100:	ADD	WS(R5),DN(R5)	;UPDATE SAMPLES TO AVERAGE
	CLR	WS(R5)		;CLEAR CHANGE SAMPLE RATE INDICATOR
	ADD	DN(R5),TML(R5)	;UPDATE CURRENT TIME
	ADC	TMH(R5)
	JSR	PC,NEXTPT	;GET NEXT AVERAGED POINT
	MOV	R0,Y7(R5)	;STORE LOW PART OF VALUE

	.IF	DF,AUTOG$
	MOV	R1,Y7H(R5)	;STORE HI PART OF VALUE
	.ENDC

	;START OF ALGORITHM FOR DIGITAL FILTER

	MOV	Y7(R5),R0	;ALGORITHM FOR GETTING CNTR WGTD VALUE
	ADD	Y1(R5),R0	; -(Y1+Y7)

	.IF	DF,AUTOG$
	MOV	Y1H(R5),R1
	ADC	R1
	ADD	Y7H(R5),R1	;         MOST SIG. HALVES
	.ENDC

	CLR	R2
	MOV	Y6(R5),R3	;+  4(Y6+Y2)
	ADD	Y2(R5),R3

	.IF	DF,AUTOG$
	ADC	R2
	ADD	Y6H(R5),R2
	ADD	Y2H(R5),R2	;         MOST SIG. HALVES
	.ENDC

	ASL	R3		
	
	.IF	DF,AUTOG$
	ROL	R2
	.ENDC

	ASL	R3

	.IF	DF,AUTOG$
	ROL	R2
	.ENDC

	SUB	R0,R3		;TERM2 - TERM1
	SBC	R2

	.IF	DF,AUTOG$
	SUB	R1,R2
	.ENDC

	MOV	Y5(R5),R0	;  + 11 * (Y5 + Y3)
	ADD	Y3(R5),R0

	.IF	DF,AUTOG$
	MOV	Y5H(R5),R4
	ADC	R4
	ADD	Y3H(R5),R4
	.ENDC

	MOV	#11.,R1
	JSR	PC,MULUNS
	ADD	R1,R3
	ADC	R2
	ADD	R0,R2

	.IF	DF,AUTOG$
	MOV	R4,R0
	$MUL	#11.,R0
	ADD	R1,R2
	.ENDC

	MOV	Y4(R5),R0	;  + 14 * Y4
	MOV	#14.,R1
	JSR	PC,MULUNS
	ADD	R1,R3
	ADC	R2
	ADD	R0,R2

	.IF	DF,AUTOG$
	MOV	Y4H(R5),R0
	$MUL	#14.,R0
	ADD	R1,R2
	BGE	DOD		;CHECK IF QUOTIENT IS POSITIVE
	CLR	R0		; IF NOT, SET Y4 TO ZERO
	CLR	R1
	BR	DOND
DOD:	MOV	R2,R0
	MOV	R3,R1
	MOV	#42.,R3		;[-(Y1+Y7)+4*(Y2+Y6)+11.*(Y3+Y5)+14.*Y4]/
	CLR	R2		;				    42.
	JSR	PC,DDIVD
DOND:	MOV	R1,Y4(R5)	;STORE NEW FILTERED POINT
	MOV	R0,Y4H(R5)
	.ENDC

	.IF	NDF,AUTOG$
	MOV	R2,R0
	MOV	R3,R1
	$DIV	#42.,R0		;[-(Y1+Y7)+4*(Y2+Y6)+11.*(Y3+Y5)+14.*Y4]/
				;                                     42.
	MOV	R0,Y4(R5)	;STORE NEW FILTERED POINT
	.ENDC

	;END OF ALGORITHM FOR DIGITAL FILTER

	;SHIFT POINTS FOR ALGORITHM DOWN ONE

	MOV	R5,R4		;SET Y(I) =  Y(I+1)
	ADD	#Y1,R4

	.IF	NDF,AUTOG$
	MOV	#6,R3
	.ENDC

	.IF	DF,AUTOG$
	MOV	#14,R3
	.ENDC

	.ENABL	LSB
1$:	MOV	OFSET(R4),(R4)+
	DEC	R3
	BNE	1$

	.IF	DF,AUTOG$
	CMP	Y3H(R5),MNH(R5)	;COMP. CENTER VALUE TO CURRENT MIN
	BLT	2$
	BEQ	3$		;IF EQUAL, CHECK LO-ORDER
	JMP	N150		;IF GREATER THAN OR EQUAL, B+C
	.ENDC

3$:	CMP	Y3(R5),MN(R5)	;CMPARE CENTER VALUE TO CURRENT MIN
	BLO	2$
	JMP	N150		;IF GREATER THAN OR EQUAL, B+C
	;NEW POINT LOWER THAN MINIMUM

2$:	CMPB	#1,BS(R5)	;ARE WE LOOKING FOR PEAK WIDTH
	BNE	N117		;IF NOT, B+C
	MOV	PH(R5),R1	;IF SO, CHECK IF LOW ENOUGH TO
	ADD	KM(R5),R1	;  CALCULATE PEAK WIDTH

	.IF	DF,AUTOG$
	MOV	PHH(R5),R0
	ADC	R0
	ADD	KMH(R5),R0
	ASR	R0		;CAL (KM+PH)/2
	.ENDC

	ROR	R1		;(KM+PH)/2 = TERM

	.IF	DF,AUTOG$
	CMP	Y3H(R5),R0	;IS CENTERED PT > TERM
	BGT	N117		;IF SO, B+C
	BLT	4$		;IF LESS, B+C
	.ENDC

	CMP	Y3(R5),R1	;IS CENTERED PT > TERM
	BHI	N117		;IF SO, B+C
4$:	MOV	TMH(R5),R0	;OTHERWISE, CALCULATE 1/2WID AT 1/2HT
	MOV	TML(R5),R1
	SUB	PTH(R5),R0
	SUB	PTL(R5),R1
	SBC	R0
	MOV	R0,WDH(R5)	;SET WIDTH
	MOV	R1,WDL(R5)
	MOVB	#2,BS(R5)	;INDICATE LOOKING FOR END PEAK ON BASLIN
	$DIV	DN(R5),R0	;IS WIDTH LESS THAN 25 PTS
	CMP	R0,#25.
	BLT	N117		;IF SO , B+C

	MOV	Y5(R5),R1	;OTHERWISE, ADD 1/2 Y5 TO ACC. AREA

	.IF	NDF,AUTOG$
	ASR	R1
	.ENDC

	.IF	DF,AUTOG$
	MOV	Y5H(R5),R0	
	ASR	R0
	ROR	R1
	.ENDC

	ADD	R1,OAL(R5)	;ADJUSTING ACC. AREA FOR STEP CHANGE
	ADC	OAH(R5)

	.IF	DF,AUTOG$
	ADD	R0,OAH(R5)
	.ENDC

	MOV	DN(R5),WS(R5)	;SET SWITCH TO HALVE SAMPLE RATE
N117:	MOV	Y3(R5),MN(R5)	;RECORD CURRENT MINIMUM VALUE

	.IF 	DF,AUTOG$
	MOV	Y3H(R5),MNH(R5)
	.ENDC

	MOV	TMH(R5),MTH(R5)	;RECORD CURRENT PT COUNTER
	MOV	TML(R5),MTL(R5)
	INC	MC(R5)		;INC MINS FOUND COUNTER
	MOV	Y3(R5),R0	;INC ACC. AREA BY
	MOV	DN(R5),R1	;  CENTERED PT. * SAMPLE RATE
	JSR	PC,MULUNS
	ADD	R1,OAL(R5)
	ADC	R0
	ADD	R0,OAH(R5)

	.IF	DF,AUTOG$
	MOV	Y3H(R5),R0
	$MUL	DN(R5),R0
	ADD	R1,OAH(R5)
	.ENDC

	ADD	CAL(R5),OAL(R5)	; AND INCREASE ACC. AREA BY AREA ACC.
	ADC	OAH(R5)		;   DURING INCREASE
	ADD	CAH(R5),OAH(R5)
	.ENABL	LSB
	TSTB	BS(R5)		;IS PEAK START ON BASELINE?
	BNE	1$		;IF NOT, B+C
	TSTB	S1(R5)		;ARE WE ON BACK SIDE OF PEAK
	BEQ	1$		;IF NOT, B+C
	CLR	OAH(R5)		;IF SO, ZERO ACC. AREA
	CLR	OAL(R5)
1$:	CLR	CAH(R5)		;CLEAR ACC. AREA DURING INCREASE
	CLR	CAL(R5)
	CMP	MC(R5),GT(R5)	;COMPARE #MINS TO GATE
	BGE	2$		;IF GREATER OR EQUAL, B+C
	JMP	N100		;OTHERWISE
2$:	MOVB	#1,S1(R5)	;INDICATE NOT ON BACKSIDE
	CLR	CC(R5)		;CLEAR MAXIMUMS COUNTER
	TSTB	S2(R5)		;WAS THERE AN INCR. AFTER A DECR. OR BASL
	BNE	3$		;IF SO, B+C
	CLR	MX(R5)		;IF NOT, SET MAX LO

	.IF 	DF,AUTOG$
	CLR	MXH(R5)
	.ENDC

	JMP	N200
3$:	MOV	CTL(R5),PTL(R5)	;RECORD PEAK TIME
	MOV	CTH(R5),PTH(R5)
	MOV	KTL(R5),LMTL(R5);RECORD LEADING MINIMUM TIME
	MOV	KTH(R5),LMTH(R5)
	MOV	MX(R5),PH(R5)	;RECORD PEAK HEIGHT
	MOV	KM(R5),LMH(R5)	;RECORD LEADING MINIMUM HEIGHT

	.IF	DF,AUTOG$
	MOV	MXH(R5),PHH(R5)	;RECORD PEAK HEIGHT(MSH)
	MOV	KMH(R5),LMHH(R5);RECORD LEADING MINIMUM HEIGHT(MSH)
	.ENDC

	MOVB	#1,BS(R5)	;INDICATE LOOKING FOR HALF HEIGHT

	JMP	N247		;PREPARE FOR NEXT PEAK
	;NEW POINT LARGER THAN CURRENT MINIMUM

N150:	MOV	Y3(R5),R0	;UPDATE AREA ACC. DURING INCR BY
	MOV	DN(R5),R1	;CURRENT AREA
	JSR	PC,MULUNS
	ADD	R1,CAL(R5)
	ADC	R0
	ADD	R0,CAH(R5)

	.IF	DF,AUTOG$
	MOV	Y3H(R5),R0
	$MUL	DN(R5),R0
	ADD	R1,CAH(R5)
	.ENDC

	MOV	MX(R5),R1	;CHECK IF NEW PT. SIGNIFICANTLY INCREASED
	ADD	HM(R5),R1	; OVER LATEST MAX
	.ENABL	LSB

	.IF	DF,AUTOG$
	MOV	MXH(R5),R0
	ADC	R0
	CMP	Y3H(R5),R0	
	BGT	1$
	BLT	2$
	.ENDC

	CMP	Y3(R5),R1
	BHI	1$
2$:	JMP	N200
1$:	MOV	TML(R5),CTL(R5)	;IF INCREASE IS SIGNIFICANT, UPDATE MAX
	MOV	TMH(R5),CTH(R5)	;  INFORMATION
	INC	CC(R5)		;UPDATE TIME,MAXS FOUND COUNT,
	MOV	Y3(R5),MX(R5)	; AND HEIGHT

	.IF	DF,AUTOG$
	MOV	Y3H(R5),MXH(R5)
	.ENDC

	CMP	CC(R5),GT(R5)	;CMPARE #MAXS TO GATE VALUE
	BGE	3$		;IF HIGH ENOUGH, B+C
	JMP	N200		;OTHERWISE WAIT
3$:	CLR	MC(R5)		;CLR MINS COUNTER
	TSTB	S1(R5)		;ARE WE ON BACKSIDE OF PEAK
	BNE	4$		;IF SO, B+C
	JMP	N160		;OTHERWISE
4$:	MOV	MN(R5),R0	;UPDATE AREA ACC. DURING INCR. BY
	MOV	DN(R5),R1	;  1/2 LEADING MINIMUM * SAMPLE RATE
	JSR	PC,MULUNS

	.IF	DF,AUTOG$
	MOV	R1,R3
	MOV	R0,R2
	MOV	MNH(R5),R0
	$MUL	DN(R5),R0
	ADD	R0,R3
	MOV	R3,R1
	MOV	R2,R0
	.ENDC

	ASR	R0
	ROR	R1
	ADD	R1,CAL(R5)	;UPDATE AREA
	ADC	R0
	ADD	R0,CAH(R5)
	MOVB	#1,S2(R5)	;IND INCREASE AFTER DECREASE
	CLRB	S1(R5)		;IND NO DECREASE
	MOV	MTL(R5),KTL(R5)	;RECORD PEAK LEADING MINIMUM TIME
	MOV	MTH(R5),KTH(R5)
	MOV	MN(R5),KM(R5)	;RECORD PEAK LEADING MINIMUM

	.IF	DF,AUTOG$
	MOV	MNH(R5),KMH(R5)	
	.ENDC

	.ENABL	LSB
	CMPB	#1,BS(R5)	;DETERMINE WHAT TO DO BY WHERE WE ARE
	BLE	1$		;IF NOT STARTING ON BASELINE,END OF PEAK
	MOV	KTL(R5),BTL(R5)	;IF STARTING ON BASELINE, RECORD NEW 
	MOV	KTH(R5),BTH(R5)	;  BASELINE TIME AND
	MOV	KM(R5),BM(R5)	;  HEIGHT

	.IF	DF,AUTOG$
	MOV	KMH(R5),BMH(R5)
	.ENDC

	JMP	N160
1$:	BNE	2$		;IF NOT LOOKING FOR WIDTH, B+C
	MOV	MTL(R5),R1	;OTHERWISE,MUST CAL. PEAK WIDTH NOW
	MOV	MTH(R5),R0	;  SINCE PEAK HAS ENDED BEFORE 
	SUB	PTH(R5),R0	;  HALF HEIGHT WAS REACHED
	SUB	PTL(R5),R1
	SBC	R0
	ASR	R0
	ROR	R1		;WIDTH EQUALS 1/2(MIN TIM - LEAD MIN TIM)
	MOV	R0,WDH(R5)	;SET WIDTH
	MOV	R1,WDL(R5)
2$:	CLR	TYPE(R5)	;IND. NOT ON BASELINE
	JSR	PC,RITOUT	;OUTPUT PEAK DATA
	MOVB	#2,BS(R5)	;IND. LOOKING FOR END ON BASELINE
	MOV	WDL(R5),R1	;CHECK WIDTH
	MOV	WDH(R5),R0
	$DIV	DN(R5),R0
	CMP	#25.,R0		
	BLE	4$		;IF WIDER THAN 24 PTS, GO LOWER SAMP RATE
	JMP	N160
4$:	MOV	Y5(R5),R1	;CORRECT ACC AREA BY 1/2 Y5

	.IF 	NDF,AUTOG$
	ASR	R1
	.ENDC

	.IF	DF,AUTOG$
	MOV	Y3H(R5),R0
	ASR	R0
	ROR	R1
	ADD	R0,OAH(R5)
	.ENDC

	ADD	R1,OAL(R5)
	ADC	OAH(R5)
	MOV	DN(R5),WS(R5)	; CHANGE. SET SWITCH TO CHANGE SAMP RATE
	;LOOKING FOR BASELINE

N160:	MOV	MX(R5),MN(R5)	;SET CURRENT MAX TO CURRENT MIN

	.IF	DF,AUTOG$
	MOV	MXH(R5),MNH(R5)
	.ENDC

N200:	CMPB	#2,BS(R5)	;HAS THE WIDTH BEEN CALCULATED YET
	.ENABL	LSB
	BEQ	1$		;IF SO, B+C
2$:	JMP	N100		;IF NOT, GO GET NEXT PT
1$:	TSTB	S1(R5)		;IS PT ON BACKSIDE OF PEAK
	BEQ	2$		;IF NOT, GO GET NEXT POINT
	MOV	WDH(R5),R0
	$MUL	WT(R5),R0	;CAL WIDTH*WIDTH TEST
	MOV	R1,R3
	MOV	WDL(R5),R0	;IF SO, TEST TO SEE IF FAR ENOUGH PAST
	MOV	WT(R5),R1	;  TO START LOOKING FOR BASELINE
	JSR	PC,MULUNS
	ADD	R3,R0
	MOV	TML(R5),R3	;CAL TIME FROM CREST TO CURRENT POINT
	MOV	TMH(R5),R2
	SUB	PTH(R5),R2
	SUB	PTL(R5),R3
	SBC	R2
	CMP	R2,R0		;COMPARE TWO CALCULATED QUANTITIES
	BGT	4$		;IF FIRST IS GREATER, B+C
	BEQ	3$		;IF HIGH PARTS EQUAL, GO CHECK LO PARTS
5$:	JMP	N100		;IF FIRST IS LESS, GO GET NEXT POINT
3$:	CMP	R3,R1		;COMPARE LSH OF TWO CAL. QUANTITIES
	BLO	5$		;IF FIRST IS LESS, GO GET NEXT POINT
4$:	MOV	Y3(R5),R0	;OTHERWISE, CALCULATE CURRENT SLOPE
	CLR	-(SP)		; CLEAR SIGN FLAG
	SUB	BM(R5),R0	;SLOPE = (CURRENT POINT-LEADING BASELINE
				;                       MINIMUM)/
	.IF	DF,AUTOG$
	MOV	Y3H(R5),R2
	SBC	R2
	SUB	BMH(R5),R2
	BPL	55$		;IF POSITIVE, B+C
	INC	(SP)		;OTHERWISE, INDICATE SIGN CHANGE
	NEG	R2
	NEG	R0
	SBC	R2
55$:	TST	R2		;CHECK FOR ZERO SLOPE
	BNE	7$
	.ENDC
	
	.IF	NDF,AUTOG$
	BGE	6$		;IF POSITIVE, B+C
	INC	(SP)		;OTHERWISE, INDICATE SIGN CHANGE
	NEG	R0
	.ENDC

6$:	TST	R0		;CHECK FOR ZERO SLOPE
	BEQ	9$		;IF NON-ZERO , B+C
7$:	MOV	#1000.,R1
	JSR	PC,MULUNS

	.IF	DF,AUTOG$
	MOV	R0,R4
	MOV	R1,R3
	MOV	R2,R0
	$MUL	#1000.,R0
	ADD	R3,R0
	MOV	R0,R1
	MOV	R4,R0
	.ENDC

	MOV	TML(R5),R3	;          (CURRENT TIME-LEADING BASELINE
	MOV	TMH(R5),R2	;                        TIME)
	SUB	BTH(R5),R2
	SUB	BTL(R5),R3
	SBC	R3
	JSR	PC,DDIVD
	TST	(SP)+
	BEQ	9$
	NEG	R0		;IF SIGNS DIFFERED, SLOPE NEGATIVE
	NEG	R1
	SBC	R0
9$:	MOV	R0,SLH(R5)
	MOV	R1,SLL(R5)
	CMP	OSH(R5),SLH(R5)	;COMPARE TO OLD SLOPE
	BGT	10$		;IF OLD GREATER, GO UPDATE AND TRY AGAIN
	BLT	11$		;IF OLD IS LESS, CHECK IF BASELINE
	CMP	OSL(R5),SLL(R5)	;COMPARE TO LSH TO OLD SLOPE
	BLOS	11$		;IF OLD IS LESS, CHECK IF BASELINE
10$:	MOV	SLL(R5),OSL(R5)	;SET OLD TO NEW
	MOV	SLH(R5),OSH(R5)
	CLRB	SC(R5)		;CLEAR SLOPE INCR COUNTER
	JMP	N100		;GO GET NEXT POINT
11$:	INCB	SC(R5)		;INCRE SLOPE INCR COUNTER
	CMPB	#2,SC(R5)	;HAS SLOPE INCR TWICE IN A ROW
	BGE	12$		;IF SO, B+C
	JMP	N100		;OTHERWISE, GO GET NEXT POINT
12$:	MOV	#1,TYPE(R5)	;IND. ENDING PEAK ON BASELINE
	JSR	PC,RITOUT	;OUTPUT PEAK DATA BLOCK
	CLRB	SC(R5)		;CLEAR SLOPE INCR. COUNTER
	MOV	#77777,OSH(R5)	;SET SLOPE TO LARGE NO.
	CLRB	BS(R5)		;SET FLAG TO INDICATE STARTING AT BASELIN
	JMP	N100		;GO GET NEXT POINT
	.SBTTL UTILITIES

	;ROUTINE TO GET NEXT AVERAGED POINT


NEXTPT:	MOV	DN(R5),CNTR2(R5)	;GET NO.OF PTS TO AVERAGE
	MOV	INPUT(R5),R2	;GET INPUT TABLE ADDRESS
	CLR	R0		;GET SUM READY
	CLR	R1	
NEXTIN:	DEC	@INPTR(R5)	;CHECK REMAINING INPUT COUNT
	BGE	NEXTC		;IF MORE INPUT, BRANCH
	NEG	@OUTPTR(R5)	;OTHERWISE, FIX OUTPTR
	ADD	@OUTSIZ(R5),@OUTPTR(R5)	;FOR RETURN
	MOV	#IRESUM-INTIL,FIRSTM(R5)	;SET OFFSET FOR RESTART
	MOV	R0,SAV0(R5)	;SAVE APPROPRIATE INFO
	MOV	R1,SAV1(R5)
	MOV	(SP)+,SAV6(R5)
	RTS	PC		;RETURN

IRESUM:	MOV	SAV0(R5),R0	;RESTORE APPROPRIATE INFO
	MOV	SAV1(R5),R1
	MOV	SAV6(R5),-(SP)
	MOV	INPUT(R5),R2	;GET ADDR OF INPUT BUFFER
	DEC	@INPTR(R5)	;DECREMENT INPUT BUFFER COUNT
NEXTC:	MOV	(R2)+,R3	;GET NEXT DATUM
	
	.ENABL	LSB
	.IF	DF,AUTOG$
	.IFF	
	BMI	6$		;IF NEGATIVE, TREAT AS ZERO
	.IFT
	CLR	R4		;GET MSH READY
	TST	AUT(R5)
	BEQ	5$		;IF NOT, B+C
	MOV	-2(R2),-(SP)	;GET GAIN BITS
	BIC	#7777,(SP)
	BIC	(SP),R3		;GET RID OF GAIN BITS IN DATA
	SUB	#4000,R3	;GET IN RIGHT RANGE(SHOULD NOT BE NEG)
	BPL	20$
	CLR	R3		;IF NOT POSITIVE: ZERO
	BR	21$
20$:	SBC	R4		;GET RIGHT SIGN(SHOULD BE POSITIVE)
	SWAB	(SP)		;PUT IN RIGHT JUSTIFIED POSITION
	ASR	(SP)
	ASR	(SP)	
	ASR	(SP)
	COM	(SP)		;GET COMPLEMENT,I.E., # OF 	SHIFTS
	BIC	#177771,(SP)	;IN 2 LEAST SIGN. BITS
	BEQ	2$		;IF DONE, B+C
4$:	ASL	R3		;NORMALIZE VALUE
	ROL	R4
	DEC	(SP)		;MORE SHIFTS
2$:	BNE	4$		;IF SO, B+C
21$:	TST	(SP)+		;POP STACK
	.ENDC

5$:	ADD	R3,R1		;KEEP SUMMING
	ADC	R0

	.IF	DF,AUTOG$
	ADD	R4,R0		;ADD MSH
	.ENDC
6$:	DEC	CNTR2(R5)	;SHOULD MORE BE SUMMED
	BNE	NEXTIN		;IF SO , B+C
	MOV	R2,INPUT(R5)	;SAVE CURRENT ADDRESS OF INPUT BUFFER
	MOV	DN(R5),R3	;GET NO. IN SAMPLES AVERAGED
	
	.IF	DF,AUTOG$
	CLR	R2		;DIVID R0,R1 BY R2,R3. RESULT IN R0,R1
	JSR	PC,DDIVD
	MOV	R0,-(SP)
	MOV	R1,R0
	MOV	(SP)+,R1
	.ENDC

	.IF	NDF,AUTOG$
	$DIV	R3,R0		;DIVD R0,R1 BY R3. RESULT R0
	.ENDC
	RTS	PC



	;ROUTINE TO OUTPUT A BLOCK OF PEAK DATA.

RITOUT:	MOV	MN(R5),R0	;UPDATE AREA BY SUBTRACTING
	MOV	DN(R5),R1	;  1/2 LEADING MINIMUM * SAMPLE RATE
	JSR	PC,MULUNS

	.IF	DF,AUTOG$
	MOV	R1,R3
	MOV	R0,R2
	MOV	MNH(R5),R0
	$MUL	DN(R5),R0
	ADD	R0,R3
	MOV	R3,R1
	MOV	R2,R0
	.ENDC

	ASR	R0
	ROR	R1
	SUB	R1,OAL(R5)
	ADC	R0
	SUB	R0,OAH(R5)

	.ENABL	LSB
	MOV	OUTPUT(R5),R3	;GET OUTPUT BUFFER ADDRESS
	DEC	@OUTPTR(R5)	;CHECK OUTPUT SPACE REMAINING
	BGE	OUTCON		;IF THERE IS ANY, BRANCH AND CONTINUE
	NEG	@INPTR(R5)	;OTHERWISE, FIX UP INPTR 
	ADD	@INSIZ(R5),@INPTR(R5)	; FOR RETURN
	MOV	#ORESUM-INTIL,FIRSTM(R5)	;SET OFFSET FOR REENTRY
	MOV	(SP)+,SAV6(R5)	;SAVE SUBROUTINE RETURN ADDRESS(INTERNAL)
	RTS	PC		;AND RETURN

ORESUM:	MOV	OUTPUT(R5),R3	;GET OUTPUT BUFFER ADDRESS
	DEC	@OUTPTR(R5)	;DECREMENT COUNT
	MOV	SAV6(R5),-(SP)	;RETURN RETURN ADDRESS TO STACK

OUTCON:	MOV	#OAL,R4		;GET ADDR OF OUTPUT BLOCK
	ADD	R5,R4
	MOV	#10.,R0		;GET BLOCK LENGTH
	TST	OUTTYP(R5)	;TEST FOR FLOATING CONVERT
	BEQ	OUTLOP		;IF NO FLOATIN POINT, BRANCH
	MOV	R0,CNTR2(R5)	;SET COUNTER
FLTLOP:	MOV	R3,-(SP)	;SAVE OUTADDRESS
	CLR	R2		;INIT POSSIBLE 3RD WORD OF RESULT
	MOV	(R4)+,R1	;GET LOW PART
	BNE	1$		;BRANCH IF NOT 0
	MOV	@R4,R0		;IS ENTIRE NUMBER 0
	BEQ	7$		;BRANCH IF YES
1$:	MOV	@R4,R0		;GET HIGH PART
	BPL	2$		;BRANCH IF POSITIVE
	NEG	R0		;NEGATE HIGH PART, C=1
	NEG	R1		;NEGATE LOW PART
	SBC	R0
2$:	MOV	#237,R3		;SET MAXIMUM EXP+1
3$:	BIT	#177400,R0	;LOOK FOR A STRING OF 8 0 BITS
	BNE	5$		;BRANCH IF NOT FOUND
	SWAB	R0		;LEFT JUSTIFY THEM
	SUB	#8.,R3		;PERFORM A SHIFT BY 8
	SWAB	R1
	BISB	R1,R0		;INSERT NEW BITS
	CLRB	R1		;REMOVE THEM
	BR	3$		;TRY AGAIN
4$:	DEC	R3		;FIX EXP COUNT
	ROL	R1		;NORMALIZE R0:R1
	ROL	R0
5$:	BPL	4$		;LOOP TILL IMPLIED NORM BIT IN SIGN
	BISB	R1,R2		;PUT IN BITS 25-32
	SWAB	R2		;JUSTIFY IT
	CLRB	R1		;REMOVE THE BITS FROM 2ND WORD
	BISB	R0,R1		;MOVE THE NEW ONES IN FROM R0
	SWAB	R1		;JUSTIFY IT
	CLRB	R0		;REMOVE THEM FROM HIGH WORD
	SWAB	R0		;JUSTIFY IT
	SWAB	R3		;GET EXP INTO HIGH BYTE
	TST	@R4		;WAS ORIGINAL NUMBER + OR -
	BPL	6$		;BRANCH IF POSITIVE, C=0
	SEC
6$:	ROR	R3		;INSERT WITH EXP
	ADD	R3,R0		;CREATE RESULT
7$:	TST	(R4)+		;BUMP DATA POINTER
	MOV	(SP)+,R3	;GET ADDRESS
	MOV	R0,(R3)+	;STORE FIRST PART
	MOV	R1,(R3)+	;STORE NEXT PART
	TST	OUTTYP(R5)	;CHECK FOR DOUBE PRECISION FLOATING
	BPL	8$		;IF NOT, BRANCH
	MOV	R2,(R3)+
	CLR	(R3)+		;STORE LAST TWO PARTS
8$:	DEC	CNTR2(R5)	;CHECK FOR MORE
	BNE	FLTLOP		;IF MORE BRANCH BACK
	BR	OUTRET		;IF NOT RETURN
OUTLOP:	MOV	(R4)+,(R3)+	;PUT OUTPUT BLOCK IN OUTPUT BUFFER
	MOV	(R4)+,(R3)+	;PUT OUTPUT BLOCK IN OUTPUT BUFFER
	DEC	R0
	BNE	OUTLOP	;DECR BLOCK WORD CNT. B+C IF NOT ZERO
OUTRET:	MOV	R3,OUTPUT(R5)	;STORE CURRENT BUFFER POINTER
	CLR	OAL(R5)		;CLEAR AREA
	CLR	OAH(R5)
	RTS	PC

	;ROUTINE TO DIVIDE R0, R1 BY R2, R3 WITH RESULT IN R0,R1

DDIVD:	MOV	R5,-(SP)	;SAVE R5
	MOV	#32.,-(SP)	;GET LOOP COUNT
	CLR	R4		;READY REMAINDER(R4+R5)
	CLR	R5
	.ENABL	LSB
1$:	ROL	R1
	ROL	R0		;EXPOSE NEW BIT OF NEWMERATOR
	ROL	R4
	ROL	R5
	CMP	R2,R5		;DOES DENOMINATOR FIT
	BHI	3$		;IF NOT, B+C(CARRY = 0)
	BLT	2$		;IF SO, B+C
	CMP	R3,R4		;IF HIGH EQUAL, CHECK LOW PARTS
	BHI	3$		;BRANCH IF DENOM. TOO BIG(C=0)
2$:	SUB	R3,R4		;SUB DENOM FROM REMAINDER
	SBC	R5
	SUB	R2,R5
	SEC			;INDECATE NEW QUOTIENT BIT
3$:	DEC	(SP)		;CHECK LOOP COUNT
	BGE	1$		;IF MORE TO COME B+C
	TST	(SP)+		;UP SP
	MOV	(SP)+,R5	;RESTORE R5
	RTS	PC		;RESULT IN R3,R2


	;UNSIGNED SINGLE PRECISION MULTIPLY
	;MULTIPLIES THE CONTENTS OF R0 BY R1 AND STORES
	;RESULTS IN R0 AND R1


MULUNS:	.ENABL	LSB
	MOV	R3,-(SP)	;SAVE REGS 2 AND 3
	MOV	R2,-(SP)
	MOV	#100000,R3	;R3 CONTAINS COMPLETION FLAG
	CLR	R2		;R2 WILL CONTAIN HIGH ORDER PRODUCT
1$:	ROR	R1		;C = MULTIPLIER BIT
	BCC	2$		;BR IF ZERO MULTIPLIER BIT
	ADD	R0,R2		;BIT MULTIPLY
2$:	ROR	R2		;SHIFT HIGH ORDER
	ROR	R3		;THE LOW ORDER & COMPLETION FLAG
	BCC	1$		;BR IF MULTIPLICATION IS NOT COMPLETE
	MOV	R2,R0		;LEAVE RESULT IN R0 & R1
	MOV	R3,R1
	MOV	(SP)+,R2	;RESTORE REGISTERS
	MOV	(SP)+,R3	
	RTS	PC



	.END