;
;Schnelle Fouriertrafo mit
;genau 256 Stuetzstellen
;haftmann#software 1993
;=================================
os equ 0f003h
anfang equ 7000h
org anfang
;Sprungtabelle u. Uebergabezelle
jr plotb ;anfang
what db tabhi ;anfang+2
jp fft ;anfang+3
jp coswin ;anfang+6
jp betrag ;anfang+9
;Schnittstellenbeschreibung
;(ShortInt = -128..127)
;(Integer = -32768..32767)
;
;*****************
;PLOT (Anfang +0)
;Zeichnet ein Oszillogramm in die
;linke "Bildschirmhaelfte" unter
;Verwendung von CAOS-LINE
;
;PE: *(Anfang+2): High-Adresse
;der abzubildenden 100h-Tabelle
; *eine 100h lange Tabelle
;mit ShortInt-Werten belegt
;
;***************
;FFT (Anfang +3)
;Führt mit 256 komplexen ShortInt-
;Daten eine FFT aus. Das Ergebnis
;sind 256 komplexe Integer-Daten
;(=400h Bytes), also die A(i) und
;B(i).
;
;PE: *in (Anfang +400h) die
;Realteile als ShortInt
; *in (Anfang +500h) die
;Imaginaerteile als ShortInt
;
;PA: *in (Anfang +400h) die
;Low-Realteile als Integer
; *in (Anfang +500h) die
;Low-Imaginaerteile als Integer
; *in (Anfang +600h) die
;High-Realteile als Integer
; *in (Anfang +700h) die
;High-Imaginaerteile als Integer
;
;Hinweis: Die FFT-Routine wandelt
;als erstes die angebotenen ShortInts
;zu Integers und rechnet intern damit.
;
;******************
;COSWIN (Anfang +6)
;Legt über eine 100h lange ShortInt-
;Tabelle ein Cosinusquadratfenster
;(auch Hanning-Fenster genannt); d.h.
;alle Werte werden mit der COS^2-Funk-
;tion multipliziert.
;
;PE: *(Anfang +2): High-Adresse
;der zu fensternden 100h-Tabelle
; *die Tabelle selbst mit 100h
;ShortInt-Werten
;
;PA: *dieselbe Tabelle gefenstert
;
;******************
;BETRAG (Anfang +9)
;Rechnet die komplexen Ausgabewerte
;der FFT in Bytes um, bereitet die
;Rücktransformation vor und erzeugt
;eine Tabelle mit Betraegen (als Byte
;= unsigned ShortInt). Geplant ist
;eine Ausgabe einer Phasenliste.
;
;PE: *Siehe PA der FFT!
;
;PA: *(Anfang +400h): 100h Imagi-
;naerteile(!!!) als ShortInt
; *(Anfang +500h): 100h Real-
;teile als ShortInt
; *(Anfang +600h): 100h Betraege
;als Byte-80h (fuer PLOT guenstig)
; *(Anfang +700h): 100h Phasen
;als ShortInt (geplant)
;-128=-Pi/2, 0=0, 127= knapp Pi/2
;
;Hinweis: Die Integerwerte werden
;durch 16 dividiert. Falls sie dann
;immer noch betragsmaeszig groeszer
;als 127 (128) sind, werden die Werte
;beschnitten. In diesem Fall kann die
;Ruecktransformation kein befriedigen-
;des Ergebnis liefern. Als Gegenmasz-
;nahme gegen dieses Clipping sind die
;Eingangswerte kleiner zu bemessen.
;Ganz sicher sind Eingangswerte nur
;im Bereich -8..8.
;
;Kernel
;*** Unterfunktion PLOT fuer BASIC ***
plotb in a,88h
bit 2,a
jr nz,plot ;fuer MC-Progs
call 0f018h
call plot
call 0f01bh
ret
plot
ld hl,0b782h
ld b,8
xor a
plo1 ld m,a ;Args zu Null
inc l
djnz plo1
ld e,a
ld a,(what)
ld d,a
ld a,(de)
add 80h
ld l,88h
ld m,a
inc e
jr plot2
plot1
ld l,82h
inc m
plot2 ld l,86h
inc m
ld l,88h
ld a,m
ld l,84h
ld m,a
ld a,(de)
add 80h
ld l,88h
ld m,a
push hl
push de
call os
db 3eh
pop de
pop hl
inc e
jr nz,plot1
ret ;(plot)
;
;*** Die eigentliche FFT ***
fft
;Vorbereitung: High-Teile Vorzeichenset!
ld h,tabhi
call xcbw
inc h
call xcbw
dec h
;
ld a,80h ;hy=n2
ld b,1 ;b=argument
fftl1 ;Aeuszere Schleife
;8fach Durchlauf
ld hy,a
ld c,0 ;c=angle
ld l,0 ;l=j
fftl2 ;Mittlere Schleife
push hl
ld a,c
call cosinus
ld (cos),hl
ld a,c
call sinus
ld (sin),hl
pop hl
push hl ;l=i
ld a,l
add hy
ld e,a
ld d,h
push bc ;angle und arg
fftl3 ;Innere Schleife
;i=l
;hl=^x(i)
;de=^x(l)
ld c,m
inc h
inc h
ld b,m
push bc ;Stack:x(i)
ex de,hl
ld c,m
inc h
inc h
ld b,m ;bc:x(l)
ex (sp),hl ;Stack:^x(l)
or a
sbc hl,bc
ld (xdum),hl
add hl,bc
add hl,bc
ex de,hl ;hl:^x(i)
ld m,d
dec h
dec h
ld m,e
pop de
;
inc d
inc h
ld c,m
inc h
inc h
ld b,m
push bc ;Stack:y(i)
ex de,hl
ld b,m
dec h
dec h
ld c,m ;bc:y(l)
ex (sp),hl ;Stack:^y(l)
or a
sbc hl,bc
ld (ydum),hl
add hl,bc
add hl,bc
ex de,hl ;hl:^y(i)
ld m,d
dec h
dec h
ld m,e
pop de
dec h
dec d
;
push hl
push de
ld de,(xdum)
ld bc,(cos)
call mult
push hl
ld de,(ydum)
ld bc,(sin)
call mult
pop de
add hl,de
pop de
ex de,hl
ld m,e
inc h
inc h
ld m,d
push hl ;hl:^y(l)
ld de,(xdum)
; ld bc,(sin)
call mult
push hl
ld de,(ydum)
ld bc,(cos)
call mult
pop de
or a
sbc hl,de
pop de
ex de,hl
inc h
ld m,d
dec h
dec h
ld m,e
dec h
ex de,hl
pop hl
;
; call os
; db 23h,'i',0
ld a,hy
add a ;n2 2mal=n1
add e
ld e,a
ld a,l
add hy ;n2 2mal=n1
jr c,fftl3e
add hy ;Ueberlauf?
ld l,a
jp nc,fftl3
fftl3e ;Innere Schleife ENDE
; call os
; db 23h,'j',0
pop bc
pop hl
inc l ;j=Startindex
ld a,c
add b
ld c,a
rla
jp nc,fftl2
;Mittlere Schleife ENDE
; call os
; db 23h,'k',0
rlc b ;Argument
ld a,hy
rrca ;n2 halbieren
jp nc,fftl1
;Aeuszere Schleife ENDE
;*** fft 2.Teil ***
;z.Z.D=H=tabhi
;de=^x(j)
;hl=^x(i)
ld e,0 ;e=j=0
ld l,0 ;l=i=0
fftl4 ;Schleife 4
ld a,l
cp e ;i<j?
jr nc,fftv1
ld b,4
fftx ld c,m
ld a,(de)
ex de,hl
ld m,c
ld (de),a
inc d
inc h
djnz fftx
dec h
dec h
dec h
dec h
ld d,h
; call os
; db 23h,'e',0
fftv1 ld c,80h ;c=k=n/2
jr fftw1
;begin (WHILE)
fftw2 ld e,a
rr c
; call os
; db 23h,'2',0
fftw1 ld a,e
sub c
jr nc,fftw2
;end (WHILE)
add c
add c
ld e,a
inc l ;i++
; call os
; db 23h,'I',0
ld a,l
inc a
jr nz,fftl4
ret ;(END FFT)
;
;*** Cosinusquadratfenster ***
coswin
ld a,(what)
ld ly,0
ld hy,a
ld hl,0 ;1.Sinuswert
coswl1
push hl ;Sinuswert
call coswup
ld a,ly
inc a
srl a
call sinus
pop de
push hl
add hl,de
srl h
rr l ;Arit.Mittel
call coswup
pop hl ;Sinuswert
jr nz,coswl1
ret
;
coswup ld b,h
ld c,l
ld d,h
ld e,l
push iy
call mult
pop iy
ld c,l
ld b,h
ld e,(iy)
ld a,e
rla
sbc a
ld d,a ;cbw
push iy
call mult
pop iy
ld (iy),l
inc ly
ret
;
;*** Betragsbildung und ***
;*** Vorbereitung Ruecktrafo ***
betrag
ld hl,tab
call betr0
inc h
call betr0
ld de,tab+256
inc h
call copy
inc h
dec d
call copy
inc d ;"Real"teil
betrag1 ld a,(de)
call quad
push hl
dec d
ld a,(de)
call quad
pop bc
add hl,bc
jr nc,betrag2
ld a,0ffh
betrag2 call sqrt ;Pythagoras
inc d
inc d
betrag3 sub 80h ;anzeigeguenstig
ld (de),a ;Betrag
dec d
inc e
jr nz,betrag1
ret
copy ;256 Bytes LDIR
push bc
ld bc,256
ldir
dec h
dec d
pop bc
ret
betr0 ;Division/16 und Anschlag
rld
ld e,m
inc h
inc h
rld
bit 7,e
jr z,betr5
inc m
jr nz,betr5;Carry-Ersatz
inc a
betr5 bit 3,a ;Vorzeichen
jr nz,betr1
and 0fh
jr nz,betr3
bit 7,m
jr z,betr2
betr3 ld m,7fh ;Anschlag+
jr betr2
;
betr1 or 0f0h
inc a
jr nz,betr4
bit 7,m
jr nz,betr2
betr4 ld m,80h ;Anschlag-
betr2 dec h
dec h
inc l
jr nz,betr0
ret
;
;*** Unterprogramme ***
xcbw ;Byte-zu-Word-Trafo
ld l,0
xcbw1 ld a,m
rla
sbc a ;wie CBW
inc h
inc h
ld m,a
dec h
dec h
inc l
jr nz,xcbw1
ret
;
cosinus ;Cosinus
add 40h
sinus ;Sinuswert ermitteln (Tabelle)
;hl:=sin(a)
;hl-Aufbau: V000000Y YYYYYYYY
;(Vorzeichen - Betrag)
ld d,0
ld l,a
rla ;Bit 7
rr d ;=Vorzeichen
rla ;Bit 6
ld a,l
jr nc,sinu1
cpl
inc a
and 3fh ;Gipfel?
jr nz,sinu1
set 0,d ;Gipfel!!!
sinu1
or 0c0h
cp 0feh
jr c,sinu2
set 0,d ;100h
sinu2 ld l,a
ld h,sintab/256
ld e,m
ex de,hl
ret
;
quad ;Quadrat hl:=a^2 vzb=>vzl
;VR:A,B,HL
bit 7,a
jr z,quad1
neg
quad1 push de
ld b,8
ld d,0
ld e,a
ld h,d
ld l,d ;hl=0
quad2 add hl,hl
rla
jr nc,quad3
add hl,de
quad3 djnz quad2
pop de
ret
;
sqrt ;Wurzel a:=sqrt(hl) vzl=>vzl
xor a
dec a
push de
ld e,a
ld d,a
sqr1 inc a
inc de
inc de
sbc hl,de
jr nc,sqr1
sra d ;halbieren
rr e ;cy=1
add hl,de
bit 7,h
jr nz,sqr2
inc a ;aufrunden
jr nz,sqr2 ;100h?
dec a ;ffh!
sqr2 pop de
ret
;
mult ;Multiplikation
;bc: 16bit Vorzeichen-Betrag
;de: 16bit ZWK
;hl: Ergebnis
;VR:hl,de,af,ly
ld hl,0
bit 0,b
jr z,mul1
add hl,de
jr mul2 ;praktisch!
mul1 push bc
xor a
ld b,a
ld ly,8
mul3 sra d
rr e
rr b
rlc c
jr nc,mul4
add b
adc hl,de
mul4 dec ly
jr nz,mul3
pop bc
rla ;aufrunden?
jr nc,mul2
inc hl
mul2 bit 7,b
ret z
ld e,l
ld d,h
ld hl,0
or a
sbc hl,de
ret
;
;*** Testteil ***
db 7fh,7fh,'SINUS',1
ld a,l
call sinus
outhl call os
db 1ah
ret
db 7fh,7fh,'MULT',1
ld b,h
ld c,l
call mult
jr outhl
db 7fh,7fh,'QUAD',1
ld a,l
call quad
jr outhl
db 7fh,7fh,'SQRT',1
call sqrt
ld l,a
ld h,0
jr outhl
db 7fh,7fh,'JPHL',1
jp (hl)
;
;*** Variablen ***
xdum dw 0
ydum dw 0
sin dw 0
cos dw 0
;*** Tabellenteil ***
ds anfang+3c0h-$
sintab
DB 00H,06H,0DH,13H
DB 19H,1FH,26H,2CH
DB 32H,38H,3EH,44H
DB 4AH,50H,56H,5CH
DB 62H,68H,6DH,73H
DB 79H,7EH,84H,89H
DB 8EH,93H,98H,9DH
DB 0A2H,0A7H,0ACH,0B1H
DB 0B5H,0B9H,0BEH,0C2H
DB 0C6H,0CAH,0CEH,0D1H
DB 0D5H,0D8H,0DCH,0DFH
DB 0E2H,0E5H,0E7H,0EAH
DB 0EDH,0EFH,0F1H,0F3H
DB 0F5H,0F7H,0F8H,0FAH
DB 0FBH,0FCH,0FDH,0FEH
DB 0FFH,0FFH,00H,00H
;Datentabellen ab anfang+400h
tab
tabhi equ $/256
; Hintrafo Ruecktrafo
;+400h: X Low B Low
;+500h: Y Low A Low
;+600h: X High Beträge
;+700h: Y High (Phasen)
END
ääää ä!ä"ä#ä$ä%ä&ä'ä(ä)ä*ä+ä,ä-ä.ä 0ä1ä2ä3ä4ä5ä7äLà8ä9ä:ä;ä<ä=ä>ä?ä@ä
Detected encoding: OEM (CP437) | 1
|
|