Rzecz o Magii 4352 Kolorów

Żyj kolorowo, czyli...4352 kolorów na ekranie ATARI XL/XE!

Głównym powodem do dumy "małych" atarowców jest liczba kolorów, jakie może uzyskać ich komputerek, gdyż Atari XL/XE używa palety 256 kolorów (szesnaście barw i tyle samo odcieni). Jest to zarówno dużo i mało. Dużo w porównaniu z innymi komputerami 8-bitowymi, a mało gdyż oczywiście chciałoby się więcej.

Większą ilość kolorów w linii można łatwo uzyskać, włączając tryby 9, 10 i 11 BASIC-a. Wszystkie one używają komórki GTIACTL, której bity 6 i 7 sterują dodatkowymi trybami graficznymi GTIA (uwaga! Tryby te nie działają na archaicznych modelach Atari, gdyż dawniej w Atari umieszczano kość CTIA, która nie rozpoznaje tych trybów). Tryb 9 pozwala na uzyskanie 16 jasności koloru tła, 11 umożliwia wyświetlenie 16 kolorów o jasności tła, a tryb 10 dziewięciu kolorów ze 128-barwnej palety. Na tym kończą się możliwości systemu Atari. Owszem, można ozdobić jeszcze ekran duszkami, lecz efekty dalej będą niezadowalające. Siła grafiki Atari kryje się bowiem w przerwaniach. Można wyświetlać na przemian linie w trybach 9 i 11, da to złudzenie prawdziwego 256-kolorowego obrazu, dodatkowo warto co 1/50 sekundy "trząść" obrazem. Efekt taki został użyty w demie "Amiga Pictures" i w programie graficznym "Digi Paint". Pora na mądrą nazwę takiego oszustwa, a zowie się to INTERLACE. Jak poznać, że nasze oko jest oszukiwane zmianami obrazu 50 razy na sekundę? Po pierwsze, mimo tak dużej częstotliwości, wprawny obserwator wyczuje migotanie, a jeśli nie, to radzę rytmicznie poruszać głową góra-dół lub lewo-prawo. Gdy zobaczysz płynące linie, możesz być pewien, że interlace jest aktywny. Powyższą metodę radzę szybko zastosować na najbliższej Amidze (AleMIGA co?).

Wszystko czego dowiedziałeś się dotychczas z tego artykułu, Drogi Czytelniku, traktuje właściwie o standardowej ilości kolorów. Pora pomęczyć trochę staruszka Atari, więc do roboty! Odpal "Quick Assemblera"! Jeśli jesteś jednak miłośnikiem innego asemblera, np. "MAC/65", to będziesz musiał zmienić "opt 21" na ".opt obj", "org" na "*=", wszystkie "equ" na "=", przed znakami "<" i ">" dodać "#", a "dta b()" zamienić na ".byte" oraz oczywiście numerować linie. Radzę pozostać jednak przy "QA", bo choć jest może słabszy, to niewątpliwie wygodniejszy.

Rozpoczynamy więc historię 4352 kolorów. Niewątpliwie dziwi Cię ta liczba: dlaczego tyle? To proste: postanowiłem uzyskać 32 odcienie 136 kolorów. Brzmi dumnie co? Dobra! Koniec marudzenia, najpierw początek programu i trochę danych:

    ******************
    * '4352 COLORS!' *
    *  done by RZoG  *
    *   of SLIGHT!   *
    ******************

          opt 21

          org $8800

    main  lda #0
          sta $22f
          jsr dlmak
          jsr tamak
          jsr on_it
          jmp loop

    hscr  dta b(0)
    pom1  dta b($f)
    pom2  dta b(0)

    line  dta b(0),b(0),b(0),b(0),b(0)
          dta b($11),b($22),b($33),b($44)
          dta b($55),b($66),b($77),b($88)
          dta b($99),b($aa),b($bb),b($cc)
          dta b($dd),b($ee),b($ff),b($fe)
          dta b($ed),b($dc),b($cb),b($ba)
          dta b($a9),b($98),b($87),b($76)
          dta b($65),b($54),b($43),b($32)
          dta b($21),b($10),b(0),b(0)

    dl    equ $9000
    tab1  equ $9200
    tab2  equ $9300
    dan   equ $9400

Jest to sam szkielet programu. Zawiera wywołania procedur, linię danych oraz rezerwuje miejsce w pamięci na ekran i niezbędne do pracy tablice. Uruchomianie tylko tej części nie da oczywiście żadnych efektów poza komunikatami o błędach.

Jako pierwszą wywołamy procedurę tworzącą ekran ("dlmak").

    dlmak ldy #0
          ldx #6
          lda #$70
    dma1  jsr dma3
          dex
          bne dma1
          ldx #136
    dma2  lda #$5f
          jsr dma3
          lda <line
          jsr dma3
          lda >line
          jsr dma3
          dex
          bne dma2
          lda #$41
          jsr dma3
          lda <dl
          jsr dma3
          lda >dl
    dma3  sta dl,y
          iny
          bne dma4
          inc dma3+2
    dma4  rts

Najpierw tworzonych jest 48 pustych linii, tak by efekt był na środku ekanu. Następnie w pętli "dma2" tworzy się 136 linii z włączonym przesuwem poziomym. Na dokładkę ustawiany jest koniec programu ANTIC-a i całość kończy się sympatycznym rts. Oczywiście zamiast tej krótkiej procedury mogłem umieścić cały program dla ANTIC-a w wierszach "dta".

