;     Analyzer 
;von Hadmut Danisch
;68oooer     3/1988
;Markt&Technik Haar
;
;
freqband= 2
;
;Diese Konstante bestimmt die Abtastfrequenz und ist somit bestimmend
;für den Analysebereich der FFT. freqband kann auf vier Werte gesetzt
;werden, die Abtastraten sind folgender Tabelle zu entnehmen, wobei die
;jeweils höchste Frequenz, die durch die FFT bestimmt werden kann, der 
;Hälfte der Abtastfrequenz entspricht. Warnung: Jeder Frequenzanteil,
;der über der halben Abtastfrequenz liegt, erzeugt falsche Analysen;
;wählt man also eine niedrige Abtastfrequenz, empfiehlt es sich,
;einen Tiefpass vor den Digitizer zu schalten.
;
;freq-
;band | Alte Sch. | Neue Sch.
;-----+-----------+----------
;  1  |  40 kHz   |  50 kHz
;  2  |  40 kHz   |  40 kHz
;  3  |  30 kHz   |  30 kHz
;  4  |  20 kHz   |  20 kHz
;
partyfreq= 3
;
;Diese Konstante kann ebenfalls vier Werte annehmen (1 bis 4);sie gibt an,
;welcher Teil des durch freqband bestimmten Frequenzbereichs zur
;Farbberechnung im Partymodus herangezogen wird. 1 ist der höchste 
;Frequenzanteil, 4 der niedrigste, allerdings gilt obige Warnung vor zu
;hohen Frequenzen ganz besonders, auch wenn es in dieser Anzeigeart
;nicht so auffällt.
breit= 320 ;Breite des IFF-Bildes
hoch=  256 ;Länge des IFF-Bildes
;
;Wichtig: Wer kein Grafikprogramm hat, das das PAL-Format mit
;256 Punkten schluckt, kann den Wert "hoch" auf 400 setzen und so
;das Bild im Interlaceformat abspeichern;dabei wird aber der zusätzliche
;Streifen am unteren Bildrand mit Datenschrott aufgefüllt, muß also
;später noch gelöscht werden!
;
Sync=      500 ;Länge der Synchronisationsschleife
inleng=    80 ;Länge des Eingabepuffers
digitn=    256 ;Anzahl der Werte
digitbits= 8 ;2er-Logarithmus von digitn
partyn=    64
partybits= 6
;Es folgen die beiden Makros, die für die Verzögerung in den Abfrage-
;schleifen zuständig sind. Bitte keine nop's löschen oder irgendetwas
;hinzufügen, dies würde alles durcheinanderbringen.
WAIT1: MACRO 
IF freqband > 2 ;abhängig von freqband werden unterschiedlich viele nop-Befehle eingefügt.
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
ENDIF
IF freqband > 3
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop 
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
ENDIF
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 ENDM
WAIT2: MACRO 
IF freqband > 1 
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
ENDIF
IF freqband > 2 
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
ENDIF
IF freqband > 3
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
ENDIF
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 ENDM
;Es folgen die verwendeten Hardwareadressen:
 CIAA=    $BFE001
 CIAB=    $BFD000
 PARPORT= CIAA+$100
 PARDIR=  CIAA+$300
 BUTDIR=  CIAA+$200
 CTRLDIR= CIAB+$200
 COPROC=  $DFF000
 POTGOR=  COPROC+$16
 DMACON=  COPROC+$96
 VPOSR=   COPROC+$4
 DMACONR= 2
 COP1LC=  COPROC+$80
 COPJMP1= COPROC+$88
 BLTAMOD= 100 ;Ab jetzt relativ zu COPROC
 BLTBMOD= 98
 BLTCMOD= 96
 BLTAFWM= 68
 BLTADAT= 116
 BLTBDAT= 114
 BLTCON0= 64
 BLTSIZE= 88
 BLTAPTL= 82
 BLTCPTH= 72
 BLTDPTH= 84
 onsprite=  $8020 ;Flagbefehle
 offsprite= $0020 
;Es folgen die Offsetwerte der verwendeten Libraryfunktionen
 OpenLibrary=   -552 ;Exec
 CloseLibrary=  -414
 Enable=        -126
 Disable=       -120
 Permit=        -138
 Forbid=        -132
 AllocMem=      -198
 FreeMem=       -210
 Delay=         -198 ;Dos
 Close=          -36
 Open=           -30
 Read=           -42
 Write=          -48
 Input=          -54
 Output=         -60
 IoErr=         -132
 OpenScreen=    -198 ;Intuition
 CloseScreen=    -66
 ScreenToFront= -252
 ScreenToBack=  -246
 ViewAddress=   -294
 Move=          -240 ;GraphicsBase
 Draw=          -246
 SetAPen=       -342
 SetRast=       -234
 Text=           -60
 LoadRGB4=      -192
 OpenFont=       -72
 CloseFont=      -78
 SetFont=        -66
;
;Es folgt das eigentliche Hauptprogramm
 code
start:
 move.l  sp,SaveSP ;SP retten
 bsr     init ;Initialisierung allgemein
 move.l  #liste1,a6 ;mit Signaldarstellung anfangen
 move.l  4(a6),a4 ;Initialisierung speziell
 jsr     (a4)
mainloop:
;Hauptschleife
 lea     10(a6),a5 ;Prozedurliste
 move.w  8(a6),d7 ;Prozeduranzahl
callloop:
 move.l  (a5)+,a4
 jsr     (a4)
 dbf     d7,callloop
 bsr     keytest ;Maustasten abfragen
 cmpi.b  #1,d0
 beq     links ;linke Taste
 cmpi.b  #2,d0
 beq     rechts ;rechte Taste
 bra.s   mainloop
;Bei Druck der rechten Taste wird auf die nächste Betriebsart weitergeschaltet
rechts:
 bsr     keytest ;warten bis wieder
 tst.b   d0 ;losgelassen
 bne.s   rechts 
 move.l  (a6),a6 ;Liste durch nächste ersetzen
 move.l  4(a6),a4
 jsr     (a4) ;Initialisierung speziell
 bra     mainloop
;Bei Druck der linken Tast wird die Anzeige gestoppt bzw. gestartet
links:
 bsr     keytest ;warten bis wieder 
 tst.b   d0 ;losgelassen
 bne.s   links
linkswait:
;auf nächste Taste warten
 bsr     keytest
 tst.b   d0
 beq.s   linkswait ;keine Taste gedrückt
 cmpi.b  #2,d0
 beq.s   linksrechts ;rechte Taste während Stopzustand
 moveq   #0,d4
links2:
 addq.l  #1,d4
 cmpi.l  #70000,d4
 bge.s   linkslong
 bsr     keytest ;linke Taste, warten bis wieder
 tst.b   d0 ;losgelassen
 bne.s   links2
 tst.b   Clearflag
 beq     mainloop ;jetzt geht's weiter
 movem.l d7/a5/a6,-(a7)
 bsr     sumclear
 movem.l (a7)+,d7/a5/a6
 bra     mainloop
linkslong:
 tst.w   Saveenable
 beq     links
 bsr     save
 bra     links
linksrechts:
 bsr     keytest ;warten bis wieder 
 tst.b   d0 ;losgelassen
 bne.s   linksrechts
 move.l  (a6),a6 ;nächste Betriebsart
 move.l  4(a6),a4
 jsr     (a4) ;Initialisierung speziell
 tst.b   flag ;wurde schon FFT durchgeführt?
 bne     lr2
 bsr     fftlong
lr2:
 bsr     show
 bra     linkswait
SaveSP:
 dc.l 0 ;der alte SP
;Die folgenden Datenlisten werden vom Hauptprogramm abgearbeitet,
;für jede Betriebsart existiert eine Liste.
;Datenliste für Anzeige der Wellenform
liste1:
 dc.l    liste2 ;nächste Liste
 dc.l    clean1 ;Initialisierung
 dc.w    1 ;Anzahl Routinen-1
 dc.l    digit ;Routinen
 dc.l    show
;Datenliste für Anzeige des Frequenzspektrums
liste2:
 dc.l    liste3
 dc.l    clean2
 dc.w    2
 dc.l    digit
 dc.l    fftlong
 dc.l    show
;Datenliste für Summation
liste3:
 dc.l    liste4
 dc.l    clean3
 dc.w    3
 dc.l    digit
 dc.l    fftlong
 dc.l    summ
 dc.l    show
;Datenliste für Party-Modus
liste4:
 dc.l    liste1
 dc.l    clean4
 dc.w    2
 dc.l    digit
 dc.l    fftshort
 dc.l    color
;Die folgende Routine sorgt für die Abfrage der Maustasten und
;bricht das Programm sofort ab, sobald beide Tasten gedrückt werden.
keytest:
 moveq   #0,d0
 move.b  CIAA,d1
 andi.b  #$40,d1
 bne.s   noleft
 ori.b   #1,d0
noleft:
 move.w  POTGOR,d1
 andi.w  #$400,d1
 bne.s   noright
 ori.b   #2,d0
noright:
 cmpi.b  #3,d0 
 beq     kill ;beenden, wenn beide Tasten
 rts
;Es folgt die Hauptinitialisierungsroutine
init:
 move.l  4,ExecBase ;Hauptinitialisierung
 move.l  #IntuitionName,a1
 move.l  #IntuiBase,a5
 bsr     getlib
 move.l  #GraphicsName,a1
 move.l  #GraphicsBase,a5
 bsr     getlib
 move.l  #DosName,a1
 move.l  #DosBase,a5
 bsr     getlib
 bsr     makekrscreen
 bsr     makescreen
 move.l  GraphicsBase,a6
 move.l  KrRastPort,a1
 moveq   #0,d0
 jsr     SetRast(a6)
 move    #219,x0
 move    #128,y0
 move    #7,radius
 move    #100,s_rad
 move    #13,kr_anz
 move    #13,kr_col
 bsr     circle
 move    #60,x0
 move    #185,y0
 move    #5,radius
 move    #60,s_rad
 move    #10,kr_anz
 move    #23,kr_col
 bsr     circle
 move    #60,x0
 move    #50,y0
 move    #5,radius
 move    #45,s_rad
 move    #8,kr_anz
 move    #31,kr_col
 bsr     circle
 move.l  DosBase,a6
 jsr     Input(a6)
 move.l  d0,dinput
 jsr     Output(a6)
 move.l  d0,doutput
 move.l  ExecBase,a6
 jsr     Forbid(a6) ;Kein Task-Switch
 jsr     Disable(a6) ;Kein Interrupt
 bsr     mauskill ;Sprites abschalten
 bsr     initpar ;Parallelschnittstelle init.
 move.l  #digitn-1,d7
 move.l  #digitbits-1,d4
 move.l  #shuffle,a0
 move.l  #spektrum,a1
 bsr     makeshuffle ;Shuffle-Liste erstellen
 move.l  #partyn-1,d7
 move.l  #partybits-1,d4
 move.l  #sshuffle,a0
 move.l  #sspektrum,a1
 bsr     makeshuffle
 rts
;Es folgen die zur Initialisierung notwendigen Variablen und Konstanten
ExecBase:      dc.l 0 ;Libraries
IntuiBase:     dc.l 0
GraphicsBase:  dc.l 0
DosBase:       dc.l 0
dinput:        dc.l 0
doutput:       dc.l 0
file:          dc.l 0
IntuitionName: dc.b "intuition.library",0
GraphicsName:  dc.b "graphics.library",0
DosName:       dc.b "dos.library",0
FontName:      dc.b "topaz.font",0
WaitText:      dc.b "Bitte warten...",0 
AutText:       dc.b "Autoren: Danisch/Reinhardt/Schwaiger",0
 even
 Waitlen= 15 ;Länge WaitText 
 Autlen=  36 ;Länge Title
Font:       dc.l 0 ;Zeiger auf Font
Screen:     dc.l 0 ;Zeiger auf Screen
RastPort:   dc.l 0 ;Zeiger auf RastPort
ViewPort:   dc.l 0 ;Zeiger auf ViewPort
BitMap:     dc.l 0 ;Zeiger auf BitMap
BitPlane1:  dc.l 0 ;Zeiger auf BitPlane
BitPlane2:  dc.l 0
BPR:        dc.w 0 ;Bytes per Row
View:       dc.l 0
KrScreen:   dc.l 0
KrRastPort: dc.l 0
KrViewPort: dc.l 0
flag:       dc.w 0 ;fft schon durchgeführt?
Clearflag:  dc.w 0 ;Summation löschen?
Saveenable: dc.w 0
digiflag:   dc.w 0 ;0=alte, 1=neue Beschaltung
NewScreen:  dc.w 0,0 ;Ecken
 dc.w 320,256 ;Format
 dc.w 2 ;BitPlanes
 dc.b 0,1 ;Pens
 dc.w 0 ;ViewModes
 dc.w $f ;Type=Customscreen
 dc.l 0 ;font
 dc.l 0 ;Title
 dc.l 0 ;Gadgets
 dc.l 0 ;CustomBitMap
NewKrScreen:
 dc.w 0,0 ;Ecken
 dc.w 320,256 ;Format
 dc.w 5 ;BitPlanes
 dc.b 0,1 ;Pens
 dc.w 0 ;ViewModes
 dc.w $f ;Type=Customscreen
 dc.l 0 ;font
 dc.l 0 ;Title
 dc.l 0 ;Gadgets
 dc.l 0 ;CustomBitMap
TextAttr:
 dc.l FontName ;Zeiger auf Fontname
 dc.w 8 ;Höhe
 dc.w 0
 dc.w 0
;Die folgende Routine öffnet eine Library
getlib:
 moveq   #0,d0
 move.l  ExecBase,a6
 jsr     OpenLibrary(a6)
 tst.l   d0
 beq     kill ;Ende, wenn nicht gefunden
 move.l  d0,(a5)
 rts
;Die folgende Routine schaltet den Mauszeiger ab, sie sperrt alle Sprites
mauskill:
 btst    #0,VPOSR+1
 beq.s   mauskill
 move.w  #offsprite,DMACON
 rts
;Die folgende Routine initialisiert die Parallelschnittstelle und
;untersucht, welche Digitizerbeschaltung vorliegt.
initpar:
 move.b  #0,PARDIR
 move.b  CTRLDIR,d0
 andi.b  #$fa,d0
 ori.b   #$04,d0
 move.b  d0,CTRLDIR
 andi.b  #$3f,BUTDIR
 move.w  POTGOR,d0 ;auch die Maustaste
 andi.w  #$f7ff,d0
 move.w  d0,POTGOR ;Initialisierung abgeschlossen
 move.l  #CIAB,a0
 move.l  #PARPORT,a1
 moveq   #$04,d0
 moveq   #$FA-256,d1
 moveq   #1,d2
 clr.w   digiflag
 or.b    d0,(a0) ;Erst mal mit Gewalt lesen
 and.b   d1,(a0)
 move.b  d0,(a1)
ibusy1:
 and.b   d2,(a0)
 beq.s   ibusy1
 move.b  (a1),d5
 move.b  d0,(a1) ;Jetzt einen Startbefehl für den Neuen
ibusy2:
 and.b   d2,(a0)
 bne.s   olddigit ;Wenn beschäftigt ist, ist es der Neue
 move.w  d2,digiflag
olddigit:
 rts
;Die folgende Routine erstellt die für die FFT nötige Shuffle-Liste.
makeshuffle:
 moveq   #0,d0
shuffleloop:
 moveq   #0,d2
 move.l  d0,d1
 move.w  d4,d3
shiftloop:
 roxr    #1,d1
 roxl    #1,d2
 dbf     d3,shiftloop
 asl     #2,d2
 lea     0(a1,d2.w),a2
 move.l  a2,(a0)+
 addq    #1,d0
 dbf     d7,shuffleloop
 rts
makekrscreen:
 move.l  #NewKrScreen,a0
 move.l  IntuiBase,a6
 jsr     OpenScreen(a6)
 tst.l   d0
 beq     kill
 move.l  d0,KrScreen
 move.l  d0,a0
 lea     84(a0),a1
 move.l  a1,KrRastPort
 lea     44(a0),a0
 move.l  a0,KrViewPort
 moveq   #32,d0
 move.l  #KrColList,a1
 move.l  GraphicsBase,a6
 jsr     LoadRGB4(a6)
 move.l  IntuiBase,a6
 jsr     ViewAddress(a6)
 move.l  d0,View
 rts
KrColList: blk.w 32,0
;Die folgende Routine öffnet den Hauptscreen mit allem was
;dazugehört, wie Farben, Font usw.
makescreen:
 move.l  #TextAttr,a0 ;Zeichensatz öffnen
 move.l  GraphicsBase,a6
 jsr     OpenFont(a6)
 tst.l   d0
 beq     kill ;Ende, wenn Zeichensatz nicht gefunden
 move.l  d0,Font
 move.l  #NewScreen,a0 ;Eröffnen des Bildschirms über Intui.
 move.l  IntuiBase,a6
 jsr     OpenScreen(a6)
 tst.l   d0
 beq     kill ;Ende, wenn kein Screen
 move.l  d0,Screen
 move.l  d0,a0
 lea     84(a0),a1
 move.l  a1,RastPort ;Adresse des RastPort-Feldes
 lea     44(a0),a3
 move.l  a3,ViewPort
 move.l  4(a1),a2 ;Zeiger auf Bitmap
 move.l  a2,BitMap
 move.l  8(a2),BitPlane1
 move.l  12(a2),BitPlane2
 move.w  (a2),BPR
 move.l  GraphicsBase,a6 ;Font setzen
 move.l  Font,a0
 move.l  RastPort,a1
 jsr     SetFont(a6)
 move.l  GraphicsBase,a6 ;Farben setzen
 move.l  ViewPort,a0
 move.l  #ColList,a1
 moveq   #4,d0
 jsr     LoadRGB4(a6)
 move.l  RastPort,a1 ;Position des Wartetextes
 moveq   #100,d0
 moveq   #120,d1
 jsr     Move(a6)
 move.l  #Waittext,a0 ;"Bitte warten..."
 move.l  #Waitlen,d0
 jsr     Text(a6)
 move.l  RastPort,a1
 moveq   #0,d0
 moveq   #25,d1
 jsr     Move(a6)
 move.l  #Auttext,a0
 move.l  #Autlen,d0
 jsr     Text(a6)
 rts
ColList:
 dc.w $444 ;Die Farben des Hauptscreens
 dc.w $090
 dc.w $009
 dc.w $000
;Es folgt die Routine, die das ganze Programm beendet
kill:
 move.w  #onsprite,DMACON ;Mauszeiger an
 move.l  Screen,a0
 move.l  a0,d0
 tst.l   d0
 beq.s   noscreen
 move.l  IntuiBase,a6
 jsr     CloseScreen(a6) ;Screen schließen
noscreen:
 move.l  KrScreen,a0
 move.l  a0,d0
 tst.l   d0
 beq.s   nokrscreen
 move.l  IntuiBase,a6
 jsr     CloseScreen(a6)
nokrscreen:
 move.l  ExecBase,a6
 jsr     Enable(a6)
 jsr     Permit(a6)
 move.l  Font,a1
 move.l  a1,d0
 tst.l   d0
 beq     nofont
 move.l  GraphicsBase,a6
 jsr     CloseFont(a6) ;Font schließen
nofont:
 move.l  ExecBase,a6
 move.l  DosBase,a1
 move.l  a1,d0
 tst.l   d0
 beq.s   nodos
 jsr     CloseLibrary(a6) ;Dos schließen
nodos:
 move.l  GraphicsBase,a1
 move.l  a1,d0
 tst.l   d0
 beq.s   nographics
 jsr     CloseLibrary(a6) ;Graphics schließen
nographics:
 move.l  IntuiBase,a1
 move.l  a1,d0
 tst.l   d0
 beq.s   nointui
 jsr     CloseLibrary(a6) ;Intuition schließen
nointui:
 move.l  SaveSP,sp ;alten Stackpointer
 rts
;Es folgen die für die einzelnen Betriebsmodi spezifischen
;Initialisierungsroutinen.
;Initialisierung für Anzeige der Wellenform
clean1:
 movem.l a5/a6/d7,-(a7)
 move.l  IntuiBase,a6
 move.l  Screen,a0
 jsr     ScreenToFront(a6)
 bsr     mauskill
 move.w  #-1,Saveenable
 move.l  GraphicsBase,a6
 move.l  RastPort,a1
 moveq   #0,d0
 jsr     SetRast(a6) ;Schirm löschen
 move.l  GraphicsBase,a6
 move.l  RastPort,a1
 moveq   #2,d0
 jsr     SetAPen(a6) ;Zeichenfarbe setzen
 tst.w   digiflag
 beq     clean1old
 move.l  #line1x,a5
 bsr     makeline
 move.l  #text1x,a5
 bsr     maketext
 bra     clean1cont
clean1old:
 move.l  #line1,a5 ;Linienliste abarbeiten
 bsr     makeline
 move.l  #text1,a5 ;Textliste abarbeiten
 bsr     maketext
clean1cont:
 move.l  #oldpoint,a0 ;Liste der Linienstartpunkte init.
 move.w  #digitn/4-1,d0
 moveq   #-1,d1
clean1loop:
 move.l  d1,(a0)+
 dbf     d0,clean1loop
 move.l  #welle,Feld ;Daten aus Feldliste 
 move.w  #digitn-1,Count ;Anzahl der Linien
 move.w  #1,Step ;Schrittweite
 move.l  #64,Startpos ;Pos. erste Linie
 move.w  #0,Offset ;Vert. Startposition
 move.w  #0,Clearflag
 movem.l (a7)+,a5/a6/d7
 rts
line1x:
line1:
 dc.w 9 ;Anzahl Linien -1
 dc.l 63,0,63,255
 dc.l 64,127,319,127
 dc.l 64,63,319,63
 dc.l 64,191,319,191
 dc.l 64,0,319,0
 dc.l 64,255,319,255
 dc.l 127,0,127,255
 dc.l 191,0,191,255
 dc.l 255,0,255,255
 dc.l 319,0,319,255
text1:
 dc.w 9 ;Anzahl Texte -1
 dc.l 0,8  ,6,str1n3
 dc.l 0,67 ,6,str1n2
 dc.l 0,131,6,str1n1
 dc.l 0,195,6,str1n2
 dc.l 0,254,6,str1n3
 dc.l 44 ,235,2,str1n4
 dc.l 92 ,235,4,str1t
 dc.l 156,235,4,str1t+4
 dc.l 220,235,4,str1t+8
 dc.l 284,235,4,str1t+12
text1x:
 dc.w 9 ;Anzahl Texte -1
 dc.l 0,8  ,6,str1n3
 dc.l 0,67 ,6,str1n2
 dc.l 0,131,6,str1n1
 dc.l 0,195,6,str1n2
 dc.l 0,254,6,str1n3
 dc.l 44 ,235,2,str1n4
 dc.l 92 ,235,4,str1x
 dc.l 156,235,4,str1x+4
 dc.l 220,235,4,str1x+8
 dc.l 284,235,4,str1x+12
str1n1: dc.b "0 Volt"
str1n2: dc.b "1.25 V"
str1n3: dc.b   "2.5  V"
str1n4: dc.b "ms",0
str1x:
IF freqband < 2
 dc.b " 1.3 2.5 3.8 5.1"
ENDIF
str1t:
IF freqband < 3
 dc.b " 1.6 3.2 4.8 6.4"
ENDIF
IF freqband = 3
 dc.b " 2.1 4.2 6.3 8.4"
ENDIF
IF freqband > 3
 dc.b " 3.2 6.4 9.612.8"
ENDIF
 even
;Initialisierung für Anzeige des Frequenzspektrums
clean2:
 movem.l a5/a6/d7,-(a7)
 move.l  GraphicsBase,a6
 move.l  RastPort,a1
 moveq   #0,d0
 jsr     SetRast(a6)
 move.l  GraphicsBase,a6
 move.l  RastPort,a1
 moveq   #2,d0
 jsr     SetAPen(a6)
 move.l  #line2,a5
 bsr     makeline
 tst.w   digiflag
 beq     clean2old
 move.l  #scale2x,a5
 bsr     makescale
 move.l  #text2x,a5
 bsr     maketext
 bra     clean2cont
clean2old:
 move.l  #scale2,a5
 bsr     makescale
 move.l  #text2,a5
 bsr     maketext
clean2cont:
 move.l  #oldpoint,a0
 move.w  #digitn/4-1,d0
 move.l  #$e5e5e5e5,d1
clean2loop:
 move.l  d1,(a0)+
 dbf     d0,clean2loop
 move.l  #spektrum,Feld
 move.w  #digitn/2-1,Count
 move.w  #2,Step
 move.l  #64,Startpos
 move.w  #$1a,Offset
 move.w  #0,Clearflag
 movem.l (a7)+,a5/a6/d7
 rts
line2:
 dc.w 6
 dc.l 63,1,63,230
 dc.l 63,230,319,230
 dc.l 64,57,319,57
 dc.l 64,115,319,115
 dc.l 64,172,319,172
 dc.l 64,1  ,319,1
 dc.l 319,1,319,230
scale2x:
IF freqband < 2
 dc.w -75 , 85 , 96 , 106,-116, 126, 137, 147
 dc.w  157,-167, 177, 187, 197, 207,-217, 227
 dc.w  237, 247, 257,-267, 277, 287, 297, 307
 dc.w -317, 0
ENDIF
scale2:
IF freqband < 3
 dc.w -76 , 88 , 101, 113,-126, 138, 151, 163
 dc.w  177,-189, 203, 215, 228, 240,-253, 265
 dc.w  278, 290, 305,-319, 0
ENDIF
IF freqband = 3
 dc.w -81 , 98 , 115, 132,-149, 166, 183, 200
 dc.w  217,-234, 251, 268, 285, 302,-319, 0
ENDIF
IF freqband > 3
 dc.w -90 ,-115,-140,-166,-191,-217,-243,-269
 dc.w -295,-319, 0
ENDIF
text2:
 dc.w 6
 dc.l 0 ,255-8 , 3,str2n1
 dc.l 64,255-9 ,32,freq1
 dc.l 64,255-1 ,32,freq2
 dc.l 0,175,5,fdb1
 dc.l 0,118,5,fdb2
 dc.l 0,60 ,5,fdb3
 dc.l 0,8  ,5,fdb4
text2x:
 dc.w 6
 dc.l 0 ,255-8 , 3,str2n1
 dc.l 64,255-9 ,32,freq1x
 dc.l 64,255-1 ,32,freq2x
 dc.l 0,175,5,fdb1
 dc.l 0,118,5,fdb2
 dc.l 0,60 ,5,fdb3
 dc.l 0,8  ,5,fdb4
str2n1: dc.b "KHz",0
fdb1:   dc.b "-6 dB",0
fdb2:   dc.b " 0 dB",0
fdb3:   dc.b " 3 dB",0
fdb4:   dc.b " 6 dB",0
freq1x:
IF freqband < 2
 dc.b " 1    5     1      1     2     2"
 dc.b "            0      5     0     5"
ENDIF
freq1:
IF freqband < 3
 dc.b " 1      5       1       1      2"
 dc.b "                0       5      0"
ENDIF
IF freqband = 3
 dc.b "  1       5          1         1"
 dc.b "                     0         5"
ENDIF
IF freqband > 3
 dc.b "   1  2  3  4   5  6  7  8  9  1"
 dc.b "                               0"
ENDIF
 freq2= freq1+32
 freq2x= freq1x+32
 even
;Initialisierungsroutine für Anzeige der Mittelwerte
clean3:
 movem.l a5/a6/d7,-(a7)
 move.l  GraphicsBase,a6
 move.l  RastPort,a1
 moveq   #0,d0
 jsr     SetRast(a6)
 move.l  GraphicsBase,a6
 move.l  RastPort,a1
 moveq   #2,d0
 jsr     SetAPen(a6)
 move.l  #line2,a5
 bsr     makeline
 tst.w   digiflag
 beq     clean3old
 move.l  #scale2x,a5
 bsr     makescale
 move.l  #text3x,a5
 bsr     maketext
 bra     clean3cont
clean3old:
 move.l  #scale2,a5
 bsr     makescale
 move.l  #text3,a5
 bsr     maketext
clean3cont:
 move.l  #oldpoint,a0
 move.w  #digitn/4-1,d0
 move.l  #$e5e5e5e5,d1
clean3loop:
 move.l  d1,(a0)+
 dbf     d0,clean3loop
 move.l  #sumshow,Feld
 move.w  #digitn/2-1,Count
 move.w  #2,Step
 move.l  #64,Startpos
 move.w  #$1a,Offset
 move.w  #-1,Clearflag
 bsr     sumclear
 movem.l (a7)+,a5/a6/d7
 rts
text3:
 dc.w 5
 dc.l 0 ,255-8 , 3,str2n1
 dc.l 64,255-9 ,32,freq1
 dc.l 64,255-1 ,32,freq2
 dc.l 0,15,6,str3n1
 dc.l 0,35,6,str3n2
 dc.l 0,43,2,str3n3
text3x:
 dc.w 5
 dc.l 0 ,255-8 , 3,str2n1
 dc.l 64,255-9 ,32,freq1x
 dc.l 64,255-1 ,32,freq2x
 dc.l 0,15,6,str3n1
 dc.l 0,35,6,str3n2
 dc.l 0,43,2,str3n3
str3n1: dc.b "Profil",0
str3n2: dc.b "Faktor",0
str3n3: dc.b "2^",0
 even
;Anzeige des Shiftfaktors:
shiftshow:
 move.l  RastPort,a1
 moveq   #16,d0
 moveq   #43,d1
 move.l  GraphicsBase,a6
 jsr     Move(a6)
 move.l  Shift,d0
 move.l  #zifflist,a0
 add.l   d0,a0
 add.l   d0,a0
 moveq   #2,d0
 move.l  RastPort,a1
 jsr     Text(a6)
 rts
zifflist:
 dc.b "0 1 2 3 4 5 6 7 8 9 1011121314151617181920"
 dc.b "2122232425262728293031",0
 even
clean4:
 movem.l a5/a6/d7,-(a7)
 clr.w   Saveenable
 move.l  KrScreen,a0
 move.l  IntuiBase,a6
 jsr     ScreenToFront(a6)
 bsr     mauskill
 move.l  #copfield,a0 ;CopField löschen
 moveq   #31,d0
cl4l1:
 clr.l   (a0)+
 dbf     d0,cl4l1
 move.l  View,a0
 move.l  4(a0),a0 ;cprlst
 move.w  8(a0),d6 ;Anzahl Befehle
 subq    #1,d6 ;Befehlsliste
 move.l  4(a0),a6 
 move.l  #copfield,a5
cl4l2:
 move.l  (a6)+,d0
 swap    d0
 andi.l  #$fff,d0
 moveq   #1,d1
 and.w   d0,d1
 bne.s   nocopcol
 subi.w  #$180,d0
 blt.s   nocopcol
 cmpi.w  #$40,d0
 bge.s   nocopcol
 lsl.w   #1,d0
 move.l  a6,d1
 subq    #2,d1
 move.l  d1,0(a5,d0)
nocopcol:
 dbf     d6,cl4l2
 moveq   #31,d0
 move.l  #copfield,a0
cl4l3:
 tst.l   (a0)+
 beq     kill
 dbf     d0,cl4l3
 move.l  #oldvalue,a0
 moveq   #7,d0
cl4l5:
 clr.l   (a0)+
 dbf     d0,cl4l5
 movem.l (a7)+,a5/a6/d7
 rts
;Es folgt die Routine zum Ziehen der Linien
makeline:
 move.w  (a5)+,d5
lineloop:
 movem.l (a5)+,d0/d1
 move.l  RastPort,a1
 jsr     Move(a6) ;Startposition setzen
 movem.l (a5)+,d0/d1
 move.l  RastPort,a1
 jsr     Draw(a6) ;Linie ziehen
 dbf     d5,lineloop
 rts
;Es folgt die Routine zum Erstellen des Skalierung
makescale:
 moveq   #0,d0
 move.l  #233,d1
 move.w  (a5)+,d0
 bne.s   makescp
 rts
makescp:
 bpl.s   makescpl
 neg.w   d0
 move.w  #236,d1
makescpl:
 move.l  d0,d6
 move.l  RastPort,a1
 jsr     Move(a6)
 moveq   #0,d0
 move.w  d6,d0
 move.l  #231,d1
 move.l  RastPort,a1
 jsr     Draw(a6)
 bra.s   makescale
;Es folgt die Routine zum Schreiben der Texte
maketext:
 move.w  (a5)+,d5
textloop:
 move.l  RastPort,a1
 movem.l (a5)+,d0/d1
 jsr     Move(a6)
 movem.l (a5)+,d0/a0
 jsr     Text(a6)
 dbf     d5,textloop
 rts
;
;Es folgt die Routine zum Einlesen der Daten vom Digitizer
;;Da es hier auf genaues Timing ankommt, wurden einige NOP-Befehle
;verwendet.
;
digit:
 move.l  #daten,a0
 move.w  #Sync,d2
 move.w  #Sync,d3
 move.w  #digitn-1,d4 
 moveq   #$04,d5
 moveq   #$fa-256,d6
 moveq   #1,d1
 move.l  #CIAB,a1
 move.l  #PARPORT,a2
 tst.w   digiflag
 beq     digold
 move.b  d0,(a2)
 move.b  (a2),d0
 nop
 nop
 nop
digit5loop:
 WAIT2
 move.b  d0,(a2)
 nop
 nop
 move.b  (a2),d0
 nop
 dbpl    d2,digit5loop
digit6loop:
 WAIT2
 move.b  d0,(a2)
 nop
 nop
 move.b  (a2),d0
 nop
 dbmi    d3,digit6loop
digit7loop:
 WAIT2
 move.b  d0,(a2)
 nop
 nop
 move.b  (a2),(a0)+
 dbf     d4,digit7loop
 bra     digend
digold:
;für die alte Beschaltung
digit1loop:
;Synchronisation
 or.b    d5,(a1)
 and.b   d6,(a1)
 WAIT1
 move.b  (a2),d0
 dbpl    d2,digit1loop
digit2loop:
 or.b    d5,(a1)
 and.b   d6,(a1)
 WAIT1
 move.b  (a2),d0
 dbmi    d3,digit2loop
digit3loop:
;einlesen
 or.b    d5,(a1)
 and.b   d6,(a1)
 WAIT1
 move.b  (a2),(a0)+
 dbf     d4,digit3loop
digend:
 move.l  #daten,a0
 move.l  #welle,a1
 move.l  #shuffle,a2
 move.w  #digitn-1,d1
digit4loop:
;in die Listen eintragen
 moveq #0,d0
 move.b  (a0)+,d0
 move.l  d0,(a1)+
 subi.w  #128,d0
 move.l  (a2)+,a3
 move.l  d0,(a3)
 dbf     d1,digit4loop
 clr.b   flag
 rts
;
;***************************************
;Die "Schnelle Fourier-Transformation"
;***************************************
fftshort:
 movem.l d7/a5/a6,-(a7)
 move.l  #daten,a0
 move.l  #sshuffle,a1
 moveq   #partyn-1,d1
fftsl1:
 moveq   #0,d0
 move.b  (a0),d0
 addq.l  #partyfreq,a0
 subi.w  #128,d0
 move.l  (a1)+,a2
 move.l  d0,(a2)
 dbf     d1,fftsl1
 move.l  #sspektrum,a6
 move.l  #4*partyn,a0
 move.w  #partyn/2-1,sqcount
 bra.s   fft
fftlong:
 movem.l d7/a5/a6,-(a7)
 move.l  #spektrum,a6
 move.l  #4*digitn,a0
 move.w  #digitn/2-1,sqcount
 move.b  #-1,flag
fft:
 moveq   #4,d7
 move.l  #sinustab,a3
fftloop1:
 moveq   #4,d6
fftfor:
 move.l  d6,d0 ;Bestimmung von Sinus und Kosinus
 subq    #4,d0
 asl.l   #5,d0
 asl.l   #4,d0
 divs    d7,d0 ;d0 jetzt zwischen 0 und 512 als zeiger auf word
 cmpi.w  #256,d0
 bge.s   gross ;größer als pi halbe
 moveq   #0,d3
 move.w  0(a3,d0.w),d3 ;-sinus
 move.l  d3,a1
 move.w  #256,d1
 sub.w   d0,d1
 move.w  0(a3,d1.w),d3 ;cosinus
 move.l  d3,a2
 bra.s   endsin
gross:
 moveq   #0,d3
 move.l  d0,d1
 sub.w   #256,d1
 sub.w   0(a3,d1.w),d3 ;cosinus
 move.l  d3,a2
 move.w  #512,d1 ;-sinus
 sub.w   d0,d1
 moveq   #0,d3
 move.w  0(a3,d1.w),d3
 move.l  d3,a1
endsin:
 move.l  d6,a5
 subq    #4,a5
 move.l  a2,d3
 move.l  a1,d2
fftloop2:
 move.l  a5,a4
 add.l   d7,a4
 move.w  2(a6,a4),d5
 move.w  0(a6,a4),d4
 move.w  d5,d1
 move.w  d4,d0
 muls    d3,d5
 muls    d3,d4
 muls    d2,d0
 muls    d2,d1
 sub.l   d0,d5
 add.l   d1,d4
 asr.l   #8,d5
 asr.l   #8,d4
 move.w  2(a6,a5),d1 ;real[i]
 move.w  0(a6,a5),d0 ;imag[i]
 sub.w   d5,d1
 sub.w   d4,d0
 move.w  d1,2(a6,a4)
 move.w  d0,0(a6,a4)
 add.w   d5,2(a6,a5)
 add.w   d4,0(a6,a5)
 add.l   d7,a5
 add.l   d7,a5
 cmp.l   a0,a5
 blt     fftloop2
 addq    #4,d6
 cmp.l   d7,d6
 ble     fftfor
 asl.l   #1,d7
 cmp.l   a0,d7
 blt     fftloop1
 move.w  sqcount,d7 ;quadrieren
 moveq   #5,d4
quadloop:
 move.w  (a6),d0
 move.w  2(a6),d1
 muls    d0,d0
 muls    d1,d1
 add.l   d1,d0
 move.w  #2,d6 ;3 durchläufe
 moveq   #15,d5 ;erster schätzwert
 move.l  d0,d2
 asr.l   #1,d2
 or.l    d0,d2
schaetzung:
 asl.l   #2,d2
 roxl.w  #1,d1
 dbf     d5,schaetzung
sqrtloop:
 tst.w   d1 ;keine Division durch null
 beq.s   sqrtend
 move.l  d0,d2
 divs    d1,d2
 add.w   d2,d1
 asr.w   #1,d1
 and.w   #$7fff,d1
 dbf     d6,sqrtloop
sqrtend:
 lsr.w   d4,d1
 andi.l  #$ffff,d1
 move.l  d1,(a6)+ 
 dbf     d7,quadloop
 movem.l (a7)+,d7/a5/a6
 rts
sqcount: dc.w 0
sinustab: dc.w 000,003,006,009,013,016,019,022
 dc.w 025,028,031,034,038,041,044,047
 dc.w 050,053,056,059,062,065,068,071
 dc.w 074,077,080,083,086,089,092,095
 dc.w 098,101,104,107,109,112,115,118
 dc.w 121,123,126,129,132,134,137,140
 dc.w 142,145,147,150,152,155,157,160
 dc.w 162,165,167,170,172,174,177,179
 dc.w 181,183,185,188,190,192,194,196
 dc.w 198,200,202,204,206,207,209,211
 dc.w 213,215,216,218,220,221,223,224
 dc.w 226,227,229,230,231,233,234,235
 dc.w 237,238,239,240,241,242,243,244
 dc.w 245,246,247,248,248,249,250,250
 dc.w 251,252,252,253,253,254,254,254
 dc.w 255,255,255,256,256,256,256,256,256
;
;Es folgt die Routine zur Anzeige der Daten im Hauptscreen
show:
 movem.l d7/a5/a6,-(a7)
 move.l  Feld,a5 ;DatenListe
 move.l  #oldpoint,a4 ;Liste der alten Endpunkte
 move.w  Count,d7 ;Anzahl
 move.l  #COPROC,a6 ;Basisadresse der Coprozessoren
 move.l  Startpos,d6 ;erste x-Adresse
showloop:
 move.l  (a5)+,d4 ;neuer Wert
 cmp.w   #$ff,d4
 ble.s   notgreat
 move.w  #$ff,d4
notgreat:
 not.b   d4
 sub.w   Offset,d4
 bge.s   Offsetok
 moveq   #0,d4
Offsetok:
 moveq   #0,d3
 move.b  (a4),d3 ;alter Wert
 move.b  d4,(a4)+ ;neuen Wert speichern
 cmp.b   d3,d4 ;wenn gleich, dann keine Linie
 beq     sloopend
showwait:
 btst    #6,DMACONR(a6)
 bne.s   showwait
 moveq   #0,d0
 move.w  d0,BLTBMOD(a6)
 move.l  #-1,BLTAFWM(a6)
 move.w  #$8000,BLTADAT(a6)
 move.w  BPR,BLTCMOD(a6)
 move.w  #-1,BLTBDAT(a6)
 move.l  BitPlane1,a0
 move.w  d6,d0
 asr.w   #3,d0
 add.l   d0,a0
 move.w  d3,d0
 mulu    BPR,d0
 add.l   d0,a0
 move.l  a0,BLTCPTH(a6)
 move.l  a0,BLTDPTH(a6)
 moveq   #$f,d1
 and.w   d6,d1
 swap    d1
 asr.l   #4,d1
 swap    d1
 sub.w   d3,d4
 blt.s   rauf
 ori.l   #$0b0af041,d1
 bra.s   richtok
rauf:
 ori.l   #$0bcaf045,d1
 neg.b   d4
 subq.b  #1,d4
richtok:
 andi.w  #$00ff,d4
 move.l  d1,BLTCON0(a6)
 moveq   #0,d0
 sub.w   d4,d0
 move.w  d0,BLTAPTL(a6)
 sub.w   d4,d0
 move.w  d0,BLTAPTL(a6)
 move.w  d4,d0
 addq.w  #1,d0
 asl.w   #6,d0
 ori.w   #2,d0
 move.w  d0,BLTSIZE(a6) ;los geht's
sloopend:
 add.w   Step,d6
 dbf     d7,showloop
sendwait:
 btst    #6,DMACONR(a6)
 bne.s   sendwait
 movem.l (a7)+,a5/a6/d7
 rts
Feld:     dc.l 0 ;Zeiger auf Datenliste
Count:    dc.w 0 ;Anzahl
Step:     dc.w 0 ;Schrittweite
Startpos: dc.l 0 ;erste Linie
Offset:   dc.w 0 ;Vert. Offset
;Es folgen die Routinen zur Bearbeitung des Frequenzmittels
sumclear: 
 movem.l d0/a0/a1,-(a7)
 move.l  #sumfeld,a0
 move.l  #sumshow,a1
 move.w  #digitn/2-1,d0
sumclloop:
 clr.l   (a0)+
 clr.l   (a1)+
 dbf     d0,sumclloop
 move.l  #0,Shift
 jsr     shiftshow
 movem.l (a7)+,d0/a0/a1
 rts
summ:
 movem.l d0-d3/d7/a0-a2/a5/a6,-(a7)
 move.l  #spektrum,a0
 move.l  #sumfeld,a1
 move.l  #sumshow,a2
 move.l  #digitn/2-1,d0
 move.l  Shift,d1
 moveq   #0,d3
summloop:
 move.l  (a1),d2
 add.l   (a0)+,d2
 bcs.s   summalert
 move.l  d2,(a1)+
 lsr.l   d1,d2
 move.l  d2,(a2)+
 cmpi.l  #230,d2
 blt     nobig
 moveq   #-1,d3
nobig:
 dbf     d0,summloop
 tst.l   d3
 beq.s   noscale
 addq.l  #1,Shift
 cmpi.l  #23,Shift
 bge.s   summalert
 jsr     shiftshow
 bra.s   noscale
summalert:
 bsr     sumclear ;Überlauf!
noscale:
 movem.l (a7)+,d0-d3/d7/a0-a2/a5/a6
 rts
Shift:   dc.l 0
;
;Es folgt die Routine, die die Kreise für den Partymodus zieht
kr_num:  dc.w 0
circle:
 clr.l   d7
 clr.l   d1
 move    s_rad,d7 ;Start-Radius (R)
 clr.l   Kr_num
loop:
 move.l  GraphicsBase,a6
 move.l  KrRastPort,a1
 move    kr_col,d0
 sub     Kr_num,d0
 jsr     SetAPen(a6) ;Stiftnummer
 move.l  d7,d6 ;DA berechnen:
 subq    #1,d6 ;DA=R-1
 clr.l   d4 ;X=0
 move.l  d7,d5 ;Y=R
kr_l_1:
 cmp     #0,d6
 bge     kr_l_2
 subq    #1,d5 ;Y=Y-1
 add     d5,d6 ;DA=DA+Y
 add     d5,d6 ;DA=DA+Y
kr_l_2:
 move    x0,d0
 add     d4,d0 ;x0+x
 move    y0,d1
 add     d5,d1 ;y0+y
 move.l  KrRastPort,a1
 jsr     Move(a6)
 move    x0,d0
 sub     d4,d0 ;x0-x
 move    y0,d1
 add     d5,d1 ;y0+y
 move.l  KrRastPort,a1
 jsr     Draw(a6)
 move    x0,d0
 add     d4,d0 ;x0+x
 move    y0,d1
 sub     d5,d1 ;y0-y
 move.l  KrRastPort,a1
 jsr     Move(a6)
 move    x0,d0
 sub     d4,d0 ;x0-x
 move    y0,d1
 sub     d5,d1 ;y0-y
 move.l  KrRastPort,a1
 jsr     Draw(a6)
 move    x0,d0
 add     d5,d0 ;x0+y
 move    y0,d1
 add     d4,d1 ;y0+x
 move.l  KrRastPort,a1
 jsr     Move(a6)
 move    x0,d0
 sub     d5,d0 ;x0-y
 move    y0,d1
 add     d4,d1 ;y0+x
 move.l  KrRastPort,a1
 jsr     Draw(a6)
 move    x0,d0
 add     d5,d0 ;x0+y
 move    y0,d1
 sub     d4,d1 ;y0-x
 move.l  KrRastPort,a1
 jsr     Move(a6)
 move    x0,d0
 sub     d5,d0 ;x0-y
 move    y0,d1
 sub     d4,d1 ;y0-x
 move.l  KrRastPort,a1
 jsr     Draw(a6)
 sub     d4,d6 ;DA=DA-X
 sub     d4,d6 ;DA=DA-X
 subq    #1,d6 ;DA=DA-1
 addq    #1,d4 ;X=X+1
 cmp     d4,d5
 ble     kr_fin
 bra     kr_l_1
kr_fin:
 sub     radius,d7
 addq    #1,Kr_num
 move    Kr_num,d1
 cmp     kr_anz,d1
 bne     loop
 rts
;
 x0:     dc.w 0
 y0:     dc.w 0
 radius: dc.w 0
 s_rad:  dc.w 0
 kr_anz: dc.w 0
 kr_col: dc.w 0
;
;Es folgen die Routinen des Party-Modus
color:
 movem.l d7/a5/a6,-(a7)
 move    #30,d7
 move.l  #sspektrum,a1 ;Neue Werte
 move.l  #oldvalue,a2 ;Alte Werte
 move.l  #MaxList,a3 ;Maximal-Datenwerte
 move.l  #Rainbow+2,a4
 move.l  #copfield+4,a5
col:
 moveq   #0,d2
 moveq   #0,d3
 moveq   #0,d6
 move.l  (a1)+,d1 ;Neuer Wert
 lsl     #1,d1
 and.l   #255,d1
 move.b  (a2),d2 ;Alter Wert
 move.b  (a3)+,d3 ;Maximal-Wert
 move.b  d3,d0
 lsr.b   #4,d0
 addq.b  #2,d0
 cmp.b   d3,d1
 blt.s   col1
 move.b  d3,d1
col1:
 cmp.b   d2,d1
 blt.s   col2
 add.b   d0,d1
 move.b  d1,d2
col2:
 sub.b   d0,d2
 bpl.s   col3
 moveq   #0,d2
col3:
 move.b  d2,(a2)+
 move.b  (a4)+,d1 ;Rot
 mulu    d2,d1
 move    d3,d4
 divu    d4,d1
 and.b   #$f,d1
 move.b  d1,d6
 lsl.w   #4,d6
 move.b  (a4),d1 ;Grün
 lsr.b   #4,d1
 mulu    d2,d1
 move    d3,d4
 divu    d4,d1
 andi.w  #$f,d1
 or.b    d1,d6
 lsl.w   #4,d6
 move.b  (a4)+,d1 ;Blau
 andi.b  #$f,d1
 mulu    d2,d1
 move    d3,d4
 divu    d4,d1
 andi.w  #$f,d1
 or.b    d1,d6
 move.l  (a5)+,a6
 move.w  d6,(a6)
 dbra    d7,col
 movem.l (a7)+,a5/a6/d7
 rts
;
Rainbow:
 dc.w $000,$f0f ;Maximal-Farbwerte
 dc.w $d0f,$b0f
 dc.w $80f,$00f
 dc.w $07f,$08f
 dc.w $09f,$0af
 dc.w $0bf,$0cf
 dc.w $0df,$0ef
 dc.w $0ff,$0fd
 dc.w $0fb,$0f8
 dc.w $0f0,$8f0
 dc.w $bf0,$df0
 dc.w $ff0,$fe0
 dc.w $fd0,$fc0
 dc.w $fb0,$fa0
 dc.w $f90,$f80
 dc.w $f70,$f00
MaxList:
IF partyfreq = 1
 dc.b 55,30,24,22,22,21,20,19,19,18
 dc.b 18,17,16,15,14,13,11,10,10, 9
 dc.b  8, 8, 8, 8, 8, 8, 8, 7, 7, 7
 dc.b  7
ENDIF
IF partyfreq = 2
 dc.b 55,30,24,22,22,21,20,19,19,18
 dc.b 18,17,16,15,14,13,11,10,10, 9
 dc.b  8, 8, 8, 8, 8, 8, 8, 7, 7, 7
 dc.b  7
ENDIF
IF partyfreq = 3
 dc.b 63,32,26,23,22,21,20,19,19,18
 dc.b 18,18,18,17,17,17,17,17,16,16
 dc.b 16,16,16,16,16,15,15,15,15,15
 dc.b 15
ENDIF
IF partyfreq = 4
 dc.b 63,32,26,23,22,21,20,19,19,18
 dc.b 18,18,18,17,17,17,17,17,16,16
 dc.b 16,16,16,16,16,15,15,15,15,15
 dc.b 15
ENDIF
 even
;Es folgen die Routinen zum Speichern des Hauptscreens als IFF-Datei
save:
 movem.l d7/a5/a6,-(a7)
 move.l  Screen,a0
 move.l  IntuiBase,a6
 jsr     ScreenToBack(a6)
 move.l  KrScreen,a0
 jsr     ScreenToBack(a6)
 move.l  ExecBase,a6
 jsr     Enable(a6)
 move.w  #onsprite,DMACON
 move.l  DosBase,a6
 bsr     dodos
 move.l  ExecBase,a6
 jsr     Disable(a6)
 move.l  Screen,a0
 move.l  IntuiBase,a6
 jsr     ScreenToFront(a6)
 bsr     mauskill
 movem.l (a7)+,d7/a5/a6
 rts
dodos:
 move.l  doutput,d1
 move.l  #dtext1,d2
 moveq   #dtl1,d3
 jsr     Write(a6)
 move.l  dinput,d1
 move.l  #instring,d2
 moveq   #inleng,d3
 jsr     Read(a6)
 cmpi.l  #2,d0
 blt     dosx
 move.l  #instring,a0
 move.b  #0,-1(a0,d0)
 move.l  a0,d1
 move.l  #1006,d2
 jsr     Open(a6)
 move.l  d0,file
 tst.l   d0
 beq     doserr
 move.l  file,d1
 move.l  #dfeld,d2
 move.l  #dflen,d3
 jsr     Write(a6)
 cmpi.l  #dflen,d0
 bne     doserr
 move.l  Bitplane1,a4
 move.l  Bitplane2,a5
 move.w  #hoch-1,d5
iffloop:
 movem.l d5/a4/a5,-(a7)
 move.l  file,d1
 move.l  4(a7),d2
 move.l  #breit/8,d3
 jsr     Write(a6)
 cmpi.l  #breit/8,d0
 beq.s   iff1
 movem.l (a7)+,d5/a4/a5
 bra     doserr
iff1:
 move.l  file,d1
 move.l  8(a7),d2
 move.l  #breit/8,d3
 jsr     Write(a6)
 cmpi.l  #breit/8,d0
 beq.s   iff2
 movem.l (a7)+,d5/a4/a5
 bra     doserr
iff2:
 movem.l (a7)+,d5/a4/a5
 adda.l  #breit/8,a4
 adda.l  #breit/8,a5
 dbf     d5,iffloop
 move.l  file,d1
 jsr     Close(a6)
 clr.l   file
dosend:
 move.l  doutput,d1
 move.l  #dtext2,d2
 move.l  #dtl2,d3
 jsr     Write(a6)
 move.l  #200,d1
 jsr     Delay(a6)
dosx:
 rts
doserr:
 jsr     IoErr(a6)
 move.l  d0,Dosern
 move.l  file,d1
 jsr     Close(a6)
 bra     dodos
Dosern: dc.l 0
dtext1: dc.b "Filename :",0
dtext2: dc.b "Bitte warten, gleich geht's weiter",$0d,$0a
dtext3:
 dtl1= dtext2-dtext1
 dtl2= dtext3-dtext2
 even
 fieldlen= breit*hoch/8
;Der Vorspann für die IFF-Datei
dfeld:
 dc.b "FORM"
 dc.l 2*fieldlen+dflen-8
 dc.b "ILBM"
 dc.b "BMHD"
 dc.l 20
 dc.w breit,hoch,0,0
 dc.b 2,0,0,0
 dc.w 0
 dc.b $a,$b
 dc.w breit,hoch
 dc.b "BODY"
 dc.l 2*fieldlen
dfeldend:
 dflen= dfeldend-dfeld
;
 data
daten:     blk.b digitn ;Lesefeld für Digitizer
welle:     blk.l digitn ;Liste für Wellenform
spektrum:  blk.l digitn ;Liste für Spektrum
sspektrum: blk.l partyn ;Liste für Party-Spektrum
oldpoint:  blk.b digitn ;Liste der alten Endpunkte
shuffle:   blk.l digitn ;Shuffle
sshuffle:  blk.l partyn ;Party-Shuffle
sumfeld:   blk.l digitn/2 ;Summation
sumshow:   blk.l digitn/2 ;Anzeigefeld
instring:  blk.b inleng+4 ;Eingabefeld
copfield:  blk.l 32 ;Zeiger auf Copper-Farbbefehle
oldvalue:  blk.b 32
 end
