System na talerzu (cz. 16.) --------------------------- AMIGA DOS Marek Pampuch ENDSHELL (zakoïcz Shell) skîadnia dla systemów 1.3,2.0, 2.1, 3.0 i 3.1: ENDSHELL W systemie 1.2 rozkaz ten nie wystëpuje Rozkaz ten powoduje zakoïczenie aktualnego procesu Shella (lub CLI) i zamyka jego okno. Przy okazji czyôci ômieci z pamiëci, a robi to zdecydowanie lepiej niû jego poprzednik EndCLI, a zatem jeôli tylko Wasz system operacyjny dopuszcza ten rozkaz, powinno sië go stosowaê zamiast EndCLI. Jeôli w momencie wprowadzenia rozkazu byîy wykonywane jakieô inne rozkazy w zamykanym Shellu, zwîaszcza uruchomione ze skryptu za pomocâ RUN, oraz korzystajâce z odwoîaï do EXEC -- rozkaz EndShell zakoïczy dziaîanie dopiero wówczas, gdy przestanâ dziaîaê tamte rozkazy. Nie naleûy sië zatem denerwowaê, jeôli okno nie zamknie sië od razu, co wprawdzie rzadko, ale sië zdarza. ENDIF (zakoïcz IF) skîadnia dla wszystkich systemów: ENDIF Rozkaz ten moûe byê uûywany tylko w skryptach. Koïczy pëtlë rozpoczëtâ przez IF. Przykîad: IF NOT WARN; jeôli kod bîëdu <>5 ECHO "cos tutaj nie gra"; wyswietl komunikat ELSE ECHO "wszystko O.K" ENDIF ENDSKIP (zakoïcz SKIP) skîadnia dla systemów 1.3, 2.0, 2.1, 3.0 i 3.1: ENDSKIP W systemie 1.2 rozkaz ten nie wystëpuje Takûe i ten rozkaz moûe wystëpowaê wyîâcznie w skryptach. Pozwala na zakoïczenie bloku, do którego nastâpiî skok przez SKIP. Wprawdzie skok taki najczëôciej wykonywany jest do etykiety (i wówczas rozkazu ENDSKIP nie potrzeba uûywaê), niemniej nieraz po skoku musi byê wykonana caîa sekwencja czynnoôci. Rozkaz generuje ponadto kod zwrotny (returncode), co moûe sië przydaê do innych celów w pisanym skrypcie. Przykîad: SKIP exit echo "1 *n" ENDSKIP echo "2 *n" IF WARN echo "3 *n" LAB exit echo "4 *n" QUIT 5 ENDIF Cyferki umieôciîem tu, abyôcie mogli lepiej zobaczyê przebieg programu. A jest na co popatrzeê. Mimo "wymuszonego" w pierwszym wierszu skoku do etykiety exit -- skok nastëpuje nie tam, a do najbliûszej po ENDSKIP instrukcji. Dodatkowo, poniewaû wszystko jest w porzâdku, nastëpuje kolejny skok do ENDIF i koïczy sië program. Wyrzuêmy teraz ze skryptu pierwszy wiersz i uruchommy go ponownie. Poniewaû nie ma SKIPA -- ENDSKIP zostanie zlekcewaûony, a poniewaû dalej wszystko jest OK -- program zakoïczy sië tak samo. Wprowadúmy nastëpnâ zmianë -- usuïmy rozkaz ENDSKIP. Jeôli dotâd nie zrozumieliôcie -- sorry, nie jestem w stanie lepiej tego wytîumaczyê. Poeksperymentujcie z tym skryptem, choê najpierw trzeba sië zastanowiê po co? ENDSKIP jest bowiem chyba najrzadziej uûywanym rozkazem AmigaDOS-u. Ja sam uûyîem go dotâd dwa razy (raz przy pisaniu ksiâûki "Moja Amiga", drugi raz -- teraz). EURO36 (tryb wyôwietlania) skîadnia dla systemów 2.1, 3.0 i 3.1: EURO36 W pozostaîych systemach rozkaz ten nie wystëpuje. Parametry rozkazu, i ich znaczenie, sâ takie same jak dla rozkazu ADDMONITOR (patrz Magazyn AMIGA nr 3/94). Pozwala na regulacjë wyôwietlania monitora pracujâcego w trybie EURO 36. Monitor umoûliwiajâcy pracë w trybie EURO36 powinien mieê odchylanie poziome 15,76 kHz, a pionowe 73 Hz. Tryb ten pozwala na wyôwietlanie obrazków bez interlace'u z rozdzielczoôciâ do 1280 x 200 pikseli, a z nim -- 1280 x 400 pikseli, jednak nie wspóîpracuje z genlockiem. Poniûej wszystkie tryby dla trybu EURO 36. Dla Amig z ukîadami ECS: rozdzielczoôê maks. liczba kolorów 640 x 200 16 640 x 400 16 640 x 200 32 640 x 400 32 1280 x 200 4 1280 x 400 4 Dla Amig z ukîadami AGA: rozdzielczoôê maks. liczba kolorów 320 x 200 256 320 x 400 256 640 x 200 256 640 x 400 256 1280 x 200 256 1280 x 400 256 EURO72 (tryb wyôwietlania) skîadnia dla systemów 2.1, 3.0 i 3.1: EURO72 W pozostaîych systemach rozkaz ten nie wystëpuje. Parametry rozkazu, i ich znaczenie, sâ takie same jak dla rozkazu ADDMONITOR (patrz Magazyn AMIGA nr 3/94). Pozwala na regulacjë wyôwietlania monitora pracujâcego w trybie EURO 72. Monitor umoûliwiajâcy pracë w trybie EURO 72 powinien mieê odchylanie poziome 31,43 kHz, a pionowe 70 Hz (jak na przykîad monitory VGA). Tryb ten pozwala na wyôwietlanie obrazków bez interlace'u z rozdzielczoôciâ do 640 x 400 pikseli, a z nim -- 640 x 800 pikseli, jednak nie wspóîpracuje z genlockiem. Poniûej wszystkie tryby dla trybu EURO 72: Dla Amig z ukîadami ECS: rozdzielczoôê maks. liczba kolorów 640 x 400 4 640 x 800 4 Dla Amig z ukîadami AGA: rozdzielczoôê maks. liczba kolorów 640 x 400 256 640 x 800 256 Jeôli Twój monitor ma nieco inne wartoôci odchylania, naleûy zastosowaê do niego specjalny sterownik o nazwie "VGAOnly". Bëdziecie mogli wówczas stosowaê w trybie EURO 72 monitory o odchylaniu od 29,32 kHz (poziomo) oraz od 69 Hz (pionowo). EVAL (ocena) skîadnia dla systemu 1.3: >nn< >dzial< >mm< [TO >n1<] [LFORMAT=>wzor<] skîadnia dla systemów 2.0, 2.1 ,3.0 i 3.1: EVAL [VALUE1=] >nn< [OP=] >dzial< [VALUE2=] >mm< [TO >n1<] [LFORMAT=>wzor<] gdzie: nn i mm to wartoôci numeryczne, dzial -- dziaîanie matematyczne, n1 -- nazwa zbioru, w jakim chcemy zapisaê wynik, a wzor -- wzorzec, z jakim ma byê sformatowany wynik (patrz niûej). wzorzec dla systemu 1.3: VALUE1/A, OP, VALUE2/M, TO/K, LFORMAT/K wzorzec dla systemów 2.0, 2.1 ,3.0 i 3.1: VALUE1/A, OP, VALUE2/M, TO/K, LFORMAT/K w systemie 1.2 rozkaz ten nie wystëpuje. W duûym uproszczeniu moûna przyjâê, ûe EVAL jest kalkulatorem dla systemu AmigaDOS. System operacyjny nie posîuguje sië nim jednak w sposób, do jakiego wszyscy przywykliômy -- mogâ byê tu wykorzystywane zarówno zmienne "zwykîe" (odnoszâce sië do pojedynczego zadania, stâd nazywane czësto lokalnymi, jak numer zadania, kod wynikowy z IF lub WHY, czy teû zwyczajna wartoôê cyfrowa), jak i tak zwane zmienne ôrodowiskowe (odnoszâce sië do caîego systemu, stâd nazywane nieraz globalnymi, jak nazwa ôcieûki dostëpu, numer wersji Kickstartu czy Workbencha, lub teû zwykîa wartoôê liczbowa). UWAGA: Shell systemu 1.3 nie rozróûnia zmiennych lokalnych i globalnych -- wszystkie sâ dla niego "ôrodowiskowe", Stâd zresztâ wziëîa sië nazwa rozkazu, wprowadzonego w tej wîaônie wersji systemu. EVAL bowiem równie dobrze moûe byê sîowem "ocena", jak i skrótem od E(nvironment)VA(riab)L(e). Co to jest takiego ta zmienna? O tym przeczytacie juû niedîugo w kolejnym suplemencie. Na poczâtku zajmiemy sië wykorzystaniem takich zmiennych w opisywanym rozkazie EVAL. Jak juû wspomniaîem, jest to "systemowy kalkulator", ale nie caîkiem taki, do jakiego zdâûyliôcie sië przyzwyczaiê. Moûna takûe mieszaê w dziaîaniach wartoôci zmiennych lokalnych i globalnych. Wszystkie poniûsze przykîady sâ jak najzupeîniej poprawne z punktu widzenia systemu (z wyjâtkiem systemu 1.3 -- patrz dalej): SETENV x 4; tworzymy zmiennâ ôrodowiskowâ i nadajemy jej wartoôê 4 EVAL $x + 1 Jeôli wpiszemy te rozkazy z rëki, to na ekranie pojawi sië cyfra 5. UWAGA: nie dotyczy to systemu 1.3, który wyôwietli na ekranie odpowiedú 0 (a dlaczego -- zaraz sië okaûe). Wynik dziaîania moûna takûe zapisaê do jakiegoô zbioru, na przykîad: EVAL $x + 1 TO ENV:iks A teraz przykîad "mieszany". Wpiszmy z rëki kolejno: SET local 24; zmienne lokalne tworzymy nie za pomocâ SETENV, lecz normalnego SET SETENV global 45 EVAL $local + $global Nieco bardziej skomplikowane jest to w systemie 1.3. Przykîad wpisany jak powyûej nie zadziaîa wîaôciwie. Po pierwsze rozkaz "set" jest dla WB 1.3 nie znany (naleûy tu uûyê takûe SETENV do tworzenia zmiennej globalnej), po drugie zaô w wyniku dziaîania EVAL znów otrzymamy...0. Dlaczego? Wynika to z niedopracowania rozkazu dla systemu 1.3. Aby zobaczyê poprawny wynik naszego prostego dziaîania na ekranie, trzeba skorzystaê z pomocy zbioru tymczasowego. W tym celu musimy wypisaê wielce skomplikowanâ formuîë: SETENV x 24 SETENV y 45 EVAL NIL: $x + $y TO=* Straszne, nieprawdaû? Po prostu AmigaDOS 1.3 nie umie normalnie liczyê (bierze sië to stâd, ûe redyrekcja nie zamyka zbioru przed zakoïczeniem rozkazu. Uciâûliwoôê ta zostaîa unicestwiona w kolejnych wersjach dziëki lepszym handlerom). Musimy zatem najpierw wczytaê aktualnâ wartoôê, jaka sië znajduje w naszym zbiorze ("iks"), a nastëpnie dodaê wartoôê (VALUE) i zapisaê "na konsolë" (stâd gwiazdka na koïcu ostatniego wiersza). Jeszcze gorzej wyglâda ta sprawa w najstarszych wersjach systemu operacyjnego 1.3, w którym Shell nie potrafi wykonaê takiej prostej redyrekcji. Niewiele lepiej majâ uûytkownicy systemu 2.0 (chodzi o najwczeôniejsze wersje, od wersji 2.04 ten bîâd zostaî juû usuniëty). Gdy bowiem po wpisaniu przykîadu "mieszanego" zechcâ sprawdziê, jakie wartoôci miaîy skîadniki dodawania, to wynik bëdzie nastëpujâcy: GETENV global Tu na ekranie pojawi sië liczba 45 i bëdzie to w porzâdku, jednak po wpisaniu: GET local zamiast oczekiwanej liczby 24 pojawi sië na ekranie komunikat: Can't get local Bierze sië to stâd, ûe nie ma wîaôciwej komunikacji pomiëdzy poszczególnymi zadaniami, a zmienne lokalne naleûâ do "innego Shella" niû ten, w którym wykonywaliômy nasze dziaîania. Na marginesie: tu akurat Shell systemu 1.3 nie bëdzie sprawiaî kîopotów. Wróêmy jednak do rozkazu EVAL. Moûemy wykorzystaê nasz "podrëczny" DOS-owski kalkulator do konwersji. Na przykîad: EVAL 0xffff da w wyniku 65535. Przedrostek "0x" oznacza konwersjë z liczby heksadecymalnej (szesnastkowej) na dziesiëtnâ. Moûna teû zastâpiê "0x" przez "#x" (w naszym wypadku "#xffff"). EVAL 052 da w wyniku 42. Przedrostek "0" oznacza konwersjë z liczby oktalnej (ósemkowej) na dziesiëtnâ (moûna teû zastosowaê "#0"). Nie naleûy natomiast poprzedzaê zerem w rozkazie EVAL liczb dziesiëtnych, bo zostanâ one wówczas potraktowane jako ósemkowe. EVAL 'H da w wyniku 72, czyli kod ASCII tej litery. Przy podawaniu liter musimy je poprzedziê znakiem apostrofu. Przypominam, ûe na "niemieckiej" klawiaturze takiego "apostrofu" nie ma i uzyskamy go naciskajâc [Alt] i [A umlaut] (czyli A z dwiema kropkami na górze). Niestety, konwersja w drugâ stronë nie jest moûliwa, bo EVAL moûe "wydawaê" tylko wartoôci cyfrowe (z jednym wyjâtkiem, patrz na koïcu). Natomiast nasz EVAL moûe jeszcze "obliczaê" wiele dziwnych wartoôci, które mogâ sië póúniej przydaê w skrypcie, i tak: * przedrostek "0e", po którym nastëpuje liczba, wykonuje na liczbie "dziwnâ" (patrz dalej) operacjë, polegajâcâ na dodaniu do tej liczby 1 i zmianie jej znaku, na przykîad. EVAL 0e10 da w wyniku -11, a EVAL 0e-10 da w wyniku 9. Podobnie bëdzie dla jakiejkolwiek innej liczby z dopuszczalnego dla EVAL zakresu od -2147483649 do +2147483647. Przy liczbach spoza tego zakresu zacznâ tu wychodziê zupeînie inne wyniki (podobnie zresztâ bëdzie przy jakichkolwiek innych dziaîaniach, bo EVAL "trawi" liczby najwyûej 32-bitowe). Identyczny wynik da przedrostek #e lub przedrostek ~ (tylda). Tych z Was, którzy sië jeszcze tego nie uczyli lub juû zapomnieli, informujë, ûe takie dziaîanie nazywa sië "negacjâ logicznâ" (NOT). * apostrof poprzedzajâcy liczbë da w wyniku kod ASCII pierwszej cyfry tej liczby, a zatem taki sam wynik, równy 51, otrzymamy przy dowolnym z poniûszych dziaîaï: EVAL '3 EVAL '31 EVAL '393939394 Oczywiôcie moûna nim wykonywaê takûe cztery podstawowe dziaîania matematyczne, takie jak (na przykîad): EVAL 2/2 EVAL 4/-2 Nawiasy zmieniajâ kolejnoôê dziaîaï i EVAL (2*3)+4 to, podobnie jak w matematyce, wcale nie to samo co: EVAL 2*(3+4) Moûna stosowaê dowolnâ liczbë nawiasów, pamiëtajâc jednak o tym, aby je "zamknâê". Jeôli tego nie zrobimy, zamiast spodziewanego komunikatu otrzymamy na ekranie informacjë: Mismatched parenthesis Nasz "kalkulator" pozwala takûe wykonywaê operacje logiczne, uûywajâc w miejscu operatora jednego ze znaków: & (AND), | (OR), ~ (NOT), XOR, na przykîad: EVAL 1 & 0 EVAL 0 | 1 i tak dalej. To nie wszystko. Moûemy takûe porównywaê wartoôci bitowo, a to za pomocâ operatora EQV, na przykîad: EVAL 1 eqv 0 Jeôli wynik takiego porównania jest logicznâ prawdâ (na przykîad 175 eqv 175), otrzymamy -1, w przeciwnym razie -- innâ cyfrë. Moûna takûe korzystaê z "shiftowania". Na przykîad w prawo przez: EVAL 1 >> 4 i w lewo (zmieniajâc odpowiednio kierunek dziubków). Z niepojëtych dla mnie przyczyn "shiftowanie" dziaîa bez zarzutu z systemem 1.3, natomiast ma duûe kîopoty w wersji ... 3.0, przy której oblicza wprawdzie poprawny wynik, ale nie przekazuje go na konsolë. Trzeba sobie tu radziê za pomocâ parametru TO, który kieruje wynik dziaîania nie na konsolë, ale do zbioru. Parametr ten jest najczëôciej stosowany w skryptach, przy wykonywaniu "zapëtlonych" obliczeï. Uwaga: Przy takiej zabawie naleûy pamiëtaê o tym, aby je jakoô zakoïczyê. Jeôli na przykîad wpisalibyômy (NIE RÓBCIE TEGO NA TWARDYM DYSKU!!!): lab start eval 2*2 to df0:TEST SKIP start BACK to w bardzo szybkim czasie zapeînimy caîy dysk zbiorem test zawierajâcym same czwórki. W naszym przypadku z "shiftowaniem" moûe to byê: EVAL 1 >> 4 TO RAM:test TYPE RAM: test Kolejnym operatorem, jaki moûemy zastosowaê w EVAL, jest "modulo" (czyli reszta z dzielenia), na przykîad: EVAL 7 mod 3 Tu znowu zawodzi Shell 1.3, mimo ûe w oryginalnej instrukcji do tego systemu kîamczuszki ze ôp. Commodore twierdzâ, ûe moûna stosowaê ten operator. LFORMAT -- pozwala na uzyskanie wyniku w okreôlonym formacie zaleûnym od zastosowanego wzorca. I tak: %c -- poda wynik jako znak; %n -- poda wynik jako liczbë dziesiëtnâ; %oZ -- poda wynik w formacie ósemkowym; %xZ -- poda wynik w formacie szesnastkowym; gdzie Z jest to liczba caîkowita okreôlajâca, ile liczb ma byê wydrukowanych (wolno go uûyê tylko z opcjâ %o i %x). W praktyce naleûy byê jednak przygotowanym na pewne niespodzianki. I tak, jeôli uûyjemy tego rozkazu z rëki, na przykîad: EVAL 2*4 LFORMAT %n to wprawdzie otrzymamy w wyniku ósemkë, ale tuû za niâ zostanie wypisany "prompt" Workbencha. Nie zawsze chcemy mieê wskaúnik zachëty w rodzaju: 84.WORKBENCH:> Naleûy zatem wprowadziê jakiô [CR]. Ale jak to zrobiê z rëki? A choêby i tak: EVAL 2*4 LFORMAT "Wynik to %n *n" (koïcowe "*n" powinniôcie pamiëtaê z niedawno opisywanego rozkazu ECHO). Jeôli pominiemy parametr okreôlajâcy dîugoôê wydruku, to zostanie wyôwietlona tylko ostatni znak wyniku, jeôli natomiast bëdzie on wiëkszy niû liczba znaków wyniku, to brakujâce pozycje zostanâ uzupeînione zerami na poczâtku. Porównajcie wyniki dwóch poniûszych dziaîaï: EVAL 2*127 "Wynik to %x *n" EVAL 2*127 "Wynik to %x4 *n" Jeôli natomiast w powyûszym dziaîaniu zastâpimy %x przez %c (tu nie stosujemy wyznacznika dîugoôci), to zostanie wyôwietlony znak, któremu odpowiada wynikowy kod ASCII. Uwaga: EVAL nie jest tu zabezpieczony przed geniuszami, którzy zacznâ sobie wpisywaê dowolne cyfry, a zatem moûna daê na przykîad równie dobrze: EVAL -1 "Wynik to %c *n" jak i: EVAL 29126 "Wynik to %x *n" Nie bëdzie jednak to robione bezmyôlnie. Taki sam znak "Ë" zostanie wyôwietlony zarówno dla liczby (wyniku) 203, jak i dla 459 czy -53. Kapewu? (Jeôli nie, to dodawajcie sobie albo odejmujcie od wîaôciwego kodu ASCII liczbë 256 lub jej wielokrotnoôê). ***************** TEN FRAGMENT RAFAÎ SPRAWDÚ SZCZEGÓLNIE UWAÛNIE ******* Ostatnim zastosowaniem rozkazu EVAL jest "licznik w pëtlach" skryptu. Moûe on wyglâdaê na przykîad tak: SETENV licz 1; ten wiersz zapisze wartoôê 1 w zmiennej ôrodowiskowej lab start; zaczynamy echo "Pëtla nr" noline; to nam wypisze kolejny numer pëtli... GETENV licz; ...który jest podany tutaj EVAL $licz + 1 to ENV:loop; tu zwiëkszymy jâ o 1 if val $licz not GT 10; a tu sprawdzimy czy nie jest wiëksza od 10 skip start back; jeôli nie to wracamy do poczâtku endif; a jeôli tak to koïczymy echo "koniec" ******************* RAF PRZEROB TO niûej SZCZEGÓLNIE DOKÎADNIE ************ Dla Amig z systemem 1.3 nasz "licznik" bëdzie nieco bardziej skomplikowany i bëdzie wyglâdaî jak poniûej: .key licz .bra { .ket } echo >env:licz {licz} lab start echo "Pëtla nr" noline type env:licz EVAL NIL: to t:qve{$$} value2=1 op=+ ? type >env:licz t:qwe{$$} if val $licz NOT GT 10 skip start back endif echo "koniec" ***** RAFAÎ CO TU JEST DO CHOLERY!!! TO TEORETYCZNIE MUSI DZIAÎAÊ (w koïcu przepisaîem ten drugi przykîad ûywcem z oryginalnego podrëcznika Commodore A NIE CHCE ANI NA A1200, ANI NA A500. MAM DOÔÊ STRACIÎEM DWA DNI I WIËCEJ NIE CHCË. jEÔLI SOBIE NIE PORADZISZ Z TYM TO SKREÔL TEN FRAGMENT, ale gîupio byîoby jakby byî przykîad dla wszystkiego poza A500 ********************************************************************** Za pomocâ rozkazu EVAL moûna takûe nieco pomieszaê, ale nie napiszë o tym, bowiem "a widelec" zechcielibyôcie to wpalcowaê na swojej Amidze. I kto by potem pîaciî alimenty? Do zobaczenia za miesiâc