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

File Name:	IIR.asm
		
Date Modified:	6/21/01	BJM


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

			Equation:
			w(n) = x(n) + A1*w(n-1) + A2*w(n-2)
			y(n) = w(n) + B1*w(n-1) + B2*w(n-2)	(single biquad structure)

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


Assumptions:
		 	The coefficient buffer should be in the order A2, A1, B2, B1 for each
			biquad section.
  
			Delay line, Output and Input buffers stored in DM Block(16-bit).
			Instructions, and Coefficients stored in PM Block(24-bit).

			Block 0:
			Coefficient buffer = { A2[0],A1[0],B2[0],B1[0],A2[1],A1[1],B2[1],... }
		
			Block 1:
			Input buffer ={ In[0],In[1],In[2],... }
			Output buffer ={ Out[0],Out[1],Out[2],... }

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

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

Cycle Count:

Memory Usage:
			Instructions Words (24-bits):
				17 (IIR) + 6 (Dline Init) instruction words
			
			Data Words (16 or 24-bits):
				Coefs 			= Number of locations for coefficients (24-bits)
				2*Biquad_secs 	= Number of locations for the delay line (16-bits)
				N_samp			= Number of samples locations for the input (16-bits)
				N_samp			= Number of samples locations for the output (16-bits)

Notes: 

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

#define N_samp          256                 
#define Biquad_secs   	2                 

.GLOBAL IIR, Zero_Dline;
.EXTERN Dline, Coefs, Outbuf;

.section/pm program;
IIR:
	SE = 0;           	
	CNTR = N_samp;                      /* Set CNTR for N input samples */
	DO filtering UNTIL CE;
		MX0 = DM(I1,M3);                /* Read Input sample */
		MY0 = 0x2000; 
		CNTR = Biquad_secs;                    				/* Loop for each biquad */
		MR = MX0*MY0(SU),MX0 = DM(I0,M3), MY0 = PM(I4,M4);  /* Scale input, fetch current biquad A2 */
		DO quads UNTIL CE;
		    MR = MR+MX0*MY0(SS),  MX1 = DM(I0,M3),  MY0 = PM(I4,M4); /* Fetch current biquad A1 */
		    MR = MR+MX1*MY0(SS),  MY0 = PM(I4,M4); 			/* Fetch current biquad B2 */
		    SR = ASHIFT MR1(HI),  MY1 = PM(I4,M4); 			/* Fetch current biquad B1 */
		    MR = MR+MX0*MY0(SS),  MX0 = DM(I0,M0),  MY0 = PM(I4,M4); /* Fetch next biquad A2 */
quads:    
			DM(I0,M3) = SR1,      MR = MR+MX1*MY1(SS); 		
filtering:	
		DM(I2,M3) = MR1;            	/* Write filtered output */
		rts (db);
		nop;nop;		


.section/pm program;
Zero_Dline:
   	CNTR=LENGTH(Dline);            
    DO zero UNTIL CE;
zero:	DM(I0,M0)=0;               		/* Zero the delay line */
	rts (db);
	nop;nop;

