*
* Ein Demo für schnelles Zeichnen.
*
* created on 26/10/89  10:18:40  by Holger Gzella
*

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

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

                lea     IntuiName,a1            * Intuition öffnen
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                move.l  d0,IntuiBase

                move.l  d0,a6

                lea     ScreenDefs,a0           * Screen öffnen
                jsr     _LVOOpenScreen(a6)
                tst.l   d0
                beq     Fault
                move.l  d0,ScreenPtr

                move.l  d0,a0
                move.l  $c0(a0),Plane

                move.l  ScreenPtr,a0
                lea     84(a0),a0
                move.l  a0,RastPort

*
* Jetzt wird der ganze Bildschirm mit der neuen SetPixel-Routine
* vollgeschrieben und anschließend wieder gelöscht ...
*

                moveq.l #11,d5                  * ab Zeile 11
                move.l  Plane,a0                * Plane laden
                move.l  #80,d2                  * 80 Bytes/Zeile

LineLoop:       moveq.l #0,d4                   * Spaltenzähler löschen

InlineLoop:     move.l  d4,d0                   * x-Koordinate laden
                move.l  d5,d1                   * y-Koordinate laden
                bsr     SetPixel                * Punkt setzen
                addq    #1,d4                   * Spaltenzähler erhöhen
                cmp     #640,d4                 * fertig?
                bne.s   InlineLoop              * nein!

                addq    #1,d5                   * Zeilenzähler erhöhen
                cmp     #256,d5                 * fertig?
                bne.s   LineLoop                * nein!

                move.l  #255,d5                 * ab Zeile 256
                move.l  Plane,a0                * Plane laden
                move.l  #80,d2                  * 80 Bytes/Zeile

LineLoop2:      moveq.l #0,d4                   * Spaltenzähler löschen

InlineLoop2:    move.l  d4,d0                   * x-Koordinate laden
                move.l  d5,d1                   * y-Koordinate laden
                bsr     UnsetPixel              * Punkt setzen
                addq    #1,d4                   * Spaltenzähler erhöhen
                cmp     #640,d4                 * fertig?
                bne.s   InlineLoop2             * nein!

                subq    #1,d5                   * Zeilenzähler erhöhen
                cmp     #10,d5                  * fertig?
                bne.s   LineLoop2               * nein!

*
* Nun wird diese Operation zum Vergleich mit der
* langsameren WritePixel-Routine ausgeführt:
*

                move.l  GfxBase,a6
                moveq.w #1,d0                   * Vordergrundfarbe 1
                move.l  RastPort,a1
                jsr     _LVOSetAPen(a6)

                moveq.l #11,d5                  * ab Zeile 11
                move.l  #80,d2                  * 80 Bytes/Zeile

LineLoop3:      moveq.l #0,d4                   * Spaltenzähler löschen

InlineLoop3:    move.l  d4,d0                   * x-Koordinate laden
                move.l  d5,d1                   * y-Koordinate laden
                move.l  RastPort,a1             * RastPort laden
                jsr     _LVOWritePixel(a6)      * Punkt setzen
                addq    #1,d4                   * Spaltenzähler erhöhen
                cmp     #640,d4                 * fertig?
                bne.s   InlineLoop3             * nein!

                addq    #1,d5                   * Zeilenzähler erhöhen
                cmp     #256,d5                 * fertig?
                bne.s   LineLoop3               * nein!

                moveq.w #0,d0                   * Hintergrundfarbe
                move.l  RastPort,a1
                jsr     _LVOSetAPen(a6)

                move.l  #255,d5                 * ab Zeile 256
                move.l  #80,d2                  * 80 Bytes/Zeile

LineLoop4:      moveq.l #0,d4                   * Spaltenzähler löschen

InlineLoop4:    move.l  d4,d0                   * x-Koordinate laden
                move.l  d5,d1                   * y-Koordinate laden
                move.l  RastPort,a1             * RastPort laden
                jsr     _LVOWritePixel(a6)      * Punkt setzen
                addq    #1,d4                   * Spaltenzähler erhöhen
                cmp     #640,d4                 * fertig?
                bne.s   InlineLoop4             * nein!

                subq    #1,d5                   * Zeilenzähler erhöhen
                cmp     #10,d5                  * fertig?
                bne.s   LineLoop4               * nein!

MouseLoop:      btst.b  #6,$bfe001
                bne.s   MouseLoop

*
* Ende - alles schließen
*

End:            move.l  ScreenPtr,a0
                move.l  IntuiBase,a6
                jsr     _LVOCloseScreen(a6)

Fault:          move.l  IntuiBase,a1
                CALLEXEC CloseLibrary

                move.l  GfxBase,a1
                CALLEXEC CloseLibrary

                moveq.l #0,d0
                rts

*
* Diese beiden Unterroutinen übernehmen das Setzen bzw. Löschen
* eines Punktes in einer Bitplane. Übergeben werden müssen:
*
* D0: x-Koordinate des zu setzenden bzw. zu löschenden Punktes.
* D1: y-Koordinate des zu setzenden bzw. zu löschenden Punktes.
* D2: Breite der gesamten BitMap in Bytes.
* A0: Zeiger auf die entsprechende Bitplane.
*

*
* Setzen eines Punktes:
*

SetPixel:       divu.w  #8,d0                   * x-Koordinate durch
                                                * 8 dividieren =
                                                * Byte des Pixels
                mulu    d2,d1                   * mit der Anzahl Bytes/Zeile
                                                * die Zeile multiplizieren
                add.w   d0,d1                   * = zu addierender Offset
                swap    d0                      * obere Hälfte ausmaskieren
                moveq   #7,d3                   * 8 Bits/Byte
                sub.w   d0,d3                   * unpassende Bits
                                                * ausmaskieren

                bset    d3,(a0,d1.w)            * Pixel (Bit) setzen
                rts                             * und zurück!

*
* Löschen eines Punktes:
*

UnsetPixel:     divu.w  #8,d0                   * x-Koordinate durch
                                                * 8 dividieren =
                                                * Byte des Pixels
                mulu    d2,d1                   * mit der Anzahl Bytes/Zeile
                                                * die Zeile multiplizieren
                add.w   d0,d1                   * = zu addierender Offset
                swap    d0                      * obere Hälfte ausmaskieren
                moveq   #7,d3                   * 8 Bits/Byte
                sub.w   d0,d3                   * unpassende Bits
                                                * ausmaskieren

                bclr    d3,(a0,d1.w)            * Pixel (Bit) löschen
                rts                             * und zurück!

*
* Datenteil
*

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

 even
ScreenDefs:     dc.w    0,0,640,256,2,1,$8000,$F,0,0
                dc.l    0,0,0

GfxBase:        dc.l    0
IntuiBase:      dc.l    0
ScreenPtr:      dc.l    0
RastPort:       dc.l    0
Plane:          dc.l    0

                END

