📄 decimate.asm
字号:
;***********************************************************
; Version 2.20.01
;***********************************************************
*********************************************************************************
; Function: firdec
; Description: Decimation filter with user specified FIR coefficients
;
; Copyright Texas instruments Inc, 1998
;-----------------------------------------------------------------------------
; Revision History:
; 1.00, A. Aboagye, 8/31/98 - Original release. From code by C. Ramirez
; 1.10, A. Aboagye, 6/30/00 - Changed MACR to MAC in single RPT loop
;********************************************************************************
; Parameter Locations on Entrance to Routine:
;
; x - Accumulator A
; h - *sp(01h)
; r - *sp(02h)
; db - *sp(03h)
; nh - *sp(04h)
; nx - *sp(05h)
; D - *sp(06h)
;******************************************************************************
; Registers Modified by This Function:
;
; Accumulator A - used for general purpose math and to return
; overflow information
; AR0 - used as index for circular addressing
; AR1 - used as repeat count for MAC's, (nh - 3)
; AR2 - pointer to output buffer, r_ptr
; AR3 - pointer to coefficient vector, h_ptr
; AR4 - pointer to input/sample buffer, x_ptr
; AR5 - pointer to delay buffer, db_ptr
; AR6 - holds number of times to skip multiplies
; due to decimation, (D-1)
; AR7 - used as repeat counter for skips
; BRC - used for iterations on NSAMPS, ((nx/D)-1)
; BK - set to length of delay buffer, nh
;******************************************************************************
.mmregs
.global _firdec
_firdec:
.if __far_mode
OFFSET .set 2
.else
OFFSET .set 1
.endif
.if __far_mode
FRAME_SZ .set 1
.else
FRAME_SZ .set 0
.endif
REG_SAVE_SZ .set 5
PARAM_OFFSET .set FRAME_SZ + REG_SAVE_SZ + OFFSET
.asg *sp(0 + FRAME_SZ), SAVE_AR1
.asg *sp(1 + FRAME_SZ), SAVE_AR6
.asg *sp(2 + FRAME_SZ), SAVE_AR7
.asg *sp(0 + REG_SAVE_SZ + FRAME_SZ), RETURN_ADDR
.asg *sp(0 + PARAM_OFFSET), h
.asg *sp(1 + PARAM_OFFSET), r
.asg *sp(2 + PARAM_OFFSET), db
.asg *sp(3 + PARAM_OFFSET), nh
.asg *sp(4 + PARAM_OFFSET), nx
.asg *sp(5 + PARAM_OFFSET), D
.asg AR1, counter
.asg AR2, r_ptr
.asg AR3, h_ptr
.asg AR4, x_ptr
.asg AR5, db_ptr
.asg AR6, Dechold
.asg AR7, Decfac
.asg BRC, rptb_cnt
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
.if FRAME_SZ
FRAME #-1 ; 1 cycle
.endif
;****************************************************************
; This section stores values to local variables. *
;****************************************************************
SSBX SXM ; 1 cycle
SSBX FRCT ; 1 cycle
STLM A, x_ptr ; 1 cycle
MVDK h, h_ptr ; 2 cycles
MVDK r, r_ptr ; 2 cycles
MVDK db, db_ptr ; 2 cycles
MVDK D, Decfac ; 2 cycles
LD nh, A ; 1 cycle
STLM A, BK ; 1 cycle
SUB #3, A ; 2 cycles
STLM A, counter ; 1 cycle
LD *db_ptr, A ; 1 cycle
STLM A, db_ptr ; 1 cycle
MAR *Decfac- ; 1 cycle
MVMM Decfac, Dechold ; 1 cycle
;****************************************************************
; This section divides the number of input samples by the *
; decimation factor (D). The value (minus 1) is then *
; loaded into the block repeat counter (BRC). *
;****************************************************************
RSBX SXM ; 1 cycle
RSBX FRCT ; 1 cycle
LD nx, A ; 1 cycle
RPT #(16-1) ; 1 cycle
SUBC D,A ; 1 cycle * 15
SUB #1, A ; 2 cycle
STLM A, BRC ; 1 cycle
SSBX SXM ; 1 cycle
SSBX FRCT ; 1 cycle
L1: RPTBD END_LOOP - 1 ; 2 cycles
;**************************************************************
; Store 1 to AR0, to use as circular addressing offset. *
;**************************************************************
STM #1, AR0 ; 2 cycles--the delay slot
;**************************************************************
; Move next input sample into delay buffer. *
;**************************************************************
MVDD *x_ptr+, *db_ptr ; 2 cycles
;**************************************************************
; Sum h * x for next r value. *
;**************************************************************
MPY *h_ptr+0%, *db_ptr+0%, A ; 1 cycle
RPT *(counter) ; 1 cycle
MAC *h_ptr+0%, *db_ptr+0%, A ; 1 cycle * nh-2
MACR *h_ptr+0%, *db_ptr, A ; 1 cycle
;**************************************************************
; Moves next (D-1) input samples into delay buffer. Once *
; Decfac has decremented to below 0 the end of repeated *
; block is reached and the next input sample will be loaded *
; and the convolution multiplies follow. *
;**************************************************************
LDM Decfac, B ; 1 cycle
SUB #1, B ; 2 cycles
BCD there, BLT ; 3 cycles
;**************************************************************
; Store r. *
;**************************************************************
STH A, *r_ptr+ ; 1 cycle --delay slot (1)
MAR *Decfac- ; 1 cycle --delay slot (2)
here: BANZD here,*Decfac- ; 2 cycles
MVDD *x_ptr+, *db_ptr ; 1 cycle These 2 cycles
MAR *db_ptr-0% ; 1 cycle repeated (Decfac-1)
there: MVMM Dechold, Decfac ; 1 cycle
END_LOOP:
;**************************************************************
; Return procedure: -FRCT = 0 *
; -db_ptr updated *
; -Accumulator A = 0 if no overflow *
; = 1 if overflow *
; -Restore auxilary registers. *
;**************************************************************
LDM db_ptr, B ; 1 cycle
MVDK db, db_ptr ; 2 cycles
LD #0, A ; 1 cycle
XC 1, AOV ; 1 cycle
LD #1, A ; 1 cycle
STL B, *db_ptr ; 1 cycle
.if FRAME_SZ
FRAME #1 ; 1 cycle
.endif
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
NOP ; 1 cycle
NOP ; delay slot 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -