Najczęściej służy programistom do usunięcia zbędnego bagażu zmiennych nagromadzonych podczas procesu twórczego. I właściwie na tym koniec, bo trzymanie tekstu programu w tej postaci na nośniku zewnętrznym jest niewydajne - program zapisywany jest w postaci linii ATASCII zakończonych EOL (kod 155), co zajmuje nieporównanie więcej miejsca niż treść programu zapisana przez SAVE/LOAD, która trzyma program w postaci stokenizowanej.
Tymczasem para LIST/ENTER ma poważną zaletę - pozwala na dołączenie innego programu do tego, który jest już załadowany w pamięci komputera.
Przeprowadźmy więc drobny eksperyment. Wpiszmy w edytorze mały program:
30LIST
zapisując go za pomocą:
LIST "D:PRG2.LST"
po czym wykonajmy NEW i wpiszmy program:
10REM THIS IS PLACEHOLDER LINE FOR FUTURE USE 20ENTER "D:PRG2.LST"
i zapiszmy go za pomocą:
SAVE "D:PRG1.BAS"
Po uruchomieniu za pomocą RUN dostaniemy znak zachęty READY. Dlaczego? Przecież kiedy listujemy pełny program wygląda on tak:
10REM THIS IS PLACEHOLDER LINE FOR FUTURE USE 20ENTER "D:PRG2.LST" 30LIST
więc po wykonaniu instrukcji ENTER powinna się wykonać następna linia programu - a więc 30 LIST!
Interpreter BASICa wykonując instrukcję ENTER wczytuje program z nośnika zewnętrznego traktując go tak, jakby to był zwykły edytor ekranowy, po czym przerywa program i oddaje sterowanie do interpretera BASICa. Dlatego instrukcja w linii 30 nie została wykonana. Mało tego - nawet gdyby linia 20 wyglądała tak:
20ENTER "D:PRG2.LST": GOTO30
sterowanie i tak wróciłoby do BASICa i reszta linii nie zostałaby wykonana.
Wyglądałoby więc na to, że para LIST/ENTER przydaje się wyłącznie na etapie tworzenia programu a nie można jej użyć podczas działania programu np. do ładowania bibliotek procedur używanych w programie :/
No cóż - spróbujmy poeksperymentować trochę.
Ponieważ kod programu zapisany za pomocą LIST jest zachowany na dysku w postaci tekstowej spróbujmy go załadować do dowolnego edytora tekstu i nieco zmodyfikujmy. Dodajmy np. parę linii tak, żeby PRG2.LST wyglądał tak:
10 30LIST
i z powrotem zapiszmy na dysku. Po wykonaniu z BASICa
RUN "D:PRG1.BAS" LIST
zobaczymy w wyniku:
20ENTER "D:PRG2.LST" 30LIST
Okazało się, że w programie usunięto linię 10! Czy to dziwi? Chyba jednak nie powinno, skoro ENTER wprowadza linie programu z nośnika zewnętrznego tak, jakby były one wprowadzane z edytora ekranowego. Możemy więc w pliku zapisywanym poleceniem LIST, a ładowanym za pomocą ENTER dokonywać wszystkich operacji dostępnych w trybie bezpośrednim - i BASIC je bez zmrużenia oka wykona!
No to w takim razie przeedytujmy jeszcze raz plik PRG2.LST:
10 30LIST GOTO30
Co teraz się stanie kiedy uruchomimy program D:PRG1.BAS ? Powinniśmy zobaczyć wylistowaną treść programu:
20ENTER "D:PRG2.LST" 30LIST
co jest skutkiem realizacji GOTO 30 w trybie bezpośrednim.
Nie trzeba chyba dodawać, że w takim pliku można zapisać również inne komendy BASICa np. przygotowujące i inicjalizujące dodatkowe zmienne, tablice, wykonujące kod maszynowy za pomocą USR(ADR(A$)) itp. Wszystko to się wykona a nie będzie zajmowało miejsca w pamięci, ponieważ wykona się jednorazowo podczas wykonywania polecenia ENTER. Jedynym efektem ubocznym, jaki da się zauważyć będzie wyświetlanie przez interpreter napisu READY po wykonaniu każdej linii (za wyjątkiem kasowania/wprowadzania linii i oddania sterowania z powrotem do programu) w trybie bezpośrednim.
Do czego można tego użyć? 1. Jednorazowa inicjalizacja zmiennych lub wykonanie kodu programu w trybie bezpośrednim bez przechowywania kolejnych linii w pamięci komputera. 2. Usuwanie lub dodawanie części programu bez utraty wartości zmiennych. 3. Wykonanie kodu, zmiana trybu graficznego, itp. W TRAKCIE ŁADOWANIA PROGRAMU :) Odpowiednik adresu INIAD ($2e2..$2e3) w pliku binarnym DOS.
Bez problemu można w ten sposób zaimplementować namiastkę mechanizmu ładowania i inicjalizacji bibliotek używanych przez program.
Mechanizm działa w Atari BASICu - powinien działać również w innych interpreterach z nim kompatybilnych (np. Turbo BASIC XL).
Podczas ładowania programu można uruchamiać uprzednio załadowane bloki programu, lecz musi się to odbywać na zasadzie skoków do podprogramu (GOSUB). Wykonanie RUN odda sterowanie do programu uprzednio zamykając wszystkie kanały I/O (również kanał 7 używany przez ENTER), co zakończy ładowanie programu i dalsza część nie załaduje się do pamięci. GOTO co prawda nie pozamyka kanałów, ani nie wyczyści zmiennych, ale będzie wykonywało program aż do napotkania ostatniej linii, po czym wykona niejawnie instrukcję END, a ta pozamyka kanały (uniemożliwiając dalsze ładowanie programu) i odda sterowanie do BASICa.
Edit: NEW również zamknie wszystkie kanały I/O, więc aby kontynuować proces należy usuwać pojedyncze linie.
Edit 2: Należy również ostrożnie postępować z instrukcjami SOUND, ponieważ standardowa komunikacja SIO wykorzystuje generator 1 i 2 POKEYa do komunikacji z magnetofonem, a 3 i 4 do komunikacji z pozostałymi urządzeniami na szynie szeregowej.
Ja korzystam z L. (nie pomylić z LOAD!) i E. również z tego względu, że tak zapisany kod programu w razie błędu na nośniku dużo łatwiej odzyskać.
Przy pomocy komendy L., edytora tekstu i E. można uzyskać linie dłuższe niż standardowo wpisywane z BASIC'a - co kiedyś przypadkowo zauważyłem, a jakiś czas temu znalazłem opis tu: ->link<- Jednak takie linie nie mogą być zmieniane bezpośrednio z BASIC'a więc osobiście unikam tworzenia długich linii.
Co więcej - BASIC ma ograniczenie na długość stokenizowanej linii do 255 bajtów (co opisane jest tutaj), więc w zasadzie mając zewnętrzny tokenizer (np. na PC) dałoby się wprowadzać znacznie dłuższe linie (w przypadku przypisań stałych tekstowych i instrukcji DATA i REM niewiele dłuższe, bo są one przepisywane 1:1), ale program dałoby się ładować/zapisywać wtedy tylko za pomocą RUN/LOAD/SAVE/CLOAD/CSAVE. Uzupełnianie programu o linie wykonywane w trybie bezpośrednim możliwe jest tylko zewnętrznym edytorem ATASCII (np. Panther, Ed, XLF, PE, itp.), bo podczas wprowadzania za pomocą ENTER są one wykonywane i nie zostają w pamięci przez co nie da się ich odtworzyć za pomocą LIST.
Faktycznie! To jest świetny pomysł aby wstępną inicjalizację zmiennych wywalić z pamięci na dysk. Ze też jak robiliśmy Kolony 2106 to na to nie wpadłem.
Ciekawe spostrzeżenie. Patrząc szerzej, wydaje mi się, że z tym ENTERem to chyba nie tak diabeł straszny. Jeśli mamy np. zmienną część w wierszach 30000+. I wtedy w TBXL, jeśli zapis jest selektywny, a nie cały LIST, czyli np.
LIST "D:plik.lst",30000,
a wczytanie:
DEL 30000,32000 ENTER "D:plik.lst
wówczas chyba będzie dobrze. Tak mi się wydaje przynajmniej.