CROOK-5 - System programowania w języku BASIC
Opis języka BASIC i zasady programowania można znaleźć w podręczniku [1]. Uzupełnienia i nowości w stosunku do tego opisu podano poniżej.
Zlecenia utajnienia programu
W celu ochrony praw autorskich oraz zabezpieczenia programów przed ingerencją osób niepowołanych wprowadzone zostały zlecenia: utajnienia programu (PAS) oraz cofnięcia utajnienia (UNPAS).
PAS <hasło>
UNPAS <hasło>
gdzie <hasło> jest nazwą trzyznakową. Program który utajniono zleceniem PAS może być umieszczony w zbiorze dyskowym wyłącznie za pomocą zleceń DMP oraz VRU (nie działają zlecenia: LIS, PLI, NLI, ani SAVE!). Cofnięcie utajnienia odbywa się przy użyciu zlecenia UNPAS, po którym musi wystąpić hasło użyte uprzednio w zleceniu PAS. Zlecenia PAS i UNPAS działają lokalnie (w obrębie bloku, w którego kontekście zostały użyte).
Dodatkowe funkcje języka BASIC
FIL$(K)
- Wartością funkcji jest tytuł zbioru dołączonego do kanału K. Jeżeli zbiór ma niepusty typ, to należy on również do wartości funkcji i jest oddzielony od nazwy zbioru kropką.
Sześć niżej podanych funkcji służy do upakowania (zmiany) wartości arytmetycznych w łańcuchowe i do rozpakowania z powrotem postaci upakowanej znakowo w łańcuchu na wartości arytmetyczne. Ma to szczególne znaczenie w tych przypadkach, gdy działa się na dużych zbiorach łańcuchowych o dostępie swobodnym (RAS), w któtych trzeba również przechowywać wartości liczbowe. Upakowanie polega na utworzeniu wartości łańcuchowej będącej obrazem kolejnych byte'ów maszynowej reprezentacji liczby. Nie zaleca się używania funkcji rozpekowujących do przetwarzania łańcuchowego obrazu liczb nie utworzonych odpowiednią funkcją upakowującą. Mechanizm ten jest przeznaczony przede wszystkim do oszczędzania pamięci, potrzebnej na przechowywanie liczb.
SIT$(X)
- Wartością funkcji jest dwuznakowy łańcuch będący obrazem 16-bitowej wartości INT(X). Nadmiar jest sygnalizowany jako błąd.
ITG(M,A$)
- Wartością funkcji jest odpowiednik 16-bitowego obrazuliczby utworzonego z dwóch kolejnych znaków wartości A$, począwszy od M-tego znaku.
SLN$(X)
- Wartością funkcji jest czteroznakowy łańcuch będący obrazem 32-bitowej liczby całkowitej długiej otrzymanej z wartości INT(X).
LNG(M,A$)
- Wartością funkcji jest odpowiednik 32-bitowego obrazu liczby utworzonego z czterech kolejnych znaków wartości A$, począwszy od M-tego znaku.
SFL$(X)
- Wartością funkcji jest sześcioznakowy łańcuch będący obrazem 48-bitowej wartości X.
FLO(M,A$)
- Wartością funkcji jest odpowiednik 48-bitowego obrazu liczby utworzonego z sześciu kolejnych znaków A$, od począwszy od M-tego znaku. Jeśli 6-znakowy fragment A$ nie stanowi obrazu znormalizowanej liczby zmiennopozycyjnej, sygnalizowany będzie błąd przy próbie użycia w działaniach arytmetycznych wartości funkcji FLO.
UWAGI:
- Wprowadzenie wyżej opisanych funkcji wymagało dopuszczenia w łańcuchach byte'u o wartości 0 (znak NUL kodu ISO-7). Znak ten nie jest z wartości łańcuchowych usuwany, jak miało to miejsce w poprzednich wersjach systemu BASIC-EXT. Dodatkową konsekwencją tego jest fakt, że pobranie wartości łańcuchowej ze zbioru typu RAS instrukcją READ #K: daje zawsze łańcuch o długości równej marginesowi zbioru, nawet wtedy, gdy zapisany był łańcuch krótszy. W tym ostatnim przypadku pierwotnie zapisana wartość łańcuchowa będzie przy odczycie uzupełniona byte'ami zerowymi (NUL). Dla większości istniejących programów zmiana powyższa nie ma żadnego znaczenia.
- Wartością funkcji CHR$(N) jest jednoznakowy łańcuch o wartości kodowej byte'u MOD(N,256), a nie MOD(N,128), jak to miało miejsce w poprzednich wersjach systemu BASIC.
Współpraca translatora z systemem
Translator BASIC został przystosowany do zmian w systemie operacyjnym. W zleceniach: OLD, APP, LGO, MERGE, SAVE, NSAVE, VRU i DMP, oraz w instrukcjach: FILE i CHAIN dopuszczalne są pełne tytuły zbiorów. Zlecenie SAVE ma postać:
[N]SAVE [<TZ>[,<nazwa modułu>]...]
Gdzie <nazwa modułu> oznacza nazwę programu głównego lub subprogramu.
Pominięcie parametrów oznacza polecenie przepisania całego programu wraz z subprogramami do zbioru o nazwie takiej samej jak nazwa programu głównego. Przy pobieraniu programu ze zbioru do pamięci analizowany jest typ zbioru. Poszczególne typy oznaczają:
- CHR, BAS, DEV, 0 - program lub subprogram w postaci znakowej,
- BAB - zbiór utworzony zleceniem VRU lub DMP,
- SUB - zbiór zawierający subprogram binarny.
W fazie realizacji programu kanał 0 jest dołączony na stałe do końcówki. Chcąc współpracować ze strumieniem zleceń należy zdefiniować kanał dołączony do zbioru STR//INT (lub dla wyjścia do STR//OUT). Analizując typ zbioru STR//INT (uzyskany za pomocą funkcji FIL$) można łatwo sprawdzić, czy program jest wykonywany w wyniku realizacji makrozlecenia. Przy operacjach WE/WY analizowany jest parametr MEM i atrybuty zbioru. Dla zbiorów sekwencyjnych (instrukcje PRINT i INPUT) musi być MEM=4 i ATR=0 lub ATR=040; dla zbiorów o dostępie swobodnym odpowiednio MEM=8 i ATR=0. Zlecenie PRINT (MAT PRINT) przy pierwszym zapisie do już istniejącego zbioru ustawia wskażnik zapisu na koniec zbioru. Chcąc zapisywać do zbioru od początku należy po instrukcji FILE wykonać instrukcję RESET #K: .
Możliwe jest wywołanie translatora z parametrem będącym dowolnym wierszem przez niego akceptowanym. Przy wywołaniu w taki spos_b system BASIC nie wyprowadza niektórych swoich standardowych komunikatów (np. komunikatu RUNNING...) - wygodnie jest zatem używać tej postaci wołania w makrozleceniach. Po zakończeniu pracy (zlecenia BYE i EXI) wartość wewnętrzna równa jest liczbie błędów jakie wystąpiły od chwili wywołania translatora. W tym sensie instrukcja STOP traktowana jest jako błąd, instrukcja zaś END nie.
Programy pomocnicze
Wszystkie programy pomocnicze przygotowane w języku BASIC są dostarczane w postaci binarnej (powinny być uruchamiane za pomocą zlecenia LGO).
DLIB - Program dwustronicowego drukowania programów napisanych w języku BASIC. Program DLIB wykonuje automatyczny podział tekstu na strony, oraz wprowadza wcięcia zwiększające czytelność wydruku.
Przygotowanie subprogramów w assemblerze
Do wykonywania operacji pomocniczych podczas przygotowywania subprogramów w assemblerze służy program FRAMES, oraz makrozlecenie BASBIN.
- FRAMES
Program przygotowania nagłówków subprogramów w assemblerze. Program przygotowuje nagłówki, słowniki, obszary robocze i inne elementy potrzebne w prawidłowym subprogramie. Do zbioru przygotowanego przez program należy dołączyć (wstawić edytorem we wskazane miejsca) instrukcje realizujące wymagane funkcje.
Po uruchomieniu programu na zapytanie:
- SUB
należy podać nazwę subprogramu i listę jego parametrów formalnych. Składnia odpowiedzi jest taka sama jak składnia instrukcji SUB języka BASIC. Parametrami mogą być zmienne, formalne zmienne indeksowane i funkcje - arytmetyczne jak i łańcuchowe. Nazwy te mogą być rozszerzone do sześciu znaków i powinny być wszystkie unikalne (nie może być np. zmiennej A i funkcji FNA).
Pojawienie się na liście parametrów zmiennej łańcuchowej spowoduje dołączenie procedury odnajdującej adres początku łańcucha będącego wartością zmiennej; funkcji definiowanej - procedury obliczania wartości tej funkcji. Dla funkcji definiowanej pojawia się dodatkowo żądanie podania wzorca wołania tej funkcji. W odpowiedzi należy podać listę parametrów zakończoną znakiem ')'. Komentarze i etykiety umieszczane w zbiorze wynikowym powinny ułatwić prawidłowe wkomponowanie instrukcji opisujących funkcje subprogramu.
Osobnego komentarza wymaga lista parametrów formalnych subprogramu. Lista ta, jak i listy parametrów funkcji, posłużą do przygotowania słownika zmiennych. W słowniku znajdują się czterosłowowe pola odpowiadające zadeklarowanym zmiennym. W pierwszym słowie znajduje się nazwa i specyfikacja typu zmiennej (używana tylko w zleceniu CAT), następne trzy (poprzedzone etykietą) zawierają miejsce gdzie przy wywołaniu subprogramu zostanie przesłana wartość parametru aktualnego. Przy powrocie z subprogramu z tego pola zostaną pobrane wartości zmiennych przekazywanych do programu wołającego.
W zależności od rodzaju i typu zmiennej w kolejnych słowach pola wartości zmiennej znajdują się:
- zmienna prosta - wartość zmiennej w postaci zmiennopozycyjnej,
- funkcja def. - wartość ostatnio wyliczonej funkcji,
- macierz arytm. - w kolejnych słowach znajdują się: liczba wierszy, liczba kolumn i adres początku tablicy w pamięci,
- wektor arytm. - jak macierz, tylko liczba kolumn równa zero,
- zmienna łańc. - w trzecim słowie indeks wskazujący pozycję zmiennej; indeks ten jest argumentem procedury #FISTRE podającej adres poczatku zmiennej,
- funkcja łańc. - jak zmienna,
- macierz łańc. - dwa słowa jak dla macierzy arytmetycznej, indeks w trzecim słowie,
- wektor łańc. - dwa słowa jak dla wektora arytmetycznego, indeks w trzecim słowie.
Uwagi:
- Przy wywołaniu funkcji definiowanej należy do odpowiednich pól w słowniku przesłać wartości argumentów (zgodnie z podanym wzorcem wywołania). Wartość funkcji zostanie umieszczona w polu wartości funkcji w liście zmiennych.
- Procedura #FISTRE służy do odnalezienia zmiennej łańcuchowej według zadanego indeksu. Procedura wraca adres zmiennej, pod którym w pierwszym słowie znajduje się długość zmiennej (liczba bajtów) dalej zaś kolejne znaki (bajty) wchodzące w skład zmiennej.
- Macierze uporządkowane są wierszami, przy czym w macierzach arytmetycznych elementy A(0,0), A(0,1), ..., A(0,M), A(1,0), ..., A(N,0) umieszczone są na końcu.
- Tekst wyprodukowany przez program jest zaopatrzony w komentarze, wyjaśniające szczegóły nie opisane w tym miejscu.
Do translacji subprogramów binarnych służy makrozlecenie:
BASBIN <TZ_we> <TZ_bin>
Parametrami są:
- <TZ_we> - tytuł zbioru zawierającego tekst żródłowy subprogramu w języku symbolicznym ASSM,
- <TZ_bin> - tytuł zbioru w którym zostanie umieszczony gotowy do załadowania (zleceniem APP) subprogram binarny.
W makrozleceniu używany jest program pomocniczy BASBIC tworzący mapę bitową adresów bezwzględnych. Z tego względu zmienne określające adresy bezwzględne w tekście subprogramu nie mogą być uwikłane w żadne (z wyjątkiem dodawania stałej) działania arytmetyczne, ani też skalowane.
Makrozlecenie może być używane także do translacji podprogramów binarnych dla translatora CEMMA.
Zmiany w działaniu translatora
- Nie jest dopuszczalne użycie zlecenia COMpile.
- W łańcuchach dopuszczalne jest używanie znaków o kodach 0-255. W związku z tym w wyniku działania instrukcji WRITE A$ oraz READ A$ łańcuch A$ zostanie uzupełniony znakami o kodzie 0 (NUL) do długości odpowiadającej wartości funkcji MRG dla użytego kanału.
- Znak cudzysłowu jest reprezentowany w łańcuchach poprzez dwa znaki cudzysłowu.
- Łańcuch będący wartością funkcji FIL$(N) jest uzupełniony o przedłużenie nazwy zbioru (TYP).
- Łańcuch będący wartością funkcji CUF$ zawiera dodatkowo numer wiersza wywołania tej funkcji.
Literatura
- ↑ Martin W.J.: "Podręcznik programowania w języku BASIC i użytkowania systemu BASIC/CROOK" Wyd. Politechniki Gdańskiej, 1982 r.
Źródło: SYSTEM OPERACYJNY CROOK-5 dla minikomputera MERA-400 (wersja 7), Zbigniew Czerniak, Marek Nikodemski, Gdańsk 1988