*
* Ein weiteres Boot-Intro ...
* ebenfalls eine Variation!
*
* written on 3/12/89  15:14:34  by Holger Gzella
*
*                                  Freischöffenweg 12
*                                  4600 Dortmund 16
*

                opt     p+

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

MEMREQS         EQU     $10000|$2               * CHIP sowie clear

                movem.l d0-d7/a0-a6,-(SP)       * Register retten

StartIt:        lea     FontName(pc),a0         * Font anpassen
                lea     TextAttr(pc),a1
                move.l  a0,(a1)

                lea     GfxName(pc),a1          * Graphics öffnen
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                lea     GfxBase(pc),a0
                move.l  d0,(a0)

                move.l  d0,a6
                lea     TextAttr(pc),a0         * Font
                jsr     _LVOOpenFont(a6)        * öffnen
                lea     FontBase(pc),a0
                move.l  d0,(a0)

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

                move.l  #52*345,d0              * Speicher
                move.l  #MEMREQS,d1             * für Bitplane
                CALLEXEC AllocMem               * allokieren
                tst.l   d0                      * hat's geklappt?
                beq     Fault2                  * nein!
                lea     Bitplane(pc),a0
                move.l  d0,(a0)                 * Zeiger retten

*
* 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(pc),a0       * Copperlist nach a0
                move.l  Bitplane(pc),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 weiter ...
*

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

                move.l   #$8001,d0              * #128/$80
                lea      Colors(pc),a1          * Farben laden
                moveq.w  #15,d1                 * 16 Abstufungen

SetEntry:       move.w   d0,(a0)+               * WAIT-Position schreiben
                move.w   #$fffe,(a0)+           * Maske schreiben
                move.w   #$180,(a0)+            * Hintergrund-Register
                move.w   (a1)+,(a0)+            * entsprechende Farbe

                add.w    #$0100,d0              * y-Koordinate erhöhen
                dbra     d1,SetEntry            * bis zum Schluß!

                move.w   #$180,(a0)+            * der Rest soll Schwarz
                move.w   #$000,(a0)+            * dargestellt werden

                move.l   #$9D01,d0              * $9D
                lea      Colors3(pc),a1         * Farben laden
                moveq.w  #15,d1                 * 16 Abstufungen

SetEntry2:      move.w   d0,(a0)+               * WAIT-Position schreiben
                move.w   #$fffe,(a0)+           * Maske schreiben
                move.w   #$182,(a0)+            * Hintergrund-Register
                move.w   (a1)+,(a0)+            * entsprechende Farbe

                add.w    #$0100,d0              * y-Koordinate erhöhen
                dbra     d1,SetEntry2           * bis zum Schluß!

                move.w   #$180,(a0)+            * der Rest soll Schwarz
                move.w   #$000,(a0)+            * dargestellt werden

                move.l   #$BC01,d0              * $BC
                lea      Colors2(pc),a1         * Farben laden
                moveq.w  #15,d1                 * 16 Abstufungen

SetEntry3:      move.w   d0,(a0)+               * WAIT-Position schreiben
                move.w   #$fffe,(a0)+           * Maske schreiben
                move.w   #$180,(a0)+            * Hintergrund-Register
                move.w   (a1)+,(a0)+            * entsprechende Farbe

                add.w    #$0100,d0              * y-Koordinate erhöhen
                dbra     d1,SetEntry3           * bis zum Schluß!

                move.w   #$180,(a0)+            * der Rest soll Schwarz
                move.w   #$000,(a0)+            * dargestellt werden

                move.l   #$fffffffe,(a0)        * und Ende ...

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

                move.w  #$1AC4,$DFF08E          * DIWSTRT setzen
                move.w  #$39D8,$DFF090          * DIWSTOP setzen
                move.w  #$0020,$DFF092          * DDFSTRT setzen
                move.w  #$00D8,$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  #4,$DFF108              * ein Modulo von vier
                move.w  #4,$DFF10A              * soll benutzt werden

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

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

                moveq.l #0,d6                   * Scrollzähler löschen
                lea     Text(pc),a6             * Scrolltext nach a6

