                  ; ------------------------------------------------------
                  ; HardwareKurs Teil 4 (Anwendung)
                  ; written 1989 by Sven Stillich using KICKass
                  ; ------------------------------------------------------
                  ;
allocmem          = -198
freemem           = -210
openlibrary       = -408
cia_a_pra         = $BFE001
dmacon            = $0096
diwstrt           = $008E
diwstop           = $0090
ddfstrt           = $0092
ddfstop           = $0094
bplcon0           = $0100
bplcon1           = $0102
bplcon2           = $0104
bpl1pth           = $00E0
bpl1ptl           = $00E2
spr0pth           = $0120
spr0ptl           = $0122
spr1pth           = $0124
spr1ptl           = $0126
color00           = $0180
color17           = $01A2
color18           = $01A4
color19           = $01A6
color20           = $01A8
color21           = $01AA
color22           = $01AC
color23           = $01AE
execbase          = $04
                  ;
                  ; ------------------------------------------------------
                  ; Speicher belegen
                  ; ------------------------------------------------------
                  ;
                  MOVE.L   execbase.s,a6
                  MOVE.L   #[128*191]+12000,d0    ; bytesize
                  MOVE.L   #$10002,d1             ; requirement: CHIP_CLR
                  JSR      allocmem(a6)           ; Speicher belegen
                  TST.L    d0
                  BEQ      error
                  MOVE.L   d0,coppermem
                  MOVE.L   d0,d1
                  ;
                  ; ------------------------------------------------------
                  ; Vorbereitungen (BPLstart eintragen/Sprites in CHIP/
                  ; CopperlistSTART kopieren...)
                  ; ------------------------------------------------------
                  ;
                  ADD.L    #[128*191]+92+136,d1   ; BPLstart in CList
                  MOVE.W   d1,planes+6            ; eintragen
                  SWAP     d1
                  MOVE.W   d1,planes+2
                  ;
                  MOVE.L   d0,a0
                  ADD.L    #[128*191]+92,a0       ; Copperlist überspringen
                  MOVE.L   a0,d1
                  LEA      data1_2(pc),a1
                  MOVEQ    #33,d0                 ; 15Zeilen+2Conlongw. *2-1
spr_copy:         MOVE.L   (a1)+,(a0)+
                  DBRA     d0,spr_copy
                  MOVE.L   d1,sprite0_con
                  MOVE.W   d1,sprite+6
                  SWAP     d1
                  MOVE.W   d1,sprite+2
                  SWAP     d1
                  ADD.L    #[17*4],d1
                  MOVE.L   d1,sprite1_con
                  MOVE.W   d1,sprite+14
                  SWAP     d1
                  MOVE.W   d1,sprite+10

                  MOVE.L   coppermem(pc),a0
                  LEA      copperbegin(pc),a1
                  MOVEQ    #19,d1
copy:             MOVE.L   (a1)+,(a0)+
                  DBRA     d1,copy
                  ;
                  ; ------------------------------------------------------
                  ; Copperlist berechnen
                  ; ------------------------------------------------------
                  ;
                  MOVE.L   #$01800000,(a0)+       ; schwarz setzen
                  MOVE.L   #190,d2                ; Zeilenzähler
                  MOVE.L   #$3D2F,d4              ; STARTzeile
                  MOVE.L   #$0F00,d5              ; Farbwert ORG

horizpos:         MOVE.L   d4,d0                  ; Zeilenanzahl+1
                  ADD.L    #$0100,d0
                  MOVE.L   d0,d4                  ; Zeilenanzahl zurück
                  MOVE.B   #00,countflag

                  ADDQ.W   #$0001,d5              ; Farbstart +$0001
                  MOVE.L   d5,d3
                  MOVEQ    #15,d1                 ; 16 Spalten ($f-$0)

vertikpos:        MOVE.W   d0,(a0)+               ; BW1 schreiben
                  MOVE.W   #$FFFE,(a0)+           ; BW2 schreiben (BFD=0)
                  MOVE.W   #color00,(a0)+         ; ($dff)0180
                  MOVE.W   d3,(a0)+               ; farbwert
                  ADDQ.W   #$0004,d0              ; 8 Pixel weiter (vert.)

                  TST.B    countflag              ; hoch oder runter zählen?
                  BNE.S    overflow

                  ADD.W    #$0010,d3              ; Farbe hoch
                  MOVE.W   d3,d6
                  AND.W    #$1000,d6
                  BEQ.S    no_overflow
                  MOVE.B   #01,countflag
                  SUB.W    #$0100,d3              ; farbe runter
overflow:         SUB.W    #$0010,d3

no_overflow:      DBRA     d1,vertikpos           ; D1 END.
                  DBRA     d2,horizpos            ; D2 END.
                  MOVE.L   #$01800000,(a0)+       ; schwarz setzen
                  MOVE.L   #$FFFFFFFE,(a0)+       ; copperlist end
                  ;
                  ; ------------------------------------------------------
                  ; CopperLIST|IRQ starten und auf Abbruch warten
                  ; ------------------------------------------------------
                  ;
                  LEA      gfxname(pc),a1
                  JSR      openlibrary(a6)        ; gfx.lib öffnen
                  MOVE.L   d0,gfxbase
                  MOVE.L   d0,a0
                  MOVE.L   50(a0),system          ; system-copperlist
                  MOVE.L   coppermem(pc),50(a0)   ; copperlist starten
                  CLR.B    countflag
                  MOVE.L   $6C.s,oldirq
                  MOVE.L   #irq,$6C.s

