FORTH cz. 11Gdy 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
|