CycleLoop:      move.l  CopperList(pc),a0       * Zeiger einladen
                add.l   #150,a0                 * auf das erste MOVE-
                                                * Statement für den
                                                * mittleren Verlauf richten

                lea     Colors3(pc),a1          * Farben laden

                lea     Offset(pc),a4
                cmp.l   #0,(a4)                 * Offset 0?
                bne.s   CompDirect              * nein - weiter

*
* Diese Stelle wird erreicht, wenn die hellblaue Farbe
* den oberen Rand des Scrollstreifens erreicht hat (also
* wurde vorher nach oben gescrollt). Jetzt wird die
* Richtung geändert und nach unten gescrollt.
*

                lea     Direction(pc),a5
                move.l  #1,(a5)                 * Richtung: nach untne

CompDirect:     cmp.l   #0,(a5)                 * nach oben scrollen?
                beq.s   ScrollUp                * freilich!

*
* Dieser Code wird ausgeführt, wenn die Scrollrichtung
* nach unten verläuft - der Offset wird erhöht.
*

                addq.l  #2,(a4)                 * Offset erhöhen
                bra.s   Compare                 * und weiter

*
* Wenn diese Stelle erreicht wird, läuft das Scrolling nach
* oben. Also muß der Offset erniedrigt werden.
*

ScrollUp:       subq.l  #2,(a4)                 * Offset -2

Compare:        cmp.l   #31,(a4)                * Offset 31?
                ble.s   ChangeEntry             * nein!

                move.l  #0,(a5)                 * Richtung ändern

*
* Diese Stelle wird praktisch immer ausgeführt.
*

ChangeEntry:    add.l   (a4),a1                 * Offset zur Farbtabelle
                                                * addieren
                moveq   #15,d0                  * 16 Abstufungen

ChangeColor:    move.w  (a1)+,(a0)              * entsprechende Farbe laden
                addq.l  #8,a0                   * Zeiger auf die nächste
                                                * MOVE-Instruktion richten
                dbra    d0,ChangeColor          * bis wir fertig sind!

Finished:       movem.l d0/a0/a4/a5,-(SP)

ScrollIt:       and.l   #$7,d6                  * sind alle 8 Pixel dieses
                                                * Buchstabens dargestellt?
                bne.s   ScrollOn                * nein ... weiterscrollen

*
* Dieser Abschnitt setzt den Font-Daten-Zeiger
* auf die letzte Zeile des Fonts.
*

                move.l  FontBase(pc),a0         * Font-Basis holen
                move.l  34(a0),a3               * Zeiger auf Font-Daten
                move.w  38(a0),d4               * Modulo des Fonts
                move.w  d4,d5
                mulu    #7,d4                   * mal die Höhe des Fonts
                add.l   d4,a3                   * Zeiger auf die letzte Zeile
                                                * der Font-Daten richten

*
* Hier wird der nächste, "hereinzuscrollende"
* Buchstabe aus dem Textstring geholt.
*

                moveq.l #0,d1

                move.b  (a6)+,d1                * nächsten Buchstaben laden
                bne.s   NotTheLast              * sollte dieser kein Nullbyte
                                                * sein, wird gescrollt, an-
                                                * sonsten der erste Buchstabe
                                                * geladen!

                lea     Text(pc),a6             * Textadresse laden
                move.b  (a6)+,d1                * Buchstaben holen

NotTheLast:     cmp.b   #127,d1                 * Sonderzeichen???
                bls.s   NoSpecialChar           * nein, alles bestens!

*
* Falls im Text ein Sonderzeichen (z.B. ein Umlaut)
* vorkommt, muß dessen ASCII-Code um 32 herunter-
* gerechnet werden, da die Zeichen mit den Codes
* 128 bis 159 ($80 bis $9f) im "topaz"-Datenblock
* nicht definiert sind. Da Sonderzeichen ASCII-Codes
* von größer als 128 haben, müssen die nicht defi-
* nierten Zeichen übersprungen werden.
*

                sub.b   #32,d1                  * $80-$9f überspringen

*
* Auch die ASCII-Codes $00-$1f (0-31) sind nicht
* im "topaz.font"-Datenblock definiert (aus be-
* greiflichen Gründen - sie sind nicht darstellbar!).
* Somit hat JEDES darstellbare Zeichen einen ASCII-Code
* von 32 oder darüber und muß um 32 Codes herunter-
* gerechnet werden.
*

NoSpecialChar:  sub.b   #32,d1                  * $00-$1f überspringen

                add.l   d1,a3                   * Zeiger korrekt setzen

ScrollOn:       move.l  Bitplane(pc),a0         * Bitplane-Zeiger laden

                add.l   #143*52,a0              * Position (Zeile 128) setzen
                move.l  #7,d1                   * 8 Zeilen scrollen

                move.l  a3,a5                   * Zeiger retten

*
* Für ein fließendes Scrolling ist es wichtig, zu warten, bis
* der Elektronenstrahl die richtige Position erreicht hat.
*

BeamSyncLoop:   move.l  $DFF004,d3              * Rasterstrahl-Position
                and.l   #$1ff00,d3              * nur vertikale Position
                cmp.l   #$08000,d3              * richtige Zeile (#128)?
                bne.s   BeamSyncLoop            * nein!

*
* Hier beginnt das eigentliche Scrolling.
*

                add.b   #$8,d6                  * Scrollzähler auf Word-
                                                * größe bringen

ScrollPlane:    moveq.l #25,d3                  * 26 Words auf einen Schlag
                moveq   #0,d2                   * welches Bit?
                move.b  (a5),d2                 * entsprechende Daten holen
                sub.l   d5,a5                   * Zeiger zurücksetzen

                roxl.w  #1,d2                   * und Daten des aktuellen
                roxl.w  d6,d2                   * Zeichens ermitteln

ScrollWord:     roxl.w  -(a0)                   * Word nach links schieben
                                                * (probieren Sie mal
                                                * ROXR.W (A0)+!)

                dbra    d3,ScrollWord           * bis alle 8 Zeilen ver-
                                                * schoben sind!

                dbra    d1,ScrollPlane          * bis die gesamte Plane,
                                                * bzw. deren Inhalt, ver-
                                                * schoben ist!

                addq    #1,d6                   * nächstes Zeichen

                movem.l (SP)+,d0/a0/a4/a5

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

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

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

                CALLEXEC CloseLibrary           * Graphics schließen

                move.l  #0,$DFF088              * COPJMP1 löschen
                move.w  #$83E0,$DFF096          * deaktivierte
                                                * DMA-Kanäle wieder
                                                * einschalten

                CALLEXEC Permit                 * Multitasking erlauben

                move.l  Bitplane(pc),a1         * Bitplane im
                move.l  #52*345,d0              * CHIP-Speicher
                CALLEXEC FreeMem                * deallokieren

Fault2:         move.l  CopperList(pc),a1       * Copperlist im
                move.l  #2000,d0                * CHIP-RAM wieder
                CALLEXEC FreeMem                * deallokieren

                movem.l (SP)+,d0-d7/a0-a6       * Register holen

Fault:          lea     ResName(pc),a1          * DOS holen
                CALLEXEC FindResident
                tst.l   d0
                beq.s   Error
                move.l  d0,a0
                move.l  22(a0),a0

                moveq   #0,d0                   * alles klar!
                rts

Error:          move.l  #$ff,d0                 * ein Fehler???!!!
                rts

*
* Auch hier wieder ein Datenteil ...
*

GfxName:        dc.b    "graphics.library",0
 even
FontName:       dc.b    "topaz.font",0
 even
ResName:        dc.b    "dos.library",0

Text:           dc.b    "Hier haben wir Boot-Intro Nr."
                dc.b    " 3 - diesmal mit Cycling!    "
                dc.b    "                           ",0
 even

GfxBase:        dc.l    0
FontBase:       dc.l    0

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

TextAttr:       dc.l    0
                dc.w    8
                dc.b    0,1

Offset:         dc.l    0                      * Offset innerhalb der
                                               * Farbtabelle
Direction:      dc.l    1                      * Scrollrichtung: 1=unten
                                               *                 0=oben

*
* Die folgenden DC.Ws beinhalten die Farben
* für den Copper-Cycle-Balken Nr. 1!
*

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

*
* Da ein zweiter Farbbalken benutzt werden soll,
* müssen wir auch für ihn Farben definieren!
*

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

*
* Auch die Vordergrundfarbe wollen wir nicht vergessen ...
*

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

                END

