Tajemnice ATARI

Piszemy DEMO


    Poprzedni odcinek cyklu zakończyliśmy przykładem pokazującym gracza na ekranie. Mogliśmy zobaczyć go bez żadnych problemów, gdyż jego kolor byt różny od jednolitego koloru tła. W przypadku, gdy na ekranie znajduje się więcej elementów graficznych w różnych kolorach, to należy określić, czy i które kolory mają być przesłonięte obiektem i odwrotnie. Nazywamy to priorytetem - kolor o wyższym priorytecie będzie zasłaniał kolor o priorytecie niższym.

Priorytety

   Rejestrem odpowiedzialnym za priorytety jest Gtiactl ($D01B) i jego cień Gtiactls ($026F). Bity 0-3 tego rejestru określają następujące priorytety kolorów:

bit 0 bit 1 bit 2 bit 3
Colpm0 Colpm0 Colpf0 Colpf0
Colpm1 Colpm1 Colpf1 Colpf1
Colpm2 Colpf0 Colpf2 Colpm0
Colpm3 Colpf1 Colpf3 Colpm1
Colpf0 Colpf2 Colpm0 Colpm2
Colpfl Colpf3 Colpm1 Colpm3
Colfp2 Colpm2 Colpm2 Colpf2
Colfp3 Colpm3 Colpm3 Colpf3
Colbak Colbak Colbak Colbak

   Ustawienie jednego z tych bitów ustawia kolory w kolejności przedstawione) w tabelce (pionowe kolumny). Ustawienie kilku bitów ustala nieokreślony priorytet. Gdy obszary o tym samym priorytecie się pokrywają to uzyskują kolor czarny.

   W rejestrze Gtiactl ważną rolę odgrywają także bity 4 i 5. Ustawienie pierwszego z nich nadaje pociskom kolor określany przez Colpf3, dzięki czemu uzyskuje się piątego gracza. Ponieważ gracz ten jest połączeniem czterech pocisków to każda jego część może być poruszana oddzielnie.

   Natomiast bit piąty oddziaływuje na priorytety. Jego ustawienie spowoduje, że gdy nastąpi nałożenie dwóch graczy to ich część wspólna otrzyma kolor powstały w wyniku operacji logiczne) ORA na dwóch kolorach tych graczy.

Kolizje

   Grafika PMG nie dawałaby dużych możliwości, gdyby nie fakt, że obiekty można w prosty sposób przemieszczać i kontrolować ich zderzenia, zarówno między sobą jak i elementami normalnej grafiki. Takie spotkania nazywane są kolizjami. Podczas zderzeń w rejestrach kolizji pojawiają się odpowiednie wartości. Tych rejestrów jest 16. Pierwsza ósemka określa kolizje obiektów z polem gry:

nazwa
rejestru
adres
(hex)
kolor koli-
zja
1 2 3
Kolm0pf D000 0 1 2 p. 0
Kolm1pf D001 0 1 2 p. 1
Kolm2pf D002 0 1 2 p. 2
Kolm3pf D003 0 1 2 p. 3
Kolp0pf D004 0 1 2 g. 0
Kolp1pf D005 0 1 2 g. 1
Kolp2pf D006 0 1 2 g.2
Kolp3pf D007 0 1 2 g. 3

   Cyfry umieszczone w kolumnach Kolor1-Kolor3 oznaczają, który bit rejestru zostanie ustawiony po wykryciu kolizji, np. jeśli gracz "zderzy się" z kolorem 2 ekranu to w rejestrze Colp2pf zostanie ustawiony bit 1.

   Kolejne osiem rejestrów określa kolizje obiektów:

Rejestr Adres g0 g1 g2 g3 kolizja
Kolm0p D008 0 1 2 3 p. 0
Kolm1p D008 0 1 2 3 p. 1
Kolm2p D008 0 1 2 3 p. 2
Kolm3p D008 0 1 2 3 p. 3
Kolp0p D008 0 1 2 3 g. 0
Kolp1p D008 0 - 2 3 g. 1
Kolp2p D008 0 1 - 3 g. 2
Kolp3p D008 0 1 2 - g. 3

   Rejestry kolizji można tylko odczytywać, gdyż przy zapisie komórki pamięci o tych adresach pełnią inną funkcję. Z tego wynika, że nie mogą być kasowane. Jest to możliwe dzięki istnieniu rejestru Hitclr ($D01E). Wpisanie dowolnej wartości do tego rejestru skasuje wartości w rejestrach kolizji.

   Tak więc procedura wykrywania kolizji powinna rozpocząć się sprawdzeniem pewnych zdarzeń w rejestrach kolizji, natomiast zakończyć wpisaniem dowolnej wartości do Hitclr, aby umożliwić odczytanie kolejnych kolizji.

Vdelay

Ważnym rejestrem jest również Vdelay ($D01C). Służy on do opóźniania o jedną linię przesyłania danych z rejestrów grafiki na ekran w przypadku korzystania z rozdzielczości dwuliniowej. Daje on możliwość umieszczenia obiektu na ekranie w rozdzielczości dwudniowej z dokładnością jednej linii ekranu. Kolejne bity rejestru Vdelay odpowiadają kolejnym pociskom i graczom:

bit 0 pocisk 0
bit 1 pocisk 1
bit 2 pocisk 2
bit 3 pocisk 3
bit 4 gracz 0
bit 5 gracz 1
bit 6 gracz 2
bit 7 gracz 3

   Po przeczytaniu tylu suchych informacji należy się czytelnikom kilka przykładów.

Przykład 1

   ...prezentuje przesuw pionowy losowych danych zapisanych w pamięci PMG.
Program   Equ $8800
List_mem  Equ %00000110
List_err  Equ %00000101
Code_mem  Equ %00010000
Code_dsk  Equ %00100000

Cdtma2    Equ $0228
Cdtmv2    Equ $021A
Colpm0s   Equ $02C0
Dmactls   Equ $022F
Gtictls   Equ $026F
Hposp0    Equ $D000
Sizep0    Equ $D008
Pmbase    Equ $D407
Pmcntl    Equ $D01D
Random    Equ $D20A

Help      Equ $F0
Help_2    Equ $F2
Pm_addr   Equ $A000
Play_1    Equ Pm_addr+$0400
Play_2    Equ Pm_addr+$0500
Play_3    Equ Pm_addr+$0600
Play_4    Equ Pm_addr+$0700

          Opt List_err+Code_mem
          Org Program

        Jsr Init_pl
        Ldx Timer_2
        Lda #$01
        Stx Cdtma2
        Sty Cdtma2+$01
        Sta Cdtmv2
        Sta Licznik
        Rts

Init_pl Ldx #$00
        Txa
L1      Sta Play_1,x
        Sta Play_2,x
        Sta Play_3,x
        Sta Play_4,x
        Inx
        Bne L1
        Ldx #$03
        Ldy #$01
        Lda >Pm_addr
        Sta Pmbase
L2      Lda Kolory,x
        Sta Colpm0s,x
        Lda Pozycje,x
        Sta Hposp0,x
        Lda #$03
        Sta Sizep0,x
        Dex
        Bpl L2
        Lda #$3E
        Sta Dmactls
        Sty Gtictls
        Iny
        Sty Pmcntl
        Rts

Licznik Dta B($01)

Timer_2 Dec Licznik
        Ldx Licznik
        Bne L4
        Jsr Wybierz
        Sta Licznik
        Ldx #$00
L3      Lda Adresy,x
        Sta Help
        Inx
        Lda Adresy,x
        Sta Help+$01
        Inx
        Txa
        Pha
        Ldy #$40
        Jsr Wybierz
        Tax
        Lda Bity-$01,x
        Sta (Help),y
        Pla
        Tax
        Cpx #$08
        Bne L3
L4      Ldx #$00
L5      Lda Adresy,x
        Sta Help
        Inx
        Lda Adresy,x
        Sta Help+$01
        Inx
        Lda Help
        Clc
        Adc #$01
        Sta Help_2
        Lda Help+$01
        Sta Help_2+$01
        Ldy #$B0
L6      Lda (Help),y
        Sta (Help_2),y
        Dey
        Cpy #$40-$01
        Bne L6
        Ldy #$40
        Lda #$00
        Sta (Help),y
        Cpx #$08
        Bne L5
        Lda #$01
        Sta Cdtmv2
        Rts

Wybierz Lda Random
        And #$07
        Clc
        Adc #$01
        Rts

Adresy  Dta A(Play_1),A(Play_2)
        Dta A(Play_3),A(Play_4)
Bity    Dta B($80),B($40)
        Dta B($20),B($10)
        Dta B($08),B($04)
        Dta B($02),B($01)
Pozycje Dta B($40),B($60)
        Dta B($80),B($A0)
Kolory  Dta B($06),B($08)
        Dta B($0A),B($0C)

        End of file
   Program rozpoczyna się skokiem do procedury Init_pl, gdzie zerowany jest obszar grafiki PMG, ustawiany jest Pmbase, kolory, pozycje i rozmiary graczy. Na koniec trzy najważniejsze rejestry Dmactls, Gtictls i Pmcntl otrzymują wartości umożliwiające ukazanie się obiektów. Program główny zawiera jeszcze tylko inicjację przerwania Timer 2.

   Procedura przerwania rozpoczyna się od etykiety Timer_2. Zmienna Licznik określa przerwy pomiędzy kolejnymi losowaniami punktów umieszczanych na ekranie. Dlatego też punkty są w dużych odległościach od siebie i nie zasłaniają całkowicie obrazu. W każdym obiegu procedury przerwania licznik jest zmniejszany. W przypadku, gdy nie jest zerem to dane grafiki PMG są przepisywane o jeden bajt w dół. Natomiast gdy Licznik osiągnie wartość zero to po drodze losowana jest nowa wartość dla Licznika i losowane są punkty poprzez ustawienie losowo wybranego bitu w odpowiednim bajcie grafiki PMG. W programie wykorzystaliśmy rejestr Random ($D20A), z którego odczytywane są wartości losowe.

Przykład 2

   Przykład ten demonstruje poziomy scrolling tekstu przy użyciu grafiki PMG.

Program   Equ $8800

List_mem  Equ %00000110
List_err  Equ %00000101
Code_mem  Equ %00010000
Code_dsk  Equ %00100000

Cdtma2    Equ $0228
Cdtmv2    Equ $021A
Charset1  Equ $E000
Colpm0s   Equ $02C0
Dmactls   Equ $022F
Gtictls   Equ $026F
Hposp0    Equ $D000
Pmbase    Equ $D407
Pmcntl    Equ $D01D
Sizep0    Equ $D008

Adres     Equ $F0
Licznik   Equ $F2
Pomoc     Equ $F3
Pomoc_2   Equ $F5
Tekst_Ad  Equ $F7
Pm_adr    Equ $A000

          Opt List_err+Code_mem
          Org Program
          Ldx #$00
          Txa
L0        Sta Play_1,x
          Sta Play_2,x
          Sta Play_3,x
          Sta Play_4,x
          Inx
          Bne L0
          Ldx Tekst
          Lda #$08
          Stx Tekst_Ad
          Sty Tekst_Ad+$01
          Sta Licznik
          Lda >Pm_adr
          Sta Pmbase
          Ldx #$03
L1        Lda #$0F
          Sta Colpm0s,x
          Lda Pozycje,x
          Sta Hposp0,x
          Lda #$03
          Sta Sizep0,x
          Dex
          Bpl L1
          Ldx #$3E
          Stx Dmactls
          Ldy #$02
          Sty Pmcntl
          Dey
          Sty Gtictls
          Ldx Timer_2
          Lda #$01
          Stx Cdtma2
          Sty Cdtma2+$01
          Sta Cdtmv2
          Rts

Timer_2   Dec Licznik
          Beq L5
          Ldx #$00
L2        Lda Adresy,x
          Sta Pomoc
          Sta Pomoc_2
          Inx
          Lda Adresy,X
          Sta Pomoc+$01
          Sta Pomoc_2+$01
          Dec Pomoc_2+$01
          Inx
          Ldy #$40
L3        Clc
          Lda (Pomoc),y
          Asl @
          Sta (Pomoc),y
          Bcc L4
          Lda (Pomoc_2),y
          Ora #$01 
          Sta (Pomoc_2),y
L4        Dey   
          Bpl L3
          Cpx #$0A
          Bne L2
          Jmp Koniec

L5        Ldx #$00
L6        Ldy #$00
          Lda (Tekst_ad),y
          Jsr Oblicz_adres
          Lda Adresy,x
          Sta Pomoc
          Lda Adresy+$01,x
          Sta Pomoc+$01
          Txa
          Pha
L7        Lda (Adres),y
          Pha
          Tya
          Asl @
          Asl @
          Asl @
          Tay
          Pla
          Ldx #$07
L8        Sta (Pomoc),y
          Iny
          Dex
          Bpl L8
          Tya
          Lsr @
          Lsr @
          Lsr @
          Tay
          Cpy #$08
          Bne L7
          Inc Tekst_ad
          Bne L9
          Inc Tekst_ad+$01
L9        Pla
          Tax
          Inx
          Inx
          Cpx #$0A
          Bne L6
          Sec
          Lda Tekst_ad
          Sbc #$04
          Sta Tekst_ad
          Bcs L10
          Dec Tekst_ad+$01
L10       Ldx Tekst_ad
          Ldy Tekst_ad+$01
          Cpy >Ktekstu
          Bne L11
          Cpx Tekst
          Stx Tekst_ad
          Sty Tekst_ad+$01
L11       Ldx #$08
          Stx Licznik
Koniec    Lda #$01
          Sta Cdtmv2
          Rts

Oblicz_adresy Pha
          And #$7F
          Lsr @
          Lsr @
          Lsr @
          Lsr @
          Lsr @
          Clc
          Adc >Charset1
          Sta Adres+$01
          Pla
          And #$1F
          Asl @
          Asl @
          Asl @
          Sta Adres
          Rts

Pozycje   Dta B($40),B($60)
          Dta B($80),B($A0)

Play_1    Equ Pm_Adr+$0450
Play_2    Equ Pm_Adr+$0550
Play_3    Equ Pm_Adr+$0650
Play_4    Equ Pm_Adr+$0750
Play_D    Equ Pm_Adr+$0850

Adresy   Dta A(Play_1),A(Play_2)
         Dta A(Play_3),A(Play_4)
         Dta A(Play_D)

Tekst  Equ *

     Dta D'    Tajemnice Atari '
     Dta D' Tomasz Bielak i'
     Dta D' Rafal Bielecki'

KTekstu Dta D'    '

     End of file

   Program główny czyści obszar PMG, następnie inicjuje grafikę PMG i przerwania Timer'a 2 podobnie. Jak w poprzednim przykładzie. Poza tym program ustawia adres tekstu (Tekst_ad) i Licznik.

   Na ekranie znajduje się czterech graczy w poczwórnej szerokości. Gracze umieszczeni są w tych samych miejscach ekranu obok siebie i ich pozycja nic zmienia się. Procedurę przerwania można podzielić na dwie części. Jedna z nich tworzy litery w obszarze PMG, druga przesuwa je. Ważną rolę odgrywa tu Licznik. Gdy ma wartość zero to tworzone jest pięć nowych liter. Piąta litera nie jest wyświetlana, lecz bierze udział w trakcie przesuwania tekstu. Dane dla kolejnej litery pobierane są ze standardowego zestawu znaków Atari - Char - set1 ($E000). Adres danych znaku oblicza procedura Oblicz_adresy. Jak wiemy, każdy znak to 8 bajtów. Jednak gracz o wysokości ośmiu linii ekranu jest za mały i byłby zbyt "spłaszczony", zwłaszcza przy poczwórnej szerokości obiektów. Dlatego też każdy bajt matrycy znaków powielany jest osiem razy w pamięci PMG. Tak dzieje się z wszystkimi pięcioma literami. Po tej operacji cztery litery pojawiają się na ekranie. Płynne przesuwanie tekstu realizowane jest przy niezerowej wartości Licznika. Przesuw płynny zmusza do przesuwania bitów poszczególnych bajtach pamięci PMG. Do tego najlepiej nadaje się rozkaz ASL procesora, dlatego że bit 7 przesuwanego znaku umieszczany jest w znaczniku C procesora. Jeśli jest on ustawiony, to należy go odtworzyć w kolejnym graczu. Nasz program realizuje to przy użyciu rozkazów BCC i ORA (okolice etykiety L3). Nawiasem mówiąc zamiana BCC na BCS daje ciekawy efekt. Bitowe przesuwanie liter powtarzane jest 8 razy (i oczywiście uzależnione jest od Licznika).

Przykład 3

   ...to prosta gra zrealizowana przy użyciu PMG. Na ekranie umieszczane są dwie postacie strzelające do siebie. Za każde trafienie przydzielana jest losowa ilość punktów.

Program  Equ $8800

List_mem Equ %00000110
List_err Equ %00000101
Code_mem Equ %00010000
Code_dsk Equ %00100000

Cdtma2  Equ     $0228
Cdtmv2  Equ     $021A
Colpm0s Equ     $02C0
Dmactls Equ     $022F
Gtictls Equ     $026F
Hitclr  Equ     $D01E
Hposp0  Equ     $D000
Hposp2  Equ     $D002
Hposp3  Equ     $D003
Hposm0  Equ     $D004
Jstick0 Equ     $0278
Kolm0p  Equ     $D008
Nmien   Equ     $D40E
Pmbase  Equ     $D407
Pmcntl  Equ     $D01D
Random  Equ     $D20A
Sizep0  Equ     $D008
Trig0s  Equ     $0284
Poz_0x  Equ     $0600
Poz_1x  Equ     $0601
Poz_0y  Equ     $0602
Poz_1y  Equ     $0603
Pm_0x   Equ     $0604
Pm_1x   Equ     $0606
Pm_0y   Equ     $0606
Pm_1y   Equ     $0607
Dod_m0  Equ     $0608
Dod_m1  Equ     $0609
Cyfry0  Equ     $060A
Cyfry1  Equ     $0610
Score   Equ     $0616
Kier_0  Equ     $061A
Kier_1  Equ     $0618
M0      Equ     $061C
M1      Equ     $061D
Przyc0  Equ     $061E
Przyc1  Equ     $061F
Pomoc   Equ     $F0
Pomoc2  Equ     $F2
Pomoc3  Equ     $F4
Adr_pl  Equ     $A000

        Opt List_err+Code_mem
        Org Program

        Jmp Start

* WYSWIETLA PUNKTY
* (X-NR GRACZA)

Punkty  Txa
        Pha
        Lda #$60
        Sta Pomoc2
        Lda Adr_pl+$0600
        Cpx #$01
        Bne L1
        Lda Adr_pl+$0700
L1      Sta Pomoc
        Sty Pomoc2+$01
        Lda >Cyfry0
        Sta Pomoc+$01
        Ldy #$00
L2      Lda (Pomoc),y
        Pha
        Asl @
        Sta Pomoc3
        Pla
        Asl @
        Asl @
        Asl @
        Sec
        Sbc Pomoc3
        Sta Pomoc3
        Tya
        Pha
        Ldx Pomoc3
        Ldy #$00
L3      Lda Znaki,x
        Sta (Pomoc2),y
        Inx
        Iny
        Cpy #$06
        Bne L3
        Clc
        Lda Pomoc2
        Adc #$08
        Sta Pomoc2
        Pla
        Tay
        Iny
        Cpy #$06
        Bne L2
        Pla
        Tax
        Rts

* DODAJ PUNKT (X-NR GRACZA)
            
Dodaj   Lda Score,x
        Bne L4
        Lda Score+$02,x
        Beq L8
L4      Txa
        Pha
        Cpx #$01
        Bne L5
        Ldx #$06
L5      Ldy #$00
L6      Inc Cyfry0,x
        Lda Cyfry0,x
        Cmp #$0A
        Bne L7
        Lda #$00
        Sta Cyfry0,x
        Inx
        Iny
        Cpy #$06
        Bne L6
L7      Pla
        Tax
        Dec Score,x
        Lda Score,x
        Cmp #$FF
        Bne L8
        Dec Score+$02,x
L8      Rts


* POKAZ GRACZA (X-NR)

Pokaz_gr Txa
         Pha
         Clc
         Adc >Adr_pl+$400
         Sta Pomoc+$01
         Lda Poz_0y,x
         Sta Pomoc
         Lda Poz_0x,x
         Sta Hposp0,x
         Lda Kier_0,x
         Tax
         Cpx #$01
         Bne L9
         Ldx #$09
L9       Ldy #$00
L10      Lda Wyglad,x
         Sta (Pomoc),y
         Inx
         Iny
         Cpy #$0A
         Bne L10
         Pla
         Tax
         Rts

* ZMAZ POCISK

Zmaz     Lda Pm_0y,x
         Tay
         Lda Adr_pl+$0300,y
         And Zgaszenie,x
         Sta Adr_pl+$0300,y
         Rts

* POKAZ POCISK
Pokaz    Lda Pm_0y,x
         Tay
         Lda Adr_pl+$0300,y
         Ora Zapalenie,x
         Sta Adr_pl+$0300,y
         Rts
 
* TIMER2

Timer_2  Ldx #0
L11      Lda Jstick0,x
         Lsr @
         Bcs L13
         Pha
         Lda Poz_0y,x
         Cmp #$22
         Beq L12
         Dec Poz_0y,x
L12      Pla 
L13      Lsr @ 
         Bcs L15
         Pha
         Lda Poz_0y,x
         Cmp #$D4
         Beq L14
         Inc Poz_0y,x
L14      Pla
L15      Lsr @
         Bcs L17
         Pha
         Lda Poz_0x,x
         Cmp #$3D
         Beq L16
         Lda #$00
         Sta Kier_0,X
         Dec Poz_0x,x
L16      Pla  
L17      Lsr @
         Bcs L19
         Pha
         Lda Poz_0x,x
         Cmp #$BD
         Beq L18
         Lda #$01
         Sta Kier_0,x 
         Inc Poz_0x,x 
L18      Pla
L19      Jsr Pokaz_gr
         Lda Trig0s,x
         Beq L20
         Lda #$00
         Sta Przyc0,x
         Jmp L23
L20      Lda Przyc0,x
         Bne L23
         Lda #$01
         Sta Przyc0,x
         Lda M0,x
         Beq L21
         Jsr Zmaz
L21      Lda #$01
         Sta M0,x
         Lda Poz_0y,x
         Clc
         Adc #$05
         Sta Pm_0y,x
         Lda Poz_0x,x
         Pha
         Lda Kier_0,x
         Tay
         Lda Dodawanie,y
         Sta Dod_m0,x
         Pla
         Cpy #$01
         Bne L22
         Clc
         Adc #$06
L22      Sta Pm_0x,x
         Sta Hposm0,x
         Jsr Pokaz
L23      Lda M0,x
         Beq L25
         Clc
         Lda Pm_0x,x
         Adc Dod_m0,x
         Sta Pm_0x,x
         Sta Hposm0,x
         Cmp #$31
         Beq L24
         Cmp #$32
         Beq L24
         Cmp #$CC
         Beq L24
         Cmp #$CD
         Beq L25
L24      Lda #$00
         Sta M0,x
         Jsr Zmaz
L25      Inx
         Cpx #$02
         Beq L26
         Jmp L11

L26      Ldx #$00
L27      Lda Kolm0p,x
         Cmp Kolizje,x
         Bne L29
         Clc
         Lda Random
         And #$3F
         Adc #$01
         Adc Score,x
         Sta Score,x
         Bcc L28
         Inc Score+$02,x
L28      Jsr Zmaz
L29      Jsr Dodaj
         Jsr Punkty
         Inx
         Cpx #$02
         Bne L27
L30      Lda #$01
         Sta Cdtmv2
         Sta Hitclr
         Rts

* PROGRAM GLOWNY       

Start    Ldx #$00
         Txa
L31      Sta Adr_pl+$0300,x
         Sta Adr_pl+$0400,x
         Sta Adr_pl+$0500,x
         Sta Adr_pl+$0600,x
         Sta Adr_pl+$0700,x
         Inx
         Bne L31

         Lda >Adr_pl
         Sta Pmbase
         Ldx #$03
L32      Lda Kolory,x
         Sta Colpm0s,x
         Lda #$00
         Sta Sizep0,x
         Dex
         Bpl L32 
         Ldx #$32
         Ldy #$C6
         Stx Hposp2
         Sty Hposp3
         Ldx #$3E
         Stx Dmactls
         Ldx #$01
         Ldy #$03
         Stx Gtictls
         Sty Pmcntl

         Ldx #$03
         Lda #$00
L33      Sta M0,x
         Dex
         Bpl L33
         Ldx #$13
L34      Sta Cyfry0,x
         Dex
         Bpl L34
         Ldx #$01
         Stx Kier_0
         Dex
         Stx Kier_1
         Ldx #$46
         Ldy #$AA
         Stx Poz_0x
         Stx Poz_0y
         Sty Poz_1x
         Sty Poz_1y
         Ldx #$00
         Jsr Punkty
         Jsr Pokaz_gr
         Inx
         Jsr Punkty
         Jsr Pokaz_gr
         Ldx Timer_2
         Stx Cdtma2
         Sty Cdtma2+$01
         Lda #$40
         Sta Nmien
         Jmp L30

         Org Program+$0400

Znaki    Dta B($36),B($7F)
         Dta B($41),B($41)
         Dta B($7F),B($36)

         Dta B($36),B($7F)
         Dta B($00),B($00)
         Dta B($00),B($00)

         Dta B($30),B($79) 
         Dta B($49),B($49)
         Dta B($4F),B($06)

         Dta B($36),B($7F)
         Dta B($49),B($49)
         Dta B($49),B($00)

         Dta B($36),B($7F)
         Dta B($08),B($08)
         Dta B($78),B($30)

         Dta B($06),B($4F)
         Dta B($49),B($49)
         Dta B($79),B($30)

         Dta B($06),B($4F)
         Dta B($49),B($49)
         Dta B($7F),B($36)

         Dta B($36),B($7F)
         Dta B($40),B($40)
         Dta B($40),B($00)

         Dta B($36),B($7F)
         Dta B($49),B($49)
         Dta B($7F),B($36)

         Dta B($36),B($7F)
         Dta B($49),B($49)
         Dta B($79),B($30)

Wyglad  Dta B($00),B($18),B($38)
        Dta B($10),B($3C),B($FC)
        Dta B($38),B($18),B($2C)
        Dta B($00),B($18),B($1C)
        Dta B($08),B($3C),B($3F)
        Dta B($1C),B($18),B($34)
        Dta B($00)
Kolory    Dta B($0F),B($96)
          Dta B($58),B($58)
