Piszemy DEMOW poprzednim artykule, zakończyliśmy część teoretyczną naszego cyklu. W tym i kolejnych artykułach zamieścimy procedury przykładowej, trzyczęściowej demonstracji. Większość z nich będzie przygotowywana w dwóch wersjach: wersja przeznaczona do samodzielnego uruchomienia spod QA oraz wersja kompilowana na dysk, będąca częścią demonstracji. Przestrzegamy przed wprowadzaniem zmian w początkowych adresach procedur i w adresach komórek na stronie zerowej, gdyż wszystkie procedury powiązane są ze sobą i nierozsądne zmiany tego typu mogą prowadzić do błędnego działania demonstracji. W szczególności zalecamy dokładne przepisywanie (bez zmian) procedur kompilowanych na dysk oraz zapisywanie ich pod nazwami proponowanymi przez nas. W pierwszej części dema będzie: na górze ekranu - napis "Tajemnice Atari" odbity w lustrze, z lewej i z prawej strony tego napisu - dwa obracające się firmowe znaczki Atari; w środku ekranu - poruszający się obrazek, otoczony z czterech stron płynącymi napisami. Natomiast na dole ekranu - przepływający tekst o znakach wysokich na 64 fizyczne linie ekranu. Na tym tekście, w prawym dolnym rogu ekranu - wskaźniki poziomu głośności poszczególnych kanałów dźwiękowych. Przez cały czas działania demonstracji komputer będzie odgrywał muzykę. Programowanie pierwszej części zaczniemy od organizacji ekranu, czyli ułożenia programu dla ANTIC'a:
Procedure Equ $9800
List_mem Equ %00000110
List_err Equ %00000101
Code_mem Equ %00010000
Code_dsk Equ %00100000
Dlptrs Equ $0230
Obrazek Equ $8000
Scroll Equ $7000
Scrol2 Equ $6600
Opt List_err+Code_mem
Org Procedure
Ldx <Dlist
Ldy >Dlist
Stx Dlptrs
Sty Dlptrs+$01
Rts
Text Dta D' TAJEMNICE ATARI '
Dlist Dta B($F0),B($70)
Dta B($57)
Dta A(Text)
Dta B($00)
Dta B($56)
Dta A(Text)
Dta B($F0)
Dta B($52)
Dta A(Scroll)
Dta B($F0)
Dta B($5E)
Dta A(Obrazek)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($1E),B($1E),B($1E)
Dta B($F0)
Dta B($52)
Dta A(Scroll)
Dta B($E0)
Dta B($00)
Dta B($54),A(Scrol2)
Dta B($54),A(Scrol2+$38)
Dta B($54),A(Scrol2+$70)
Dta B($54),A(Scrol2+$A8)
Dta B($54),A(Scrol2+$E0)
Dta B($54),A(Scrol2+$118)
Dta B($54),A(Scrol2+$150)
Dta B($54),A(Scrol2+$188)
Dta B($41)
Dta A(Dlist)
End of file
Pierwszy rozkaz ANTIC'a uaktywnia pierwsze przerwanie Display List (i zarazem tworzy 8 pustych linii). W trakcie tworzenia
ekranu przerwanie to wywoływane jest aż pięć razy. Ustawia ono
kolory i pozycje obiektów oraz niektóre rejestry sprzętowe (np.
HScrol). Dokładny opis poszczególnych wywołań tego przerwania
zamieścimy w jednym z następnych odcinków. Kolejny rozkaz to
następne osiem pustych linii, po których tworzone są dwie linie
trybów tekstowych ANTIC'a (oddzielone jedną pustą linią). Jedna
w trybie $07, druga - w $06. W nich umieszczony jest tekst "Tajemnice Atari". Dodatkowo ustawiony bit 4 (HSC) w rozkazach ANTIC'a umożliwia ustawienie na środku tego tekstu. Po kolejnych
ośmiu pustych liniach ANTIC tworzy linię trybu $02, w której będzie płynął napis. Następna grupa rozkazów umożliwia pokazanie obrazka oddzielonego od płynącego napisu ośmioma pustymi
liniami i identycznej linii z płynącym napisem, kak powyżej. Ostatnia grupa rozkazów to rozkazy tworzące osiem linii trybu $04, po
których będzie przesuwał się "duży" tekst. Ostatni rozkaz to zakończenie programu ANTICa.Jak wynika z deklaracji etykiet, obrazek umieszczony będzie w pamięci od adresu $8000, tekst do dwóch małych płynących napisów - od adresu $7000, a pamięć ekranu dla dużego płynącego napisu - od adresu $6600. Powyższa procedura nadaje się zarówno do uruchomienia, jak i do ostatecznego skompilowania na dysk. Proponujemy zapisać ją pod nazwą "DLI.ASM". Drugą istotną procedurą do pierwszej części jest "PLAYER.ASM", uaktywniająca grafikę PMG:
Procedure Equ $9B5B
List_mem Equ %00000110
List_err Equ %00000101
Code_mem Equ %00010000
Code_dsk Equ %00100000
Dmactls Equ $022F
Gtictls Equ $026F
Pmcntl Equ $D01D
Pmbase Equ $D407
Sizep0 Equ $D008
Sizep2 Equ $D00A
Start_pl Equ $9000
Opt List_err+Code_dsk
Org Procedure
Jmp Init_pl
IntProc Ldx #$00
L0 Lda Dane_pl,x
Sta Start_pl+$416,x
Sta Start_pl+$616,x
Inx
Cpx #$10
Bne L0
L1 Lda Dane_pl,x
Sta Start_pl+$506,x
Sta Start_pl+$706,x
Inx
Cpx #$20
Bne L1
Clc
Lda L0+$01
Adc #$20
Sta L0+$01
Sta L1+$01
Lda L0+$02
Adc #$00
Sta L0+$02
Sta L1+$02
Inc Licznik
Lda Licznik
Cmp #$0A
Bne Koniec
Ldx #$00
Stx Licznik
Ldx <Dane_pl
Ldy >Dane_pl
Stx L0+$01
Stx L1+$01
Sty L0+$02
Sty L1+$02
Koniec Rts
Init_pl Ldy #$07
L2 Ldx #$00
Txa
L3 Sta Start_pl,x
Inx
Bne L3
Inc L3+$02
Dey
Bpl L2
Ldx #$07
L4 Lda Dane_2,x
Sta Start_pl+$539,x
Sta Start_pl+$59A,x
Lda Dane_3,x
Sta Start_pl+$739,x
Sta Start_pl+$79A,x
Dex
Bpl L4
Ldx >Start_pl
Stx Pmbase
Ldx #$3E
Stx Dmactls
Ldx #$01
Stx Gtictls
Ldx #$00
Stx Sizep0
Stx Sizep2
Ldx #$03
Stx Pmcntl
Cdtma2 Equ $0228
Cdtmv2 Equ $021A
Colpm0s Equ $02C0
Hposp0 Equ $D000
Hposp1 Equ $D001
Hposp2 Equ $D002
Hposp3 Equ $D003
Lda #$3D
Sta Dmactl
Lda #$30
Sta Hposp0
Lda #$38
Sta Hposp1
Lda #$C0
Sta Hposp2
Lda #$C8
Sta Hposp3
Ldx #$03
Lda #$0F
L5 Sta Colpm0s,x
Dex
Bpl L5
Ldx <Timer2
Ldy >Timer2
Stx Cdtma2
Sty Cdtma2+$01
End Lda #$02
Sta Cdtmv2
Rts
Timer2 Jsr IntProc
Jmp End
Licznik Dta B($00)
Dane_pl Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($1D)
Dta B($19),B($39),B($F1)
Dta B($E1),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B8),B($98),B($9C)
Dta B($8F),B($87),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($1D),B($19)
Dta B($39),B($71),B($61)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B8)
Dta B($98),B($9C),B($8E)
Dta B($86),B($06),B($06)
Dta B($06),B($06),B($06)
Dta B($06),B($06),B($06)
Dta B($06),B($06),B($06)
Dta B($0E),B($0C),B($1C)
Dta B($38),B($30),B($E0)
Dta B($E0),B($E0),B($E0)
Dta B($E0),B($E0),B($E0)
Dta B($E0),B($E0),B($E0)
Dta B($E0),B($F0),B($B0)
Dta B($B8),B($9C),B($8C)
Dta B($06),B($06),B($06)
Dta B($06),B($06),B($06)
Dta B($06),B($06),B($06)
Dta B($06),B($06),B($0E)
Dta B($0C),B($0C),B($0C)
Dta B($1C),B($E0),B($E0)
Dta B($E0),B($E0),B($E0)
Dta B($E0),B($E0),B($E0)
Dta B($E0),B($E0),B($E0)
Dta B($F0),B($B0),B($B0)
Dta B($B0),B($B8),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($03),B($03)
Dta B($03),B($03),B($07)
Dta B($C0),B($C0),B($C0)
Dta B($C0),B($C0),B($C0)
Dta B($C0),B($C0),B($C0)
Dta B($C0),B($C0),B($E0)
Dta B($60),B($60),B($60)
Dta B($70),B($01),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($01),B($01)
Dta B($01),B($01),B($80)
Dta B($80),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($03),B($03),B($03)
Dta B($03),B($03),B($03)
Dta B($03),B($03),B($03)
Dta B($03),B($03),B($07)
Dta B($06),B($06),B($06)
Dta B($0E),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($80),B($80),B($80)
Dta B($C0),B($C0),B($C0)
Dta B($C0),B($E0),B($07)
Dta B($07),B($07),B($07)
Dta B($07),B($07),B($07)
Dta B($07),B($07),B($07)
Dta B($07),B($0F),B($0D)
Dta B($0D),B($0D),B($1D)
Dta B($60),B($60),B($60)
Dta B($60),B($60),B($60)
Dta B($60),B($60),B($60)
Dta B($60),B($60),B($70)
Dta B($30),B($30),B($30)
Dta B($38),B($07),B($07)
Dta B($07),B($07),B($07)
Dta B($07),B($07),B($07)
Dta B($07),B($07),B($07)
Dta B($0F),B($0D),B($1D)
Dta B($39),B($31),B($60)
Dta B($60),B($60),B($60)
Dta B($60),B($60),B($60)
Dta B($60),B($60),B($60)
Dta B($60),B($70),B($30)
Dta B($38),B($1C),B($0C)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($0D)
Dta B($0D),B($0D),B($1D)
Dta B($19),B($39),B($71)
Dta B($61),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B0),B($B0),B($B0)
Dta B($B8),B($98),B($9C)
Dta B($8E),B($86)
Dane_2 Dta B($FF),B($FE),B($FC)
Dta B($F8),B($F0),B($E0)
Dta B($C0) B($80)
Dane_3 Dta B($01),B($03),B($07)
Dta B($0F),B($1F),B($3F)
Dta B($7F),B($FF)
End of file
Procedura czyści obszar pamięci PMG, następnie tablice Dane_2
i Dane_3 przepisuje w odpowiednie miejsca pamięci. Są to ozdobne
początki i zakończenia małych płynących napisów. Następnie inicjalizowana jest grafika PMG i ustawiany wektor przerwania Timer 2 na
procedurę IntProc.Każdy ze znaczków Atari złożony jest z dwóch graczy PMG. Procedura przerwania IntProc, za każdym wywołaniem, przepisuje inną fazę obrotu znaczków Atari z tablicy Dane_pl. Jedna faza zajmuje $20 bajtów, po $10 bajtów na każdego gracza. Po przepisaniu program modyftkuje sam siebie, tak aby przy następnym obiegu przerwania przepisywać z innego miejsca tablicy Dane_pl. Faz jest dziesięć. Program przystosowany jest do samodzielnego uruchomienia. Aby utworzyć wersję, którą następnie skompilujemy na dysk należy wyrzucić fragment programu rozpoczynający się od etykiety Cdtma2 do rozkazu Jmp End włącznie. Ciąg dalszy w następnym numerze Tajemnic Atari. Tomasz Bielak
Rafał Bielecki |