/**************************************************************

File Name:	FIR.asm
		
Date Modified:	6/22/01 BM


Description:
			Subroutine that implements a FIR Filter given
			coefficients and samples.

			Equation:	y(n) = Summation from k=0 to M of h(k)*x(n-k)

Calling Parameters:
			b0,i0 = address of delay line buffer
			l0 = length of delay line buffer
			b1,i1 = address of input samples buffer
			b4,i4 = address of coefficients buffer
			l4 = length of coefficients buffer
			b2,i2 = address of output buffer
			m1 = 1
			m3 = -1
			m4 = 1

Assumptions:
			
			Delay line must be of length TAPS
			Delay line , Output and Input buffers stored in DM Block. 
			Instructions, and Coefficients stored in PM Block.

Return Values:
			i2 = output buffer
			i0 = delay line pointer 

Registers Affected:
			i0,i1,i2,i4,MX,MY,MR,SR

Cycle Count:
			7 + Bin_Samp(Taps-1 + 4) +  cache misses
			
Memory Usage:
			Instructions Words (24-bits):
				11 + Taps-1 instruction words
			
			Data Words (16 or 24-bits):
				Number of taps locations for coefficients (24-bits)
				Number of taps locations for the delay line buffer (16-bits)
				Number of samples locations for the input buffer (16-bits)
				Number of samples locations for the output buffer (16-bits)

Notes: 

**************************************************************/
#define     Samps_per_Bin	40        /* Number of Input samples in each bin */
#define     Taps       		31        /* Number of filter taps */

.GLOBAL fir;

/* program memory code */
.section/pm program;

fir:
	MR = 0, MX0 = DM(I1,M1), MY0 = PM(I4,m4);  	/* Read Input sample and coefficient */
    DM(I0,M3) = MX0;                    		/* Put Input sample in delay line */
  
  	CNTR=Samps_per_Bin;            /* Set CNTR to Samps_per_Bin for each bin */
    DO mult_acc UNTIL CE;    
    .repeat (Taps-1);              
		MR=MR+MX0*MY0(SS), MX0=DM(I0,M3), MY0=PM(I4,M4);
	.end_repeat;	
		MR=MR+MX0*MY0(SS), MX0=DM(I0,M1), MY0=PM(I4,M4);
        SR=ASHIFT MR2 (HI), MX0=DM(I1,M1); 		
        SR=SR OR LSHIFT MR1 (LO), DM(I0,M3) = MX0;
mult_acc:
        MR = 0, DM(I2,M1)=SR0;          		/* Write to output */
		rts (db);
	   	MX0 = DM(I0,M1);                     	/* Update delay pointer */
    	MX0 = DM(I1,M3);                    	
   	
   