wait:             BTST     #06,cia_a_pra          ; maustaste abfragen
                  BNE.S    wait

                  ;
                  ; ------------------------------------------------------
                  ; alte Copperlist|IRQ installieren
                  ; Speicher wieder freigeben
                  ; ------------------------------------------------------
                  ;
                  MOVE.L   system(pc),50(a0)
                  MOVE.L   oldirq(pc),$6C.s
                  ;
                  MOVE.L   coppermem(pc),a1       ; speicher freigeben
                  MOVE.L   #[128*191]+12000,d0
                  JSR      freemem(a6)
error:            RTS                             ; PROGRAMM ENDE
                  ;
                  ;
                  ; ------------------------------------------------------
                  ; ------------------------------------------------------
                  ; Interrupt (muß nicht im CHIPram liegen)
                  ; ------------------------------------------------------
                  ;
irq:              MOVEM.L d0-d7/a0-a6,-(sp)
                  ;
                  TST.B   countflag
                  BNE.S   left
                  ADD.L   #$00010000,sprite0_val
                  ADD.L   #$00010000,sprite1_val
                  CMP.L   #$8ECE9D00,sprite0_val        ; rechte BPLpos ?
                  BNE.S   do_it                         ; nein => weiter
                  MOVE.B  #01,countflag
                  BRA.S   do_it
left:             CMP.B   #01,countflag
                  BNE.S   out
                  SUB.L   #$00020000,sprite0_val
                  SUB.L   #$00020000,sprite1_val
                  CMP.L   #$8E4A9D00,sprite0_val        ; rechte BPLpos ?
                  BNE.S   do_it                            ; nein => weiter
                  MOVE.B  #00,countflag

do_it:            MOVE.L  sprite0_con(pc),a0            ; Kontrolregister
                  MOVE.L  sprite1_con(pc),a1
                  MOVE.L  sprite0_val(pc),(a0)          ; Werte
                  MOVE.L  sprite1_val(pc),(a1)
                  ;
out:              MOVEM.L (sp)+,d0-d7/a0-a6
                  DC.W    $4EF9
oldirq:           DC.L    0
                  ;
                  ; ------------------------------------------------------
                  ; Strukturen, Storages, Konstanten, ...
                  ; ------------------------------------------------------
                  ;
gfxname:          DC.B  'graphics.library',0
gfxbase:          DC.L  0
coppermem:        DC.L  0
system:           DC.L  0
sprite0_con:      DC.L  0
sprite1_con:      DC.L  0
sprite0_val:      DC.L  $8E2A9D00
sprite1_val:      DC.L  $8E2A9D80
countflag:        DC.B  0
                  EVEN
 data1_2:         DC.W  $305A,$3F00                         ; Kontrollwort
                  DC.W  %0000011111000000,%0000000000000000 ; Planes 1,2
                  DC.W  %0001111111110000,%0000000000000000
                  DC.W  %0011111000000000,%0000000111111000
                  DC.W  %0111100000000000,%0000011111111100
                  DC.W  %0111000001111100,%0000111111111100
                  DC.W  %1110001111111110,%0001111111111110
                  DC.W  %1100011111111110,%0011111111111110
                  DC.W  %1100111110000010,%0011111110000000
                  DC.W  %1100111100011110,%0011111100000000
                  DC.W  %1001111001110000,%0111111000001110
                  DC.W  %0001110011000000,%0111110000111100
                  DC.W  %0011100110001100,%0111100001111100
                  DC.W  %0011101100111000,%0011100011111000
                  DC.W  %0000011001110000,%0000000111110000
                  DC.W  %0000010011000000,%0000001111000000
                  DC.W  0,0                                 ; Ende
                  ;
data3_4:          DC.W  $305A,$3F80                         ; Kontrollwort
                  DC.W  %0000000000000000,%0000000000000000 ; Planes 3,4
                  DC.W  %0000000000000000,%0000000000000000
                  DC.W  %0000000000000000,%0000000000000000
                  DC.W  %0000000000000000,%0000000000000000
                  DC.W  %0000000000000000,%0000000000000000
                  DC.W  %0000000000000000,%0000000000000000
                  DC.W  %0000000000000000,%0000000000000000
                  DC.W  %0000000001111110,%0000000000000000
                  DC.W  %0000000011111110,%0000000000000000
                  DC.W  %0000000111111110,%0000000000000000
                  DC.W  %0000001111111100,%0000000000000000
                  DC.W  %0000011111111100,%0000000000000000
                  DC.W  %0000011111111000,%0000000000000000
                  DC.W  %0001111111110000,%0000000000000000
                  DC.W  %0000011111000000,%0000000000000000
                  DC.W  0,0                                 ; Ende
                  ;
copperbegin:      DC.W  diwstrt,$2981,diwstop,$29C1     ; statischer Anfang
                  DC.W  ddfstrt,$0038,ddfstop,$00D0     ; der CList (wird
                  DC.W  bplcon1,$0000                   ; ins CHIPmem
                  DC.W  bplcon0,%0001001000000000       ; kopiert)
                  DC.W  bplcon2,%0000000000000100
planes:           DC.W  bpl1pth,$0000,bpl1ptl,$0000
sprite:           DC.W  spr0pth,$0000,spr0ptl,$0000
                  DC.W  spr1pth,$0000,spr1ptl,$0000
                  DC.W  color17,$0339,color18,$044A
                  DC.W  color19,$055B,color20,$066C
                  DC.W  color21,$077D,color22,$089E
                  DC.W  color23,$0AAF

