Tajemnice ATARI

Piszemy DEMO


    Do końca cyklu redagowanego przez nas zostały już tylko dwa odcinki. W dzisiejszym zamieścimy wszystkie procedury potrzebne do uruchomienia drugiej części demonstracji: PLAYER2.ASM, SKOCZEK.ASM, DLI2.ASM i BARY.ASM.

    Pierwsza z nich przygotowuje grafikę PMG:
Procedure Equ $9FD5

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

Colpm1s   Equ $02C1 
Hposp1    Equ $D001
Pomoc     Equ $0080 
Start_pl  Equ $9000

          Opt List_err+Code_dsk
          Org Procedure


          Ldx <Start_pl
          Ldy >Start_pl
          Stx Pomoc
          Sty Pomoc+$01
          Ldy #$00
          Tya 
L1        Sta (Pomoc),y
          Iny
          Bne L1
          Inc Pomoc+$01
          Ldx Pomoc+$01
          Cpx #$98
          Bne L1

          Ldx #$A0
          Ldy #$0F
          Stx Hposp1
          Sty Colpm1s
          Rts

          End of file
    Procedura czyści obszar pamięci PMG (od etykiety Start_pl) oraz ustawia kolor i pozycję pierwszego z graczy. Tego gracza będzie obsługiwała procedura WSKAZNIK.ASM, zamieszczona w poprzednim artykule.

    Druga z procedur, SKOCZEK.ASM, w odróżnieniu od PLAYER2.ASM będzie wykonywana co 1/50 sekundy, a jej zadaniem jest ruch pionowy obrazka z pierwszej części demonstracji.
Procedure Equ $A10C

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

Dlptrs    Equ $0230

Pomoc     Equ $008A

          Opt List_err+Code_dsk
          Org Procedure

          Jmp Init_proc

Int_proc  Inc Pomoc
          Ldy Pomoc
          Cpy #$4C
          Bne L1
          Ldy #$00
          Sty Pomoc
L1        Lda Tablica,y
          Sta Dlptrs
          Rts

Init_proc Ldx #$26 
          Ldy #$00
L2        Lda Tablica,x
          Sta Tablica+$26,y
          Iny
          Dex
          Bne L2
          Rts


Tablica   Dta B($92),B($92),B($91)
          Dta B($91),B($90),B($90)
          Dta B($8F),B($8E),B($8D)
          Dta B($8B),B($89),B($87)
          Dta B($85),B($83),B($81)
          Dta B($7E),B($7B),B($77)
          Dta B($73),B($6F),B($6B)
          Dta B($67),B($63),B($5E)
          Dta B($59),B($54),B($4F)
          Dta B($49),B($43),B($3C)
          Dta B($36),B($30),B($29)
          Dta B($22),B($1A),B($12)
          Dta B($0B),B($00)

          End of File
    Wywołanie procedury spowoduje powielenie wartości z tablicy Tablica w odwrotnej kolejności (etykieta Init_proc). Procedura wywoływana jest co 1/50 sekundy od etykiety Int_proc, gdzie z tablicy Tablica pobierana jest kolejna wartość i wpisywana do rejestru Dlptrs. Żeby uzyskać pożądany efekt konieczne jest skonstruowanie odpowiedniej Display List, co robi procedura następna (DLI2.ASM):
Procedure Equ $A000

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

Colpf0s   Equ $02C4 
Colpf1s   Equ $02C5 
Colpf2s   Equ $02C6 
Dlptrs    Equ $0230 
Dmactls   Equ $022F

Ekran     Equ $6600
Obrazek   Equ $8000
Pomoc     Equ $0080

          Opt List_err+Code_dsk
          Org Procedure

          Jmp Init_Dl
          Org Procedure+$92

Dlist     Dta B($70),B($70)
          Dta B($4E)
          Dta A(0brazek+$02)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($0E),B($0E),B($0E)
          Dta B($41),A(Dlist)

Init_Dl   Ldx #$00
          Txa
L1        Sta Procedure,x 
          Inx  
          Cpx #$92
          Bne L1
          Lda #$3E
          Ldx <Procedure
          Ldy >Procedure
          Sta Dmactls
          Stx Dlptrs
          Sty Dlptrs+$01
          Ldx #$62
          Ldy #$86
          Lda #$9C
          Stx Colpf0s
          Sty Cocpf1s
          Sta Colpf2s
          Rts
         
          End of file
    Właściwy program dla ANTIC'a rozpoczyna się od etykiety Dlist, czyli $92 bajty od początku procedury (dyrektywa Org Procedure+$92). Program (etykieta Init_Dl) zeruje powstałą "dziurę". Jak pamiętamy, każde $00 w programie ANTIC'a tworzy jedną pustą linię na ekranie. Zmieniając wartość Dlptrs zmieniamy ilość pustych linii przed obrazkiem, co powoduje ruch obrazka w pionie.

    Po wyzerowaniu fragmentu Display List procedura DLI2.ASM ustawia wektor Dlptrs, wpisuje odpowiednie wartości do Dmactls i rejestrów kolorów.

    Ostatnia procedura drugiej części demonstracji to BARY.ASM. Procedura ta wyświetla na ekranie poruszające się, różnokolorowe linie ekranu zwane potocznie "barami":
Procedure Equ $A17D

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

Colbak    Equ $D01A
Skstat    Equ $D20F
Vcount    Equ $D40B
Wsync     Equ $D40A

Tab_rur   Equ $6D00

          Opt List_err+Code_dsk
          Org Procedure

          Jsr Przepisz
L1        Jsr Czysc_tab
          Jsr Wstaw_rury
          Jsr Pokaz_rury
          Lda Skstat
          And #$08
          Bne L1
          Rts

Przepisz  Ldx #$3F
          Ldy #$00
L2        Lda Pozycje,x
          Sta Pozycje+$40,y
          Iny
          Dex
          Bpl L2
          Rts

Czysc_tab Lda #$00
          Tax
L3        Sta Tab_rur,x
          Inx
          Cpx #$DF
          Bne L3
          Rts

Wstaw_rury Ldx #$00
L4        Txa
          Pha
          Ldy Poz_rur,x
          Lda Pozycje,y
          Tay
          Inc Poz_rur,x
          Lda Poz_rur,x
          And #$7F
          Sta Poz_rur,x
          Lda Tab_Kolorow,x
          Tax
          Lda #$0D 
          Sta Count
L5        Sta Kolory,x
          Sta Tab_rur,y
          Inx
          Iny
          Dec Count
          Lda Count
          Bne L5
          Pla
          Tax
          Inx
          Cpx #$05
          Bne L4
          Rts

Pokaz_rury Lda Vcount
          Cmp #$08
          Bne Pokaz_rury
          Ldy #$00
L6        Lda Tab_rur,y
          Sta Wsync
          Sta Colbak
          Iny
          Cpy #$DF
          Bne L6
          Rts

Tab_kolorow Dta B($00),B($0D),B($1A)
          Dta B($27),B($34)

Poz_rur   Dta B($00),B($05),B($0A)
          Dta B($0F),B($14)

Count     Dta B($00)

Kolory    Dta B($F2),B($F4),B($F6)
          Dta B($F8),B($FA),B($FC)
          Dta B($FE),B($FC),B($FA)
          Dta B($F8),B($F6),B($F4)
          Dta B(F2)

          Dta B($92),B($94),B($96)
          Dta B($98),B($9A),B($9C)
          Dta B($9E),B($9C),B($9A)
          Dta B($98),B($96),B($94)
          Dta B($92)

          Dta B($32),B($34),B($36)
          Dta B($38),B($3A),B($3C)
          Dta B($3E),B($3C),B($3A)
          Dta B($38),B($36),B($34)
          Dta B($32)

          Dta B($C2),B($C4),B($C6)
          Dta B($C8),B($CA),B($CC)
          Dta B($CE),B($CC),B($CA)
          Dta B($C8),B($C6),B($C4)
          Dta B($C2)

          Dta B($02),B($04),B($06)
          Dta B($08),B($0A),B($0C)
          Dta B($0E),B($0C),B($0A)
          Dta B($08),B($06),B($04)
          Dta B($02)