Ekran już jest, teraz będą potrzebne dwie tablice kolorów (wyświetlane na przemian), co pozwoli uzyskać z 16 barw magiczną liczbę ich ilości, czyli 136.

    tamak lda #0
          tay
    tam1  sta dan,y
          iny
          adc #$10
          bne tam1
          ldx #0
    tam2  lda pom1
          sta pom2
    tam3  ldy pom2
          lda dan,y
          sta tab1,x
          ldy pom1
          lda dan,y
          sta tab2,x
          inx
          dec pom2
          bpl tam3
          dec pom1
          bpl tam2

W tym (jak i w innych) miejscu programu możesz wysilić się i poprawić mój celowo nieco toporny algorytm. W pętli "tam1" tworzona jest szesnastobajtowa tablica pomocnicza. Następna pętla tworzy pierwszą główną tablicę (15, potem 14, 13 itd. ciągów liczb zmniejszających się o 16 ($10)), jako trzecia tworzona jest podobna, lecz zawierająca, po kolei: 15, 14, ... wartości takich samych. Tak zbudowane tablice pozwalają uzyskać wyżej wspomniane 136 kolorów z kombinacji szesnastu barw, zgodnie z prawami kombinatoryki. Dla jasności: dlaczego nie 256 przypominam, że nałożenie niebieskiego i żółtego daje zielony, tak jak i nałożenie żółtego na niebieski.

Następnie trzeba ustawić pewne komórki w pamięci komputera. $230 to adres programu ANTIC-a, $22f jego szerokość i cechy specjalne. Ustawienie reszty powoduje wyświetlanie tzw. sprite'ów bez sprite'ów, czyli pionowych pasów (które w tym przypadku zasłaniają nie używane (lewą i prawą) części ekranu) oraz ustalenie kolorów ekranu.

    on_it lda <dl
          sta $230
          lda >dl
          sta $231

          lda #$21
          sta $22f

          lda #$ff
          sta $d00d
          sta $d00e

          lda #3
          sta $d008
          sta $d009

          lda #$0
          sta $2c0
          sta $2c1
          sta $2c8

          lda #34
          sta $d000
          lda #190
          sta $d001

          rts

Myślę, że nie muszę tłumaczyć, jaka komórka odpowiada za co i dlaczego tak, a nie inaczej. W przypadku wątpliwości zajrzyj do mapy pamięci ATARI XL/XE, sam popróbuj zmieniać wartości lub napisz do redakcji "Barymaga", jeśli będziesz miał jakiś konkretny problem.

Nadszedł już czas na ujawnienie najważniejszej części programu, czyli jego głównej pętli. Ci, którzy potrafią mogą umieścić ją na przerwaniu Display Listu (adres w komórce $200), lecz do naszych celów wystarczy oczekiwanie aż ANTIC zacznie tworzyć linię 54. W komórkę $d01b, czyli wspomnianym już wcześniej rejestrze GTIACTL ustawiamy bity tak, by uaktywnić dziewiąty tryb graficzny BASIC-a. Następnie, kolejno liczby z tablicy pierwszej przepisywane są do rejestru tła wraz z opóźnieniem do kolejnej linii (sta $d40a). Powyższa operacja zmienia kolor każdej kolejnej linii. W dalszej części do rejestru Hscrol ($d404), odpowiadającego za przesuw poziomy wpisywane są na przemian zero i dwójka, rozkaz różnicy logicznej (EOR) pozwala na wydatne skrócenie programu. Następnie zwiększany jest rejestr X i gdy osiągnie on wartość 136 oznacza to, że tablice (jak również ekran) skończyły się. Potem tło uzyskuje kolor czarny, program modyfikuje swoją część tak, aby używana była druga tablica i powtarzany jest trick z wartością przesuwu poziomego, by wychylenia linii zmieniały się. Na końcu sprawdzam czy nie jest naciśnięty klawisz "Shift", jeśli nie - wywołuję skok z powrotem do pętli głównej. Wszystkie instrukcje EOR pozwalają wydatnie zmniejszyć długość programu.

    loop  lda #27
    lo1   cmp $d40b
          bne lo1

          lda #$40
          sta $d01b
          sta $d40a

          ldx #0
    lo2   lda tab1,x
          sta $d40a
          sta $d01a

          lda hscr
          eor #2
          sta hscr
          sta $d404

          inx
          cpx #136
          bne lo2

          lda #$0
          sta $d40a
          sta $d01a

          lda lo2+2
          eor #1
          sta lo2+2

          lda hscr
          eor #2
          sta hscr

          lda $d20f
          and #$8
          bne loop

    exit  lda #0
          sta $d000
          sta $d001
          rts

          end

Po wpisaniu całego programu wreszcie możesz go zasemblować i uruchomić. Na ekranie powinno pokazać się 4352 kolorów. Obraz trochę miga, ale można to nieco zniwelować poprzez dodanie do pętli głównej (po rozkazie sta $d404) sekwencji:

          lda lo2+2
          eor #1
          sta lo2+2

Powoduje to zmianę tablicy, z której pobierane są kolory co linię, a nie jak miało to miejsce w poprzedniej wersji (raz na ramkę). Ma to również pewien efekt uboczny. Choć liczba kolorów nie zmieniła się i jest nadal ich 4352, to barwy są jakby bledsze. Efekt ten prawdopodobnie nie występuje w monitorach wyższej klasy, lecz zawsze można przecież podkręcić kontrast. Więcej kolorów da się uzyskać zwiększając ilość faz ekranowych, lecz taki zabieg spowoduje większe migotanie.

Wielu przyjemnych eksperymentów z grafiką "małego" Atari życzy
RZÓG

Nota redakcyjna: Na dysku z magazynem nagrane są programy pomocnicze do powyższego artykułu. Więcej szczegółów możecie znaleźć w artykule "Zawartość dysku".

- P.W. -