Zgaszenie Dta B($FC),B($F3)
Zapalenie Dta B($03),B($0C)
Dodawanie Dta B($FB),B($02)
Kolizje   Dta B($02),B($01)

          End of File

   Aby umożliwić dokładniejszą analizę programu podamy znaczenie zmiennych i stałych w nim użytych. Kolejne zmienne 3 umieszczone są w kolejnych komórkach 8 stronie. Poz_0x do Poz_1y okreslają pozycje obu postaci (pionowe i poziome). Podobnie Pm_0x do Pm_1y określają pozycję wystrzelonych nabojów. Dod_m0 i Dod_m1 określają jaką wartość dodawać do pozycji X pocisków. Kolejne dwie zmienne Cyfry0 i Cyfry1 są sześciobajtowe. Każdy bajt to liczba z przedziału od 0 do 9 oznaczająca kolejną cyfrę licznika punktów gracza. Score to czterobajtowa zmienna określająca ile punktów należy dodać każdemu z graczy w najbliższej przyszłości. W każdym obiegu przerwania dodawany jest jeden punkt, dopóki Score każdego gracza nic wyzeruje się. Takie zwiększanie punktów powoduje, że dodane punkty nie pojawiają się natychmiast. Dużym ułatwieniem od strony programowej jest zapisanie w pamięci najpierw dwóch młodszych bajtów punktów graczy, a potem starszych, nie tak jak zwykle: młodszy/starszy gracza 0 i młodszy/starszy gracza 1. Dzięki takiemu rozwiązaniu odwołania do młodszego lub starszego bajtu punktów gracza o numerze w rejestrze X stają się prostsze, gdyż bajt młodszy określa etykieta Score, starszy natomiast Score+$02 (rejestr X zawiera oczywiście numer gracza).

   Kolejne dwie zmienne Kier_0 i Kier_1 określają kierunek odpowiedniego gracza. Gracz zwrócony w lewo wygląda zupełnie inaczej, niż gracz obrócony w prawo. I te właśnie zmienne decydują o tym skąd pobierać dane do wyglądu postaci.

   M0 i M1 to zmienne logiczne. Wartość $01 umieszczona w nich oznacza, że pocisk wystrzelony przez odpowiedniego gracza znajduje się na ekranie i porusza się w stronę określoną przez kierunek gracza.

   Za każdym obiegiem przerwania sprawdzane są przyciski joystick'ów obu graczy. Zmienne Przyc0 i Przyc1 przyjmują wartość 1 w momencie naciśnięcia przycisków joystick'ów, co umożliwia poruszanie się pocisków i jednocześnie zapobiega podwójnemu odczytaniu wartości z komrórek odpowiadających za stan przycisków joystick'ów.

   Program główny inicjuje PMG i Timer'a 2 oraz ustawia wartości początkowe zmiennym. Cała gra wykonywana jest przez przerwanie Timer'a 2, który wywołuje inne procedury. Procedura zaczynająca się od etykiety Punkty wyświetla punkty graczy pobierając dane dla wyglądu odpowiedniej cyfry z tablicy Znaki. Kolejna procedura, Dodaj, sprawdza, czy nie pozostały do dodania jakieś punkty graczom i jeśli tak, to zwiększa odpowiednio Liczniki i zwiększa Score. Jest ona wywoływana w każdym obiegu przerwania. Procedura Pokaz_gr umieszcza na ekranie graczy w odpowiednich pozycjach. Podobne zadanie pełni procedura Pokaż dla pocisków, odwrotne zadanie - Zmaz. Procedury wykorzystują maski bitowe Zapalenie i Zgaszenie.

   W samej procedurze przerwania Timer'a 2 nowa dla nas jest tylko obsługa joystick'a.    Joystick na cztery zasadnicze położenia: w lewo, w prawo, do przodu i wstecz. Osiem bitów rejestru PortA ($D300) przedstawia położenie dwóch joystick'ów wg tabeli:

bit joystick kierunek
0 0 do przodu
1 0 wstecz
2 0 w lewo
3 0 w prawo
4 1 do przodu
5 1 wstecz
6 1 w lewo
7 1 w prawo

   Normalnie wszystkie bity są ustawione. Zmiana położenia joystick'a powoduje wyzerowanie odpowiedniego bitu (lub bitów). Zazwyczaj jednak korzysta się z rejestrów cieni Jstick0 ($0278) i Jstick1 ($0279). W pierwszym z nich cztery najmłodsze bity określają położenie joystick'a 0, natomiast rejestr drugi określa położenie joystick'a 1 (też bity 0-3). Do wykrywania stanu przycisków joystick'ów służą rejestry GTIA o nazwach Trig0 ($D010) i Trig1 ($D011) oraz ich cienie Trig0s ($0284) i Trig1s ($0285). Skasowanie bitu 0 oznacza, że przycisk został naciśnięty.

   Gra może uprzyjemnić pisanie programów w Basic'u, pod warunkiem, że w programie głównym umieści się rozkaz PLA procesora. W następnym artykule zajmiemy się dźwiękiem Atari.

   Dla tych, którzy preferują dane homogenizowane, przedstawiamy poniżej ostatni przykład z "Piszemy DEMO" w postaci danych szesnastkowych. Należy je połączyć ze Zgrywusem+ z TA 2/92, co pozwoli uzyskać program maszynowy, zdatny do uruchomienia bezpośrednio pod kontrolą DOS lub COS.
1000 REM *--------------------------*
1002 REM : DEMO-GRA                 :
1004 REM :  R. Bielecki, T. Bielak  :
1006 REM : (c) 1992 Tajemnice ATARI :
1008 REM *--------------------------*
1010 DATA ffff00885f8a4cd1898a48a960
1020 DATA 85f2a90aa0a6e001d004a910a0
1030 DATA a785f084f3a90685f1a000b1f0
1040 DATA 480a85f4680a0a0a38e5f485f4
1050 DATA 9848a6f4a000bd008c91f2e8c8
1060 DATA c006d0f518a5f2690885f268a8
1070 DATA c8c006d0d268aa60bd1606d005
1080 DATA bd1806f02e8a48e001d002a206
1090 DATA a000fe0a06bd0a06c90ad00ba9
1100 DATA 009d0a06e8c8c006d0eb68aade
1110 DATA 1606bd1606c9ffd003de180660
1120 DATA 8a481869a485f1bd020685f0bd
1130 DATA 00069d00d0bd1a06aae001d002
1140 DATA a209a000bd3c8c91f0e8c8c00a
1150 DATA d0f568aa60bd0606a8b900a33d
1160 DATA 538c9900a360bd0606a8b900a3
1170 DATA 1d558c9900a360a200bd78024a
1180 DATA b00c48bd0206c922f003de0206
1190 DATA 684ab00c48bd0206c9d4f003fe
1200 DATA 0206684ab01148bd0006c93df0
1210 DATA 08a9009d1a06de0006684ab011
1220 DATA 48bd0006c9bdf008a9019d1a06
1230 DATA fe000668208988bd8402f008a9
1240 DATA 009d1e064c6b89bd1e06d03aa9
1250 DATA 019d1e06bd1c06f00320b588a9
1260 DATA 019d1c06bd02061869059d0606
1270 DATA bd000648bd1a06a8b9578c9d08
1280 DATA 0668c001d0031869069d04069d
1290 DATA 04d020c388bd1c06f02518bd04
1300 DATA 067d08069d04069d04d0c931f0
1310 DATA 0cc932f008c9ccf004c9cdd008
1320 DATA a9009d1c0620b588e8e002f003
1330 DATA 4cd388a200bd08d0dd598cd016
1340 DATA 18ad0ad2293f69017d16069d16
1350 DATA 069003fe180620b58820508820
1360 DATA 0388e8e002d0d7a9018d1a028d
1370 DATA 1ed060a2008a9d00a39d00a49d
1380 DATA 00a59d00a69d00a7e8d0eea9a0
1390 DATA 8d07d4a203bd4f8c9dc002a900
1400 DATA 9d08d0ca10f2a232a0c68e02d0
1410 DATA 8c03d0a23e8e2f02a201a0038e
1420 DATA 6f028c1dd0a203a9009d1c06ca
1430 DATA 10faa2139d0a06ca10faa2018e
1440 DATA 1a06ca8e1b06a246a0aa8e0006
1450 DATA 8e02068c01068c0306a2002003
1460 DATA 88208988e8200388208988a2d1
1470 DATA a0888e28028c2902a9408d0ed4
1480 DATA 4cc889008c5a8c367f41417f36
1490 DATA 367f00000000307949494f0636
1500 DATA 7f49494900367f08087830064f
1510 DATA 49497930064f49497f36367f40
1520 DATA 404000367f49497f36367f4949
1530 DATA 7930001838103cfc38182c0018
1540 DATA 1c083c3f1c1834000f965858fc
1550 DATA f3030cfe020201e002e1020088


Tomasz Bielak
Rafał Bielecki

Powrót na start | Powrót do spisu treści | Powrót na stronę główną

Pixel 2001