Tajemnice ATARI

PISZEMY DEMO

Przerwanie Display List

    W tym artykule postaramy się wyjaśnić znaczenie bitu siódmego w rozkazie programu ANTIC'a. Ustawienie tego bitu powoduje wykonanie procedury przerwania Display List. Wektor Dliv ($200 - 512) wskazuje na tą procedurę. Ponieważ przerwanie Display List należy do przerwań typu NMI (Non Maskable Interrupt - przerwanie niemaskowalne, czyli takie, które nie może być zignorowane przez CPU - musi być wykonane) konieczne jest ustawienie 617 bitu w rejestrze Nmien ($D40E - 54286), czyli zezwolenie na wykonanie przerwań NMI. Procedura przerwania Display List musi kończyć się rozkazem RTI procesora. W procedurze mogą być wykorzystywane wszystkie rejestry procesora, lecz ich wartości muszą być takie same przed wywołaniem jak i po jej wykonaniu. W tym celu wartości modyfikowanych rejestrów należy przechować w konkretnych komórkach pamięci, a jeszcze lepiej - odłożyć na stos (nie zapominając o ściągnięciu ich przed wyjściem z procedury. Spójrzmy na następujący przykład:
Program  Equ $8800
List_mem Equ %00000110
List_err Equ %00000101
Code_mem Equ %00010000
Code_dsk Equ %00100000

Dliv     Equ $200
Dlptrs   Equ $230
Colpf2   Equ $D018
Wsync    Equ $D40A
Nmien    Equ $D40E

Pom      Equ $F0

       Opt List_err+Code_mem
         Org Program
         Lda Dlptrs
         Sta Pom
         Lda Dlptrs+1
         Sta Pom+1
         Lda Dliv
         Pha
         Lda Dliv+l
         Pha
         Ldy #$10
         Lda (Pom),y
         Ora #$80
         Sta (Pom),y
         Lda Przerw
         Sta Dliv+l
         Lda #$C0
         Sta Nmien
         Jsr Klawisz
         Lda #$0
         Sta Nmien
         Sei
         Pla
         Sta Dliv+l
         Pla
         Sta Dliv
         Lda #$FF
         Sta Nmien
         Cli
         Rts

Przerw   Pha
         Lda #$06
         Sta Wsync
         Sta Colpf2
         Pla
         Rti

         End of File
   (do programu należy dołączyć procedurę klawisz z pierwszego artykułu).

    Na początku robimy kopię wektora Dlptrs na stronie zerowej (etykieta Pom) aby po odłożeniu wektora przerwania Dliv na stos ustawić siódmy bit w 16 rozkazie programu ANTIC'a przy pomocy adresowania pośredniego Y. Następnie ustawiamy wektor Dliv na adres naszej procedury przerwania (etykieta Przerw), po czym zezwalamy na wykonanie przerwania NMI (wartość $C0 wpisywana do Nmien). Wykonując procedurę klawisz, komputer oczekuje na naciśnięcie klawisza. W tym czasie możemy oglądać efekt działania procedury przerwania. W procedurze wykorzystywany jest akumulator, dlatego odkładamy go na stos. W trakcie działania przerwania wpisywana jest tylko wartość $06 do rejestrów Wsync i Colpf2.

Co nieco o kolorach

   Rejestr Colpf2 jest jednym z dziewięciu rejestrów kolorów. ANTIC tworzy strukturę obrazu, natomiast kolory dostarcza GTIA. Ponieważ w tym artykule zajmujemy się przerwaniem Display List, z którym (przeważnie) łączy się zmiana kolorów, dlatego jesteśmy zmuszeni zająć się po części tym tematem. Jak wspomnieliśmy wyżej istnieje dziewięć rejestrów kolorów, znajdujących się w obszarze pamięci od $D012-$D01A (53266-53274). Każdy rejestr posiada swój cień. Rejestry cienie (Shadow Registers) kolorów umieszczone są w pamięci od adresu $2C0-$2C8 (704-712). W komputerach ATARI większość rejestrów wykorzystywanych przez specjalizowane układy komputera (rejestry sprzętowe) posiada kopie w normalnych komórkach RAM (rejestry cienie). Zawartość cieni przepisywana jest do rejestrów sprzętowych podczas przerwania VBLK, czyli inaczej mówiąc po utworzeniu całego obrazu (co 1/50 sekundy). UWAGA: Rejestry sprzętowe kolorów przeznaczone są tylko do zapisu. Odczytywane z nich wartości nie są zgodne z zapisywanymi. Każdy z rejestrów kolorów ma taką samą strukturę, tzn. cztery najstarsze bity określają kolor, a pozostałe stopień jasności koloru. W ten sposób wybieramy z 256 barw, czyli z całej palety ATARI. Poniższa tabela zestawia wszystkie dostępne kolory:

kod kolor
$0x szary
$1x złoty
$2x pomarańczowy
$3x czerwony
$4x różowy
$5x purpurowy
$6x fioletowy
$7x zimny niebieski
$8x niebieski
$9x błękitny
$Ax turkusowy
$Bx niebiesko-zielony
$Cx zielony
$Dx żółto-zielony
$Ex pomarańczowo-zielony
$Fx żółty

    Więcej szczegółów na temat kolorów podamy przy opisie funkcji i rejestrów GTIA. Do analizy procedury naszego przerwania wystarczy nam informacja, że rejestr Colpf2 w trybie ANTIC'a 2 określa kolor tła. Wróćmy do naszego przykładu. Jak już wspomnieliśmy w trakcie przerwania VBLK rejestr sprzętowy Colpf2 otrzymuje wartość cienia Colpf2S. Rozpoczyna się tworzenie obrazu. Wartość koloru kolejnych linii pobierana jest z rejestru sprzętowego. Po wykonaniu 16 rozkazu ANTIC'a, czyli po wyświetleniu 12 linii procedura przerwania Display List modyfikuje rejestr sprzętowy. Oznacza to, że reszta linii wyświetlana będzie w innym kolorze, po czym cały cykl wyświetlania obrazu zaczyna się od początku. Zauważmy, że 7 bit ustawiony jest w 16 rozkazie programu ANTIC"a tworzącym 11 linię. Oznacza to, że przerwanie wykonywane jest po wyświetleniu tej linii (na początku linii 12).

Rola rejestru Wsync

   A jaką rolę odgrywa Wsync? Procesor ATARI jest na tyle szybki, że w momencie zmiany rejestru sprzętowego wiązka elektronów tworzących pojedynczą linię obrazu może znaleźć się w środku tej linii (gdyby nie był tak szybki, to też by mogła - przyp. red.). W takim przypadku kolor zmieniany jest od tego miejsca. Jeśli natomiast do rejestru Wsync (Wait for Synchronization - $D40A - 54282) wpiszemy dowolną wartość, to wykonanie programu zostanie wstrzymane do najbliższej synchronizacji poziomej, czyli do momentu kiedy wiązka elektronów nie wyświetli całej linii. Dzięki temu zmiana koloru następuje w kolejnej fizycznej linii ekranu.

    Przerwanie Display List w przykładach

   Na koniec popatrzmy na dwa przykłady programów.

    Program pierwszy:
Program  Equ $8800

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

Dliv     Equ $200 
Dlptrs   Equ $230 
Colpf2   Equ $D018 
Wsync    Equ $D40A 
Nmien    Equ $D40E

Pom      Equ $F0
         
       Opt List_err+Code_mem
         Org Program

         Lda Dlptrs
         Sta Pom
         Lda Dlptrs+1
         Sta Pom+1
         Lda Dliv
         Pha
         Lda Dliv+l
         Pha
         Ldy #$0A
         Lda (Pom),y
         Ora #$80
         Sta (Pom),y
         Lda Przerw
         Sta Dliv+l
         Lda #$C0
         Sta Nmien
         Jsr Klawisz
         Lda #$0
         Sta Nmien
         Sei
         Pla
         Sta Dliv+l
         Pla
         Sta Dliv
         Lda #$FF
         Sta Nmien
         Cli
         Rts

Przerw   Pha
         Txa
         Pha
         Lda #$22 
         Ldx #$10
L1       Sta Wsync
         Sta Colpf2
         Dex
         Bne L1
         Lda #$2A
         Sta Wsync
         Sta Colpf2
         Pla
         Tax
         Pla
         Rti

         End of File
   Program drugi:
Program  Equ $8800

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

Dliv     Equ $200 
Dlptrs   Equ $230 
Colpf2   Equ $D018 
Wsync    Equ $D40A 
Nmien    Equ $D40E

Pom      Equ $F0
Kolor    Equ $F2

       Opt List_err+Code_mem
         Org Program

         Lda #$2A
         Sta Kolor
         Lda Dlptrs
         Sta Pom
         Lda Dlptrs+1
         Sta Pom+1
         Lda Dliv
         Pha
         Lda Dliv+l
         Pha
         Ldy #$0A
         Lda (Pom),y
         Ora #$80
         Sta (Pom),y
         Ldy #$0C
         Sta (Pom),y
         Lda Przerw
         Sta Dliv+l
         Lda #$C0
         Sta Nmien
         Jsr Klawisz
         Lda #$0
         Sta Nmien
         Sei
         Pla
         Sta Dliv+l
         Pla
         Sta Dliv
         Lda #$FF
         Sta Nmien
         Cli
         Rts

Przerw   Pha
         Lda Kolor
         Eor #$08
         Sta Kolor
         Sta Wsync
         Sta Colpf2
         Pla
         Rti
 
         End of File
   Oba wykorzystują przerwanie Display List i oba realizują to samo mimo różnych algorytmów. Zadaniem obu programów jest zmiana koloru tła ekranu w dwóch jego miejscach. Zasadnicza różnica polega na tym, że program pierwszy wywołuje raz przerwanie Display List w trakcie wyświetlania natomiast program drugi robi to dwukrotnie. W programie pierwszym po wywołaniu procedury przerwania (etykieta Przerw) do akumulatora wpisywana jest wartość pierwszego koloru. Następnie w pętli wywoływanej 16 razy zawartość akumulatora zostaje wpisana do rejestru Colpf2 (modyfikacja koloru tła) i Wsync (znaczenie tej operacji opisaliśmy powyżej). Po 16 przebiegu pętli modyfikujemy na nowo oba te rejestry (wpisując wartość $2A). Efekt zmiany kolorów realizowany przez program pierwszy można zaprogramować o wiele prościej, wykorzystując dodatkową komórkę pamięci. Metoda ta została przedstawiona w programie drugim. Dodatkowa komórka (etykieta Kolor) zastosowana jest po to, aby przechowywać aktualną wartość wyświetlanego koloru. Przed uruchomieniem przerwania komórka ta otrzymuje wartość $2A. Dwukrotne wywołanie procedury przerwania Display List (etykieta Przerw) jest możliwe dzięki ustawieniu 7 bitu w dwóch rozkazach programu ANTIC'a. Przy pierwszym wywołaniu procedury, dzięki zastosowaniu instrukcji logicznej EOR "Kolor" otrzyma wartość $22, przepisywaną do rejestru Colpf2 (pierwsza modyfikacja koloru tła). Przy wywołaniu drugim "Kolor" otrzyma ponownie wartość $2A (druga modyfikacja koloru tła). UWAGA: Rozwiązanie drugie jest lepsze, gdyż stosowanie pętli wewnątrz procedury Display List opóźnia pracę programu wykonywanego bezpośrednio przez procesor.

    Kolejny odcinek cyklu poświęcimy ciekawszym przykładom wykorzystania przerwania Display List.


Tomasz Bielak
Rafał Bielecki



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

Pixel 2002