📄 src_flt.asm
字号:
[p3] = p4; // save pointer to stage data handle
pvt_src:
/******** IPDC comment *******/
// r7 = [p0++]; // r7 - > input signal ('in*' buffer)
// i3 = r7; // i3 - > input signal
// b3 = r7; // b3 set for circular buffering
/******************************/
/*********IPDC addition*******/
p4 = 44;
r7 = [p0++p4]; // r7 -> input signal 'inx'
i3 = r7;
p4 = -40;
r5 = [p0++p4];
b3 = r5;
/******************************/
r5 = [p0++];
r5 = r5 << 2; // double the length (4 bytes per word)
l3 = r5; // l3 = Size of Input Stage (SIS)
/******** IPDC comment *******/
// r6 = [p0++];
// i2 = r6; // i2 -> output signal 'inx'+1 buffer (output buffer)
// b2 = r6; // b2 set for circular buffering
/******************************/
/*********IPDC addition*******/
p4 = 40;
r6 = [p0++p4];
i2 = r6; // i2 -> output signal 'inx'+1 buffer (output buffer)
p4 = -36;
r6 = [p0++p4];
b2 = r6; // b2 set for circular buffering
/******************************/
r6 = [p0++];
r6 = r6 << 2; // double the output size (4 bytes per word)
l2 = r6; // l2 = Size of Output Stage (SOS)
r3 = [p0++]; // r3 -> the filter coefficients
r6 = [p0++]; // r6 = poly-phase filter size
p3 = r6; // save poly-phase into p3
r6 = [p0++]; // r6 = UPR (filter step)
r6 = r6 << 2; // post increment must be two bytes
m1 = r6; // post increment set to UPR
p4 = 8; // always skip over UPR (2*4bytes) in the up SRC
r0 = [p0++p4]; // r0 = DNR
r0 = r0 << 2; // four bytes per word
r6 = [p0++]; // r6 = NOS
p5 = r6; // p5 = Number of Outputs (NOS)
p4 = -40; // Backup 10 words (10x4)
// r1.l = w[p0]; // r1.l = Number of shifts (can be left shift=upshift or right shift=downshift)
r6 = [p0++p4];
m2 = r6; // m2 = Number of shifts
r2 = 0; // set poly index value to 0
i1 = r3; // i1 -> filter coefficients
// CC = r6 <= 0;
// IF !CC JUMP pvt_positive; // if # of shifts > 0, jump over
// CC = r6 < 0;
// IF CC JUMP pvt_negative; // if # of shifts < 0, jump over
LSETUP(PVT_OUT_BEGIN, PVT_OUT_END) LC0 = p5;
PVT_OUT_BEGIN:
m3 = i3; // save i3 into m3;
A1=A0=0 || R6=[I1] || R5=[I3--]; // r6=filter coef, r5='inx' buffer
// i1 += m1;
LSETUP(PVT_FILTER_BEGIN, PVT_FILTER_END) LC1 = p3;
PVT_FILTER_BEGIN:
R4=(A0+=R6.H*R5.H), A1+=R6.H*R5.L (M)||i1 += m1;
PVT_FILTER_END:
R1=(A1+=R5.H*R6.L) (M) || R6=[I1] || R5=[I3--];
i1 += m1;
// R1=R1>>16;
// R4=R4+R1 (S);
r5 = m2;
/******** IPDC comment *******/
// A1 = A1>>16;
/******************************/
/*********IPDC addition*******/
A1=A1>>>15;
/******************************/
A0+=A1;
A0 = ASHIFT A0 BY r5.l;
r6 = A0; // high half-word extraction with 16-bit saturation. Rounding cntrl by
// RND_MOD. 0 = unbiased rounding = default
[i2++] = r6; // save output into 'inx'+1
// R6.H=(A1+=R6.L*R5.H) || NOP || NOP;
// [i2++] = r4; // save output into 'inx'+1
//new_poly:
r7 = r2; // r7 = poly_index
r7 = r7 + r0; // r7 = poly_index + DNR
i3 = m3; // restore i3
r6 = m1; // r6 = UPR
test_address:
r5 = r7 - r6; // (poly_index + DNR)-UPR
CC = r5 < 0;
IF CC JUMP next_address; // if true, jump over
r7 = r5; // r7 = new poly_index
m0 = 4;
i3 += m0; // increment by 1 word (4 bytes)
JUMP test_address; // test the new poly_index
next_address:
r2 = r7; // save the new address
r7 = r7 + r3; // r7 -> adjusted filter address
PVT_OUT_END:
i1 = r7; // i1 -> poly-phase filter
pvt_return:
r7 = i3; // update r7 -> 'inx' buffer
p4 = 8; // 2 words (2*4bytes per word)
[p0++p4] = r7; // save the input signal
r6 = i2;
[p0] = r6; // save the output signal address
over_pivotstage:
p3.l = pt2_fundst;
p3.h = pt2_fundst;
p0 = [p3]; // p0 -> fundamental structure
r0 = [p0++]; // r0 = number of down stages
CC = r0 <= 0;
IF CC JUMP return_src_core; // if number of down stages = 0, RTS
DOWNSTAGE_BEGIN:
p3.l = st_handle;
p3.h = st_handle;
p4 = [p3]; // p4 -> current stage data handle
r7 = [p4++];
p0 = r7; // p0 -> stage data
[p3] = p4; // save pointer to stage data handle
dn_src:
/******** IPDC comment *******/
// r7 = [p0++]; // r7 -> input signal 'inx'
// i3 = r7; // i3 -> input signal 'inx'
// b3 = r7; // b3 set for circular buffering
/******************************/
/*********IPDC addition*******/
p4 = 44;
r7 = [p0++p4]; // r7 -> input signal 'inx'
i3 = r7;
p4 = -40;
r5 = [p0++p4];
b3 = r5;
/******************************/
r5 = [p0++];
r5 = r5 << 2; // double the length (4 bytes per word)
l3 = r5; // l3 = Size of Input Stage (SIS)
/******** IPDC comment *******/
// r6 = [p0++];
// i2 = r6; // i2 -> output signal 'inx'+1 buffer (output buffer)
// b2 = r6; // b2 set for circular buffering
/******************************/
/*********IPDC addition*******/
p4 = 40;
r6 = [p0++p4];
i2 = r6; // i2 -> output signal 'inx'+1 buffer (output buffer)
p4 = -36;
r6 = [p0++p4];
b2 = r6; // b2 set for circular buffering
/******************************/
r6 = [p0++];
r6 = r6 << 2; // double the output size (2 bytes per word)
l2 = r6; // l2 = Size of Output Stage (SOS)
p4 = 8; // always skip over DNR (2*4bytes) in the up SRC
r3 = [p0++]; // r3 -> the filter coefficients
r6 = [p0++p4]; // r6 = filter length
p3 = r6;
r4 = [p0++p4]; // r4 = DNR
r4 = r4 << 2; // Four bytes per word
m3 = r4;
p5 = [p0++]; // p5 = number of outputs
p4 = -40; // Backup 10 words (10x4)
r2 = [p0++p4]; // r2 = number of shifts
LSETUP(DN_OUT_BEGIN, DN_OUT_END) LC0 = p5;
DN_OUT_BEGIN:
i1 = r3; // i1 -> filter coefficients
m1 = i3; // save i3 into m1
A1=A0=0 || R6=[I1++] || R5=[I3--]; // r6=filter coef, r5='inx' buffer
LSETUP(DOWN_FILTER_BEGIN, DOWN_FILTER_END) LC1 = p3;
DOWN_FILTER_BEGIN:
R4=(A0+=R6.H*R5.H), A1+=R6.H*R5.L (M);
DOWN_FILTER_END:
R1=(A1+=R5.H*R6.L) (M) || R6=[I1++] || R5=[I3--];
// R1=R1>>16;
// R4=R4+R1 (S);
/******** IPDC comment *******/
// A1 = A1>>16;
/******************************/
/*********IPDC addition*******/
A1=A1>>>15;
/******************************/
A0+=A1;
A0 = ASHIFT A0 BY r2.l;
r6 = A0; // high half-word extraction with 16-bit saturation. Rounding cntrl by
// RND_MOD. 0 = unbiased rounding = default
[i2++] = r6; // save output into 'inx'+1
// JUMP shiftDone;
//shiftPos: // Left Shift = Up shift = positive number
// A1 = ASHIFT A1 BY r2.l;
// r6.h = A1; // high half-word extraction with 16-bit saturation. Rounding cntrl by
// RND_MOD. 0 = unbiased rounding = default
// w[i2++] = r6.h; // save output into 'inx'+1
//shiftDone:
i3 = m1; // restore i3
DN_OUT_END:
i3 += m3; // increment by 4 bytes per word
r7 = i3;
p4 = 8; // 2 words (2*4bytes per word)
[p0++p4] = r7; // save the input signal address
r6 = i2;
[p0] = r6; // save the output signal address
DOWNSTAGE_END:
r0 += -1; // Check number of downstages
CC = r0 <= 0;
IF !CC JUMP DOWNSTAGE_BEGIN; // if # equal to 0, jump to DOWNSTAGE_BEGIN
return_src_core:
#ifdef BUFIN
p3.l = diff_offset; // p3 -> Offset difference to strip leading zeroes off of final buffer
p3.h = diff_offset;
r7 = w[p3]; // r7 = number of outputs samples per block
// r7 = 147;
p5 = r7; // p5 = number of outputs samples per block (OSPB)
r7 = r7 << 2; // 4 bytes per word.
m2 = r7;
i2 -= m2; // modify i2 = i2-#OSPB (backup pointer by output block size)
i3 = p2; // i3 -> 'outputData'
l3 = 0; // non-circular
LSETUP(READ_OUTS_BEGIN, READ_OUTS_END) LC0 = p5;
READ_OUTS_BEGIN:
r6 = [i2++]; // get 32-bit output from buffer
READ_OUTS_END:
w[i3++] = r6.h; // write 16-bit output to 'outputData'
// p2 = i3; // save i3 into p2
// JUMP go_back; // jump if more inputs
#endif
RETURN_TO_SENDER:
(R7:4,P5:3)=[SP++]; // Pop R7 ...P5
L0=0;
L1=0;
L2=0;
L3=0;
RTS;
_src_flt.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -