*
* Copper-Rolling über die Hardware!
*
* written on 30/10/89  21:48:43  by Holger Gzella
*
* Ganz lustig: ein Copper-Balken, der zwischen den Zeilen
* 80 und 200 pendelt.
*

                incdir "asm:"
                include "exec/exec_lib.i"
                include "libraries/dos_lib.i"

StartIt:        lea     DosName,a1              * DOS-Library öffnen
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                move.l  d0,DosBase

                move.l  #2000,d0                * 2000 Bytes
                move.l  #$10002,d1              * CHIP-Memory
                CALLEXEC AllocMem               * allokieren
                tst.l   d0                      * alles klar?
                beq     Fault                   * nein - beenden!
                move.l  d0,CopperList           * Zeiger sichern

*
* Jetzt wird die Maschine übernommen.
*

                CALLEXEC Forbid                 * kein Multitasking
                move.w   #$3a0,$DFF096          * Copper-, Sprite- und
                                                * Bitplane-DMA sowie DMAEN
                                                * löschen

*
* Nun wird die Copperlist erstellt - ein Farbverlauf mit
* den Farben, die in der Tabelle im Datenteil stehen ...
*

                move.l   CopperList,a0          * Copperlist nach a0

                move.w   #$180,(a0)+            * bis zum Verlauf
                move.w   #$000,(a0)+            * schwarzer Hintergrund

                move.l   #$5001,d0              * Verlauf ab Zeile #80 ($50)
                lea      Colors,a1              * Farben laden
                moveq.w  #30,d1                 * 30+1=31 Abstufungen

SetEntry:       move.w   d0,(a0)+               * Position in die Liste
                move.w   #$fffe,(a0)+           * Maske in die Liste
                move.w   #$180,(a0)+            * Hintergrund-Register
                move.w   (a1)+,(a0)+            * und Tabellen-Farbwert
                add.w    #$0100,d0              * y-Position erhöhen
                dbra     d1,SetEntry            * bis zum bitteren Ende!

                move.w   #$180,(a0)+            * der Rest soll
                move.w   #$000,(a0)+            * schwarz sein!
                move.l   #$fffffffe,(a0)        * Ende!

                move.l   CopperList,$DFF080     * List manipulieren
                move.l   #0,$DFF088             * COPJMP1 löschen

                move.w   #$8280,$DFF096         * Copper-DMA und DMAEN
                                                * aktivieren

*
* Dies ist das Herz des Programms - die Roll-Routine!
*

                move.l   DosBase,a6
                move.l   #80,LineCounter        * fängt ab Zeile 80 an
                move.l   #1,Direction           * Richtung: nach unten!

RolLoop:        move.l   CopperList,a0          * Liste laden
                add.l    #4,a0                  * Zeiger auf 1. WAIT

                cmp.l    #200,LineCounter       * Zeile 200 erreicht?
                blo.s    IsItTop                * nein, noch nicht

*
* Dieser Teil wird ausgeführt, wenn die Rasterzeile 200
* von unserem Balken erreicht worden ist, und ändert die Richtung:
* statt nach unten rollt der Balken nach oben bis zur Zeile 80!
*

                move.l   #0,Direction           * Richtung: nach oben!

IsItTop:        cmp.l    #80,LineCounter        * Zeile 80 erreicht?
                bhi.s    RollIt                 * höher?

                move.l   #1,Direction           * Richtung: nach unten

*
* Der jetzt kommende Teil wird auf jeden Fall ausgeführt
* und schiebt den Balken eine Rasterzeile nach oben oder unten.
*

RollIt:         cmp.l    #1,Direction          * nach unten rollen?
                beq.s    RollDown              * jawoll!

*
* Anscheinend soll nach oben gerollt werden. Nun denn, der
* Amiga macht's möglich; sehen Sie selbst!
*

RollUp:         moveq    #30,d0                * 30+1=31 Zeilen rollen
                                               * (dies ist die Höhe des
                                               * Balkens, tatsächlich
                                               * gerollt wird natürlich
                                               * nur jede Zeile einmal)

RollCopper1:    sub.w    #$0100,(a0)           * Zeilennummer der WAIT-
                                               * Instruktion -1
                addq.l   #8,a0                 * 8 Bytes weiter steht
                                               * der nächste WAIT!
                dbra     d0,RollCopper1        * bis zum Ende rollen ...

                subq.l   #1,LineCounter        * Zeilenzähler -1
                bra      Finished              * fertig gerollt!

*
* Wie's das Schicksal so will, soll nach unten gerollt
* werden, was aber keine Schwierigkeiten bereiten dürfte.
*

RollDown:       moveq    #30,d0                * 30+1=31 Zeilen des
                                               * Balkens rollen

RollCopper2:    add.w    #$100,(a0)            * Zeilennummer der be-
                                               * treffenden WAIT-
                                               * Instruktion erhöhen
                addq.l   #8,a0                 * nach 8 Bytes kommt der
                                               * nächste WAIT-Befehl
                dbra     d0,RollCopper2        * bis zum Ende rollen!

                addq.l   #1,LineCounter        * Zeilenzähler erhöhen

*
* Nun wird noch 2 IntuiTicks (1/25stel Sekunde) gewartet ...
*

Finished:       moveq.l  #2,d1
                jsr      _LVODelay(a6)

                btst.b   #6,$bfe001             * Maustaste abfragen
                bne      RolLoop                * nicht gedrückt

*
* Hier wird der ursprüngliche Zustand wieder hergestellt.
*

                lea      GfxName,a1             * Graphics öffnen
                moveq.l  #0,d0
                CALLEXEC OpenLibrary
                move.l   d0,a1

                move.l   38(a1),$DFF080         * System-List wieder
                                                * aktivieren

                CALLEXEC CloseLibrary           * Graphics schließen

                move.l   DosBase,a1             * DOS schließen
                CALLEXEC CloseLibrary

                move.l   #0,$DFF088             * COPJMP1 löschen
                move.w   #$83e0,$DFF096         * Copper-, Blitter-, Sprite-
                                                * und Bitplane-DMA sowie
                                                * DMAEN aktivieren

                CALLEXEC Permit                 * Multitasking erlauben

                move.l   CopperList,a1          * Copperlist im
                move.l   #2000,d0               * CHIP-RAM wieder
                CALLEXEC FreeMem                * deallokieren

Fault:          moveq    #0,d0                  * Ende!
                rts

*
* Auch hier wieder ein Datenteil ...
*

GfxName:        dc.b     "graphics.library",0
 even
DosName:        dc.b     "dos.library",0
 even

DosBase:        dc.l     0
CopperList:     dc.l     0

Direction:      dc.l     1                      * Rollrichtung
LineCounter:    dc.l     0                      * Zeilenzähler

*
* Dies sind die Farben des Rollbalkens. Setzen Sie ruhig Ihre
* eigenen Farbwerte im Amiga-RGB-Format ein (hier sind es
* Rot-Werte), aber achten Sie darauf, nicht mehr als 30
* Einträge zu verwenden oder ändern Sie die Rollroutine.
*

Colors:         dc.w     $000,$100,$200,$300,$400,$500,$600,$700,$800
                dc.w     $900,$A00,$B00,$C00,$D00,$E00,$F00,$E00,$D00
                dc.w     $C00,$B00,$A00,$900,$800,$700,$600,$500,$400
                dc.w     $300,$200,$100,$000

                END

