📄 dspfunc.dsp
字号:
/****************************************************************************/
/* $$01/10/2000 checked dsp basic module data variables and function */
/* $$01/16/2001 modified and printed,Author: Jason.wang (zhigang wang) */
/* $$01/16/2001 Email: wzg119@yeah.net, BP: 86+02195950-161452 */
/* $$01/16/2001 This modlue is not optimized! should be test on Emulator */
/****************************************************************************/
.MODULE/SEG=App_PM Dspfunc;
/****************************************************************************/
#include "ld8a.inc"
#include "tab_ld8a.inc"
/*****************************************************************************
* calculate pow value of Z = 2 ^ (Integer.fraction) *
* the value is approximated by a table and linear interpolation *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* $$01/11/2000 move dm data table to pm data table *
* Calling Parameters *
* MR1: Q0 Integer part. (range: 0<=val<=30) *
* MR0: Q15 Fractional part. (range: 0.0<=val<1.0) *
* Return Values *
* SR0 = LSW of Z Q0 *
* SR1 = MSW of Z Q0 *
* Altered Registers: MR,SR,SE,AR,I5,AY0,MY0 *
* Computation Time : 18 cycles *
******************************************************************************/
.ENTRY Pow2;
Pow2: I5=^tabpow;
SR=ASHIFT MR0 BY 6(LO);
M5=SR1;
MODIFY(I5,M5);
AY0=30;
AR=MR1-AY0,MR1=PM(I5,M4);
AR=PASS SR1,SE=AR;
SR=LSHIFT SR0 BY -1 (LO);
SR=SR OR ASHIFT AR BY -1(HI);
AR=SR0 AND H#7FFF;
AY0=PM(I5,M4);
AR=MR1-AY0,MY0=AR;
MR0=0;
MR=MR-AR*MY0 (SS);
SR=LSHIFT MR0 (LO);
SR=SR OR ASHIFT MR1 (HI);
AR=PASS SR1;
SR=LSHIFT MR0 (HI),MR1=SR0;
MR0=SR0;
MR=MR(RND),SR1=AR;
SR0=MR1;
RTS;
/*****************************************************************************
* calculate log2 value of Z=log2(X) *
* X is positive and if X is negative or zero, result is 0 *
* The function Log2(X) is approximated by a table and linear interpolation *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* $$01/11/2000 move dm data table to pm data table *
* Calling Parameters *
* MR0 = LSW of X Q0 *
* MR1 = MSW of X Q0 *
* Return Values *
* SR1: Q0 Integer part of Z (range: 0<=val<=30) *
* SR0: Q15 Fractional part of Z (range: 0<=val<1) *
* Altered Registers: MR,SR,SE,AR,AF,AY0,MY0,I5 *
* Computation Time : 30 cycles *
******************************************************************************/
.ENTRY Log2;
Log2: AF=PASS MR1;
IF GE JUMP Log2_check;
Log2_rts: SR0=0;
SR1=0;
RTS;
Log2_check: AR=MR0 OR AF;
IF EQ JUMP Log2_rts;
I5=^tablog;
SE=EXP MR1 (HI);
SE=EXP MR0 (LO);
SR=NORM MR0 (LO),AY0=SE;
SR=SR OR NORM MR1 (HI);
MR0=SR1;
SR=LSHIFT SR0 BY -9(LO);
SR=SR OR ASHIFT MR0 BY -9(HI);
AR=SR1-32;
M5=AR;
MODIFY(I5,M5);
MR=0;
AR=PASS SR1, MR1=PM(I5,M4);
SR=LSHIFT SR0 BY -1(LO);
SR=SR OR ASHIFT AR BY -1(HI);
AR=SR0 AND H#7FFF;
SR0=30;
AR=SR0+AY0,MY0=AR;
AY0=PM(I5,M4);
AR=MR1-AY0,SR1=AR;
MR=MR-AR*MY0 (SS);
SR0=MR1;
RTS;
/*****************************************************************************
* calculate value of Z=1/sqrt(X) *
* X is positive and if X is negative or zero, result is 1 (3fff ffff) *
* The function 1/sqrt(X) is approximated by a table and linear interpolation *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* $$01/11/2000 move dm data table to pm data table *
* Calling Parameters *
* MR0 = LSW of X Q0 *
* MR1 = MSW of X Q0 *
* Return Values *
* SR0 = LSW of Z Q30 (range: 0<=val<1) *
* SR1 = MSW of Z Q30 (range: 0<=val<1) *
* Altered Registers: MR,SR,SE,AR,AF,I5,AY0,MY0 *
* Computation Time : 40 cycles *
******************************************************************************/
.ENTRY Inv_sqrt;
Inv_sqrt: AF=PASS MR1;
IF GE JUMP sqrt_check;
sqrt_rts: SR0=H#FFFF;
SR1=H#3FFF;
RTS;
sqrt_check: AR=MR0 OR AF;
IF EQ JUMP sqrt_rts;
I5=^tabsqr;
SE=EXP MR1 (HI);
SE=EXP MR0 (LO);
SR=NORM MR0 (LO),AY0=SE;
SR=SR OR NORM MR1 (HI);
AR=30;
AR=AR+AY0,MR0=SR1;
AF=AR AND H#0001;
IF NE JUMP sqrt_next;
SR=LSHIFT SR0 BY -1(LO);
SR=SR OR ASHIFT MR0 BY -1(HI);
sqrt_next: MR1=SR1;
MR0=SR0;
SR=ASHIFT AR BY -1(LO);
AR=SR0+1;
SR=LSHIFT MR0 BY -9(LO);
SR=SR OR ASHIFT MR1 BY -9(HI);
AR=PASS SR1,AY0=AR;
SR=LSHIFT SR0 BY -1(LO);
SR=SR OR ASHIFT AR BY -1(HI);
AR=AR-16;
M5=AR;
MODIFY(I5,M5);
AR=SR0 AND H#7FFF;
MR=0,MY0=AR;
AR=-AY0,MR1=PM(I5,M4);
AY0=PM(I5,M4);
AR=MR1-AY0,SE=AR;
MR=MR-AR*MY0(SS);
SR=LSHIFT MR0 (LO);
SR=SR OR ASHIFT MR1 (HI);
RTS;
/*****************************************************************************
* Function Name : Div_32 *
* Fractional integer division of two 32 bit numbers. *
* L_num / L_denom. L_num and L_denom must be positive and L_num < L_denom. *
* L_denom = denom_hi<<16 + denom_lo<<1 denom_hi is a normalize number. *
* The result is in Q30. *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* Calling Parameters *
* MX1,MX0 : L_num *
* MY1,MY0 : denom_hi,denom_lo *
* Return Values *
* SR1,SR0 : result_hi,result_lo *
* Altered Registers: MR,MF,SR,AR,AF,AY0,AY1,MX0,MX1,MY0,MY1 *
* Computation Time : 18 cycles *
******************************************************************************/
.ENTRY Div_32;
Div_32: MR=0,AR=MY1;
MR0=H#3FFF;
SR=ASHIFT AR BY 0(LO);
CALL div_s;
AY0=H#FFFF;
AY1=H#7FFF;
AR=PASS 1,SR0=AR;
MF=SR0 * MY0(SS);
MR=AR * MF(SS);
MR=MR+SR0*MY1(SS);
DIS AR_SAT;
AR=AY0-MR0,MY0=SR0;
ENA AR_SAT;
SR0=AR,AR=AY1-MR1+C-1;
SR=LSHIFT SR0 BY -1(LO);
AR=PASS 1,SR1=AR;
MF=SR0 * MY0(SS);
MR=AR * MF(SS);
MR=MR+SR1*MY0(SS);
SR=LSHIFT MR0 BY -1(LO);
AR=PASS 1,MY1=MR1;
MR=MX1 * MY1(SS),MY0=SR0;
MF=MX1 * MY0(SS),SR0=MX0;
SR=LSHIFT SR0 BY -1(LO);
MR=MR+AR*MF(SS),MX0=SR0;
MF=MX0 * MY1(SS);
MR=MR+AR * MF(SS);
SR=LSHIFT MR0 BY 2(LO);
SR=SR OR ASHIFT MR1 BY 2(HI);
RTS;
/*****************************************************************************
* Produces a result which is the fractional integer division of var1 by *
* var2; var1 and var2 must be positive and var2 must be greater or equal *
* to var1; the result is positive (leading bit equal to 0) and truncated *
* to 16 bits. *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* Calling Parameters *
* MR = 16-bit dividend *
* SR = 16-bit divisor *
* Return Values *
* AR = 16-bit result *
* Altered Registers: MR,SR,AR,AF,AY0,AY1 *
* Computation Time : 18 cycles *
******************************************************************************/
.ENTRY div_s;
div_s: AR=PASS MR0,AY0=SR0;
IF EQ RTS;
AR=MR0-AY0,AY1=SR1;
AR=H#7FFF;
IF EQ RTS;
// CNTR=15;
AR=PASS 0;
CNTR=15;
DO divs_loop UNTIL CE;
SR=LSHIFT AR BY 1(LO);
AF=PASS SR0;
SR=LSHIFT MR0 BY 1(LO);
SR=SR OR ASHIFT MR1 BY 1(HI);
AR=SR0-AY0,MR0=SR0;
MR1=SR1,AR=SR1-AY1+C-1;
IF LT JUMP divs_loop;
DIS AR_SAT;
AR=MR0-AY0;
ENA AR_SAT;
MR0=AR,AR=MR1-AY1+C-1;
AF=AF+1,MR1=AR;
AR=PASS MR1;
IF NOT AV JUMP divs_loop;
AR=H#0000;
AR=PASS MR1;
IF GE AR=AR-1;
MR0=AR;
divs_loop: AR=PASS AF;
RTS;
/*****************************************************************************
* Random generator--- seed = seed*31821 + 13849; *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* Calling Parameters *
* MX0 : random seed *
* Return Values *
* AR : random data *
* Altered Registers: MR,SR,AR,AY0,MX0,MY0 *
* Computation Time : 18 cycles *
******************************************************************************/
.ENTRY Random;
Random: MY0=31821;
MR=MX0*MY0(SS),AR=AY0;
SR=LSHIFT MR0 BY -1(LO);
SR=SR OR ASHIFT MR1 BY -1(HI);
DIS AR_SAT;
AY0=13849;
AR=SR0+AY0,AY0=AR;
ENA AR_SAT;
MX0=AR;
RTS;
/*****************************************************************************
* Gaussian generation *
* Xi = uniform v.a. in [-32768, 32767] *
* Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1) *
* output : Z x 512 < 2^12 *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* Calling Parameters *
* MX0 : random seed *
* Return Values *
* SR0 : Gauss seed *
* Altered Registers: MR,SR,AR,AY0,AY1,MX0,MY0 *
* Computation Time : 18 cycles *
******************************************************************************/
.ENTRY Gauss;
Gauss: AY0=0;
AY1=0;
CNTR=12;
DO sum_guass UNTIL CE;
CALL Random;
SR=ASHIFT AR BY 0(LO);
DIS AR_SAT;
AR=SR0+AY0;
ENA AR_SAT;
AY0=AR,AR=SR1+AY1+C;
AY1=AR;
IF NOT AV JUMP sum_guass;
AR=H#0000;
AR=PASS AY1;
IF GE AR=AR-1;
AY0=AR;
sum_guass: SR0=AY0;
SR=LSHIFT SR0 BY -7(LO);
SR=SR OR ASHIFT AR BY -7(HI);
RTS;
/*****************************************************************************
* Square root function : returns sqrt(Num/2) *
* $$01/10/2000 basic DSP function used in encoder and decoder *
* Calling Parameters *
* AY1 : MSW of X *
* AY0 : LSW of X *
* Return Values *
* AX0 : in UNSIGNED format *
* Altered Registers: AX0,AY0,AY1,AR,MR,SR *
* Computation Time : 18 cycles *
******************************************************************************/
.ENTRY Sqrt;
//Sqrt: CNTR=14;
Sqrt: AX0=H#0000;
AF=PASS H#4000;
CNTR=14;
DO sqrt_loop UNTIL CE;
AR=AX0+AF;
MR=AR * AR(UU);
NONE=AY0-MR0;
NONE=AY1-MR1+C-1;
IF NOT AC AR=PASS AX0;
AR=PASS AF,AX0=AR;
SR=LSHIFT AR BY -1(LO);
sqrt_loop: AF=PASS SR0;
RTS;
/*****************************************************************************/
.ENDMOD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -