iir32.asm

来自「CCS3.3自带的TI 5400系列DSP的dsplib文件。文档说明可以在TI」· 汇编 代码 · 共 344 行

ASM
344
字号
;***********************************************************
; Version 2.20.01                                           
;***********************************************************
;****************************************************************
;  Function:	iir32
;  Description: 32 bit infinite impulse response filter
;
;  Copyright Texas instruments Inc, 1998
;----------------------------------------------------------------
;  Revision History:
;  1.00, K. Baldwin. 8/31/98 - Original release.
;  2.00  Cesar Iovescu, 10/04/01. Use a1/2 insead of a1 to avoid overflow.
;  2.01  Magdalena, 6/7/02. Eliminated overflow by aligning the stack on 32 bits
;****************************************************************

	.bss temp_buff, 2

;Far-mode adjustment

         .if __far_mode
OFFSET   .set  2
FRAME_SZ .set   4
         .else
OFFSET   .set  1
FRAME_SZ .set  6
         .endif


REG_SAVE_SZ	.set   5

PARAM_OFFSET	.set   OFFSET + FRAME_SZ + REG_SAVE_SZ

	.mmregs
  

        .asg    0, nbiquads
        .asg    4, tmp2_low
        .asg    3, tmp2_high
        .asg    2, tmp_low 
        .asg    1, tmp_high
        .asg    0 + FRAME_SZ, SAVE_AR7
        .asg    1 + FRAME_SZ, SAVE_AR6
        .asg    2 + FRAME_SZ, SAVE_AR1
 
        .asg    0 + FRAME_SZ + REG_SAVE_SZ, RETURN_ADDR
        .asg    0 + PARAM_OFFSET, h
        .asg    1 + PARAM_OFFSET, r
        .asg    2 + PARAM_OFFSET, db
        .asg    3 + PARAM_OFFSET, nb
        .asg    4 + PARAM_OFFSET, nx

        .asg    AR1, r_ptr
	.asg	AR2, h_ptr
	.asg	AR3, tmp_buff_ptr
	.asg	AR4, db_high_ptr
        .asg    AR5, db_low_ptr
        .asg    AR6, x_ptr
        .asg    AR5, tmp_ptr
        .asg    AR7, nbiq
        .asg    BRC, nsamples 

	.text
 	.global _iir32
_iir32

; Save contents of AR1 and AR6                            
; Reserve stack space for local variables                 
; Set sign extension mode                                 
; Set FRCT bit                                                           
;----------------------------------------------------------------


	PSHM	AR1             			; 1 cycle
	PSHM    AR6                                     ; 1 cycle
	PSHM	AR7                                     ; 1 cycle
        PSHM    ST0                                 ; 1 cycle
        PSHM    ST1                                 ; 1 cycle
        RSBX    OVA                                 ; 1 cycle
        RSBX    OVB                                 ; 1 cycle
 
        FRAME   #-FRAME_SZ                              ; 1 cycle

        SSBX    SXM                                     ; 1 cycle
        RSBX    FRCT                                    ; 1 cycle
        STM     #2, AR0                                 ; 2 cycles
        STM     #temp_buff, tmp_buff_ptr                ; 2 cycles

;
; Store pointer to input sample buffer locally                
;----------------------------------------------------------------
	
        STLM    A, x_ptr                                ; 1 cycle

;
; Save pointer to coefficients H[k]                           
;----------------------------------------------------------------

        LD      *sp(db), B                              ; 1 cycle
        STLM    B, db_low_ptr                           ; 1 cycle
        MVDK    *sp(h), h_ptr                           ; 2 cycles
        MVDK    *db_low_ptr, db_high_ptr                ; 2 cycles

;
; Calculate value of sample counter                          
;----------------------------------------------------------------
        LD      *sp(nx), A                              ; 1 cycle
        SUB     #1, A                                   ; 2 cycles
        STLM    A, nsamples                             ; 1 cycle
        MVMM    db_high_ptr, db_low_ptr                 ; 1 cycle
        
;
; Calculate value of BIQUAD counter                          
;----------------------------------------------------------------

        LD      *sp(nb), A                              ; 1 cycle
        SUB     #1, A                                   ; 2 cycles
        STL     A, nbiquads                             ; 1 cycle
        STLM    A, nbiq                                 ; 1 cycle

;
; Set BK register to length of delay buffer                   
; This is determined by the number of biquads to perform      
;   nbiq * 5   = # of coefficients                            
; In this case, since each element is 32 bits long, the       
; actual length is 3 * nbiq , 2 * 3 * nbiq                    
;----------------------------------------------------------------

        STM      #6, T                                  ; 2 cycles	                    
        MPY     *sp(nb), A                              ; 2 cycles
        STLM    A, BK                                   ; 1 cycle
        


        SSBX  FRCT                                      ; 1 cycle
        MAR   *db_high_ptr+                             ; 1 cycle 
   
;
; Main loop for each data sample - apply filter              
;----------------------------------------------------------------           

SAMPLE_LOOP:

        RPTBD    END_SAMPLE_LOOP-1                      ; 2 cycles
	MVDK	*sp(r), r_ptr                           ; 2 cycles
 

LOOP_START:
;
; Get next input sample from input data buffer              
;----------------------------------------------------------------

        LD      *x_ptr+, 16, A                          ; 1 cycle
        STL     A, *tmp_buff_ptr+                       ; 1 cycle
        STH     A, *tmp_buff_ptr-                       ; 1 cycle

        ; Update BIQUAD counter and coefficient pointer

	MVDK   nbiquads, nbiq                           ; 2 cycles
        MVDK    *sp(h), h_ptr                           ; 2 cycles

BIQUAD_LOOP:
;
;                                                               
; BIQUAD's are calculated as follows                            
;    tmp = b2*d[n-2] + b1*d[n-1]                                
;    d[n] = x[n] or y[n]   (depending on BIQUAD)                
;    d[n] = a2*d[n-2] + a1*d[n-1] + d[n]                        
;    y[n] = b0*d[n] + tmp                                       
;----------------------------------------------------------------                                                               


;
; Calculate b2 * d2                                            
;----------------------------------------------------------------

        LD	#0, B                                    ; 1 cycle
        MPY     *h_ptr , *db_high_ptr, A                 ; 1 cycle 
        MACSU   *db_low_ptr+0%, *h_ptr+, B               ; 1 cycle 
        MACSU   *h_ptr+, *db_high_ptr+0%, B              ; 1 cycle 

;
; Calculate b1 * d1                                            
;----------------------------------------------------------------                
	
        MAC     *h_ptr , *db_high_ptr, A                 ; 1 cycle 
        MACSU   *db_low_ptr+0%, *h_ptr+, B               ; 1 cycle 
        MACSU   *h_ptr+, *db_high_ptr+0%, B              ; 1 cycle

;
; Store b2*d[n-2] + b1 *d[n-1] in temporary location           
;----------------------------------------------------------------

        ADD     B, -16, A  								 ; 1 cycle                            
        STL     A, tmp_low                               ; 1 cycle
        STH     A, tmp_high                              ; 1 cycle
        STM     #-4, AR0                                 ; 2 cycles

;
; Update d[n],   d[n] = x[n] or d[n] = y[n] (from prev BIQUAD) 
;----------------------------------------------------------------

	MVDD    *tmp_buff_ptr+, *db_low_ptr              ; 1 cycle
        MVDD    *tmp_buff_ptr-, *db_high_ptr             ; 1 cycle

;
; Pointer delay buffer back to d[n-2]                          
;----------------------------------------------------------------

        MAR     *db_low_ptr+0%                           ; 1 cycle
        MAR     *db_high_ptr+0%                          ; 1 cycle
        STM     #2, AR0                                  ; 1 cycle

;
; For the time being skip over b0 to point to a2               
;----------------------------------------------------------------

        MAR      *+h_ptr(2)				 ; 2 cycles
    
;
; Calculate a2 * d[n-2]                                        
;----------------------------------------------------------------
 
        LD	#0, B                                    ; 1 cycle
        MPY     *h_ptr , *db_high_ptr, A                 ; 1 cycle
        MACSU   *db_low_ptr+0%, *h_ptr+, B               ; 1 cycle
        MACSU   *h_ptr+, *db_high_ptr+0% , B             ; 1 cycle

        ADD     B, -16, A  								 ; 1 cycle                            
        STL     A, tmp2_low                               ; 1 cycle
        STH     A, tmp2_high                              ; 1 cycle
 

;
; Calculate 2*(a1/2 * d[n-1])                                        
;----------------------------------------------------------------

		LD	#0, B  	
        MPY     *h_ptr , *db_high_ptr, A      			 ; 1 cycle
        MACSU   *db_low_ptr+0%, *h_ptr+, B               ; 1 cycle
        MACSU   *h_ptr+ , *db_high_ptr+0%, B             ; 1 cycle

		ADD     B, -16, A  								 ; 1 cycle
		SFTA	A, 1									 ; 1 cycle
		DADD	tmp2_high, A							 ; 2 cycles
;     
; Update d[n]                                                  
; Accumulator A = a2 * d[n-2] +2*(a1/2 * d[n-1])                    
; The add old d[n] which contains x[n]/y[n] fed from data      
; sample or last BIQUAD respectively.                          
;----------------------------------------------------------------
  
                                 
         NEG   A                                          ; 1 cycle
         DADD  *db_high_ptr,A                             ; 2 cycles
 
         STH   A, *db_high_ptr                            ; 1 cycle
         STL   A, *db_low_ptr                             ; 1 cycle

;
; Adjust coefficent pointer to point to b0                    
;----------------------------------------------------------------

         MAR *+h_ptr(-6)                                  ;  2 cycles

;
; Calculate b0 * d[n]                                         
;----------------------------------------------------------------
     
         LD    #0, B                                       ; 1 cycle 
         MPY     *h_ptr , *db_high_ptr, A                  ; 1 cycle
         MACSU   *db_low_ptr+0%, *h_ptr+, B                ; 1 cycle 
         MACSU   *h_ptr+ , *db_high_ptr+0%, B              ; 1 cycle

;
; Update y[n] - will be used as new x[n] for next BIQUAD      
;----------------------------------------------------------------           

         ADD   B, -16, A                                   ; 1 cycle
         DADD  tmp_high, A                                 ; 2 cycles

;
; Point to next BIQUAD coefficients                           
;----------------------------------------------------------------

         MAR *+h_ptr(4)                                    ; 2 cycles
    
        BANZD   BIQUAD_LOOP, *nbiq-                        ; 5 cycles
         STL   A, *tmp_buff_ptr+                           ; 1 cycle
         STH   A, *tmp_buff_ptr-                           ; 1 cycle
             
;
; Round result before store                                   
;----------------------------------------------------------------

        ADD     #01h,15, A                                 ; 2 cycles
        STH     A, *r_ptr+                                 ; 1 cycle

;
; Update delay buffer pointer so that last d[n] becomes d[n-1]
;----------------------------------------------------------------
   
        MAR     *db_low_ptr+0%                             ; 1 cycle
        MAR     *db_high_ptr+0%                            ; 1 cycle

END_SAMPLE_LOOP:    
          

;
; Return current pointer into delay buffer                
; Return overflow status                                  
;----------------------------------------------------------------

RETURN:
        LDM      db_low_ptr, B                            ; 1 cycle
        MVDK     *sp(db), db_high_ptr                     ; 1 cycle

        LD      #0, A                                     ; 1 cycle
        XC      1, BOV                                    ; 2 cycles if true
        LD      #1, A                                     ; 1 cycle
        XC      1, AOV                                    ; 2 cycles if true
        LD      #1, A                                     ; 1 cycle

        FRAME   #FRAME_SZ                                 ; 1 cycle
   
        POPM    ST1                             ; 1 cycle
        POPM    ST0                             ; 1 cycle

	POPM	AR7				          ; 1 cycle
        POPM    AR6                                       ; 1 cycle
	POPM	AR1			                  ; 1 cycle

 

        .if __far_mode
           FRETD                                          ; 4 cycles
        .else
	   RETD                                           ; 3 cycles
        .endif
        STL     B, *db_high_ptr                           ; 1 cycle
        NOP                                               ; 1 cycle

;end of file. please do not remove. it is left here to ensure that no lines of code are removed by any editor

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?