Pozycje   Dta B($01),B($01),B($02)
          Dta B($03),B($04),B($05)
          Dta B($06),B($08),B($0A)
          Dta B($0C),B($0E),B($11)
          Dta B($14),B($17),B($1A)
          Dta B($1D),B($21),B($25)
          Dta B($29),B($2D),B($31)
          Dta B($35),B($3A),B($3E)
          Dta B($43),B($48),B($4D)
          Dta B($51),B($56),B($5B)
          Dta B($60),B($65),B($6B)
          Dta B($70),B($75),B($7A)
          Dta B($7F),B($83),B($88)
          Dta B($8D),B($92),B($96)
          Dta B($9B),B($9F),B($A3)
          Dta B($A7),B($AB),B($AF)
          Dta B($B3),B($B6),B($B9)
          Dta B($BC),B($BF),B($C2)
          Dta B($C4),B($C6),B($C8)
          Dta B($CA),B($CB),B($CC)
          Dta B($CD),B($CE)B($CF)
          Dta B($CF)

          End of file
    Główny program składa się z wywołania kilku podprocedur, dopóki nie zostanie naciśnięty klawisz SHIFT. Jeden raz wywoływana jest podprocedura Przepisz, która powiela tablicę pozycji "barów" w odwrotnej kolejności. "Bary" tworzone są w tablicy Tab_rur. W tablicy tej każdy bajt odpowiada za kolor odpowiedniej linii ekranu. Kolejna podprocedura Czysc_tab zeruje tę tablicę, natomiast Wstaw_rury przepisuje odpowiednie wartości do tej tablicy. Podprocedura Wstaw_rury korzysta z dodatkowych tablic: Kolory - tu zamieszczone są wartości kolorów dla poszczególnych "barów". Każdy "bar" zajmuje 13 linii ekranu, czyli zawiera się w 13 bajtach. Każdy blok 13 bajtów w tablicy Kolory określa wygląd jednego z "barów". Pobieranie danych z tej tablicy jest proste dzięki dodatkowej tablicy Tab_kolorów, która określa, z którego miejsca tablicy Kolory pobierać dane dla kolejnych "barów". Tablica Poz_rur zawiera początkowe pozycje "barów", czyli określa, w które miejsce tablicy Tab_rur przepisywane będą kolejne "bary". Tablica ta modyfikowana jest po każdorazowym utworzeniu "barów". Dodatkowy bajt Count służy jako licznik do przepisywania 13 bajów koloru "bara" (etykieta L5). Ostatnia podprocedura Pokaz_rury tablicę Tab_rur do rejestru Colbak, czyli tworzy "bary" na ekranie.

    Na zakończenie oglądnijmy efekt działania powyższych procedur. Do uruchomienia drugiej części potrzebne będą następujące zbiory z poprzedniego odcinka: CZYSC.OBJ (czyści pamięć), MUZYKA.OBJ i OBRAZEK.DAT. Oprócz tego zbiór PLAYER.OBJ inicjujący grafikę PMG oraz procedury dzisiejsze: WSKAZNIK.OBJ, PLAYER2.0BJ, DLI2.0BJ, SKOCZEK.OBJ i procedura uruchamiająca RUN.OBJ:
Procedure Equ $0600

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

Nmien     Equ $D40E
Sizep1    Equ $D009
Skctl     Equ $D20F
Vvblk     Equ $0222

Bary      Equ $A17D
Dli2      Equ $A000
Music     Equ $7400
Player    Equ $9B5B
Play_2    Equ $9FD5
Reset     Equ $E474
Skoczek   Equ $A10C
Wskaznik  Equ $9F95

          Opt List_err+Code_dsk
          Org Procedure

RUN       Ldx Vvblk
          Ldy Vvblk+$01
          Stx Koniec+$01
          Sty Koniec+$02

          Lda #$03
          Sta Skctl
          Ldx <Przerw
          Ldy >Przerw
          Lda #$C0
          Stx Vvblk 
          Sty Vvblk+$01
          Sta Nmien

          Jsr Dli2
          Jsr Player
          Jsr Play_2 
          Lda #$03
          Sta Sizepl
          Jsr Skoczek
          Jsr Bary
          Jmp Reset

Przerw    Jsr Music+$01
          Jsr Wskaznik
          Jsr Skoczek+$03 
Koniec    Jmp Koniec

          Org $02E0
 
          Dta A($0600)

          End of File
    Zamieszczamy również nieco zmieniony program w Basic'u z poprzedniego odcinka cyklu, który pozwoli na stworzenie samodzielnie działającego zbioru DEMO.COM.
10 REM
20 REM PROGRAM LACZACY ZBIORY
30 REM
40 COM NAZWA$(14)
50 OPEN #l,8,0,"D:DEMO.COM"
60 FOR L=0 TO 40:READ D
70 POKE 1536+L,D:NEXT L
80 FOR L=0 TO 9:READ NAZWA$;? NAZWA$
90 OPEN #2,4,0,NAZWA$
100 D=USR(1536,32,7,14000)
110 X=USR(1536,16,11,D)
120 CLOSE #2:NEXT L:CLOSE #1:END
897 REM
898 REM PROGRAM MASZYNOWY
899 REM
900 DATA 104,104,104,170,104,104,157 
910 DATA 66,3,104,157,73,3,104,157
920 DATA 72,3,169,0,157,68,3,169,100
930 DATA 157,69,3,32,86,228,189,72,3
940 DATA 133,212,189,73,3,133,213,96
997 REM
998 REM NAZWY ZBIOROW
999 REM
1000 DATA D:CZYSC.OBJ 
1010 DATA D:MUZYKA.OBJ
1020 DATA D:PLAYER.OBJ
1030 DATA D:WSKAZNIK.OBJ
1040 DATA D:PLAYER2.0BJ
1050 DATA D:DLI2.0BJ
1060 DATA D:SKOCZEK.OBJ
1070 DATA D:BARY.OBJ
1080 DATA D:OBRAZEK.DAT
1090 DATA D:RUN.OBJ


Tomasz Bielak
Rafał Bielecki



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

Pixel 2002