Morgan Olsson wrote: > > Or what is it: > > I just added new routines in the project from where i pulled out the code > for MOMA filter i posted here recently. > Sum16: ;commented in english > ;Summs a interval of 2-byte variables to 3-byte T4:T3:T2 > ;MSB at adress of LSB +1. > ;Before call, state in W the total number of 2byte variables to sum. > ;And set FSR to point to the low byte of first variabe to sum. > ;(FSR may point in bank 0 or 1 regardless of back select :) ) > ;FSR get incremented by two for each variable summed > > movwf T1 ;store number of variables to temp reg T1 > movlw 4 ;Preload destination with 000004h > movwf T2 ;(New; for correct rounding in this application > clrf T3 ;where we sum 8 variables; > clrf T4 ;For normal SUM use we clear all T4:T3:T2) > Sum16loop: > movf INDF,W ;Get low byte, > addwf T2,F ;and add to low byte result > ifcs ;If carry, > incf T3,F ; inc middle byte result > ifzs ;If wrapped to Zero, > incf T4,F ; inc high byte result Suppose the addwf T2,F sets C and Z. Then, T4 will be incremented and the shift right 3 done below will cause the upper nibble of T3 to 'flicker'. It might be better to do something like this: movf INDF,W addwf T2,F rlf known_zero,W addwf T3,F rlf known_zero,W addwf T4,F > > incf FSR,F ;Point to MSB in, > movf INDF,W ;get it, > addwf T3,F ;and add to middle byte result > ifcs ;If carry, > incf T4,F ; inc high byte result > However, since you're doing something like: sum = sum + sample[i] where sum is 24 bits, and sample[i] is 16 bits, it might be better to do this: movf INDF,W ;Get low byte, incf FSR,F addwf T2,F movf INDF,W skpnc incfsz INDF,W addwf T3,F skpnc incf T4,F incf FSR,F ;Point to next variable low byte ... This way you only have to deal with the carry once. (I think this is right, but it's not tested.) Should I add comments? > incf FSR,F ;Point to next variable low byte > decfsz T1,F ;Decrease counter for variables to add, > goto Sum16loop;if not done add next variable > return ;the sum +4 is now in T4:T3:T2 > > ;and after this routine: > ;Divide by 8 = shift logical left 3 steps > STL 3, T1 > FilAdiv8loop: > cc ;clear carry > rrf T4, F > rrf T3, F > rrf T2, F > decfsz T1, F > goto FilAdiv8loop > > ;And the averaged result is in T3:T2 > for the shift right 3, you might want to just unroll the loop: rrf T4,F rrf T3,F rrf T2,F rrf T4,W andlw 00011111b movwf T4 rrf T3,F rrf T2,F rrf T4,F rrf T3,F rrf T2,F It's 3 instructions longer, but twice as fast (11 cycles vs 23 cycles) Scott