Tajemnice ATARI

FORTH cz. 11

    W poprzednim numerze TA zamieszczony został listing Edytora Fortha. Edytor ten napisałem cztery lata temu. Używam go do tej pory i sądzę, że czytelnikom zainteresowanym programowaniem w języku FORTH, będzie on dobrze służył. W tym odcinku zajmiemy się opisem pozostałych funkcji tego edytora.

    Gdy wywołamy edytor (np. 10 L), na ekranie ukażą się dwie pionowe linie wyznaczające lewy i prawy margines pola edycji. Z lewej strony znajduje się numer aktualnie wywołanego ekranu, oraz liczba określająca ilość linii wprowadzonych do bufora. Jeden ekran FORTHa składa się z 1024 bajtów i najczęściej bywa przedstawiany w postaci 16 mil po 64 znaki. Ja zastosowałem linie o długości 32 znaków, gdyż mieszczą się one w całości na ekranie wyświetlanym przez nasz komputer. W związku z tym cały ekran posiada 32 linie.

    Każdą z linii wyświetlanych na ekranie można wprowadzić do bufora. Linię znajdującą się w buforze można następnie umieścić w dowolnym miejscu bieżącego ekranu lub przenieść do innego.

    Aby wprowadzić linę do bufora należy najechać na nią kursorem, a następnie nacisnąć SHIFT i DELETE. Gdy powtórzymy tę czynność, wprowadzimy do bufora kolejną linię tekstu. Możemy w taki sposób umieścić tam cały ekran, a następnie przenieść go pod inny numer.

    Wyprowadzenie linii z bufora następuje po naciśnięciu klawisza TAB.

    Uwaga: klawisz RETURN nie pełni w tym edytorze funkcji znacznika końca linii, gdyż wszystkie linie mają zawsze długość 32 znaków (także puste). Klawisz ten przenosi jedynie kursor do początku nowej linii, oraz czyści bufor.

    Przejdźmy teraz do opisu edytora w wersji kasetowej, gdyż różni się on znacznie od wersji przeznaczonej dla stacji dysków. Podstawowa różnica polega na tym, że w pamięci komputera jest przechowywane jednocześnie 14 ekranów tworzących jeden blok. Pisany program może składać się z dowolnej ilości takich bloków, jednak podczas kompilacji muszą one być oddzielnie doczytywane. Praca na jednym bloku jest bardzo wygodna, gdyż umożliwia szybki dostęp do każdego ekranu zawartego w danym bloku. Cały blok ekranów jest umieszczany w pamięci, nad którą znajduje się ROM, nie zabiera więc pamięci dostępnej dla pisanego programu. Dzięki takiemu usytuowaniu bloku, nie znika on z pamięci komputera nawet po wykonaniu zimnego startu.

    Wersja kasetowa edytora ma kilka dodatkowych funkcji ułatwiających korzystanie z magnetofonu. Są to następujące słowa wywoływane z FORTHa:

    C:EDIT - odczyt bloku ekranów zapisanych na taśmie do pamięci. Wejście do Edytora następuje po wpisaniu:

nrek L .

gdzie nrek to numer wywoływanego ekranu zawierający się w przedziale od 0 do 15.

    C:FLUSH - zapis całego bloku ekranów na kasetę.

    nrek LOAD - podobnie, jak w wersji dyskowej, jest to kompilacja ekranu o numerze nrek. Podany ekran musi znajdować się w bloku wprowadzonym wcześniej za pomocą C:EDIT. Aby kompilacja nie została zakończona na wywołanym ekranie, należy umieścić w końcowych liniach ekranu znak: -->

    Wprowadziłem także słowo umożliwiające przenoszenie ekranów do Edytora FORTHa z Edytora Wprowadzania. Uzyskujemy w ten sposób możliwość zapisu na taśmę wersji źródłowej wprowadzanego programu. Dzięki temu każdy z czytelników będzie mógł dowolnie modyfikować programy wklepane z Tajemnic Atari. Aby dokonać wyżej opisanych czynności należy, po zakończeniu wprowadzania programu przy pomocy EDW, napisać:

EDW-EDIT

    a następnie wywołać Edytor FORTHa, np. 1 L. aby zobaczyć wprowadzony tekst. Po wyjściu z edytora (przy pomocy klawiszy ESC i SPACJA) możemy zapisać całość na kasecie słowem: C:FLUSH

    Właściciele magnetofonów zainteresowani językiem FORTH nie mieli niestety możliwości poznania ciekawych słów znajdujących się na dyskietce zawierającej implementację EXTENDED fig-FORTH. Aby im to umożliwić wprowadziłem do Edytora FORTHa słowo:

D:EDIT

    Umożliwia ono przeniesienie do Edytora FORTHa w wersji kasetowej dowolnych ekranów z dysku. Wywołując powyższe słowo, należy podać przed nim dwie liczby, określające numer pierwszego i ostatniego ekranu, które chcemy przenieść, np. 10 21 D:EDIT. Warunkiem koniecznym do przeprowadzenia takiej operacji jest oczywiście dobra znajomość z właścicielem stacji dysków.

    Udało mi się przedstawić Czytelnikom najważniejsze słowa języka FORTH, oraz podstawowe narzędzia (ASSEMBLER i EDYTOR), niezbędne do pisania własnych programów. Myślę więc, że zaczną powstawać ciekawe programy w tym języku tworzone przez Czytelników. Ja chciałbym na razie zakończyć ten cykl poświęcony językowi FORTH. Czekam jednak na propozycje Czytelników i jeśli takie się pojawią - zostaną zamieszczone w Tajemnicach Atari. Wszystkim czytelnikom, pragnącym pogłębić swoją znajomość z językiem, polecałbym książkę Jana Ruszczyca pt. "Poznajemy FORTH". Została ona wydana przez wydawnictwo SOETO, mieszczące się na ulicy Hożej 50 w Warszawie.

    Przez wszystkie odcinki tego cyklu przedstawiałem mój subiektywny punkt widzenia na temat języka FORTH. Na zakończenie pragnę więc trochę przewrotnie przedstawić opinię poważnych znawców z dziedziny informatyki. Oto ona:

    "Język FORTH jest tylko i wyłącznie ciekawostką informatyczną, która nie ma i nie znajdzie żadnego praktycznego (poważnego) zastosowania."

    Na koniec - część edytora przeznaczona dla posiadaczy magnetofonów, która nie zmieściła się w poprzednim odcinku cyklu:
01AU ( ED-KASETA )
0200
03TN 0 VARIABLE PDL
04N8 XSAVE 12 + CONSTANT Z%
05JN XSAVE 14 + CONSTANT D% HEX
06PU CODE PST BEGIN, D40B LDA,
074G 0< NOT UNTIL, BEGIN, D40B LDA,
08A9 0< UNTIL, FF # LDA, D40A STA,
099K SEI, D301 DEC, RTS, C;
0APH CODE >BL MAC PST
0B70 BEGIN, DEY, Z% )Y LDA,
0C5J D% )Y STA, 0 # CPY, 0=
0D1V UNTIL, D301 INC, CLI, RTS, C;
0ES7 CODE PMV  XSAVE STX,
0F67 PDL 1+ LDX, 0 # LDY,
0GTC 0 # CPX, 0= NOT IF,
0HBK BEGIN, MAC >BL Z% 1+ INC, D%
0IO1 1+ INC, DEX, 0= UNTIL, THEN,
0J6A PDL LDA, 0= NOT
0KAH IF, PDL LDY, MAC >BL THEN,
0L8S XSAVE LDX, NEXT JMP, C; DECIMAL
0MMR : PMOVE  PDL ! D% ! Z% ! PMV ;
0NAM HEX 2800 CONSTANT G28
0OSU : 2DL OVER + DUP >R G28 < 0=
0P6R IF DUP G28 < 0=
0QSI IF >R 0 0 C000 R G28 - +
0RRG R> R SWAP -
0SD3 ELSE >R D800 R + G28 R> -
0TIN C000 R G28 - ENDIF ELSE
0UDT >R D800 R + R> R SWAP - 0 0
0V4P ENDIF R> DROP >R OVER R> SWAP ;
10MH   -->
1100
1200
13V5 : >ROM ROT >R 2DL R + ROT ROT
14H3 PMOVE R> ROT ROT PMOVE ;
157D : <ROM ROT >R 2DL R + SWAP
166E PMOVE R> SWAP PMOVE ; DECIMAL
1700
18ML HEX 340 VARIABLE IOCB
19RM 0 VARIABLE IO.X
1ALR 0 VARIABLE IO.CH
1B39 : IOCC 10 * 70 MIN DUP IO.X C!
1C3E 340 + IOCB ! ;
1D2G : <IO>  <BUILDS , DOES> @ IOCB
1EU4 @ + ; 2 <IO> COM
1FOB 4 <IO> BAL 8 <IO> BLL
1GG4 A <IO> AX1 B <IO> AX2
1HRB CODE XCIO XSAVE STX, IO.X LDX,
1I3G IO.CH LDA, E456 JSR,
1JID XSAVE LDX, IO.CH STA, TYA,
1K4J PUSH0A JMP, C;
1LEL : OPEN IOCC AX2 C! AX1 C!
1M24 BAL ! 03 COM C! XCIO ;
1NJB : <C> IOCC 0C COM C! XCIO ;
1OTB : GB IOCC 7 COM C! BLL !
1PEO BAL ! XCIO ;
1Q1V : PB IOCC B COM C! BLL !
1R3H BAL ! XCIO ; DECIMAL
1SF8 67 VARIABLE C:
1T5S : <0> C: SWAP 128 3
1U3T OPEN DROP ;
1VR3 : OPL 4 <O> ; : OPS 8 <O> ;
20M7 : CLO 3 <C> DROP ; ->
2100
2200
23EA : GETR B/BUF 3 GB ;
24LL : PUTR B/BUF 3 PB ;
2536 0 VARIABLE AROM
263C 0 VARIABLE ROM
27LG 0 VARIABLE S-L
283J : NARC >R AROM ! PAD R>
299N PAD AROM @ B/BUF ROM @
2ALA IF <ROM ELSE >R SWAP R>
2BID CMOVE ENDIF ;
2CKR : +NC S-L @
2DIT IF PAD AROM @ B/BUF
2EAB ROM @ IF >ROM ELSE CMOVE ENDIF
2F1J B/BUF AROM +! ELSE B/BUF
2GRH AROM +! PAD AROM @ B/BUF
2H09 ROM @ IF <ROM ELSE
2I1M >R SWAP R> CMOVE ENDIF ENDIF ;
2JFS 0 VARIABLE #ER
2K91 : BCAS NARC 0
2LGK DO DUP S-L @ IF SETR ELSE
2MFS PUTR ENDIF #ER !
2N6E #ER C@ 1 = IF +NC
2OE5 ELSE #ER @ % 136 = #ER @ 4 =
2PVC + 0= IF I 0=
2QV3 IF 3 ELSE 2 ENDIF #ER !
2R50 ELSE #ER @ % 136 =
2SA3 IF l #ER ! ENDIF ENDIF LEAVE
2TNO ENDIF LOOP DROP -l #ER +! ;
2U55 : LCAS l S-L ! OPL BCAS CLO ;
2V9G : SCAS 0 S-L ! OPS BCAS CLO ;
301A -->
3100
3200
33E7 : INDEX EMPTY-BUFFERS
34MQ INDEX ;
351Q 1024 CONSTANT &24
36DD : B>R DUP >R BLOCK R> B/BUF *
370C &24 - B/BUF >ROM ;
38L4 : BR DUP >R BUFFER R> B/BUF *
39QK &24 - B/BUF ; : B<R BR <ROM ;
3A6O : ER B/SCR * DUP
3B72 B/SCR + SWAP ;
3C1J : E>R ER DO I B>R LOOP ;
3D0B : E<R ER DO I B<R LOOP ;
3EEE ( NREKR --- )
3FUD 0 VARIABLE FR
3G9B : FROM % 14 0
3HCO DO FR &24 I * 2 >ROM
3I8P LOOP ;
3J33( --- )
3K00
3L39 0 VARIABLE SR
3MU5 : ILR SR SWAP l - &24
3NO5 * 2 <ROM SR @ ;
30H5 ( NREK --- F=0 )
3P00
3Q79 : ILROM 0 0 14
3RB0 DO I ILR
3SD5 IF LEAVE ELSE 1+ ENDIF
3TGG -l +LOOP % 14 SWAP - ;
3UOP ( -- ILEKR )
3V00
40A1 -->
4100
4200
43O0 : YF % 252 l ILR 256
44JA <=< IF FROM ENDIF ;
45JM : 0WA 0 WARNING ! ;
4600
478D : E. EMPTY-BUFFERS 0WA YF
485A SCR @ l MAX % 14 MIN DUP SCR !
4944 >R R E<R R ILR 0= IF
4AQG CLEAR ENDIF (E)
4B8V EXFO R> E>R ;
4C33 ( --- )
4D00
4EGK : ?DNR 0 OVER % 15 <=< IF
4FGL 1 ELSE DROP
4G6J CR ." Zly numer"
4HRS CR BEEP 0 ENDIF ;
4IGU : L. ?DNR IF SCR ! E. ENDIF ;
4JEE ( NREKR --- )
4K52 : CSOU 8 0 DO 0 53760 I + C!
4LMB 2 +LOOP ;
4M33 ( --- )
4NMF : C:FLUSH 1 ROM !
4O6K 0 ILROM B/SCR * SCAS CSOU ;
4P33 ( --- )
4QMU : C:EDIT 0WA FROM 1 ROM !
4R9P 0 [ 14 8 * ] LITERAL LCAS
4S72 #ER @ IF CR ." Blad odczytu"
4T6V BEEP CR ENDIF ;
4U33 ( --- )
4V00
50A1 -->
5133 ( --- )
5200
53E0 : IND EMPTY-BUFFERS YF
54SN % 15 1 DO I B/SCR * DUP
55GB B<R BLOCK DUP C@
566Q IF % 32 -TRAILING CR I .
57UH TYPE ELSE DROP ENDIF
588P LOOP ;
5933 ( --- )
5ACA : LOAD ?DNR IF 0WA BEGIN l CG
5BJA ! EMPTY-BUFFERS DUP ILR IF DUP
5CEG E<R DUP >R LOAD R> 1+ ENDIF
5DBI CG @ UNTIL DROP ENDIF ;
5EL0 ( NREK --- )
5FDO : E<EW ER DO I BR >R
5G9A 37000 + SWAP R> CMOVE LOOP ;
5HL0 ( NREK --- )
5ILE : EDW-EDIT FROM EW AB @
5JNJ &24 / 1+ l DO EMPTY-BUFFERS
5KJH I E<EW I E>R LOOP ;
5LBO ( --- Z EDW do EDYTORA )
5MOR : D:EDIT 0WA FROM OVER - 1+
5NB0 % 14 MIN OVER + EMPTY-BUFFERS
5O8D B/SCR * SWAP B/SCR *
5P9R 0 ROT ROT DO I BLOCK OVER
5QHN B/BUF >ROM B/BUF + LOOP DROP ;
5RBD ( EKR1 EK2 --- )
5SQJ : CLEAR SCR @ ?DNR IF SCR @
5TKO EMPTY-BUFFERS
5UMT E<R CLEAR SCR @ E>R ENDIF ;
5VD2 ( END )

Roland Pantoła




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

Pixel 2002