*
* Demo für Blitter-Queue-Strukturen (Löschmodus)
*
* written on 15/11/89  15:02:17  by Holger Gzella
*

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

*
* Libraries und Window öffnen
*
                lea     GfxName,a1
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                move.l  d0,GfxBase

                lea     IntuiName,a1
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                move.l  d0,IntuiBase

                move.l  d0,a6
                lea     WindowDefs,a0
                jsr     _LVOOpenWindow(a6)
                tst.l   d0
                beq     Fault
                move.l  d0,WindowPtr

*
* Hautprogramm - ein Rechteck zeichnen auf darauf warten, daß
* der Benutzer das Schließsymbol anklickt.
*

                move.l  d0,a0                   * WindowPtr nach A1
                move.l  50(a0),RastPort         * und den RastPort holen
                move.l  RastPort,a1
                move.l  4(a1),a2                * BitMap laden
                move.l  8(a2),Bitplane          * Zeiger auf Plane 1
                move.l  8(a2),QPlane

                move.l  GfxBase,a6
                moveq.b #0,d0                   * jam1
                jsr     _LVOSetDrMd(a6)         * Zeichenmodus setzen

*
* Ein Rechteck im Window zeichnen: von (15;20) nach (300;75)
*

                move.l  RastPort,a1
                move.w  #15,d0
                move.w  #20,d1
                move.w  #300,d2
                move.w  #75,d3
                jsr     DrawRectangle

*
* An dieser Stelle wird die Blitter-Routine eingebunden ...
*

                move.l  GfxBase,a6
                lea     Queue,a1                * Queue-Adresse laden
                jsr     _LVOQBlit(a6)           * und Queue einbinden!

*
* Hier wird's interessant ... nun wird gewartet, bis der Benutzer
* das Schließsymbol angeklickt hat. Zweifellos ein gutes Beispiel
* für die IDCMP-Handhabung.
*

MessageLoop:    move.l  WindowPtr,a0            * WindowPtr holen
                move.l  $56(a0),a0              * UserPort holen
                move.l  a0,a5                   * und retten
                move.b  $f(a0),d1               * SigBit holen
                moveq   #0,d0                   * und in
                bset    d1,d0                   * Bitmaske wandeln
                CALLEXEC Wait                   * warten

*
* Dieser Teil wird ausgeführt, wenn eine Message (Nachricht)
* angekommen ist und Wait den Task weiterlaufen läßt. Nun werden
* die wichtigen Parameter (eigentlich nur, um was für eine Nachricht
* es sich handelt) gerettet und entsprechend reagiert.
*

                move.l  a5,a0                   * UserPort holen
                CALLEXEC GetMsg                 * Nachricht holen
                move.l  d0,a1                   * Message nach A1
                move.l  $14(a1),d4              * Art der Message holen
                CALLEXEC ReplyMsg               * und beantworten

                cmpi.l  #$200,d4                * Schließsymbol betätigt?
                beq     End                     * ja!

                bra     MessageLoop             * Schleife

*
* Ende - alles schließen
*

End:            move.l  WindowPtr,a0
                move.l  IntuiBase,a6
                jsr     _LVOCloseWindow(a6)

Fault:          move.l  IntuiBase,a1
                CALLEXEC CloseLibrary

                move.l  GfxBase,a1
                CALLEXEC CloseLibrary

                moveq.l #0,d0
                rts

*
* Dies ist die Routine, um die es geht. Sie zeichnet ein Rechteck
* in die BitMap des angegebenen RastPorts. Sie benötigt diese Parameter:
*
* A6: Zeiger auf die Graphics-Basisadresse (GfxBase)
* A1: Zeiger auf den RastPort
* D0: x-Koordinate der linken, oberen Ecke
* D1: y-Koordinate der linken, oberen Ecke
* D2: x-Koordinate der rechten, unteren Ecke
* D3: y-Koordinate der rechten, unteren Ecke
*

DrawRectangle:  movem.l d0-d7/a0-a6,-(SP)       * alle Register sichern
                move.l  a1,a5                   * RastPort sichern
                subq.w  #2,d0                   * Koordinaten für den
                subq.w  #2,d1                   * Schatten
                movem.w d0-d3,-(SP)             * Register auf den Stack
                moveq.w #2,d0                   * Farbe wechseln
                jsr     _LVOSetAPen(a6)
                movem.w (SP)+,d0-d3             * Register vom Stack
                movem.w d0-d3,-(SP)             * nochmal draufkopieren
                move.l  a5,a1                   * RastPort holen
                jsr     _LVORectFill(a6)        * Schatten zeichnen
                move.l  a5,a1                   * RastPort holen
                moveq.w #1,d0                   * Farbe wechseln
                jsr     _LVOSetAPen(a6)
                movem.w (SP)+,d0-d3             * Register vom Stack
                move.l  a5,a1                   * RastPort holen
                addq.w  #2,d0                   * Koordinaten für das
                addq.w  #2,d1                   * richtige Rechteck
                jsr     _LVORectFill(a6)        * Rechteck zeichnen
                movem.l (SP)+,d0-d7/a0-a6       * alle Register holen
                rts                             * und zurück

*
* Hier steht die Routine, die vom System aufgerufen wird ...
*

*
* Nun wird gelöscht ...
* wir werden den Aescending-Mode benutzen, was sich an
* dieser Stelle empfiehlt. Dazu müssen die BLTxPTH/L-
* Register auf das erste Word des Ausschnittes gerichtet werden.
*
* Es wird der Bereich von (32;192) bis (240;224) (relativ
* zum Screen) gelöscht.
*

*
* Folgende Parameter werden übergeben:
*
* A0 - Zeiger auf die Custom-Basis $DFF000.
* A1 - Zeiger auf die entsprechende Bltnode-Struktur. Diese enthält
*      in unserem Fall ein zusätzliches Feld (Offset 18) mit einem
*      Zeiger auf die entsprechende Plane.
*

Function:       movem.l d1-d7/a0-a6,-(SP)       * Register sichern

                move.l  18(a1),a0               * Plane holen
                add.l   #192*80+4,a0            * ab Zeile 64/Byte 4

                move.l  a0,$DFF054              * BLTDPTH/L (Ziel D) setzen
                move.w  #54,$DFF066             * BLTDMOD: Modulo 54 Bytes
                move.w  #256,$DFF040            * BLTCON0: Minterm $00
                                                * (LF7 bis LF0 gelöscht)
                                                * sowie DMA für Ziel D
                                                * aktivieren
                move.w  #0,$DFF042              * BLTCON1 setzen:
                                                * nichts aktiviert ...
                move.w  #32*64+13,$DFF058       * BLTSIZE setzen und
                                                * Blitter starten:
                                                * Breite: 13 Words
                                                * Höhe: 32 Zeilen

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

DasWars:        moveq   #0,d0                   * Ende!
                rts

*
* Datenteil ...
*

GfxName:        dc.b    "graphics.library",0
 even
IntuiName:      dc.b    "intuition.library",0
 even

even
WindowDefs:     dc.w    0,156,640,100,1
                dc.l    $200,$E,0,0,Titel,0,0,0,0
                dc.w    1

Titel:          dc.b    "Blitter-Queues",0
 even

GfxBase:        dc.l    0
IntuiBase:      dc.l    0
WindowPtr:      dc.l    0
RastPort:       dc.l    0

Bitplane:       dc.l    0

*
* Dies ist die Bltnode-Struktur ...
*

Queue:          dc.l    0                       * keine nächste Struktur
                dc.l    Function                * Blitter-Routine
                dc.b    0,0                     * nicht so wichtig ...
                dc.w    0,0
                dc.l    0

QPlane:         dc.l    0                       * ein zusätzliches Feld:
                                                * die Adresse der zu
                                                * benutzenden Plane

                END

