📄 interp.asm
字号:
;***********************************************************
; Version 2.20.01
;***********************************************************
;********************************************************************************
; Function: firinterp
; Description: Interpolation 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
; 2.00, Li Yuan, 5/24/01 - modified final db pointer adjustment.
;********************************************************************************
; Parameter Locations on Entrance to Routine:
;
; x - Accumulator A
; h - *sp(01h)
; r - *sp(02h)
; db - *sp(03h)
; nh - *sp(04h)
; nx - *sp(05h)
; I - *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/I) - 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 insert zeros
; due to interpolation, (I-1)
; AR7 - used as repeat counter for zeros
; BRC - used for iterations on NSAMPS, (nx-1)
; BK - set to length of delay buffer, nh
;*****************************************************************************
.mmregs
.global _firinterp
_firinterp:
.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
;**************************************************************
; Assign names to stack refernces and auxilary registers. *
;**************************************************************
.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), I
.asg AR1, counter
.asg AR2, r_ptr
.asg AR3, h_ptr
.asg AR4, x_ptr
.asg AR5, db_ptr
.asg AR7, Intfac
.asg AR6, Inthold
.asg BRC, rptb_cnt
;**************************************************************
; Save the auxilary registers. *
;**************************************************************
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 stack 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 I, Intfac ; 2 cycles
LD nh, A ; 1 cycle
STLM A, BK ; 1 cycle
LD *db_ptr, A ; 1 cycle
STLM A, db_ptr ; 1 cycle
LD nx, A ; 1 cycle
SUB #1, A ; 2 cycle
STLM A, BRC ; 1 cycle
;**************************************************************
; Loads I to AR0, to use as circular addressing offset. *
;**************************************************************
MVMM Intfac, AR0 ; 1 cycle
;**************************************************************
; Divide nh by I, and load ((nh/I) - 3) to counter for *
; repeated MAC instructions. *
;**************************************************************
RSBX SXM ; 1 cycle
RSBX FRCT ; 1 cycle
LD nh, A ; 1 cycle
RPT #(16-1) ; 1 cycle
SUBC I,A ; 1 cycle * 15
SUB #3, A ; 2 cycle
STLM A, counter ; 1 cycle
SSBX SXM ; 1 cycle
SSBX FRCT ; 1 cycle
L1: RPTBD END_LOOP - 1 ; 2 cycles
;**************************************************************
; I-1 stored in order to insert I-1 zeros between samples. *
;**************************************************************
MAR *Intfac- ; 1 cycle --delay
MVMM Intfac, Inthold ; 1 cycle slot--
;**************************************************************
; Move next input sample into delay buffer. *
;**************************************************************
MVDD *x_ptr+, *db_ptr ; 2 cycles
;**************************************************************
; Sum h * x for next r value. Does only non-zero multiplies. *
;**************************************************************
norm: PSHM h_ptr ; 1 cycle
PSHM db_ptr ; 1 cycle
MPY *h_ptr+0%, *db_ptr+0%, A ; 1 cycle
RPT *(counter) ; 1 cycle
MACR *h_ptr+0%, *db_ptr+0%, A ; 1 cycle*((nh/I)-2)
MACR *h_ptr+0%, *db_ptr, A ; 1 cycle
POPM db_ptr ; 1 cycle
POPM h_ptr ; 1 cycle
MAR *db_ptr-% ; 1 cycle
;**************************************************************
; Store r. *
;**************************************************************
STH A, *r_ptr+ ; 1 cycle
;**************************************************************
; Stores 0 in delay buffer if Intfac has not yet decremented *
; to below 0 and branches to do multiplies. Otherwise, end *
; of repeated block is reached and the next input sample *
; will be loaded. *
;**************************************************************
LDM Intfac, A ; 1 cycle
SUB #1,A ; 2 cycles
ST #0, *db_ptr+% ; 2 cycles
BCD norm, AGEQ ; 3 cycles
there: MAR *Intfac- ; 1 cycle --delay
MAR *h_ptr+% ; 1 cycle slot--
MVMM Inthold, Intfac ; 1 cycle
MVDK h, h_ptr ; 2 cycles
MAR *db_ptr-0% ; 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 + -