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 + -
显示快捷键?