*
* Playfield-Demo - unter Berücksichtigung der "graphics.library"
*
* written on 4/11/89  16:05:40  by Holger Gzella
*

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

MEMREQS         EQU     $10000|$2               * CHIP u. clear

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

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

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

                move.l  #40*256,d0              * Speicher
                move.l  #MEMREQS,d1             * für Bitplane
                CALLEXEC AllocMem               * allokieren
                tst.l   d0                      * hat's geklappt?
                beq     Fault2                  * nein!
                move.l  d0,Bitplane             * Zeiger retten
                move.l  d0,Plane

*
* Jetzt wird die Maschine übernommen.
*

                CALLEXEC Forbid                 * kein Multitasking
                move.w  #$3e0,$DFF096           * Copper-, Sprite- und
                                                * andere DMAs 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.l  Bitplane,d2             * Bitplane nach d2
                swap    d2                      * auf oberes Word richten

*
* Hier werden erstmal die Bitplane-Zeiger zurückgesetzt.
*

                move.w  #$0E0,(a0)+             * Register: BPL1PTH
                move.w  d2,(a0)+                * oberes Word des Plane-
                                                * zeigers setzen
                move.w  #$0E2,(a0)+             * Register: BPL1PTL
                swap    d2                      * unteres Word holen
                move.w  d2,(a0)+                * und setzen

*
* Jetzt geht's recht normal weiter ...
*

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

                move.w  #$5001,d0               * Verlauf ab Zeile #80
                lea     Colors,a1               * Hintergrundfarben laden
                lea     Colors2,a2              * Vordergrundfarben 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  #$182,(a0)+             * Vordergrund-Register
                move.w  (a1)+,(a0)+             * und Tabellen-Farbwert 1
                move.w  #$180,(a0)+             * Hintergrund-Register 1
                move.w  (a2)+,(a0)+             * und Tabellen-Farbwert 2
                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.w  #0,$DFF088              * COPJMP1 löschen

                move.w  #$2981,$DFF08E          * DIWSTRT setzen
                move.w  #$29C1,$DFF090          * DIWSTOP setzen
                move.w  #$0038,$DFF092          * DDFSTRT setzen
                move.w  #$00D0,$DFF094          * DDFSTOP setzen
                move.w  #$1000,$DFF100          * 1 Plane - BPLCON0 setzen
                move.w  #0,$DFF102              * kein Scrolling
                move.w  #0,$DFF104              * kein Dual-Playfield
                move.w  #0,$DFF108              * kein Modulo
                move.w  #0,$DFF10A              * soll benutzt werden

                move.w  #$83C0,$DFF096          * alle wichtigen DMAs und
                                                * und DMAEN aktivieren

*
* Nun wird ein RastPort initialisiert ...
*

                lea     RastPort,a1             * RastPort laden
                move.l  GfxBase,a6              * Graphics laden
                jsr     _LVOInitRastPort(a6)    * RastPort initialisieren

                lea     RastPort,a1             * RastPort laden
                lea     BitMap,a0               * BitMap laden
                move.l  a0,4(a1)                * und eintragen

*
* An dieser Stelle wird etwas gezeichnet ...
*

                moveq.w #52,d0                  * x-Koordinate 52
                moveq.w #114,d1                 * y-Koordinate 114
                jsr     _LVOMove(a6)            * Move

                lea     Text,a0                 * Text laden
                lea     RastPort,a1             * RastPort laden
                moveq.w #27,d0                  * 27 Zeichen
                jsr     _LVOText(a6)            * und Text ausgeben

*
* Hier steht die Routine für das Copper-Rolling ...
*

                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   #12,a0                  * Zeiger auf 1. WAIT

                cmp.l   #200,LineCounter        * Zeile 200 erreicht?
                blt.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
                add.l   #12,a0                  * 12 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
                add.l   #12,a0                  * nach 12 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.
*

                move.l  GfxBase,a1              * Graphics laden
                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          * deaktivierte
                                                * DMA-Kanäle wieder
                                                * einschalten

                CALLEXEC Permit                 * Multitasking erlauben

                move.l  Bitplane,a1             * Bitplane im
                move.l  #40*256,d0              * CHIP-Speicher
                CALLEXEC FreeMem                * deallokieren

Fault2:         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

Text:           dc.b     "*** P L A Y F I E L D ! ***",0
 even

GfxBase:        dc.l     0
DosBase:        dc.l     0

CopperList:     dc.l     0                      * Zeiger auf die Copperlist
Bitplane:       dc.l     0                      * Zeiger auf die Plane

RastPort:       ds.b     100                    * Speicher für einen RastPort

BitMap:         dc.w     40                     * 40 Bytes pro Zeile
                dc.w     256                    * 256 Zeilen
                dc.b     0,1,0,0                * 1 Bitplane
Plane:          dc.l     0                      * Zeiger

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

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

Colors:         dc.w     $F00,$F10,$F20,$F30,$F40,$F50,$F60,$F70,$F80
                dc.w     $F90,$FA0,$FB0,$FC0,$FD0,$FE0,$FF0,$FE0,$FD0
                dc.w     $FC0,$FB0,$FA0,$F90,$F80,$F70,$F60,$F50,$F40
                dc.w     $F30,$F20,$F10,$F00

*
* Hier sind noch ein paar coole, blaue Werte für
* die Vordergrundfarbe ...
*

Colors2:        dc.w     $00F,$01F,$02F,$03F,$04F,$05F,$06F,$07F,$08F
                dc.w     $09F,$0AF,$0BF,$0CF,$0DF,$0EF,$0FF,$0EF,$0DF
                dc.w     $0CF,$0BF,$0AF,$09F,$08F,$07F,$06F,$05F,$04F
                dc.w     $03F,$02F,$01F,$00F

                END

