File: FNVLOP.MC of Tape: Various/ETH/eth11-2
(Source file text)
.TITLE THE ENVELOPE PROCESSING SUBROUTINE(NVELOP) ;LABORATORY SUBROUTINES ;DEC-11 ;FILENAME FNVLOP.MAC ;FILE ID FNVLOP.1 .CSECT FNVLOP ; 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 CONDITIONAL ASSEMBLY PARAMETERS ; TO DEFINE EITHER CONDITIONAL ASSEMBLY PARAMETER, DELETE THE ; SEMI-COLON(;) WHICH PRECEEDS THE LINE CONTAINING THE ; APPROPRIATE PARAMETER. ;EIS=1 ;EAE=1 .IFDF EAE DIV=177300 AC=DIV+2 MQ=AC+2 MUL=MQ+2 EAESR=MUL+3 .ENDC ;CONDITIONAL ASSEMBLY PARAMETER DESCRIPTIONS ; ;EIS "EIS" IS A CONDITIONAL ASSEMBLY PARAMETER ; AFFECTING THIS MODULE. IF NOT DEFINED, SUBROUTINES WHICH MIMIC ; THESE FUNCTIONS 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". ; .SBTTL GLOBALS AND MACRO DEFINITIONS ;INTERNAL GLOBAL .GLOBL NVELOP ;REGISTER DEFINITIONS(NEEDED FOR RT-11) R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ;MACRO DEFINITION .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 .SBTTL MULR0 ROUTINE .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 .ENDC .SBTTL OFSETS INTO PARAMETER - VARIABLE TABLE ; THE FOLLOWING IS A LIST OF THE OFFSETS INTO THE PARAMETER - ; VARIABLE TABLE (REGISTER FIVE(R5)CONTAINS THE ADDRESS OF THIS ; TABLE WHEN "NVELOP" IS CALLED) USED BY THIS ROUTINE. NOFC=0 ;NO. OF EXTRA CHANNELS OF DATA IGT=2 ;SENSITIVITY, # OF PTS NEEDED ON EACH SIDE OF PEAK BAS=4 ;BASELINE VALUE FOR DATA PATH OUTTYP=BAS+2 ;OUTPUT DATA TYPE SPECIFIER. SEE ITABLE(4) ERROR=OUTTYP+2 ;ELEMENT TO INDICATE POSSIBLE ERROR. SEE ITABLE(5) FIRSTM=ERROR+2 ;ZER0 ON FIRST CALL TO ROUTINE ONLY PK=FIRSTM+2 ;PEAK FOUND INDICATOR TML=PK+2 ;LO-ORDER OF LOCAL TIMER TMH=TML+2 ;HI TTL=TMH+2 ;LO-ORDER OF TOTAL TIMER TTH=TTL+2 ;HI CAL=TTH+2 ;LO-ORDER OF AREA ACCUMULATED DURING INCREASING TREND CAH=CAL+2 ;HI MX=CAH+2 ;CURRENT MAXIMUM VALUE MN=MX+2 ;CURRENT MINIMUM VALUE MC=MN+2 ;MINIMUMS COUNTER CC=MC+2 ;MAXIMUMS COUNTER T0L=CC+2 ;INITIAL TIME OF LOCAL TIME SEGMENT T0H=T0L+2 ;HI-ORDER TYPE=T0H+2 ;PEAK TYPE. =0 IF ENDS ON VALLEY, =1 IF AT THRESHOLD OAL=TYPE+4 ;LO-ORDER OF AREA OF CURRENT PEAK OAH=OAL+2 ;HI OCNL=OAH+2 ;LO-ORDER OF SUMMATION FOR, OR ACTUAL,CENTROID OCNH=OCNL+2 ;HI WDL=OCNH+2 ;LO-ORDER OF PEAK WIDTH WDH=WDL+2 ;HI TOPTL=WDH+2 ;LO-ORDER OF TIME OF PEAK TOPTH=TOPTL+2 ;HI TOP=TOPTH+2 ;PEAK HEIGHT FTML=TOP+4 ;LO-ORDER OF LEADING TIME OF PEAK FTMH=FTML+2 ;HI ADCV1L=FTMH+2 ;PLACE FOR TWO ADDITIONAL CHANNEL VALUES ADCV1H=ADCV1L+2 ADCV2L=ADCV1H+2 ADCV2H=ADCV2L+2 NOFEL=ADCV2H+2 ;NO. OF ELEMENTS TO OUTPUT SAVR=NOFEL+2 ;LOCATION TO SAVE REGISTERS AT CRITICAL TIMES CCNL=SAVR+2 ;LO-ORDER OF PARTIAL CENTROID SUMMATION CCNH=CCNL+2 ;HI CTL=CCNH+2 ;LO-ORDER OF TIME OF LATEST MAXIMUM CTH=CTL+2 ;HI CNT=CTH+2 ;LOCATION NEEDED FOR A COUNTER S1=CNT+2 ;INDICATES A DECREASING TREND WHEN SET S2=S1+1 ;INDICATES AN INCREASING TREND WHEN SET INPUT=S2+1 ;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 OUTPTR=OUTSIZ+2 ;ADDRESS OF OUTPUT BUFFER POINTER .SBTTL CALL STATEMET DESCRIPTION ;FORMAT OF FORTRAN CALL SHOULD BE AS FOLLOWS: ;CALL NVELOP(ITABLE,INPUT,INSIZ,INPTR,OUTPUT,OUTSIZ,OUTPTR) ;WHERE ;"ITABLE" IS AN INTEGER*2 ARRAY OF LENGTH 51. ELEMENTS OF ; THIS ARRAY CONTAIN PARAMETERS WHICH ARE USED TO GIVE FINAL ; DEFINITION TO THE ENVELOPE PROCESSING ALGORITHM. THEY ARE AS ; FOLLOWS: ; 1) ITABLE(1) IS A VALUE INDICATING THE NUMBER OF ; ADDITIONAL VALUES RECORDE WHEN THE INPUT ; CURVE BROKE THRESHOLD. ; 2) ITABLE(2) IS A VALUE REPRESENTING THE NUMBER OF POINTS ; NEEDED TO BE ON EACH SIDE OF A PEAK FOR IT ; TO BE CONSIDERED A PEAK(SENSITIVITY) ; 3) ITABLE(3) IS THE ASSUMED BASELINE VALUE. IT IS ; CALCULATED BY THE "ACQUISITION WITH ; THRESHOLDING MODULE" OR MAY BE SUPPLIED BY ; THE USER. IF THE USER DOES NOT WISH TO ; SUPPLY THIS VALUE IT SHOULD BE SET TO A ; NUMBER LESS THAN ZERO WHICH WILL CAUSE THE ; SUBROUTINE TO ASSUME THE DATA IS COMING ; FROM THE "ACQUISITION WITH THRESHOLDING" ; MODULE AND THAT THE FIRST INPUT WORD ; RECEIVED IS THE BASELINE VALUE. ; 4) ITABLE(4) ELEMENT SPECIFYING 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 ; 5) ITABLE(5) THIS ELEMENT CONTAINS THE ERROR INDICATION ; ON RETURN FROM SUBROUTINE ; = 0 => NO ERROR ; = N => ITABLE(N) IS IN ERROR(USUALLY NEG.) ; = -N => NTH ARGUMENT IN CALL IS FAULTY ; = -8 => NOT ENOUGH ARGUMENTS IN CALL ; !!! NOTE !!! ; IF ITABLE IS OMITTED, THE SUBROUTINE WILL CAUSE A ; FATAL MEMORY TRAP ERROR. ; ; 6) ITABLE(6) 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. ;"INPUT" IS AN INTEGER*2 ARRAY OF LENGTH AT LEAST EQUAL TO ; "INSIZ". THE INPUT ARRAY MUST HAVE THE FORMAT OF THE OUTPUT ; FROM THE "ACQUISITION WITH THRESHOLDING" MODULE. THUS THE ; VERY FIRST ELEMENT OF THE INPUT ARRAY ON THE FIRST CALL TO ; THIS SUBROUTINE MUST BE THE BASELINE VALUE UNLESS "ITABLE(3)" ; NON-NEGATIVE. IF SO, "ITABLE(3) IS TAKEN AS BASELINE AND DATA ; IS ASSUMED TO NOT INCLUDE A BASELINE VALUE. IF "ITABLE(3)" IS ; NEGATIVE, THE BASELINE VALUE READ FROM THE DATA IS STORED IN ; "ITABLE(3)". THE DATA STREAM IN "INPUT" SHOULD THEREFORE HAVE ; THE FOLLOWING FORM: ; ; BASELINE VALUE IF ITABLE(3) IS NEG, FOR ; FIRST INPUT ARRAY ONLY ; REJECT COUNT(LOW) NO. OF SAMPLE PERIODS ; REJECT COUNT(HIGH) BELOW THRESHOLD ; ADDITIONAL INPUT VALUE #1 OPTIONALLY READ WHEN DATA ; ADDITIONAL INPUT VALUE #2 BREAKS THRESHOLD. ; MONITORED INPUT VALUE DATA VALUES ABOVE ; MONITORED INPUT VALUE THRESHOLD ; MONITORED INPUT VALUE ; . ; . ; . ; ZERO(0) INDICATES NEW ENVELOPE ; REJECT COUNT(LOW) ; REJECT COUNT(HIGH) ; ADDITIONAL INPUT VALUE #1(OPTIONAL) ; ADDITIONAL INPUT VALUE #2(OPTIONAL) ; MONITORED INPUT VALUE ; MONITORED INPUT VALUE ; . ; . ; . ; ;"INSIZ" IS AN INTEGER*2 VARIABLE EQUAL TO THE NUMBER OF ELEMENTS ; IN ARRAY "INPUT" TO PROCESS. ;"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 "INSIZ" 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 "NVELOP" 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 ([7+"ITABLE(1)"],XXX) WHERE "XXX" IS ; AT LEAST "OUTSIZ". FOR EVERY VALUE OF THE SECOND SUBSCRIPT ; THERE ARE (7+"ITABLE(1)") PEAK DATA DESCRIPTOR ELEMENTS AS ; FOLLOWS: ; ; NOTE: THE DATA TYPE OF "OUTPUT" IS ASSUMED TO BE ; THAT SPECIFIED BY "ITABLE(4)". ; PROPER VALUE FOR REENTRY(SEE (B)). ; ; 1) OUTPUT(1,N) IS THE TYPE OF NTH PEAK ; = 1 IF ENDS AT THRESHOLD ; = 0 IF ENDS ON VALLEY ; 2) OUTPUT(2,N) IS THE AREA OF NTH THE PEAK ; 3) OUTPUT(3,N) IS THE CENTROID OF NTH THE PEAK ; 4) OUTPUT(4,N) IS THE WIDTH OF NTH THE PEAK ; 5) OUTPUT(5,N) IS THE POSITION OF NTH THE PEAK ; 6) OUTPUT(6,N) IS THE HEIGHT OF NTH THE PEAK ; 7) OUTPUT(7,N) IS THE STARTING POSITION OF THE NTH PEAK ; ; O 8) OUTPUT(8,N) IS THE FIRST ADDITIONAL VALUE PROVIDED AT ; P THE START OF THE CURRENT ENVELOP. ; T ; I ; O 9) OUTPUT(9,N) IS THE SECOND ADDITIONAL VALUE PROVIDED ; N AT THE START OF THE CURRENT ENVELOPE. ; A ; L ; ; NOTE: ALL TIMES AND WIDTHS ARE MEASURED IN ; SAMPLE PERIODS, AND ALL HEIGHTS ARE ; MEASURED IN INPUT UNITS. ;"OUTSIZ" 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". ;"OUTPTR" 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, "OUTPTR" 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, "OUTPTR" SHOULD BE SET EQUAL TO THE LAST ; VALUE OF THE SECOND SUBSCRIPT OF THE ARRAY "OUTPUT" ; WHICH POINTS TO PEAK DATA. ALTERNATIVELY, "OUTPTR" ; 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 "NVELOP" ONE OF TWO CONDITIONS ; EXISTS, AND "OUTPTR" WILL HAVE A VALUE ; INDICATING THE CONDITION AS FOLLOWS: ; 1) IF ALL ELEMENTS IN "OUTPUT" HAVE BEEN ; FILLED WITH PEAK DATA, "OUTPTR" WILL ; EQUAL (-1) ON RETURN. ; 2) IF SOME ELEMENTS IN "OUTPUT" HAVE NOT ; BEEN FILLED, "OUTPTR" WILL HAVE THE ; PROPER VALUE FOR REENTRY(SEE (B)). ; CAUTION!!!! ; NOTE: IF "OUTPTR" = -1 ON REENTRY TO THE ; ROUTINE, IT WILL DEFAULT TO A VALUE OF ; ZERO"0". .SBTTL NVELOP ENTRY POINT NVELOP: MOV R5,R2 ;COPY R5 MOVB (R2),R3 ;GET NO. OF ENTRIES BNE SOME ;IF NONE, ; !!! NOTE INTENTIONAL M-TRAP ERROR IF FIRST ARG IS OMITTED TRAPER: MOV R1,1 ;FATAL ERROR IF FIRST ARG IS OMITTED ; 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 ;CHECK FOR DEFAULTED ARG BEQ TRAPER ;IF FIRST ARG DEFAULTED, GO M-TRAP 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 #1,R3 ;SET UP TO REPORT POSSIBLE ERRORS TST NOFC(R4) ;CHECK SOME PARAMETERS BLT ERRET ;IF NEG, ERROR CMP #2,NOFC(R4) ;IF GREATER THAN 2 BLT ERRET ;ERROR INC R3 TST IGT(R4) ;CHECK ONE MORE BLE ERRET ;ERROR IF NEGATIVE ADD #INPUT,R4 ;GET ADDRESS TO STORE I/O ADDRESSES AT NEG R3 ;SET R3 TO -2 INLOOP: MOV (R2),(R4)+ ;STORE NEXT QUANTITY CMP #-1,(R2)+ ;CHECK FOR DEFAULTED ARG BEQ ERRET ;IF DEFAULTED, GO RETURN WITH ERROR DEC R3 CMP R3,#-8. ;CHECK FOR ALL ARGS CHECKED BNE INLOOP ;COUNT THEM MOV #-3,R3 ;SET R3 TO -3. USE TO REPORT ERRORS MOV @INPTR(R5),R4 ;GET OFFSET BGE 3$ ;IF TAKEN CARE OF BY USER, BRANCH CLR R4 ;IF NOT, ZERO POINTER 3$: ASL R4 ;IN BYTES ADD R4,INPUT(R5) ;GET INPUT BUFFER POINTING RIGHT ASR R4 ;GET BACK POINTER NEG R4 ;PREPARE TO OBTAIN INPUT COUNT TST @INSIZ(R5) ;CHECK IF ARRAY SIZE IS OK BLE ERRET ;IF NOT, ERROR, RETURN DEC R3 ;UPDATE POSSIBLE ERROR INDICATOR ADD @INSIZ(R5),R4 ; FIND REMAINING COUNT BLT ERRET ;ERROR RETURN IF ARRAY POINTER FAULTY SUB #2,R3 ;UPDATE POSSIBLE ERROR INDICATOR MOV #7,R1 ;GET NO. OF WORDS ADD NOFC(R5),R1 ;GET NO. OF OUTPUT ELEMENTS MOV R1,NOFEL(R5) ;STORE TOTAL NO. OF OUTPUT ELEMENTS MOV @OUTPTR(R5),R2 ;GET OUTPUT OFFSET BGT 4$ ;IF TAKEN CARE OF BY USER, BRANCH CLR R2 ;OTHERWISE, SET POINTER TO ZERO BR 5$ ;SKIP OUTPUT BUFFER ADJUSTMENT 4$: ASL R1 ;IN BYTES ASL R1 ;IN BYTES TST OUTTYP(R5) ;SEE IF DOUBLE PRECISION REAL BGE 1$ ;IF NOT BRANCH ASL R1 ;OTHERWISE, DOUBLE 1$: MOV R2,R0 ;GET POINTER IN REG FOR MULTIPLY $MUL R1,R0 ADD R1,OUTPUT(R5) ;GET OUTPUT BUFFER POINTING RIGNT NEG R2 ;GET REMAINING COUNT FROM OUTPTR 5$: TST @OUTSIZ(R5) ;CHECK OUTPUT ARRAY SIZE BLE ERRET ;IF FAULTY, ERROR, RETURN DEC R3 ;UPDATE POSSIBLE INDICATOR ADD @OUTSIZ(R5),R2 ; FIND REMAINING COUNT BLT ERRET ;IF ARRAY POINTER FAULTY, ERROR, RETURN 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 #6,R3 ;IF NONE OF THE ABOVE, ERROR BR ERRET ;INDICATE AND RETUR 2$: MOV R4,@INPTR(R5) ;STORE INPUT COUNTER MOV R2,@OUTPTR(R5) ;STORE OUTPUT COUNTER ADD FIRSTM(R5),PC ;GO RESUME - PIC,REENTRANTLY ; COMES HERE ONLY ONCE, AT START, TO GET BASELINE VALUE , ; AND THEN PASSES IT ON THROUGH THE OUTPUT BUFFER INTIL: MOV R4,@INPTR(R5) ;STORE INPUT COUNTER MOV R2,@OUTPTR(R5) ;STORE OUTPUT COUNTER TST BAS(R5) ;CHECK TO READ BASELINE VALUE BGE INTIL1 ;IF NO NEED TO READ, BRANCH JSR PC,NEXTPT ;OTHERWISE, GET BASELINE VALUE MOV R3,BAS(R5) ;AND STORE IT BGE INTIL1 ;MUST BE POSITIVE, HOWEVER CLR BAS(R5) ;IF NOT, THEN MAKE IT ZERO INTIL1: MOV #18.,R2 MOV R5,R4 ADD #TYPE,R4 INTIL2: CLR (R4)+ ;CLEAR OUTPUT DATA DEC R2 BNE INTIL2 CLR TTL(R5) ;ZERO TOTAL TIMER CLR TTH(R5) CLR FTML(R5) ;ZERO INITIAL TIME OF PEAK CLR FTMH(R5) BR N101 ;GO START PROCESS ; RE-INITIALIZE ALMOST EVERYTHING AT START OF NEW ENVELOPE ; MOV BAS(R5),YX(R5) ;CLEAR PREVIOUS VALUE N20: CLRB PK(R5) ;CLEAR PEAK FOUND INDICATION CLR CAL(R5) ;CLEAR AREA ACCUM. DURING INCREASE CLR CAH(R5) CLR CCNL(R5) ;CLEAR PARTIAL CENTROID CALCULATION CLR CCNH(R5) CLR TML(R5) ;CLEAR LOCAL TIMER CLR TMH(R5) MOV TTL(R5),FTML(R5) ;SET BEGIN TIME TO CURRENT TIME MOV TTH(R5),FTMH(R5) INC FTML(R5) ;CORRECT BEGIN TIME BNE N30 INC FTMH(R5) N30: CLR TOP(R5) ;CLEAR LAST PEAK VALUE CLR TOPTL(R5) ;CLEAR PEAK TIME CLR TOPTH(R5) CLR OCNL(R5) ;CLEAR CENTROID SUMMATION CLR OCNH(R5) CLR OAL(R5) ;CLEAR TOTAL AREA CLR OAH(R5) N50: MOV #77777,MN(R5) ;SET MIN TO VERY LARGE NUMBER MOV #100000,MX(R5) ;SET CURRENT MAX TO VERY LARGE NEG NUMBER CLR MC(R5) ;CLEAR NO. OF DECREASES COUNTER CLR CC(R5) ;CLEAR NO. OF INCREASES COUNTER MOVB #1,S1(R5) ;IND. INCREASING TREND CLRB S2(R5) ;IND. NO DECREASING TREND N100: JSR PC,NEXTPT ;GET NEXT INPUT TST R3 ;IS THIS A REAL DATA POINT BNE N115 ;IF SO, B+C 5$: MOV TTL(R5),WDL(R5) ;FIND WIDTH MOV TTH(R5),WDH(R5) SUB FTMH(R5),WDH(R5) SUB FTML(R5),WDL(R5) SBC WDH(R5) BNE 1$ ;TEST IF WIDTH IS LESS THAN SIX CMP #6,WDL(R5) ; IF WIDER, BRANCH TO 1$ BHI N101 ;OTHERWISE FORGET PEAK 1$: MOV #1,TYPE(R5) ;INDICATE PEAK ENDS ON THRESHOLD JSR PC,RITOUT ;GO OUTPUT PEAK BLOCK N101: JSR PC,NEXTPT ;GET LO-PART OF REJECT COUNT MOV R3,T0L(R5) ;SAVE LOW PART OF REJECT COUNT JSR PC,NEXTPT ;GET HI-ORDER PART TST R3 ;CHECK FOR POSITIVE BGE 1$ ;IF NOT NEGATIVE, BRANCH MOV #-2,ERROR(R5) ;INDICATE ERROR IN INPUT MOV #N101-INTIL,FIRSTM(R5) ;STORE RE-ENTRY ADDRESS RTS PC ;RETURN 1$: ADD T0L(R5),TTL(R5) ;ADD TO TOTAL TIME ADC TTH(R5) ADD R3,TTH(R5) ;ADD TO TOTAL TIME MOV TTL(R5),T0L(R5) ;SAVE T0 OF ENVELOP MOV TTH(R5),T0H(R5) MOV NOFC(R5),CNT(R5);GET NO. OF EXTRA CHANNELS BEQ N20 ;IF NO EXTRA CHANNELS, BRANCH JSR PC,NEXTPT ;GET FIRST EXTRA CHANNEL DATA CLR ADCV1H(R5) ;PREPARE HIGH PART MOV R3,ADCV1L(R5) ;STORE LOW PART BGE 22$ ;IF POSITIVE, BRANCH DEC ADCV1H(R5) ;OTHERWISE, EXTEND SIGN 22$: DEC CNT(R5) ;CHECK IF TWO EXTRA CHANNELS BEQ N20 ; IF ONLY ONE BRAHCN JSR PC,NEXTPT ;GET NEXT EXTRA CHANNEL DATA CLR ADCV2H(R5) ;PREPARE HIGH PART MOV R3,ADCV2L(R5) ;STORE LOW PART BGE 23$ ;IF POSITIVE, BRANCH DEC ADCV2H(R5) ;OTHERWISE, EXTEND SIGN 23$: JMP N20 ;GO REINITIALIZE ;GOT A NEW DATUM N115: INC TML(R5) ;INC. LOCAL TIMER BNE 1$ INC TMH(R5) 1$: INC TTL(R5) ;INC. TOTAL TIMER BNE 2$ INC TTH(R5) 2$: TST R3 ;CHECK FOR NEGATIVE INPUT BLE 25$ ;MUST BE POSITIVE SUB BAS(R5),R3 ;SUBTRACT BASELINE VALUE ; ADD YX(R5),R3 ;GET "AVERAGED" POINT ; ASR R3 BGE 3$ ;IF INPUT IS BELOW THRESHOLD 25$: CLR R3 ; ZERO VALUE 3$: CMP R3,MN(R5) ;TEST IF LOWER THAN CURRENT MINIMUM BGT N150 ;IF NOT, B+C .SBTTL FOUND NEW MINIMUM NEWMIN: MOV R3,MN(R5) ;STORE NEW MINIMUM INC MC(R5) ;INCR. MINS COUNTER MOV TML(R5),R0 ;GET LOCAL TIME $MUL R3,R0 ;MUL BY NEW VALUE ADD R1,OCNL(R5) ;ADD TO CENTROID SUMMATION ADC R0 ADD R0,OCNH(R5) MOV TMH(R5),R0 ;DO SAME FOR MSH OF LOCAL TIME $MUL R3,R0 ADD R1,OCNH(R5) ADD CCNL(R5),OCNL(R5) ;ADD PARTIAL CENTR. SUM FOR INCR ADC OCNH(R5) ADD CCNH(R5),OCNH(R5) CLR CCNL(R5) ;CLEAR PARTIAL CENTROID SUMMATION CLR CCNH(R5) ADD R3,OAL(R5) ;ADD TO TOTAL AREA ADC OAH(R5) ADD CAL(R5),OAL(R5) ;ADD PARTIAL AREA FROM INCR ADC OAH(R5) ADD CAH(R5),OAH(R5) CLR CAL(R5) ;CLEAR PARTIAL AREAS CLR CAH(R5) CMP MC(R5),IGT(R5) ;ENOUGH POINTS DURING INCREAS BGE 1$ ;IF SO, B+C JMP N100 ;OTHERWISE GET NEXT POINT 1$: TSTB S2(R5) ;IS THIS AFTER A CREST BNE N130 ;IF SO, B+C MOVB #1,S1(R5) ;IND. DECREASING TREND CLR CC(R5) ; SO CLEAR INCREASES COUNTER MOV #100000,MX(R5) ;IF NOT, SET PHONY MAX JMP N100 ;AND GET NEXT POINT ;FOUND PEAK N130: MOVB #1,PK(R5) ;INDICATE FOUND A PEAK MOV MX(R5),TOP(R5) ;SAVE CREST VALUE MOV CTL(R5),TOPTL(R5) ;SAVE CREST TIME MOV CTH(R5),TOPTH(R5) JMP N50 ;CONTINUE .SBTTL CHECK FOR NEW MAXIMUM N150: ADD R3,CAL(R5) ;INCR. AREA FROM INCREASING TREND ADC CAH(R5) MOV TML(R5),R0 ;MULT LOCAL TIME BY CUR. VALUE AND ADD $MUL R3,R0 ;TO PARTIAL CENTROID SUMMATION ADD R1,CCNL(R5) ADC R0 ADD R0,CCNH(R5) MOV TMH(R5),R0 ;SAME FOR MSH OF LOCAL TIME $MUL R3,R0 ADD R1,CCNH(R5) CMP R3,MX(R5) ;IS NEW VALUE LARGER THAN OLD MAX BGE 1$ ;IF SO, B+C JMP N100 ;OTHERWISE GET A NEW POINT 1$: MOV R3,MX(R5) ;SAVE NEW MAX MOV TTL(R5),CTL(R5) ;SAVE NEW MAX TIME MOV TTH(R5),CTH(R5) INC CC(R5) ;INCR INCREASE COUNTER CMP CC(R5),IGT(R5) ;GOT ENOUGH INCREASES FOR A TREND BGE 2$ ;IF SO, B+C JMP N100 ;OTHERWISE, GET NEXT POINT 2$: CLR MC(R5) ;CLEAR DECREASES COUNTER MOV MX(R5),MN(R5) ; AND SET MIN TO CURR VALUE TSTB S1(R5) ;IS THIS AN INCREASE AFTER A DECREASE BNE 3$ ;IF SO, B+C JMP N100 ;IF NOT, GO GET NEXT POINT 3$: MOVB #1,S2(R5) ;IND. INCREASING TREND CLRB S1(R5) ; NOT DECREASING TSTB PK(R5) ;HAS THERE BEEN A PEAK FOUND BNE 4$ ;IF SO, IT IS ENDING ON A VALLEY,SO B+C JMP N100 ;IF NOT, THIS IS START OF FIRST PEAK 4$: CLRB PK(R5) ;CLEAR PEAK FOUND FLAG MOV TTL(R5),WDL(R5) ;GET WIDTH MOV TTH(R5),WDH(R5) SUB FTMH(R5),WDH(R5) SUB FTML(R5),WDL(R5) SBC WDH(R5) CLR TYPE(R5) ;INDICATE TYPE OF PEAK(ENDS ON VALLEY) JSR PC,RITOUT ;GO OUTPUT PEAK BLOCK MOV TTL(R5),FTML(R5);RECORD BEGIN OF NEXT PEAK TIME MOV TTH(R5),FTMH(R5) JMP N30 ;INITIALIZE SOME VARIABLES .SBTTL UTILITY ROUTINES ;ROUTINE TO GET NEXT POINT NEXTPT: MOV INPUT(R5),R2 ;GET INPUT TABLE ADDRESS 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 (SP)+,SAVR(R5) RTS PC ;RETURN IRESUM: MOV SAVR(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 MOV R2,INPUT(R5) ;SAVE CURRENT ADDRESS OF INPUT BUFFER RTS PC ;ROUTINE TO OUTPUT A BLOCK OF PEAK DATA. RITOUT: MOV OCNL(R5),R1 ;DIV OCN/OA + T0 = OCN MOV OCNH(R5),R0 MOV OAL(R5),R3 MOV OAH(R5),R2 JSR PC,DDIVD ADD T0L(R5),R1 ADC R0 ADD T0H(R5),R0 MOV R1,OCNL(R5) MOV R0,OCNH(R5) 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)+,SAVR(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 SAVR(R5),-(SP) ;RETURN RETURN ADDRESS TO STACK OUTCON: MOV #TYPE,R4 ;GET ADDR OF OUTPUT BLOCK ADD R5,R4 MOV NOFEL(R5),R0 ;GET BLOCK LENGTH TST OUTTYP(R5) ;TEST FOR FLOATING CONVERT BEQ OUTLOP ;IF NO FLOATIN POINT, BRANCH MOV R0,CNT(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 CNT(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 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 .END