• Dodajemy nowe funkcje do programów AmigaDOS-u na przykładzie programu AllowBad

16.04.2011 14:36, autor artykułu: Aleksander "APC74" Chyliński
odsłon: 2460, powiększ obrazki, wersja do wydruku,

Coraz ciężej jest dostać dobre dyskietki do Amigi - a te, które posiadam, coraz częściej padają. Od dawna do formatowania dyskietek zamiast systemowej komendy Format używam świetnego programu, autorstwa Mikołaja Całusińskiego, o nazwie AllowBad. Dzięki temu poleceniu nawet nośników w stanie - zdawałoby się - krytycznym można jeszcze użyć. Oczywiście Superfroga z "padaczek" uruchomić się nie da, ale do przenoszenia jakichś małych pliczków między komputerami takie przywrócone do życia dyskietki są w sam raz.
W ciągu tych wszystkich lat używania AllowBada brakowało mi w nim kilku drobiazgów. Po pierwsze - dobrze byłoby, gdyby program oznaczał uszkodzone dyskietki, zmieniając im nazwę np. na BadFloppy, żeby od razu po włożeniu takiej dyskietki do napędu było widać, że jest niepełnosprawna. Druga sprawa to konieczność podawania programowi, przy każdym jego uruchomieniu, parametrów DRIVE (czyli urządzenia, w którym będziemy formatować dyskietki, np. DF0:, SD1: itp.) oraz parametru NAME (nazwy dla formatowanej dyskietki). To, że są te opcje wymagane przez program to oczywistość, ale gdy formatuje się nośniki zawsze w tym samym napędzie i zwykle nadaje się im tą samą nazwę, to fajnie byłoby, gdyby można było je jakoś na stałe zdefiniować w programie i nie musieć za każdym razem, gdy korzystam z AllowBada ich wklepywać. Rozwój programu zatrzymał się w roku 1996 i raczej nie ma co liczyć na to, że autor doda te dwa drobiazgi do niego. Dlatego też postanowiłem wziąć sprawy we własne ręce i napisać nakładkę na program w postaci skryptu AmigaDOSu, który "dorzuci" do AllowBada te brakujące mi funkcje.
Poniżej zamieszczam skrypt uzupełniony o komentarze. Skrypt ten można uruchamiać jak inne polecenia AmigaDOS, przekazując mu parametry (to tak na wypadek, gdybym jednak chciał sformatować dyskietkę w urządzeniu innym niż domyślne DF0: itp.). Parametry są żywcem przepisane ze składni polecenia AllowBad, z małym wyjątkiem - dodałem tu opcję BADDISKNAME służącą do podawania nazwy dla uszkodzonej dyskietki.


.KEY DRIVE/K,NAME/K,BADDISKNAME/K,OFS/S,INTL/S,INTERNATIONAL/S,DIRCACHE/S
.BRA {
.KET }
;polecenie .KEY (szczegółowy opis polecenia) pozwala nam na przekazanie do skryptu parametrów, tak jak ma to miejsce w przypadku poleceń/programów uruchamianych z linii poleceń. Jak widać, jest to w zasadzie standardowy wzorzec ADOS (więcej o wzorcach znajdziesz tu).
;poleceń .BRA i .KET (sczegółowy opis tu) użyłem, ponieważ w skrypcie korzystam z redyrekcji (przekierowań strumieni/wyjścia), żeby nie zaciemniać składni skryptu.

Echo "C:AllowBad " >T:AllowBad_skrypt NOLINE
;Przekierowując wyjście polecenia Echo (opis polecenia) z ekranu do pliku, rozpoczynam budowę skryptu uruchamiającego dla polecenia AllowBad.

Echo "Log skryptu patchującego AllowBad" >T:AllowBad.log
Echo "Utworzony: " >>T:AllowBad.log NOLINE
Date >>T:AllowBad.log
Echo "" >>T:AllowBad.log
Echo "---------------------------------" >>T:AllowBad.log
;A tu zakładam sobie plik logu dla skryptu. Zwróć uwagę, że o ile w pierwszym przypadku (przy zakładaniu plików logu i skryptu uruchamiającego AllowBad) przy przekierowaniu użyłem jednego znaku '>' to już dalej używam podwójnego znaku przekierowania ('>>'). Przekierowanie oznaczone jednym znakiem '>' tworzy nowy plik lub też - gdy taki plik już istnieje, usuwa go i zakłada nowy (nadpisuje jego zawartość). Przekierowanie za pomocą podwójnego znaku, czyli '>>' dopisuje dane do już istniejącego pliku na jego końcu, nie zamazując jego zawartości (lub też zakłada nowy plik, jeżeli taki plik nie istnieje).


IF {DRIVE}NULL EQ NULL
;Sprawdzam, czy skrypt został wywołany z parametrem DRIVE. Wpisanie nazwy parametru w nawiasach powoduje podanie jego wartości - czyli gdybyśmy uruchomili skrypt z parametrem DRIVE DF1:, to do polecenia IF zwrócona zostałaby wartość DF1:. Jeżeli skrypt zostanie uruchomiony bez tego parametru to poleceniu IF nic nie zostanie zwrócone, dlatego też dodałem do wartości parametru DRIVE wartość NULL - wtedy polecenie IF będzie miało co porównywać (opcja EQ) niezależnie od tego, czy parametr zostanie podany - czy też nie. Oczywiście zamiast 'NULL' można podać cokolwiek innego, ważne jest tylko to, żeby zarówno przed opcją EQ, jak i za nią użyć takiego samego ciągu znaków.
;Podsumowując: jeżeli nie podano zmiennej DRIVE przy uruchomieniu skryptu, to:

Echo "- Nie wskazano napędu dyskietek - ustawiam napęd na DF0:" >>T:AllowBad.log
;dodajemy stosowny wpis do logu skryptu,

Echo "DRIVE DF0:" >>T:AllowBad_skrypt NOLINE
;dopisujemy do naszego skryptu startowego dla AllowBad domyślny napęd (tu DF0: - ale zawsze możecie go zmienić na coś bardziej Wam odpowiadającego :) ).

ELSE
; (opis polecenia ELSE) jeżeli jednak podano parametr DRIVE przy uruchomieniu skryptu to:

Echo "+ Wybrany napęd dyskietek to {DRIVE}" >>T:AllowBad.log
;dodajemy stosowny wpis do logu skryptu,

Echo "DRIVE {DRIVE}" >>T:AllowBad_skrypt NOLINE
;przekazujemy do naszego skryptu nazwę tego urządzenia.

ENDIF
;koniec warunku dla parametru DRIVE.


IF {NAME}NULL EQ NULL
;sprawdzamy, czy podano NAME. Jeżeli nie

Echo "- Nie wybrano nazwy dla dyskietki - ustawiam nazwę na Fresh" >>T:AllowBad.log
;dodajemy stosowny wpis do logu

Echo " NAME Fresh" >>T:AllowBad_skrypt NOLINE
;dopisujemy domyślną nazwę dla sformatowanej dyskietki - będzie to nazwa dodana w przypadku gdy w trakcie formatowania AllowBad nie wykrył błędów na nosniku.

Set ABDiskName Fresh
;ustawiam zmienną lokalną z domyślną nazwą dla "bezbłędnej" dyskietki (więcej o poleceniu SET). Zmienną wykorzystamy później przy sprawdzaniu, czy dyskietka zawiera błędy, czy nie.

ELSE
;Jeżeli jednak podano nazwę dla bezbłędnie sformatowanej dyskietki to:

Echo "+ Nazwa dla dyskietki to {NAME}" >>T:AllowBad.log
;dodajemy stosowny wpis do logu

Echo " NAME {NAME}" >>T:AllowBad_skrypt NOLINE
;i dopisujemy podaną nazwę do naszego skryptu startowego

Set ABDiskName {NAME}
;ustawiamy też zmienną lokalną dla poprawnie sformatowanej dyskietki.

ENDIF
;Koniec warunku dla parametru NAME


IF {BADDISKNAME}NULL EQ NULL
;Jeżeli nie podano nazwy dla dyskietki zawierającej błędy:

Echo "- Nazwa dla dyskietki z błędami nie została wybrana - ustawiam na BadFloppy" >>T:AllowBad.log
;dodajemy stosowny wpis do logu

Set ABBadDiskName BadFloppy
;ustawiamy zmienną lokalną z domyślną nazwą dla dyskietki z błędami. Tym razem nie dodajemy tej zmiennej dla skryptu uruchamiającego AllowBada, gdyż program ten nie obsługuje tej zmiennej. Jej obsługą zajmiemy się w dalszej części skryptu, przy sprawdzaniu, czy dyskietka zawiera błędy, czy nie.

ELSE
; Jeżeli podano nazwę dla dyskietki z błędami, to:

Echo "+ Nazwa dla dyskietki z błędami to {BADDISKNAME}" >>T:AllowBad.log
;dodajemy stosowny wpis do logu

Set ABBadDiskName {BADDISKNAME}
;oraz tworzymy zmienną lokalną zawierającą tę nazwę.

ENDIF
;Koniec warunku dla parametru ABBadDiskName


IF {OFS}NULL EQ NULL
;jeżeli nie podano parametru OFS to:

Echo "- Opcja OFS nie została wybrana" >>T:AllowBad.log
;tylko informujemy o tym w logu i niczego nie dopisujemy do skryptu startowego

ELSE
;Jeżeli jednak podano parametr OFS to:

Echo "+ Opcja OFS została wybrana" >>T:AllowBad.log
;dodajemy stosowny wpis do logu

Echo " OFS" >>T:AllowBad_skrypt NOLINE
;dopisujemy parametr OFS do skryptu startowego AllowBada

ENDIF
;Koniec warunku dla OFS


Set ABINTL 0
;W programie AllowBad zmienną włączającą formatowanie dyskietki w trybie international można podać jako INTL lub INTERNATIONAL. Skrypt również ma taką możliwość - jednak, by ustrzec się sytuacji, że podamy jednocześnie obydwie zmienne (co może ogłupić program), zastosowałem zmienną lokalną ABINTL, która pozwoli nam sprawdzić i ewentualnie zignorować drugie (zbędne) wywołanie parametru INTERNATIONAL. Na początku ustawiam tą zmienną na 0, co będzie oznaczało, że parametr INTL nie został podany.

IF {INTL}NULL EQ NULL
;Jeżeli parametr INTL nie został podany to:

Echo "- Opcja INTL nie została wybrana" >>T:AllowBad.log
;dodajemy stosowny wpis do logu

ELSE
;Jeżeli jednak parametr INT został podany w trakcie uruchamiania skryptu to:

Echo "+ Opcja INTL została wybrana" >>T:AllowBad.log
;dodajemy informację o tym w logu

Echo " INTL" >>T:AllowBad_skrypt NOLINE
;dopisujemy zmienną w skrypcie startowym AloowBada

Set ABINTL 1
;ustawiamy wartość zmiennej lokalnej ABINTL na 1, co spowoduje, że skrypt nawet nie sprawdzi, czy podano również parametr INTERNATIONAL.

ENDIF
;Koniec warunku dla INTL


IF $ABINTL EQ 0
;Jeżeli nie podano parametru INTL (czyli, jeżeli wartość zmiennej ABINTL wynosi 0 - zauważ, że wartość zmiennej pobieramy, podając przed jej nazwą znak $ a nie, jak ma to miejsce w przypadku parametrów - ujmując je w nawiasy).

IF {INTERNATIONAL}NULL EQ NULL
;Jeżeli nie podano również parametru INTERNATIONAL:

Echo "- Opcja INTERNATIONAL nie została wybrana" >>T:AllowBad.log
;dodajemy informację o tym w logu

ELSE
;Jeżeli jednak podano parametr INTERNATIONAL

Echo "+ Opcja INTERNATIONAL została wybrana" >>T:AllowBad.log
;dodajemy informację o tym w logu

Echo " INTERNATIONAL" >>T:AllowBad_skrypt NOLINE
;dopisujemy zmienną do skryptu startowego AllowBada

ENDIF
;koniec warunku dla INTERNATIONAL

ENDIF
; Koniec warunku dla ABINTL

IF {DIRCACHE}NULL EQ NULL
;Jeżeli nie podano parametru DIRCACHE

Echo "- Opcja DIRCACHE nie została wybrana" >>T:AllowBad.log
;dodajemy informację o tym w logu

ELSE
;Jeśli jednak podano parametr DIRCACHE

Echo "+ Opcja DIRCACHE została wybrana" >>T:AllowBad.log
;dodajemy informację o tym w logu

Echo " DIRCACHE" >>T:AllowBad_skrypt NOLINE
;dopisujemy parametr DIRCACHE do skryptu startowego dla AllowBada

ENDIF
;Koniec warunku dla DIRCACHE


Execute T:AllowBad_skrypt
;Uruchamiamy wygenerowany skrypt startowy dla AllowBada


Assign $ABDiskName: EXISTS >NIL:
;Może się zdarzyć tak, że dyskietka jest tak bardzo uszkodzona, że nie da się jej sformatować nawet za pomocą programu AllowBad (np. gdy ma uszkodzony cylinder 0 - tu znajdują się informacje o formacie dyskietki, bootblock). Dlatego też najpierw sprawdzamy za pomocą polecenia Assign (więcej o poleceniu znajdziecie tu), czy programowi udało się sformatować dyskietkę - a właściwie czy dyskietka o nazwie zawartej w zmiennej lokalnej ABDiskName istnieje (domyślnie będzie to dyskietka o nazwie Fresh:).

IF NOT WARN
; jeżeli polecenie Assign nie zwróciło błędu (jeżeli dyskietka o podanej nazwie istnieje) to sprawdzamy dalej (jeżeli Assign zwrócił błąd, to pomijamy dalsze sprawdzanie):

IF EXISTS $ABDiskName:dummy.bad
;jeżeli na naszej świerzo sformatowanej dyskietce istnieje plik o nazwie dummy.bad - to znaczy, że AllowBad znalazł na niej ścieżki zawierające błędy i za pomocą tego pliku je zablokował.

Relabel $ABDiskName: $ABBadDiskName >NIL:
; W takim razie zmieniamy nazwę dyskietki za pomocą polecenia Relabel (opis polecenia) na tą podaną za pomocą parametru BADDISKNAME (lub też domyślną - BadFloppy) i którą skopiowaliśmy do zmiennej lokalnej ABBadDiskName

ENDIF
;Koniec warunku dla zmiany nazwy uszkodzonej dyskietki.

ENDIF
;Koniec warunku dla sprawdzania, czy dyskietkę udało się sformatować.


UnSet ABDiskName
UnSet ABBadDiskName
UnSet ABINTL
;Sprzątamy po sobie - usuwamy zmienne lokalne z pamięci komputera.

W tym archiwum znajdziecie oryginalny skrypt - bez komentarzy.

 głosów: 1   
1 komentarzostatni: 18.04.2011 11:15
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem