MAPA PAMIĘCI
W systemie operacyjnym komputerów ATARI XL/XE istnieje osiem kanałów wejścia/wyjścia, stanowiących swoisty pomost pomiędzy programami aplikacyjnymi (czyli - najogólniej mówiąc - tymi, które odczytujemy z dysku lub kasety przy pomocy DOS-a albo COS-a), a urządzeniami zewnętrznymi. Dzięki nim, pisząc program nie musimy martwić się specyficznymi cechami np. stacji dysków, czy też drukarki - wystarczy poinformować OS, że mamy ochotę wymienić informacje z dowolnym z peryferiów, a on już zajmie się organizacją naszej współpracy. Kanały wejścia/wyjścia zostaną opisane w jednym z najbliższych odcinków tego cyklu, teraz natomiast chciałbym powiedzieć kilka słów o jednym z urządzeń zewnętrznych, które większości z nas wydaje się integralną częścią komputera. Tym urządzeniem jest ekran, określany często angielskim słowem screen, od którego pochodzi jego symboliczna, używana przez system, nazwa "S:". Wbrew pozorom nie jest to pomyłka - ekran traktowany jest w przypadku małego ATARI jak urządzenie peryferyjne i cała współpraca z nim organizowana jest tak, jak z każdym innym urządzeniem. Tu mała uwaga: pod pojęciem ekran rozumiem w tym wypadku ekran graficzny, ponieważ ekran tekstowy to już zupełnie inne urządzenie.
Chyba każdy z użytkowników ATARI XL/XE widział, jak na ekranie wyświetlany jest jednocześnie tekst i grafika. W takim przypadku system operacyjny uruchamia jakby dwa niezależne tory myślenia - jeden związany z urządzeniem "S:" (grafika w górnej części ekranu), a drugi z urządzeniem "E:" (tekst w dole ekranu; nazwa urządzenia pochodzi od angielskiego słowa editor, które w tym przypadku bardzo trudno ładnie przetłumaczyć na język polski). Cztery wiersze tekstu w dolnej części ekranu stanowią tak zwane okienko tekstowe, które używa stu sześćdziesięciu bajtów pamięci operacyjnej poniżej tzw. RAMTOP-u (patrz opis komórki 106, czyli $6a). Obydwa obszary mają niezależne kursory (w przypadku części graficznej kursor jest umowny, bo przecież nie widać go na obrazku tak, jak w tekście) i kilka innych, specyficznych dla nich cech. Wiele informacji o stanie poszczególnych składowych wyświetlanego obrazu jest przechowywanych w komórkach 656-703 ($0290-$02bf), które chciałbym w tej chwili opisać.
Numer wiersza, w którym znajduje się kursor. Dotyczy to okienka tekstowego, a więc możemy tu znaleźć wartości od 0 do 3.
657, 658, |
$0291, $0292 |
TXTCOL |
Numer kolumny, w której znajduje się kursor. Dotyczy to okienka tekstowego, a więc możemy tu znaleźć
wartości od 0 do 39. Wynika z tego, że starszy bajt numeru kolumny jest zawsze równy 0.
Ta komórka zawiera tryb graficzny okienka tekstowego. Jest to odpowiednik komórki DINDEX (patrz 87, $57) i dopóki SWPFLG (patrz 123, $7b) zawiera zero, tutaj także możemy znaleźć zero. Oznacza to, że okienko tekstowe jest inicjowane w trybie graficznym 0.
660, 661, |
$0294, $0295 |
TXTMSC |
Adres początku pamięci dla okna tekstowego. Jest to odpowiednik SAVMSC (patrz 88, 89, $58, $59) dla trybu z okienkiem tekstowym.
662-667, |
$0296-$029B |
TXTOLD |
W tym obszarze znajdują się odpowiedniki komórek OLDROW (90. $5a), OLDCOL (91, 92, $5b, $5c), OLDCHR (93, $5d) i OLDADR (94, 950 $5e, $50 używane przez system operacyjny wtedy, gdy na ekranie wyświetlany jest jednocześnie tekst i grafika.
Rejestr pomocniczy używany przez procedury obsługujące ekran podczas przesuwania jego zawartości.
Rejestr pomocniczy.
Rejestr pomocniczy.
Rejestr pomocniczy.
W tej komórce system operacyjny przechowuje tzw. maskę dla piksela, którego dotyczy aktualnie wykonywana operacja. W zależności od trybu graficznego. Jeden bajt pamięci ekranu reprezentuje od jednego do ośmiu pikseli. Chcąc wykonać na ekranie jakąkolwiek operację (np. narysowanie punktu), OS musi wiedzieć nie tylko, który bajt ma zostać zmodyfikowany, ale także, której części bajtu ma dotyczyć operacja. Weźmy na przykład tryb graficzny, w którym jeden piksel ma szerokość jednego cyklu koloru. Oznacza to, że do zapisania jednego piksela potrzeba dwóch bitów, w związku z czym w jednym bajcie mieszczą się informacje o czterech pikselach. Ponieważ system operacyjny w danej chwili dokonuje jakichś operacji tylko na jednym punkcie ekranu, to musi wyraźnie sprecyzować, o który punkt (w tym wypadku dwa bity) w bajcie mu chodzi. Robi to przy pomocy maski, czyli bajtu, w którym ustawione są bity, odpowiadające odpowiedniemu pikselowi. Być może brzmi to dość zawile, lecz w istocie jest proste: np. kiedy DMASK zawiera %00110000, to oznacza to, że system operuje na drugim. Licząc od lewej, pikselu, zawartym w jakimś bajcie. Liczba %00001100 oznacza trzeci piksel, a np. liczba %00000100 oznacza szósty piksel w trybie graficznym, gdzie punkt zakodowany jest jednym bitem (choćby tryb graficzny 8).
Rejestr pomocniczy do przechowywania maski bitowej.
Znacznik klawisza ESC. Normalnie zawiera zero, jest tu wpisywana liczba 128, jeśli został naciśnięty klawisz ESC. Wartość zero jest przywracana po wysłaniu na ekran następnego znaku. Patrz także DSPFLG (766, $02fe).
675-689, |
$02a3-$02bl |
TABMAP |
Umowna mapa pozycji tabulacji. Jest to obszar złożony z 15 bajtów (jak łatwo policzyć 15*8=120), których bity odpowiadają kolumnom w linii logicznej. Bit ustawiony oznacza tzw. przystanek tabulacji, czyli miejsce, w którym zatrzyma się kursor po naciśnięciu klawisza TAB. Dlaczego akurat potrzeba na to 120 bitów? Edytor ekranowy ATARI XL/XE operuje na tzw. liniach logicznych, z których każda składa się z trzech linii fizycznych (trzech wierszy na ekranie po 40 bajtów) i stąd właśnie bierze się ograniczenie dla długości wiersza programu w BASIC-u. Aby ustawić własne przystanki tabulacji należy przede wszystkim wyobrazić sobie linię logiczną w postaci ciągu zer i wplecionych pomiędzy nie jedynek, symbolizujących miejsca zatrzymywania kursora. Np. aby ustawić tabulację na pozycjach 1,3, 12, 25 trzeba utworzyć mapę postaci:
10100000000100000000000010000000 ...
Po podzieleniu ciągu bitów na bajty otrzymamy:
10100000 00010000 00000000 10000000 ...
Oznacza to, że powinniśmy w BASIC-u wykonać ciąg instrukcji:
POKE 675, 160
POKE 676, 16
POKE 677, 0
POKE 678, 128
itd.
System operacyjny przywraca standardową mapę tabulacji po naciśnięciu klawisza RESET i po zmianie trybu graficznego. Patrz także PTABW (201, $c9).
690-693, |
$02b2-$02b5 |
LOGMAP |
Mapa linii logicznych edytora ekranowego. Spośród czterech bajtów tej struktury używane są tylko trzy. Każdy bit jednego z tych trzech bajtów symbolizuje jedną z linii fizycznych na ekranie - jak łatwo się domyślić, przewiduje się używanie 24 takich linii. Oto schemat przyporządkowania bitów poszczególnym liniom:
690 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
691 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
692 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
693 |
- |
- |
- |
- |
- |
- |
- |
- |
Ustawienie któregoś z tych bitów oznacza, że w odpowiadającej mu linii fizycznej zaczyna się linia logiczna. Mapa linii logicznych jest zapisywana wartościami początkowymi podczas obsługi RESET-a i po zmianie trybu graficznego.
Znacznik inwersji znaków. Przed wyświetleniem na ekran, prawie (nie dotyczy to tzw. kodów sterujących, np. ESC, czy też BELL) wszystkie znaki ATASCII mają siódmy bit wyzerowany. Podczas wyświetlania ich, procedury obsługujące ekran wykonują operację różnicy symetrycznej na kodzie każdego znaku i zawartości INVFLG.
Różnica symetryczna to operacja logiczna, dająca wyniki według tabelki:
Wbrew pozorom, aby używać różnicy symetrycznej nie trzeba wcale uczyć się tej tabelki na pamięć! Wystarczy wiedzieć, że jest to swego rodzaju porównanie bitów, którego wynikiem jest jedynka zawsze wtedy, gdy porównywane bity są różne. Wypada dodać, że w przypadku dokonywania operacji różnicy symetrycznej (nazwijmy ją wreszcie po imieniu - wszyscy programiści używają nazwy EOR) na dwóch bajtach, porównywane są odpowiednie bity każdego z nich, a więc bit siódmy pierwszego bajtu z bitem siódmym drugiego bajtu itd. Jak łatwo zauważyć - łatwo jest przy pomocy omawianej operacji zamienić na przeciwne wszystkie bity w bajcie - wystarczy ten bajt "zEORować" z liczbą 255, czyli dwójkowo %11111111. Wszystkie jedynki w zamienianym bajcie zmienią się w zera (1 EOR 1 = 0), a wszystkie zera zmienią się w jedynki (0 EOR 1=1). Oczywiście kolejny taki EOR przywróci poprzedni stan bitów. Można więc także używać operacji różnicy symetrycznej do naprzemiennej zmiany jakiegoś bitu, czy też całego bajtu, wiedząc, że każdy EOR "przestawia" go na przeciwny.
Wracając do rzeczy - ponieważ normalną zawartością komórki 694 jest zero, to kody znaków podczas "EORowania" Ich z tymże zerem nie zmieniają się.
W komórce INVFLG może znaleźć się jedna z dwóch wartości: 0 lub 128. System operacyjny wpisuje je tu na przemian po każdym naciśnięciu klawisza ATARI LOGO (to ten w prawym, dolnym rogu klawiatury, zwany żargonowo "inwersem"). Oczywiście nic nie stoi na przeszkodzie temu, aby wpisać tu liczbę 128 samemu, lecz należy pamiętać, że ma to znaczenie tylko podczas
wprowadzania znaków z klawiatury - podczas wypisywania np. zmiennej tekstowej nic się nie zmieni. Uwaga: omyłkowe wpisanie innej, niedozwolonej liczby może znacznie utrudnić dalszy dialog z komputerem.
Rezultaty eksperymentów z komórką INWLG można będzie zobaczyć po wstukaniu (i ewentualnej modyfikacji wiersza 30) poniższego maleńkiego programiku:
10 CLR :DIM A$(10)
20 INPUT A$
30 POKE 694,128:INPUT A$
40 POKE 694,0:END
Znacznik operacji wypełniania dla komendy DRAW. Jeśli aktualnie wykonywaną komendą jest DRAW, w tej komórce znajduje się zero. Jeśli żądaną komendą jest FILL, to jest tu wpisywana wartość niezerowa. Zwracam uwagę na to, że chodzi mi o wewnętrzne operacje wykonywane przez system operacyjny za pośrednictwem kanałów wejścia/wyjścia, które zostaną opisane później.
Rejestr pomocniczy używany wraz z ROWCRS (84,$54).
697, 698, |
$02b9, $02ba |
TMPCOL |
Rejestr pomocniczy używany wraz z COLCRS (85, 86, $55, $56).
Flaga przesuwania zawartości ekranu, używana przez system operacyjny, kiedy zachodzi konieczność wykonania takiej akcji. Zawiera pomniejszoną o jeden liczbę linii fizycznych, które zostały usunięte na górze ekranu, aby zrobić miejsce dla nowych informacji, dopisywanych u dołu. SCRFLG jest ściśle związana z liniami logicznymi edytora, dlatego wpisywana tu wartość jest jedną z liczb od 0 do 2 włącznie.
Bardzo ciekawe jest to, że przesuwanie zawartości okienka tekstowego odbywa się identycznie, jak przesuwanie całego ekranu w trybie graficznym 0. System operacyjny przemieszcza w pamięci nie tylko dane, reprezentujące zawartość okienka, ale także dodatkowo 800 bajtów pamięci poniżej obszaru zajmowanego przez okienko tekstowe. Warto o tym pamiętać, jeśli zdecydujemy się na umieszczenie w tym miejscu jakichś znaczących informacji.
Rejestr tymczasowy, używany tylko podczas wykonywania komendy DRAW. Jest w nim chwilowo przechowywana zawartość komórki ATACHR (763, $02fb).
Rejestr tymczasowy, używany podobnie, jak HOLD4.
Flaga dla klawiszy SHIFT i CONTROL. Normalnie jest tu wpisywana liczba 64 ($40), co oznacza, że wpisywane z klawiatury litery będą wyświetlane jako wielkie. Wyzerowanie SHFLOK spowoduje przejście w tryb małych liter, zaś wpisanie tu liczby 128 zadziała jak naciskanie klawiszy z wciśniętym dodatkowo klawiszem CONTROL, czyli spowoduje wyświetlanie znaczków graficznych. Proponuję wpisanie w BASIC-u instrukcji:
? PEEK(702)
a potem naciśnięcie klawisza CAPS i wpisanie jej ponownie. Widać, że zawartość SHFLOK nieco się zmieniła.
Ta komórka pamięci zawiera liczbę, mówiącą o ilości wierszy ekranu, dostępnych dla wypisywania w nich tekstów. Dla trybu graficznego 0 jest tu liczba 24, dla trybów z okienkiem tekstowym - liczba 4, zaś dla trybów graficznych - liczba 0. Wypada dodać, że tryby graficzne 1 i 2 są traktowane jak grafika, czyli powodują zapisanie tutaj wartości zero. Na podstawie BOTSCR procedury systemowe, obsługujące ekran stwierdzają, czy aktualnie jest wyświetlane okienko tekstowe.
Ciekawostką jest fakt, że poprzez wpisanie tutaj liczby 4 można dodać okienko tekstowe do ekranu w trybie graficznym 0. Górne 20 wierszy nie będzie wtedy przesuwane - można tam umieścić np. stały opis dostępnych poleceń lub instrukcje dla użytkownika.
Komórki pamięci od 704 do 712 ($02c0-$02c8) są rejestrami koloru dla graczy, pocisków oraz ekranu. Są to komórki-cienie sprzętowych rejestrów 53266-53274 ($d012-$d01a). Ich zawartość można zmieniać w BASIC-u przy pomocy instrukcji SETCOLOR lub POKE. Pożądany kolor uzyskujemy, wpisując tu liczby według wzoru:
kolor = numer koloru * 16 + jasność * 2
Nasze ATARI jest w stanie wyprodukować 16 różnych kolorów, z których każdy może być wyświetlony w jednym z ośmiu stopni jasności (tylko ośmiu, bo najmłodszy bit rejestrów koloru jest ignorowany). W praktyce uzyskanie wszystkich tych kolorów jednocześnie wymaga zastosowania specjalnych technik programowania, ale jest możliwe. Oto tablica dostępnych kolorów:
0 |
Czarny |
1 |
Rdzawy |
2 |
Czerwono-pomarańczowy |
3 |
Ciemnopomarańczowy |
4 |
Czerwony |
5 |
Lawendowy |
6 |
Kobaltowy |
7 |
Ultramaryna |
8 |
Niebieski |
9 |
Ciemnoniebieski |
10 |
Niebiesko-szary |
11 |
Oliwkowo-zielony |
12 |
Zielony |
13 |
Ciemnozielony |
14 |
Pomarańczowo-zielony |
15 |
Pomarańczowy |
Nieco dalej w tym numerze TA, w artykule z cyklu "Piszemy demo" umieszczona jest tabelka kolorów, których nazwy nieco różnią się od podanych wyżej. Wydaje mi się, że ta różnica wynika z różnej interpretacji barw, oraz (a może przede wszystkim) ze sposobu prezentowania kolorów ATARI przez różne telewizory. Sprawę tę pozostawiam do oceny Czytelnikom.
Muszę z przykrością stwierdzić, że mimo ładnych nazw, kolory produkowane przez nasz ulubiony komputer nie są najładniejsze i zdarzyło mi się słyszeć narzekania autorów gier na temat kolorów ATARI. Niestety, w czasach, kiedy powstawały modele XL/XE na rynku nie było takich układów elektronicznych, jakich używa się w komputerach domowych współcześnie.
Ogólnie mówiąc, rejestry koloru mają następującą strukturę:
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
kolor |
jasność |
nieużywany |
Oznacza to, że liczba, jaką znajdujemy w takim rejestrze zawiera informacje o kolorze i jego jasności, zakodowane na odpowiednich bitach. Aby uzyskać np. kolor czerwony o jasności 6 należy rozpisać go w taki sposób:
kolor = 4 * 16 + 6 * 2
co po wyliczeniu daje 76. Taką liczbę należy wpisać do odpowiedniego rejestru koloru.
Kolor dla gracza 1 pocisku 0. Cień rejestru 53266 ($d012). W trybie 10 GTIA ta komórka pamięci zawiera kolor tła, normalnie pobierany z komórki 712. Do zmiany kolorów graczy i pocisków nie można używać instrukcji SETCOLOR - nadaje się do tego jedynie instrukcja POKE.
Kolor dla gracza i pocisku 1. Cień rejestru 53267 ($d013).
Kolor dla gracza i pocisku 2. Cień rejestru 53268 ($d014).
Kolor dla gracza i pocisku 3. Cień rejestru 53269 ($d015).
Kiedy z czterech pocisków tworzony jest piąty gracz, to ma on kolor zawarty w rejestrze COLOR3 (712, $02c7).
Rejestr koloru 0 dla pola gry. Cień rejestru 53270 ($d016). Ustawiany w BASIC-u przy pomocy instrukcji SETCOLOR 0. W trybach graficznych 1 i 2 ten kolor używany jest do wyświetlania wielkich liter.
Rejestr koloru 1 dla pola gry. Cień rejestru 53271 ($d017). Ustawiany w BASIC-u przy pomocy instrukcji SETCOLOR 1. W trybach graficznych 1 i 2 ten kolor używany jest do wyświetlania małych liter, zaś w trybach 0 i 8 jest używany jako kolor tekstu lub rysunku.
Rejestr koloru 2 dla pola gry. Cień rejestru 53272 ($d018). Ustawiany w BASIC-u przy pomocy instrukcji SETCOLOR 2. W trybach graficznych 1 i 2 ten kolor używany jest do wyświetlania wielkich liter w inwersji, zaś w trybach 0 i 8 jako kolor tła. Użycie kolorów w trybie graficznym 8 jest o tyle ciekawe, że praktyce na ekranie da się uzyskać więcej niż dwa kolory. Poprzez umiejętny dobór pikseli można spowodować, że zobaczymy aż cztery kolory. Tę technikę nazwano po angielsku artefacting. Za książką I. Chadwicka "Mapping The ATARI" podaję kombinacje bitów, pozwalające na bliższe przyjrzenie się tym "artefaktom":
00 01 00 kolor A
00 11 00 kolor B
00 10 00 kolor C
00 01 10 kolor D
Jedynki oznaczają piksele zapalone; pokazano tu po trzy grupy dwupikselowe, ponieważ cała sztuka polega na umiejętnym doborze takich grup, z których każda ma szerokość jednego cyklu koloru.
Rejestr koloru 3 dla pola gry. Cień rejestru 53273 ($d019). Ustawiany w BASIC-u przy pomocy instrukcji SETCOLOR 3. W trybach graficznych 1 i 2 ten kolor używany jest do wyświetlania małych liter w inwersji.
Rejestr koloru tła i ramki wokół pola gry. Cień rejestru 53274 ($d01a). W trybie 10 GTIA staje się normalnym rejestrem koloru, ponieważ funkcje rejestru koloru tła przejmuje PCOLR0 (704, $02c0).
Domyślnymi wartościami kolorów graczy są zera, a kolorów pola gry i tła liczby:
PCOLOR0 |
40 |
2 |
8 |
PCOLOR1 |
202 |
12 |
10 |
PCOLOR2 |
148 |
9 |
4 |
PCOLOR3 |
70 |
4 |
6 |
PCOLOR4 |
0 |
0 |
0 |
Jarosław Syrylak
|