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.