/************************************************************** 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;