home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
assembler-kurs
/
listings3
/
listing7v2.s
< prev
next >
Wrap
Text File
|
1977-12-31
|
16KB
|
562 lines
; Listing7v2.s - Sprite im Dual-Playfield-Mode
; In diesem Listing ewzeigen wir die verschiedenen Prioritätslevel der
; Sprites gegenüber den zwei Playfields. Die Sprites bewegen sich von Oben nach
; Unten. Jedesmal, wenn sie unten angekommen sind, beginnen sie wieder
; von oben, nur mit einer anderen Priorität.
; Das Ende des Programmes muß abgewartet werden.
SECTION CipundCop,CODE
Anfang:
move.l 4.w,a6 ; Execbase
jsr -$78(a6) ; Disable
lea GfxName(PC),a1 ; Name lib
jsr -$198(a6) ; OpenLibrary
move.l d0,GfxBase
move.l d0,a6
move.l $26(a6),OldCop ; speichern die alte COP
; Pointen auf die übliche Art unsere Pic´s an
MOVE.L #PIC1,d0
LEA BPLPOINTERS1,A1
MOVEQ #3-1,D1
POINTBP:
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
swap d0
ADD.L #40*256,d0
addq.w #8,a1
dbra d1,POINTBP
MOVE.L #PIC2,d0
LEA BPLPOINTERS2,A1
MOVEQ #3-1,D1
POINTBP2:
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
swap d0
ADD.L #40*256,d0
addq.w #8,a1
dbra d1,POINTBP2
; Pointen auf die Sprites
MOVE.L #MEINSprite0,d0 ; Adresse des Sprite in d0
LEA SpritePointers,a1 ; Pointer in der Copperlist
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite1,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite2,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite3,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite4,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite5,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite6,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
MOVE.L #MEINSprite7,d0 ; Adresse des Sprite in d0
addq.w #8,a1 ; nächsten SpritePOINTERS
move.w d0,6(a1)
swap d0
move.w d0,2(a1)
move.l #COPPERLIST,$dff080 ; unsere COP
move.w d0,$dff088 ; START COP
move.w #0,$dff1fc ; NO AGA!
move.w #$c00,$dff106 ; NO AGA!
lea PriList(PC),a0 ; a0 pointet auf die Liste mit Prioritätsleveln
move.w #$0000,$dff104 ; BPLCON2
; mit diesem Wert sind alle Sprites unter
; beiden Playfields
Warte1:
cmpi.b #$ff,$dff006 ; Zeile 255?
bne.s Warte1
bsr.s BewegeSprites ; Bewegt die Sprites nach unten
Warte2:
cmpi.b #$ff,$dff006 ; Zeile 255?
beq.s Warte2
cmp.w #250,Hoehe ; Haben die Sprites den unteren Rand erreicht?
blo.s Warte1 ; nein, dann bewege sie weiter
move.w #$2c,Hoehe ; Ja. Setz sie wieder ganz nach oben
cmp.l #EndPriList,a0 ; Haben wir die Prioritlevel alle durchgemacht?
beq.s Raus ; wenn ja, dann steig aus.
move.w (a0)+,$dff104 ; Wenn nicht, gib den nächsten Wert in BPLCON2
bra.s Warte1
Raus:
move.l OldCop(PC),$dff080 ; Pointen auf die SystemCOP
move.w d0,$dff088 ; Starten die alte COP
move.l 4.w,a6
jsr -$7e(a6) ; Enable
move.l gfxbase(PC),a1
jsr -$19e(a6) ; Closelibrary
rts
; Daten
GfxName:
dc.b "graphics.library",0,0
GfxBase:
dc.l 0
OldCop:
dc.l 0
; Diese Routine bewegt die 8 Sprites um einen Pixel pro Durchgang nach unten.
; Alle Sprites haben die selbe Höhe.
BewegeSprites:
; bewegt den Sprite 0
addq.w #1,Hoehe
move.w Hoehe(PC),d0
CLR.B VHBITS0 ; Lösche die Bits 8 der horizontalen Position
MOVE.b d0,VSTART0 ; Kopiere die Bit von 0 bis 7 in VSTART
BTST.l #8,D0 ; ist die Position größer als 255?
BEQ.S NOBIGVSTART ; wenn nicht, dann geh weitde, denn das Bit wurde
; bereits mit CLR.b VHBITS gelöscht
BSET.b #2,VHBITS0 ; ansonsten setze Bit 8 der vertikalen Startposition
; auf 1
NOBIGVSTART:
ADDQ.W #8,D0 ; Zähle die Länge des Sprite dazu, um die
; Endposition zu ermitteln (VSTOP)
move.b d0,VSTOP0 ; Gib die Bit von 0 bis 7 in VSTOP
BTST.l #8,D0 ; ist die Position größer als 255 ?
BEQ.S NOBIGVSTOP ; wenn nicht, dann geh weiter, denn das Bit wurde
; bereits mit CLR.b VHBITS gelöscht
BSET.b #1,VHBITS0 ; ansonsten setze Bit 8 der vertikalen Startposition
; auf 1
NOBIGVSTOP:
; kopiere die Höhe in die anderen Sprites
move.b vstart0,vstart1 ; kopiert VSTART
move.w vstop0,vstop1 ; kopiert VSTOP und VHBITS
move.b vstart0,vstart2 ; kopiert VSTART
move.w vstop0,vstop2 ; kopiert VSTOP und VHBITS
move.b vstart0,vstart3 ; kopiert VSTART
move.w vstop0,vstop3 ; kopiert VSTOP und VHBITS
move.b vstart0,vstart4 ; kopiert VSTART
move.w vstop0,vstop4 ; kopiert VSTOP und VHBITS
move.b vstart0,vstart5 ; kopiert VSTART
move.w vstop0,vstop5 ; kopiert VSTOP und VHBITS
move.b vstart0,vstart6 ; kopiert VSTART
move.w vstop0,vstop6 ; kopiert VSTOP und VHBITS
move.b vstart0,vstart7 ; kopiert VSTART
move.w vstop0,vstop7 ; kopiert VSTOP und VHBITS
EndeBewegeSprites:
rts
Hoehe:
dc.w $2c
; Das ist die Liste mit dne Prioritätswerten. Ihr könnt sie variieren, wie
; ihr wollt. Nach dem letzten Wert muß aber das Label EndPriList stehen.
; Diese Werte werden in BPLCON2 geschrieben. Bemerkt den Unterschied zu
; Listing7v1.s, hier wird ein Screen im Dual-Playfield verwendet, somit können
; wir für jedes Playfield eigene Prioritätslevel vergeben.
; Ich erinnere euch daran, daß zwischen den Sprites die Prioritäten fix
; verteilt sind, und zwar so: der Sprite 0 hat die höchste Priorität, der
; Sprite 7 die kleinste.
PriList:
dc.w $0008 ; %001000 - mit disem Wert sind die Prioritäten:
; Playfield 1 (über allem)
; Sprite 0 und 1
; Playfield 2
; Sprite 2,3,4,5,6,7 (unter allem)
dc.w $0010 ; %010000 - mit diesem Wert sind die Prioritäten:
; Playfield 1 (über allem)
; Sprite 0,1,2,3
; Playfield 2
; Sprite 4,5,6,7 (unter allem)
dc.w $0018 ; %011000 - mit diesem Wert sind die Prioritäten:
; Playfield 1 (über allem)
; Sprite 0,1,2,3,4,5
; Playfield 2
; Sprite 6,7 (unter allem)
dc.w $0020 ; %100000 - mit diesem Wert sind die Prioritäten:
; Playfield 1 (über allem)
; Sprite 0,1,2,3,4,5,6,7
; Playfield 2
dc.w $0021 ; %100001 - mit diesem Wert sind die Prioritäten:
; Sprite 0 und 1 (über allem)
; Playfield 1
; Sprite 2,3,4,5,6,7
; Playfield 2 (unter allem)
dc.w $0022 ; %100010 - mit diesem Wert sind die Prioritäten:
; Sprite 0,1,2,3 (über allem)
; Playfield 1
; Sprite 4,5,6,7
; Playfield 2 (unter allem)
dc.w $0023 ; %100011 - mit diesem Wert sind die Prioritäten:
; Sprite 0,1,2,3,4,5 (über allem)
; Playfield 1
; Sprite 6,7
; Playfield 2 (unter allem)
dc.w $0024 ; %100100 - mit diesem Wert sind die Prioritäten:
; Sprite 0,1,2,3,4,5,6,7 (über allem)
; Playfield 1
; Playfield 2 (unter allem)
EndPriList:
SECTION GRAPHIC,DATA_C
COPPERLIST:
SpritePointers:
dc.w $120,0,$122,0,$124,0,$126,0,$128,0 ; Sprite
dc.w $12a,0,$12c,0,$12e,0,$130,0,$132,0
dc.w $134,0,$136,0,$138,0,$13a,0,$13c,0
dc.w $13e,0
dc.w $8E,$2c81 ; DiwStrt
dc.w $90,$2cc1 ; DiwStop
dc.w $92,$38 ; DdfStart
dc.w $94,$d0 ; DdfStop
; wir haben das BPLCON2 aus der Copperlist entfernt, da wie es
; "manuell" mit dem Prozessor manipulieren.
dc.w $102,0 ; BplCon1
dc.w $108,0 ; Bpl1Mod
dc.w $10a,0 ; Bpl2Mod
; 5432109876543210
dc.w $100,%0110011000000000 ; Bit 10 an = Dual Playfield
; verwende 6 Planes = 8 Farben pro
; Playfield
BPLPOINTERS1:
dc.w $e0,0,$e2,0 ;erstes Bitplane Playfield 1 (BPLPT1)
dc.w $e8,0,$ea,0 ;zweites Bitplane Playfield 1 (BPLPT3)
dc.w $f0,0,$f2,0 ;drittes Bitplane Playfield 1 (BPLPT5)
BPLPOINTERS2:
dc.w $e4,0,$e6,0 ;erstes Bitplane Playfield 2 (BPLPT2)
dc.w $ec,0,$ee,0 ;zweites Bitplane Playfield 2 (BPLPT4)
dc.w $f4,0,$f6,0 ;drittes Bitplane Playfield 2 (BPLPT6)
dc.w $180,$110 ; Palette Playfield 1
dc.w $182,$005 ; Farben von 0 bis 7
dc.w $184,$a40
dc.w $186,$f80
dc.w $188,$f00
dc.w $18a,$0f0
dc.w $18c,$00f
dc.w $18e,$080
; Palette Playfield 2
dc.w $192,$367 ; Farben von 9 bis 15
dc.w $194,$0cc ; COLOR8 ist durchsichtig, er wird nicht gesetzt
dc.w $196,$a0a
dc.w $198,$242
dc.w $19a,$282
dc.w $19c,$861
dc.w $19e,$ff0
dc.w $1A2,$F00 ; Palette der Sprites
dc.w $1A4,$0F0
dc.w $1A6,$FF0
dc.w $1AA,$FFF
dc.w $1AC,$0BD
dc.w $1AE,$D50
dc.w $1B2,$00F
dc.w $1B4,$F0F
dc.w $1B6,$BBB
dc.w $1BA,$8E0
dc.w $1BC,$a70
dc.w $1BE,$d00
dc.w $FFFF,$FFFE ; Ende der Copperlist
; Die zwei Playfields
PIC1: incbin "dual1.raw"
PIC2: incbin "dual2.raw"
; ************ Hier die Sprite: KLARERWEISE in CHIP RAM! ************
; Referenztabelle zur Definition der Farben:
; für die Sprite 0 und 1
; BINÄR 00=COLOR 0 (TRANSPARENT)
; BINÄR 10=COLOR 1 (ROT)
; BINÄR 01=COLOR 2 (GRÜN)
; BINÄR 11=COLOR 3 (GELB)
MEINSprite0: ; Länge: 13 Zeilen
VSTART0:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART0:
dc.b $60 ; Horizontale Pos. (von $40 bis $d8)
VSTOP0:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
VHBITS0:
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111001110001111
dc.w %0011111111111100,%1100010001000011
dc.w %0111111111111110,%1000010001000001
dc.w %0111111111111110,%1000010001000001
dc.w %0011111111111100,%1100010001000011
dc.w %0000111111110000,%1111001110001111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
MEINSprite1: ; Länge: 13 Zeilen
VSTART1:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART1:
dc.b $60+14 ; Horizontale Pos. (von $40 bis $d8)
VSTOP1:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111000010001111
dc.w %0011111111111100,%1100000110000011
dc.w %0111111111111110,%1000000010000001
dc.w %0111111111111110,%1000000010000001
dc.w %0011111111111100,%1100000010000011
dc.w %0000111111110000,%1111000111001111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
; für die Sprite 2 und 3
; BINÄR 00=COLOR 0 (TRANSPARENT)
; BINÄR 10=COLOR 1 (WEIß)
; BINÄR 01=COLOR 2 (WASSER)
; BINÄR 11=COLOR 3 (ORANGE)
MEINSprite2: ; Länge: 13 Zeilen
VSTART2:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART2:
dc.b $60+(14*2) ; Horizontale Pos. (von $40 bis $d8)
VSTOP2:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111000111001111
dc.w %0011111111111100,%1100001000100011
dc.w %0111111111111110,%1000000000100001
dc.w %0111111111111110,%1000000111000001
dc.w %0011111111111100,%1100001000000011
dc.w %0000111111110000,%1111001111101111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
MEINSprite3: ; Länge: 13 Zeilen
VSTART3:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART3:
dc.b $60+(14*3) ; Horizontale Pos. (von $40 bis $d8)
VSTOP3:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111001111101111
dc.w %0011111111111100,%1100000000100011
dc.w %0111111111111110,%1000000111100001
dc.w %0111111111111110,%1000000000100001
dc.w %0011111111111100,%1100000000100011
dc.w %0000111111110000,%1111001111101111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
; für die Sprite 4 und 5
; BINÄR 00=COLOR 0 (TRANSPARENT)
; BINÄR 10=COLOR 1 (BLAU)
; BINÄR 01=COLOR 2 (VIOLETT)
; BINÄR 11=COLOR 3 (GRAU)
MEINSprite4: ; Länge: 13 Zeilen
VSTART4:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART4:
dc.b $60+(14*4) ; Horizontale Pos. (von $40 bis $d8)
VSTOP4:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111001001001111
dc.w %0011111111111100,%1100001001000011
dc.w %0111111111111110,%1000001111000001
dc.w %0111111111111110,%1000000001000001
dc.w %0011111111111100,%1100000001000011
dc.w %0000111111110000,%1111000001001111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
MEINSprite5: ; Länge: 13 Zeilen
VSTART5:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART5:
dc.b $60+(14*5) ; Horizontale Pos. (von $40 bis $d8)
VSTOP5:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111001111001111
dc.w %0011111111111100,%1100001000000011
dc.w %0111111111111110,%1000001111000001
dc.w %0111111111111110,%1000000001000001
dc.w %0011111111111100,%1100000001000011
dc.w %0000111111110000,%1111001111001111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
; für die Sprite 6 und 7
; BINÄR 00=COLOR 0 (TRANSPARENT)
; BINÄR 10=COLOR 1 (HELLGRÜN)
; BINÄR 01=COLOR 2 (BRAUN)
; BINÄR 11=COLOR 3 (DUNKELROT)
MEINSprite6: ; Länge: 13 Zeilen
VSTART6:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART6:
dc.b $60+(14*6) ; Horizontale Pos. (von $40 bis $d8)
VSTOP6:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111001111001111
dc.w %0011111111111100,%1100001000000011
dc.w %0111111111111110,%1000001111000001
dc.w %0111111111111110,%1000001001000001
dc.w %0011111111111100,%1100001001000011
dc.w %0000111111110000,%1111001111001111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
MEINSprite7: ; Länge: 13 Zeilen
VSTART7:
dc.b $60 ; Vertikale Pos. (von $2c bis $f2)
HSTART7:
dc.b $60+(14*7) ; Horizontale Pos. (von $40 bis $d8)
VSTOP7:
dc.b $68 ; $60+13=$6d ; Ende Vertikal
dc.b $00
dc.w %0000001111000000,%0111110000111110
dc.w %0000111111110000,%1111001111001111
dc.w %0011111111111100,%1100000001000011
dc.w %0111111111111110,%1000000001000001
dc.w %0111111111111110,%1000000001000001
dc.w %0011111111111100,%1100000001000011
dc.w %0000111111110000,%1111000001001111
dc.w %0000001111000000,%0111110000111110
dc.w 0,0 ; Ende des Sprite
end
Dieses Beispiel zeigt, wie die Prioritäten der Sprites gegenüber einem
Bildschirm in Dual-Playfield-Mode funktioniert. Für jedes Playfield kenn
ein anderer Prioritätslevel gesetzt werden. Für dieses Beispiel haben wir
eine Liste mit Werten verwendet. Eine Liste ist praktisch eine Reihe von
Werten, wie eine TABELLE. Mit einem Adressregister (in diesem Fall a0)
pointen wir auf den ersten Wert, und zwar mit der Anweisung:
lea PriList(PC),a0
Jedesmal wenn ein Wert gelesen wird, bewegen wir das Register a0 auf den
darauf folgenden Wert, mittels indirekter Adressierung mit Postinkrement:
move.w (a0)+,$dff104 ; Geben den Wert in BPLCON2
Wenn wir den letzten Wert erreicht haben, wird a0 dazugebracht, auf die
Adresse im Speicher zu pointen, die dem letzten Wert folgt. Das ist die
Adresse des Label EndPriList. Wenn a0 gleich EndPriList wird, dann haben
wir das Ende der Liste erreicht, und wir steigen vom Program aus.
Ihr könnt die Werte in der Liste austauschen, und so ein bißchen
herumexperimentieren. Versucht z.B. $0011, ihr werdet die Sprite 0 und 1
über allen beiden Playfields sehen, die Sprites 2 und 3 über Playfield 2
und unter dem ersten, während der Rest der Sprites unter beiden Playfields
sein wird.
BEMERKUNG: In diesem Beispiel verändern wir die Priorität, indem wir
direkt ins Register $dff104 (BPLCON2) schreiben. Das ist möglich, weil wir
die Zeile für dessen Definition aus der Copperlist entfernt haben, also
die Zeile:
dc.w $104,0 ; BPLCON2
Wenn ihr versucht, sie wieder einzufügen, dann werdet ihr sehen, daß der
Effekt anulliert wird, da die Copperlist ja bei jedem Fotogramm ausgeführt
wird, und damit BPLCON2 gelöscht wird. Es ist also möglich, einige
Register mit dem Copper zu verändern, und andere direkt mit dem Prozessor,
aber ich rate euch, wann immer es möglich ist, den Copper zu verwenden. Er
ist besser und leichter zu synchronisieren,die richtige Zeile auszuwählen,
um auf ein Register zugreifen zu können.
AdÜ: "BUCO" bedeutet soviel wie "Loch"... (Hatte keine Zeit, das Bild
neuzuzeichen).