📄 rifft.asm
字号:
ST B,*AR3 ; QR':= (PR+QI)/2
||LD *AR3+,B ; B := QR
ST A,*AR2 ; PI':= (PI+QR)/2
||SUB *AR2+0%,A ; A := PI-QR
ST A,*AR3+0% ; QI':= (PI-QR)/2
||LD *AR2,A ; A := PR
s2end:
; Remaining stages -------------------------------------------------------------
STM #512,BK ; circular buffer size BK=512 always
ST #128,@sav_sin ; init index of twiddle table, 128 for
; 3rd stage, ... 4 for 8th stage, ...
STM #128,AR0 ; index of twiddle table for 3rd stage
STM #TWI2,AR4 ; AR4 points to WR
STM #TWI1,AR5 ; AR5 points to WI
STM #-3+LOGN,AR7 ; init stage counter
ST #-1+N/8,@sav_grp ; init group counter
STM #3,AR6 ; init butterfly counter = #flies - 1
ST #8,@sav_idx ; init index for input data
stage:
STM #DATA,AR2 ; AR2->PR (AR2 points to PR)
LD @sav_idx, A
ADD *(AR2),A
STLM A,AR3 ; AR3->QR (AR3 points to QR)
MVDK @sav_grp,AR1 ; AR1 contains group counter
group:
MVMD AR6,BRC ; # of butterflies in each group
RPTBD bend-1
LD *AR4,T ; T := WR
MPY *AR3+,A ; A := QR*WR || AR3->QI
MASR *AR5+0%,*AR3-,A ; A := QR*WR-QI*WI || AR3->QR
ADD *AR2,16,A,B ; B := (QR*WR-QI*WI)+PR
ST B,*AR2 ; PR':=((QR*WR-QI*WI)+PR)/2
||SUB *AR2+,B ; B := PR-(QR*WR-QI*WI) || AR2->PI
ST B,*AR3 ; QR':= (PR-(QR*WR-QI*WI))/2
||MPY *AR3+,A ; A := QR*WI [T=WI] || AR3->QI
MACR *AR3,*AR4+0%,A ; A := QR*WI+QI*WR
ADD *AR2,16,A,B ; B := (QR*WI+QI*WR)+PI
ST B,*AR2 ; PI':=((QR*WI+QI*WR)+PI)/2
||SUB *AR2+,B ; B := PI-(QR*WI+QI*WR) || AR2->PR
ST B,*AR3+ ; QI':= (PI-(QR*WI+QI*WR))/2 || AR3->QR
||LD *AR4,T ; T := WR
MPY *AR3+,A ; A := QR*WR || AR3->QI
bend:
; Update pointers for next group
PSHM AR0 ; preserve AR0
MVDK @sav_idx,AR0
MAR *AR2+0 ; increment P pointer for next group
MAR *AR3+0 ; increment Q pointer for next group
BANZD group,*AR1-
POPM AR0 ; restore AR0
MAR *AR3-
; Update counters and indices for next stage
LD @sav_idx,A
SUB #1,A,B ; B = A-1
STLM B,AR6 ; update butterfly counter = #flies-1
STL A,1,@sav_idx ; double the index of data table
LD @sav_grp,A
STL A,ASM,@sav_grp ; half the offset to next group
LD @sav_sin,A
STL A,ASM,@sav_sin ; half the index of twiddle table
BANZD stage,*AR7-
MVDK @sav_sin,AR0 ; AR0 contains index of twiddle table
;-------------------------------------------------------------------------------
; P H A S E T H R E E
;
; REGISTER USAGE: AR0 index of twiddle tables
; AR2 pointer to R[k], I[k], RP[k], IP[k]
; AR3 pointer to R[N-k], I[N-k], RP[N-k], IP[N-k]
; AR6 pointer to RM[k], IM[k]
; AR7 pointer to RM[N-k], IM[N-k]
;-------------------------------------------------------------------------------
STM #DATA+2,AR2 ; AR2 points to R[k] (temp RP[k])
STM #DATA+2*N-2,AR3 ; AR3 points to R[N-k] (temp RP[N-k])
STM #DATA+2*N+3,AR7 ; AR7 points to temp RM[N-k]
STM #DATA+4*N-1,AR6 ; AR6 points to temp RM[k]
STM #-2+N/2,BRC
RPTBD p3end-1
STM #3,AR0
; Compute intermediate values RP, RM, IP, IM
ADD *AR2,*AR3,A ; A := R[k]+R[N-k] = 2*RP[k]
SUB *AR2,*AR3,B ; B := R[k]-R[N-k] = 2*RM[k]
STH A,ASM,*AR2+ ; store RP[k] at AR[k]
STH A,ASM,*AR3+ ; store RP[N-k]=RP[k] at AR[N-k]
STH B,ASM,*AR6- ; store RM[k] at AI[2N-k]
NEG B ; B := R[N-k]-R[k] = 2*RM[N-k]
STH B,ASM,*AR7- ; store RM[N-k] at AI[N+k]
ADD *AR2,*AR3,A ; A := I[k]+I[N-k] = 2*IP[k]
SUB *AR2,*AR3,B ; B := I[k]-I[N-k] = 2*IM[k]
STH A,ASM,*AR2+ ; store IP[k] at AI[k]
STH A,ASM,*AR3-0 ; store IP[N-k]=IP[k] at AI[N-k]
STH B,ASM,*AR6- ; store IM[k] at AR[2N-k]
NEG B ; B := I[N-k]-I[k] = 2*IM[N-k]
STH B,ASM,*AR7+0 ; store IM[N-k] at AR[N+k]
p3end:
ST #0,*AR6- ; RM[N/2]=0
ST #0,*AR6 ; IM[N/2]=0
;-------------------------------------------------------------------------------
; P H A S E F O U R
;
; (one stage; outputs divided by 2 to prevent overflow)
;
; REGISTER USAGE: AR0 index of twiddle tables
; AR2 pointer to RP[k], IP[k], AR[k], AI[k]
; AR3 pointer to RM[k], IM[k], AR[2N-k], AI[2N-k]
; AR4 pointer to cos(k*pi/N), AI[0]
; AR5 pointer to sin(k*pi/N), AR[N], AI[N]
;-------------------------------------------------------------------------------
; Compute AR[0], AI[0], AR[N], AI[N]
STM #DATA,AR2 ; AR2 points to AR[0] (temp RP[0])
STM #DATA+1,AR4 ; AR4 points to AI[0] (temp IP[0])
STM #DATA+2*N+1,AR5 ; AR5 points to AI[N]
ADD *AR2,*AR4,A ; A := RP[0]+IP[0]
SUB *AR2,*AR4,B ; B := RP[0]-IP[0]
STH A,ASM,*AR2+ ; AR[0] = (RP[0]+IP[0])/2
ST #0,*AR2 ; AI[0] = 0
MVDD *AR2+,*AR5- ; AI[N] = 0
STH B,ASM,*AR5 ; AR[N] = (RP[0]-IP[0])/2
; Compute final output values AR[k], AI[k]
STM #DATA+4*N-1,AR3 ; AR3 points to AI[2N-1] (temp RM[1])
STM #TWI2+512/N,AR4 ; AR4 is pointer to cosine
STM #TWI1+512/N,AR5 ; AR5 is pointer to sine
STM #N-2,BRC
RPTBD p4end-1
STM #512/N,AR0 ; index of twiddle tables
LD *AR2+,16,A ; A := RP[k] || AR2->IP[k]
MACR *AR4,*AR2,A ; A := A+cos(k*pi/N)*IP[k]
MACR *AR5,*AR3-,A ; A := A+sin(k*pi/N)*RM[k] || AR3->IM[k]
LD *AR3+,16,B ; B := IM[k] || AR3->RM[k]
MACR *AR5+0%,*AR2-,B ; B := B+sin(k*pi/N)*IP[k] || AR2->RP[k]
MASR *AR4+0%,*AR3,B ; B := B-cos(k*pi/N)*RM[k]
STH A,ASM,*AR2+ ; AR[k] = A/2
STH B,ASM,*AR2+ ; AI[k] = B/2
NEG B ; B := -B
STH B,ASM,*AR3- ; AI[2N-k] = -AI[k] = B/2
STH A,ASM,*AR3- ; AR[2N-k] = AR[k] = A/2
p4end:
B p4end
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -