Tajemnice ATARI

FORTH

    W poprzednim odcinku rozważań o języku FORTH poznaliśmy dwa ważne słowa operujące na pamięci komputera. Były to:

C@ i @



   W języku TURBO BASIC XL znaleźlibyśmy odpowiadające im instrukcje:

PEEK i DPEEK

   Poznajmy teraz dwa nowe słowa operujące bezpośrednio na pamięci RAM. Są to:

C! i !

   Wpisują one podaną wartość w dowolne komórki pamięci. W TURBO BASIC XL ich odpowiednikami byłyby instrukcje: POKE i DPOKE

   Słowa C! i ! potrzebują dwóch liczb jako parametrów wejściowych; są to odpowiednio: wartość i adres. Aby wpisać wartość np. 4 do komórki 82, wykonajmy następującą sekwencję:

4 82 C! RETURN

   Lewy margines w edytorze został przesunięty do 4. kolumny, a więc zadanie zostało wykonane. Aby przetestować drugie z poznanych słów, napiszmy:

88 @ 40 + 88 ! RETURN

   Niby nic się nie stało, lecz podczas próby wejścia kursorem na pierwszą linię ekranu, zniknie on nam z oczu. Co się stało?

88 @ Pobrało adres początku ekranu (znajdujący się w komórkach 88 i 89) na stos.

40 + Dodało do adresu wartość 40 (przesunęło adres o 40 bajtów).

88 ! Wpisało zmieniony adres do odpowiednich komórek.

   Uzyskaliśmy przesunięcie o jedną linię ekranu wprowadzania w stosunku do wyświetlanego obrazu. W takim wypadku ostatnia linia dostępna dla kursora jest niewidoczna.

   To samo zadanie możemy wykonać znacznie prościej, pisząc:

40 88 +! RETURN

   Widzimy w tym zapisie nie znane nam słowo +! . Powoduje ono zwiększenie liczby dwu bajtowej spod podanego adresu (w przykładzie 88 i starszego czyli 89), o podaną wartość (czyli 40).

   Aby powrócić do początkowych parametrów edytora, naciśnijmy w tym momencie klawisz RESET.

   Zdobyte przed chwilą wiadomości umożliwią nam stworzenie nowego słowa, związanego z zegarem. Piszemy:

: 0ZEGAR! 0 19 ! ; RETURN

   Słowo to umożliwi nam wyzerowanie komórek zegara.

   Wszystkim, którzy mieli do czynienia z innymi językami programowania, dziwna może się wydawać nazwa zaczynająca się od znaku 0.

   Język FORTH nie ma jednak żadnych ograniczeń związanych ze znakami występującymi w nazwie lub z ich kolejnością. W skład nazwy mogą wchodzić wszystkie znaki o kodach ATASCII od 33 do 122. Poprawna z punktu widzenia języka byłaby np. następująca nazwa:

([*^*])

   Stworzone przez nas słowa 0ZEGAR! oraz ZEGAR@ (poprzedni numer TA), możemy wykorzystać do testowania szybkości działania dowolnych słów FORTHa.

ON BYŁ STAŁY, TYLKO ONE SIĘ ZMIENIAŁY.

   W języku FORTH spotykamy jeden rodzaj zmiennych: są to zmienne globalne. Można je wykorzystać w każdym nowo tworzonym słowie. Rolę zmiennych lokalnych (znanych z innych języków strukturalnych) przejmuje stos.

   Deklaracja zmiennej może wyglądać następująco:

0 VARIABLE ONE RETURN

  • 0 to wartość początkowa zmiennej (zawsze musi być podana).
  • VARIABLE deklaracja zmiennej.
  • ONE nazwa deklarowanej zmiennej.

       Tak zadeklarowana zmienna ma długość dwóch bajtów, może przyjmować wartość) od -32768 do 32767 ze znakiem lub od 0 do 65535 bez znaku. Spróbujmy wykonać powyższą deklarację na komputerze Gdy mamy już zmienną w słowniku, sprawdźmy jej wartość. Piszemy:

    ONE . RETURN

       Na ekranie zamiast wartości 0 pojawiła się jakaś dziwna liczba. Co ona oznacza?

       W języku FORTH wywołaniu nazwy zmiennej nie daje nam wartości, lecz adres gdzie ta wartość jest przechowywana. Być może wydaje się to niepotrzebną komplikacją, jednak umożliwia szeroki dostęp do zmiennej np. z poziomu Assemblera FORTHa.

       Aby uzyskać wartość zmiennej, a nie jej adres, postępujemy tak jak byśmy pobierali wartość z dowolnych komórek pamięci. Piszemy więc:

    ONE @ . RETURN

       Istnieje słowo ? (znak zapytania), które wyświetla bezpośrednio na ekran wartość spod adresu lub zmiennej. Można więc uprościć zapis:

    ONE ? RETURN

       W jaki sposób wprowadzić nową wartość do zmiennej? Uważny czytelnik domyśla się zapewne, ze skoro nazwa zmiennej daje adres wprowadzania, zastosujemy poznane na początku tego artykułu słowo ! (wykrzyknik). Wprowadźmy więc liczbę 10:

    10 ONE ! RETURN

       i sprawdzamy:

    ONE ? RETURN

       Na ekranie pojawiła się liczba 10, a więc wszystko przebiegło poprawnie.

       Wszyscy zauważyli na pewno, że działania na zmiennych nie różnią się niczym od działań na komórkach pamięci. Filozofia języka FORTH opiera się, między innymi na jawności struktur. Przecież zmienna to pewien wydzielony obszar pamięci.

       W językach programowania trudno obejść się bez deklaracji stałej. Zadeklarujmy więc stałą ON o wartości 711:

    711 CONSTANT ON RETURN

       CONSTANT - to słowo deklarujące stałą. Sprawdzamy:

    ON . RETURN

       Na ekranie pojawiła się wartość 711, czyli wartość stałej.

       Jeżeli często stosujemy w programie jakąś liczbę, dobrze jest zadeklarować ją jako stałą. Korzyści są wielorakie: lepsza czytelność programu , łatwość dokonywania zmian oraz oszczędność pamięci. Odwołanie się do stałej wymaga tylko dwóch bijtów pamięci, a do liczby - czterech.

       Nic nie stoi na przeszkodzie, aby zadeklarować jako stałą dowolny adres pamięci komputera. Tak też zrobiliśmy ze stałą ON.

       Zobaczmy, co zostanie wykonane, gdy napiszemy następującą sekwencję:

    6000 ON ! RETURN

       Zmieniły się kolory ramki.

       Zapis tego działania wygląda może dość dziwnie. Na pierwszy rzut oka wynikało by z niego że wpisujemy liczbę 6000 do stałej ON. Czy więc stała jest rzeczywiście stała (czyżby ON się zmieniał)?

       Liczba 6000 została wpisana pod adres 711 i 712 (tam są rejestry kolorów), a nie do stałej. Możemy to sprawdzić:

    ON . RETURN

       Stała ma dalej wartość 711.

       Adres zmiennej zdefiniowanej przy pomocy słowa VARIABLE, jest określany przez kompilator FORTHa. Nie mamy możliwości ingerencji w ustawienie tego adresu tylko zdefiniowanie adresu jako stałej (CONSTANT) daje nam możliwość umieszczenia (quasi) zmiennej w dowolnym miejscu, np. na stronie zerowej. Musimy jednak uważać, aby obszar ten nie kolidował z systemem operacyjnym komputera lub FORTHa.

       Wielu czytelników znających inne języki programowania zdziwił zapewne fakt istnienia w języku FORTH, tylko jednego rodzaju zmiennych. A gdzie zmienne łańcuchowe, tablice jedno i dwuwymiarowe, zapytają oni?

       FORTH posiada słowa, które umożliwiają tworzenie nowych, własnych definicji. Można tego dokonać w tak prosty sposób, że istnienie różnych typów definicji zmiennych wydaje się bezcelowe. Nie ma np. większego problemu aby stworzyć definicję tablicy 3 lub 4- wymiarowej o dowolnej długości elementów. Sposoby tworzenia definicji zostaną przedstawione w dalszych odcinkach tego cyklu.

       Obecnie chciałbym przedstawić jedynie słowo, które zwiększa obszar pamięci zajmowanej przez zmienną. Zmienna tak powiększona może przechowywać np. łańcuch znaków. Definicja zmiennej zajmującej obszar 10 bajtów, wyglądałaby następująco:

    0 VARIABLE ALA 8 ALLOT RETURN

       0 VARIABLE ALA to deklaracja zmiennej 2-bajtowej o nazwie ALA i wartości początkowej 0.

       8 ALLOT zwiększyło obszar zajmowany przez zmienną o 8 bajtów.

       Słowo ALLOT daje sygnał kompilatorowi aby zostawił w słowniku "dziurę" o wielkości liczby będącej na stosie, w naszym przypadku 8 bajtów. Słowo to możemy stosować w dowolnym miejscu w słowniku, oczywiście jeżeli ma to jakiś sens.

    ACH, TE BŁĘDY!

       Tryb wprowadzania nowych słów, jaki stosujemy obecnie, nie jest właściwy dla języka FORTH. Jest to tzw. tryb bezpośredni (wykorzystujący standardowy edytor ATARI), a służący normalnie do wywoływania pojedynczych słów lub ich testowania. FORTH ma własny edytor, umożliwiający zapis tekstu źródłowego na dyskietkę. Edytory znajdujące się na dyskietce implementacji Extended fig FORTH, są kłopotliwe w użytkowaniu. Pozostańmy więc podczas nauki przy dobrze nam znanym edytorze BASICa. W niedługim czasie spróbuję przedstawić własny edytor i mam nadzieję, że znikną wtedy wszystkie kłopoty związane z wprowadzaniem danych.

       Póki co, chciałbym zwrócić uwagę na parę spraw.

       Jeżeli po napisaniu przykładu i naciśnięciu klawisza RETURN, nie pojawił się napis OK, oznacza to że wystąpił błąd. Posiadacze stacji dysków powinni mieć włączoną stację z dyskietką FORTHa. Na dyskietce tej znajdują się komunikaty o błędach. Są one czytane i wyświetlane na ekran.

       Posiadaczom magnetofonów radziłbym wprowadzić następującą sekwencję:

    0 WARNING !

       Następnie, zapisanie FORTHa słowem CSAVE na taśmie i używanie tej wersji.

       WARNING to standardowa zmienna, wpływająca na formę wyprowadzanych komunikatów. Gdy ma ona wartość 0, komunikaty nie będą czytane ze stacji dysków, podawany będzie jedynie numer błędu.

       Czasami może wystąpić błąd podczas definiowania nowych słów. W takim przypadku po sprawdzeniu wyglądu słownika, zauważymy obecność nowej nazwy. Jednak wywołanie tego słowa (przez napisanie jego nazwy) spowoduje wyświetlenie znaku zapytania. Oznacza to brak słowa w słowniku, gdyż tylko jego część została skompilowana.

       Aby usunąć ten "śmieć" ze słownika, należy napisać:

    SMUDGE RETURN

       a następnie:

    FORGET CCC RETURN

       W miejsce ccc wpisujemy nazwę słowa, które zamierzamy usunąć. Nie będę na razie tłumaczył działania słowa SMUDGE. Jeżeli chodzi o słowo FORGET, to pełni ono bardzo ważną rolę. Umożliwia nam usunięcie ze słownika dowolnego słowa (także poprawnie skompilowanego). Należy jednak pamiętać, że zostaną usunięte także wszystkie słowa, znajdujące się nad kasowanym słowem.

       FORGET nie będzie działało w części słownika objętego tzw. ochroną przed kasowaniem. Standardowo objęty jest taką ochroną podstawowy słownik języka FORTH. Ochronę tę można oczywiście usunąć, lecz wymaga to większej znajomości budowy słów.

       Uwaga: zapisanie FORTHa słowem SAVE lub CSAVE nakłada automatycznie, ochronę na cały zapisywany słownik.

    DWA SŁOWA O SŁOWNICZKU

       Aby umożliwić łatwe odszukanie dowolnego słowa języka FORTH, zamieszczam poniżej krótki słowniczek z poznanymi już słowami.

       Co jakiś czas będę się starał prezentować podobne słowniczki w miarę rozszerzania naszych wiadomości.

       W pierwszej linii, obok nazwy przedstawiłem symbolicznie dane wejściowe, niezbędne dla danego słowa. Miejsce słowa oznaczone zostało symbolem ---, za nim znajdują się czasami dane wyjścowe. Dane te zostają na stosie po wykonaniu słowa (np. dodawanie zostawia na stosie wynik z dodawania, czyli sumę).

       Jeżeli jest tylko znak ---. oznacza to, że słowo nie wpływa bezpośrednio na stan stosu.

       W zastosowanej notacji szczyt stosu znajduje się po prawej stronie ciągu danych.

    SŁOWNICZEK

    Operacje na pamięci komputera


    @ adr -- n

       Pobiera spod adresu adr i adr+1 wartość n i umieszcza na stosie.

    C@ adr -- b

       Pobiera spod adresu adr jeden bajt b i umieszcza go na stosie.

    ! n adr ---

       Umieszcza pod adresem adr i adr+l liczbę dwubajtową n.

    C! b adr ---

       Umieszcza pod adresem adr młodszy bajt liczby b.

    +! n adr ---

       Zwiększa liczbę dwubajtową znajdującą się pod adresem adr i adr+1, o wartość n.

       We wszystkich powyższych przypadkach zamiast adresu adr, może wystąpić nazwa zmiennej.

    Deklaracje


    : --- ccc

       Otwiera deklarację nowego słowa o nazwie ccc. W miejscu ccc umieszczamy oczywiście dowolną nazwę. Deklaracja ta musi być zakończona średnikiem.

    ; ---

       Kończy deklarację dwukropkową. Przed średnikiem niezbędna jest spacja.

    VARIABLE n -- CCC

       Słowo deklarujące zmienną o nazwie ccc i wartości początkowej n. Wywołanie tak zadeklarowanej zmiennej ccc spowoduje umieszczenie jej adresu na stosie.

    CONSTANT n -- ccc

       Słowo deklarujące stałą o nazwie ccc i wartości n. Wywołanie tak zadeklarowanej stałej ccc spowoduje umieszczenie wartości n na stosie.

    Działania


    + - * /    n1 n2 --- wynik

       Słowa te zostawiają na stosie wynik odpowiedniego działania na dwóch liczbach ze znakiem n1 i n2.

    Wyprowadzanie liczb na ekran
    . n ---

       Wyświetli wartość n na ekranie, interpretując ją jako liczbę ze znakiem.

    U. n ---

       Jak wyżej, lecz n jest interpretowane jako liczba bez znaku.

    ? adr ---

       Wyświetla na ekran wartość znajdującą się pod adresem adr i adr+1.

    Inne


    ALLOT n ---


       Podczas kompilacji zostawia w słowniku wolne miejsce o długości n bajtów.

    VLIST ---

       Powoduje wyświetlenie nazw, wszystkich słów będących w słowniku. Wyświetlanie można przerwać naciskając np. spację w odpowiednim momencie.

    FORGET --- ccc

       Usuwa ze słownika słowo o nazwie ccc wraz z wszystkimi słowami wprowadzonymi później niż ccc.

    WARNING --- adr

       Zmienna wpływająca na format komunikatów o błędach. Gdy ma wartość 0, komunikaty nie będą czytane ze stacji a wyświetlane będą jedynie numery błędów.

    SAVE ---

       Powoduje zapisanie całego FORTHa na dyskietkę, wraz z nowo wprowadzonymi słowami.

    CSAVE ---

       Jak wyżej, lecz zapis na taśmę.

       Na koniec artykułu mała dygresja, która nasunęła mi się po obejrzeniu implementacji tego języka na inne komputery, w tym ATARI ST.

       Pamiętajmy, że poznając Pana FORTHa uczymy się efektywnego języka na wszystkie komputery, nie tylko na ATARI XL/XE.

    Roland Pantoła



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

    Pixel 2001