Tajemnice ATARI

FORTH cz. 6

    W poprzednim odcinku zajmowaliśmy się słowem WORD. Było ono używane do wprowadzania dowolnego ciągu znaków do komputera. Wielu czytelników zauważyło zapewne, że nie da się użyć tego słowa do wprowadzania tekstu w czasie wykonywania programu, gdyż nie czeka ono na wykonanie tej czynności. Aby tego dokonać, można wykorzystać słowo QUERY. Słowo to czeka na wprowadzenie tekstu o długości mniejszej od 80 znaków. Umieszcza tekst w buforze terminalu, skąd można go przesłać w inne miejsce. Adres bufora terminalu można odczytać ze zmiennej TIB. Słowo to jest wykorzystywane przez system operacyjny języka FORTH. Użycie go wewnątrz programu wprowadzi tekst do bufora terminalu, lecz zaraz po tym system FORTH-a będzie się starał zinterpretować tekst jako nazwę słowa ze słownika. Takie działanie spowoduje prawie zawsze sygnalizację błędu. Aby tego uniknąć, należy bezpośrednio za QUERY zastosować słowo WORD, które przyjmuje tekst spod TIB jako nową nazwę. Przykład:

: INPUT$ QUERY 155 WORD HERE ; RETURN

    Nasze nowo zadeklarowane słowo wprowadza tekst (aż do znaku o kodzie 155, czyli RETURN) pod adres, który wyprowadzi na stos słowo HERE. Adres ten będzie zostawiany na stosie po każdym użyciu słowa INPUT$. Sprawdźmy:

: TEST INPUT$ CR COUNT TYPE ; RETURN

    Po wykonaniu słowa TEST komputer będzie czekał na wprowadzenie tekstu, a następnie wyświetli go w nowej linii. Słowo INPUT$ działa podobnie jak instrukcja INPUT ze zmienną tekstową w Atari Basic. Stworzyliśmy słowo wprowadzające dowolny tekst, co jednak uczynić, gdy wprowadzamy liczbę? Gdyby użyć tylko słowa INPUT$, mielibyśmy dostęp do liczby zapisanej w formie ciągu cyfr. Aby uzyskać zamianę tego ciągu na wartość, należy użyć słowa NUMBER. Słowo to przekształca ciąg cyfr, poprzedzonych bajtem długości, na wartość. Parametrem wejściowym tego słowa jest adres początku ciągu znaków, a wartością wyjściową, pozostawioną na stosie, są dwie liczby określające wartość ciągu cyfr. Słowo NUMBER przekształca zapis na liczbę 4-bajtową, co możemy odczytać jako dwie liczby 2-bajtowe. Gdy korzystamy tylko z zakresu mieszczącego się w dwóch bajtach (a tak jest najczęściej), kasujemy słowem DROP liczbę 0 ze szczytu stosu i wykorzystujemy jedynie liczbę znajdującą się niżej.

    Stwórzmy teraz słowo wprowadzające liczbę z klawiatury i zostawiające jej wartość na stosie:

: INPUT INPUT$ NUMBER DROP ; RETURN

   i sprawdźmy pisząc:

INPUT . RETURN

DZIAŁANIA NA BLOKACH PAMIĘCI

   W powyższym opisie, dotyczącym słów wprowadzających ciąg znaków, wspomniałem o przenoszeniu go w inne miejsce. Na szczęście, nie trzeba tworzyć w języku FORTH słowa wykonującego to zadanie, gdyż posiada on je w słowniku. Słowo to ma nazwę CMOVE i wymaga trzech liczb jako parametrów wejściowych. Pierwsza liczba określa adres, spod którego pobieramy dany blok pamięci. Druga - to adres docelowy, a trzecia określa długość przenoszonego bloku. Aby sprawdzić jego działanie, wyczyśćmy ekran (SHIFT i CLEAR). Następnie w lewym górnym rogu ekranu piszemy dowolne zdanie np. Ala ma kota. Nie zatwierdzając napisu klawiszem RETURN przenosimy kursor przy pomocy kilku naciśnięć klawisza BREAK w dolną część ekranu. Po tych czynnościach piszemy:

88 @ DUP 80 + 40 CMOVE RETURN

    Nasz napis przeniesiony został o dwie linie niżej. Słowo CMOVE jest napisane w języku maszynowym, posiada więc bardzo dużą szybkość działania i znajduje szerokie zastosowanie. Uwaga: CMOVE zaczyna przenoszenie od pierwszego bajtu i przesuwa działanie ku wyższym adresom. Jeżeli adres docelowy jest wyższy od adresu pobrania o małą wartość i obszary w związku z tym częściowo się pokrywają, dochodzi do utraty części danych. W takich sytuacjach należy stosować słowo CMOVE> występujące w niektórych implementacjach języka FORTH. Niestety, w Extended fig FORTH nie ma go w słowniku i należy je stworzyć samemu. Zajmiemy się tym podczas omawiania ASSEMBLERA FORTH-a.

    Często podczas programowania zachodzi potrzeba wypełniania pewnego obszaru pamięci tą samą wartością. Funkcję tę spełnia słowo FILL. Piszemy:

88 @ 960 33 FILL RETURN

   Po wykonaniu powyższej sekwencji cały ekran został wypełniony literami A. Pierwszym parametrem słowa FILL (88 @) był adres początku wypełnianego obszaru. Drugi (960) - to długość tego obszaru, a trzeci - wartość wypełniania. W języku FORTH istnieją jeszcze dwa słowa zbudowane w oparciu o słowo FILL. Są to: ERASE oraz BLANKS .

    Oba potrzebują jako parametr wejściowy adres obszaru oraz jego długość. Pierwsze z nich wypełnia podany obszar zerami (czyszczenie), a drugie kodami spacji.

EDYTOR WPROWADZANIA

   Poznane do tej pory słowa języka FORTH, umożliwią nam tworzenie dłuższych programów. Niestety, wprowadzenie nawet kilku wierszy w trybie bezpośrednim jest bardzo uciążliwe, gdyż trudno ustrzec się od błędów. Także tworzone słowa musiały mieścić się w dwóch liniach. Aby usunąć te niedogodności i ułatwić czytelnikom wprowadzanie dłuższych programów w języku FORTH, przedstawiam poniżej Edytor Wprowadzania. Spełnia on tą samą funkcję jak Generator Kodów Kontrolnych w języku Basic. Działanie EDW ( Edytora Wprowadzania ) jest jednak nieco inne. Podstawową różnicą jest konieczność wprowadzania kodów kontrolnych razem z danymi. Dzięki tej zmianie komputer zajmuje się kontrolowaniem poprawności, nie ma więc możliwości wprowadzenia błędnego zapisu.

    Aby zainstalować edytor, należy wklepać poniższe sekwencje do komputera, oczywiście po wczytaniu FORTHa. Podczas tych czynności nie będziemy mieli żadnej kontroli poprawności wprowadzanego tekstu, należy więc robić to ze szczególną uwagą. Wprowadzanie odbywać się będzie w trybie bezpośrednim, czyli w takim, jaki używaliśmy do wprowadzania prezentowanych przykładów. Każda z sekwencji zaczyna się na początku linii, a kończy znaczkiem (RE), gdzie oczywiście należy nacisnąć RETURN. Każdy taki zapis wprowadzamy jednym ciągiem aż do (RE), nie zwracając uwagi na miejsce przeniesienia do nowej linii. Wszyscy posiadacze magnetofonów powinni najpierw wpisać:

O WARNING !

    Właściciele stacji dysków wkładają do stacji dyskietkę z językiem FORTH. Jeżeli pojawi się napis "ok", możemy wprowadzać następną sekwencję, gdy to nie nastąpi, musimy spróbować jeszcze raz. Można poprawiać błędny zapis widniejący jeszcze na ekranie, należy jednak wtedy usunąć komunikat o błędzie, ustawić kursor wewnątrz napisu i nacisnąć klawisz RETURN. Uwaga na spacje! A więc do dzieła:

( EDYTOR WPROWADZANIA ) RETURN
: <=< OVER > >R < R> * ; RETURN
37000 CONSTANT AD0 RETURN
0 VARIABLE AB RETURN
0 VARIABLE *K RETURN
0 VARIABLE LIN RETURN
0 VARIABLE EN RETURN
: AF AD0 AB @ + ; RETURN
: B32 32 BASE ! ; RETURN
: NK IF 0 0 ELSE B32 AF NUMBER DECIMAL 1024 U/ ENDIF ; RETURN
: N1 0 AF COUNT OVER + SWAP ; RETURN
: NU N1 DO I C@ 47 OVER 58 <==< 64 ROT 87 <=< + 0= + LOOP NK ; RETURN
: K0 1 *K +! C@ *K @ * EN +! + 1024 MOD ; RETURN
: K1 DO I K0 I C@ 0= IF I 38 BLANKS LEAVE ENDIF LOOP ; RETURN
: KP 0 *K ! 4 AC C! 32 AF 5 + C! NU 0 EN ! ; RETURN
: KOD= KP >R >R 0 AF 38 + AF 6 + K1 R> = R> LIN @ = SWAP OVER * ; RETURN
: .R2 0 <# # # #> TYPE SPACE ; RETURN
: ?L LIN @ B32 .R2 DECIMAL ; RETURN
: WP 125 EMIT 1 LIN +! ." Wprowadz linie " ?L CR CR ; RETURN
: ?DOB DROP AF 6 + AF 32 CMOVE 32 AB +! WP 1 ; RETURN
: ?Z CR CR AF 1+ 37 TYPE 155 EMIT 28 EMIT 0 ; RETURN
: LL ." Teraz ma byc linia " ?L ; RETURN
: ?ZLE 125 EMIT 0= IF LL ELSE ." Popraw:" ENDIF ?Z ; RETURN
: KO KOD= IF ?DOB ELSE ?ZLE ENDIF EN @ 1442 = * ; RETURN
: GO 125 EMIT CR ." GOTOWE!" CR ; RETURN
: E1 1 82 C! 0 AB ! LIN ! WP ; RETURN
: BBL AF 1024 AB @ OVER MOD - DUP AB +! BLANKS ; RETURN
: EDW El BEGIN AF 39 ERASE AF 1+ 37 EXPECT KO UNTIL BBL GO ; RETURN


    Poniższe słowa wprowadzają tylko właściciele stacji dysków.

: BSAV OVER + SWAP DO DUP I 0 R/W B/BUF + LOOP DROP ; RETURN
: EDW-SAVE AD0 SWAP B/SCR * AB @ B/BUF / BSAV ; RETURN


    A kolejne właściciele magnetofonów.

1 VARIABLE CD RETURN
: --> 0 CD ! ;RETURN
: BF< 16 8 DO DUP I 8 - B/BUF * + I BUFFER B/BUF CMOVE LOOP DROP ; RETURN
: EL EMPTY-BUFFERS DUP BF< 1 CD ! 1 LOAD ; RETURN
: EDW-COMP AD0 0 WARNING BEGIN EL 1024 + CD @ UNTIL DROP ; RETURN

    Jeżeli wszystko przebiegło poprawnie, jesteśmy od tej pory szczęśliwymi posiadaczami Edytora Wprowadzania. No, nie całkiem, gdyż należy pamiętać o utrwaleniu naszej pracy słowem SAVE na dysk lub CSAVE na kasetę. Uwaga: w mil zaczynającej się od : --> po zatwierdzeniu klawiszem RETURN, pojawi się napis MSG # 4 lub "Isn't unique", a dopiero na końcu "ok". Nie należy się tym przejmować, gdyż komunikat informuje o deklaracji słowa o nazwie będącej już w pamięci. Edytor wywołujemy pisząc EDW. W tym momencie pojawi się napis: "Wprowadź linię 01", podajemy więc linię, której kod zaczyna się od 01. Wprowadźmy na próbę znane nam słowa:

011M ( 0ZEGAR1 ZEGAR@ )
0200
03SM : 0 ZEGAR! 0 19 ! ;
04HN : ZEGAR@ 20 C@ 19 C@ 256 * ;
05D2 ( END )

    Pierwsza linia zawiera komentarz, który będzie nagłówkiem ekranu. Ostatnia zawiera instrukcję wyjścia z edytora. Po wprowadzeniu każdej linii należy nacisnąć RETURN. Jeżeli edytor nie zawiera błędów, to po wpisaniu z jego pomocą powyższych linii, pojawi się napis GOTOWE!.

    W tym momencie właściciele magnetofonów mogą skompilować wprowadzony tekst słowem EDW-COMP ., a następnie zapisać na taśmę za pomocą CSAVE. Posiadacze stacji dysków, maga zapisać program w wersji źródłowej słowem EDW-SAVE.

    Uwaga: przed wywołaniem tego słowa należy podać numer ekranu, od którego program zostanie zapisany. Przypominam, że ekrany mogą mleć numery od l do 87. Aby skompilować tak zapisany program źródłowy, należy użyć sekwencji:

NRekr LOAD RETURN

    W miejsce NRekr wstawiamy numer ekranu, od którego program został zapisany. Wszystkim posiadaczom stacji dysków polecałbym wpisanie tekstu źródłowego Edytora Wprowadzania, przy pomocy tego edytora wprowadzonego wcześniej w trybie bezpośrednim. Następnie zapisujemy tekst źródłowy na czystym dysku sformatowanym w gęstości S lub E, pisząc np. 5 EDW-SAVE . Od tej pory będziemy mogli dołączać edytor do FORTHa przez wywołanie 5 LOAD . Tekst edytora (tym razem już z kodami) zamieszczam poniżej.
01J5 ( EDytor Wprowadzania )
0200
03E5 ( w jezyku FORTH )
0400
05CO ( autor: Roland Pantola )
065T ( [c] 1992 Tajemnice Atari )
0700
08JG : <=< OVER > >R < R> * ;
09NK 37000 CONSTANT AD0
0AM1 0 VARIABLE AB
0BH2 0 VARIABLE *K
0CV4 0 VARIABLE LIN
0DSD 0 VARIABLE EN
0EA7 : AF AD0 AB @ + ;
0FHP : B32 32 BASE ! ;
0G0V : NK IF 0 0 ELSE B32 AF NUMBER
0HL8 DECIMAL 1024 U/ ENDIF ;
0IH0 : N1 0 AF COUNT OVER + SWAP ;
0JM9 : NU N1 DO I C@ 47 OVER 58 <=<
0KA0 64 ROT 87 <=< + 0= + LOOP NK ;
0LRU : K0 1 *K +! C@ *K @ * DUP EN
0M6V +! + 1024 MOD ;
0N6A : K1 DO I KO
0O3M I C@ 0= IF I 38 BLANKS
0PPI LEAVE ENDIF LOOP ;
0QPL : KP 0 *K ! 4 AF C!
0R90 32 AF 5 + C! NU 0 EN ! ;
0SH5 : KOD= KP >R >R 0
0T5M AF 38 + AF 6 + K1
0U42 R> = R> LIN @ = SWAP OVER *
0VA1 ->
1000
1100
1200
13LJ : .R2 0 <# # # #> TYPE SPACE ;
1496 ?L LIN @ B32 .R2 DECIMAL ;
15EG : WP 125 EMIT 1 LIN +!
1661 ." Wprowadz linie " ?L CR CR ;
17G4 : ?DOB DROP AF 6 + AF 32
18G7 CMOVE 32 AB +! WP 1 ;
19B4 : ?Z CR CR AF 1+ 37 TYPE
1AHM 155 EMIT 28 EMIT 0 ;
1BS2 : LL ." Teraz ma byc linia "
1CH3 ?L ;
1DB4 : ?ZLE 125 EMIT 0= IF LL
1EFF ELSE ." Popraw:" ENDIF ?Z ;
1F0F : KO KOD= IF ?DOB ELSE ?ZLE
1GTQ ENDIF EN @ 1442 = * ;
1HH8 : GO 125 EMIT
1IK1 CR ." GOTOWE!" CR ;
1JIS : E1 1 82 C! 0 AB ! 0 LIN !
1JI3  WP ;
1LGM : BBL AF 1024 AB @ OVER MOD -
1MT2 DUP AB +! BLANKS ;
1N00
1OMD : EDW El BEGIN AF 39 ERASE AF
1PIP 1+ 37 EXPECT KO UNTIL BBL GO ;
1Q00
1RK4 ( ---
1SVG ( wlacza edytor wprowadzania )
1TOO
1UA1 ->
1V00
2000
21IP ( EDW-SAVE )
2200
23MA : BSAV OVER + SWAP DO DUP I 0
24TK  R/W B/BUF + LOOP DROP ;
2500
26IP : EDW-SAVE AD0 SWAP B/SCR *
27RN AB @ B/BUF / BSAV ;
2800
29QK ( NREK --
2AJ8 ( zapisuje wprowadzony blok na 
2BEB ( dysk od ekranu numer NREK
2CD2 ( END )
    Uwaga! Edytor Wprowadzania nie będzie działał w ELKOMP-FORTH, gdyż implementacja ta nie posiada możliwości poprawiania wprowadzanego tekstu. Najlepszym wyjściem jest wprowadzenie edytora w implementacji Extended fig FORTH. Posiadacze magnetofonów powinni poszukać tej implementacji u kolegów ze stacją dysków, a następnie nagrać na kasetę słowem CSAVE.

    Proszę o listowne relacje z prób instalowania EDW w swoich komputerach.

Roland Pantoła



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

Pixel 2002