IDEAL NOJUMPS SMART P386 ; Use 386 instructions MODEL medium EXTRN _Points:word, _Passes:word, _BitReversed:word, _SinTable:word CODESEG ; ; void RealFFT(int near *DataTable); ; PROC C RealFFT PUBLIC RealFFT ARG DataTable:word LOCAL sptr:word,But_per_group:word,twiddle:word LOCAL Endptr1:word,Endptr2:word,Sval:dword,Cval:dword LOCAL HRplus:dword,HRminus:dword,HIplus:dword,HIminus:dword USES SI,DI mov ax,[DataTable] mov bx,[_Points] shl bx,1 add ax,bx mov [Endptr1],ax ; Point to end of buffer (begin+points*2) shr bx,1 ; Butterflies for 1st pass=(Points/4) (*4 for indexing pairs of ints) ; ; Beginning of a new pass through the data ; Pass: mov si,[DataTable] mov di,si add di,bx mov [But_per_group],bx ; save this value for later mov bx,[_SinTable] mov [sptr],bx ; ; Beginning of a new group (groups all use the same sin/cos values) ; Set: mov bx,[sptr] add [sptr],4 movsx ecx,[word ptr bx] ; sin is always in ECX movsx edx,[word ptr bx+2] ; cos is always in EDX mov [Endptr2],di ; End pointer for this group ; ; Beginning of a Butterfly ; Butterfly: movsx eax,[word ptr di] ; Get Br movsx ebx,[word ptr di+2] ; Get Bi imul eax,edx imul ebx,ecx add eax,ebx movsx ebx,[word ptr si] ; Get Ar sar eax,15 ; v1 = Br*cos + Bi*sin sub ebx,eax sar ebx,1 mov [si],bx ; Ar = Ar - v1 add ebx,eax movsx eax,[word ptr di] ; Get Br mov [word ptr di],bx ; Br = Ar + v1 movsx ebx,[word ptr di+2] ; Get Bi imul eax,ecx imul ebx,edx sub eax,ebx movsx ebx,[word ptr si+2] ; Get Ai sar eax,15 ; v2 = Br*sin - Bi*cos sub ebx,eax sar ebx,1 mov [di+2],bx ; Bi = Ai - v2 add ebx,eax mov [si+2],bx ; Ai = Ai + v2 add si,4 add di,4 ; ; End of Butterfly ; cmp si,[Endptr2] jb short Butterfly mov si,di add di,[But_per_group] ; ; End of Group ; cmp si,[Endptr1] jb short Set ; ; End of Pass ; mov bx,[But_per_group] shr bx,1 cmp bx,2 jne Pass ; ; Reconstruct the output for the real input ; mov bx,[DataTable] movsx eax,[word ptr bx] ; Handle bin 0 case special movsx ecx,[word ptr bx+2] add eax,ecx mov [bx],ax mov [word ptr bx+2],0 mov si,[_BitReversed] ; Set up index pointers add si,2 mov di,[_Points] add di,si sub di,4 Loopit: mov bx,[di] ; Point to Hr(N-n) add bx,bx ; Double it for integers add bx,[DataTable] movsx eax,[word ptr bx] ; Get Hr(N-n) movsx ecx,[word ptr bx+2] ; Get Hi(N-n) mov bx,[si] ; Point to Hr(n) add bx,bx ; Double it for integers add bx,[_SinTable] movsx edx,[word ptr bx] mov [Sval],edx movsx edx,[word ptr bx+2] mov [Cval],edx sub bx,[_SinTable] add bx,[DataTable] movsx edx,[word ptr bx+2] ; Get Hi(n) sub edx,ecx ; edx=Hi(n)-Hi(N-n) sal ecx,1 add ecx,edx ; ecx=Hi(n)+Hi(N-n) mov [HIminus],edx mov [HIplus],ecx movsx edx,[word ptr bx] ; Get Hr(n) sub edx,eax ; edx=Hr(n)-Hr(N-n) sal eax,1 add eax,edx ; eax=Hr(n)+Hr(N-n) mov [HRminus],edx imul ecx,[Cval] ; Multiply Hi+ by (-COS) imul edx,[Sval] ; Multiply Hr- by (-SIN) sub ecx,edx sar ecx,15 sub eax,ecx ; eax=(Hr+) - (Hi+)(-COS) + (Hr-)(-SIN) sar eax,1 ; *0.5 add ecx,eax ; ecx=(Hr+) + (Hi+)(-COS) - (Hr-)(-SIN) ; *0.5 mov [bx],ax ; Save Fr(n) mov eax,[HIplus] imul eax,[Sval] mov edx,[HRminus] imul edx,[Cval] add eax,edx sar eax,15 mov edx,[HIminus] sub eax,edx ; eax=(-(Hi-) + (Hr-)(-COS) + (Hi+)(-SIN)) sar eax,1 ; *0.5 add edx,eax ; edx=( (Hi-) + (Hr-)(-COS) + (Hi+)(-SIN)) *0.5 mov [bx+2],dx ; Save Fi(n) mov bx,[di] ; Point to Hr(N-n) add bx,bx ; Double it for integers add bx,[DataTable] mov [bx],cx ; Save Fr(N-n) mov [bx+2],ax ; Save Fi(N-n) add si,2 sub di,2 cmp si,di jbe Loopit ret ENDP RealFFT end