DROBNOSTI O SPARTADOSu
Jak možná víte, vytvořil jsem před časem nový DOS pro osmibitové Atari - BW-DOS. Tento systém se snaží o maximální kompatibilitu se SpartaDOSem při minimální délce programu. A právě kvůli zmíněné kompatibilitě jsem během programování prováděl rozsáhlé srovnávací testy se SpartaDOSem, při kterých vyšlo najevo mnoho zajímavého také o něm. Tyto informace se však do návodu k BW-DOSu tématicky nehodí, takže jsem dlouho nevěděl, co s nimi, a nechal je povalovat na "haldě" odložených papírů. Nakonec jsem usoudil, že by bylo škoda je navždy utopit ve zmíněné "haldě", a začal jsem tedy psát tento článek.
SpartaDOS je jedním z nejlepších DOSů pro Atari XL/XE, prakticky jediný opravdu "dospělý" systém na tomto počítači. Proto si ho oblíbilo mnoho uživatelů, zvlášť ti pokročilejší a programátoři. Největší rozšíření dosáhl na americkém kontinentu.
SpartaDOS bohužel obsahuje také různé chyby a nedostatky, které dokáží práci s ním čas od času pořádně znepříjemnit. Nejlepším řešením těchto situací je prevence. Pokud o chybách víme, můžeme předcházet vzniku rizikových situací, a následky chyb tím eliminovat.
Právě proto nyní uvedu seznam chyb a nedostatků SpartaDOSu. Vztahuje se k verzím SpartaDOSu 3.2d, 3.2e, 3.2f a z větší části i 3.2g. SpartaDOS uvedených verzí obsahuje následující - více či méně závažné - chyby:
- Chyba ve vnitřní struktuře SpartaDOSu způsobuje v určité situaci znehodnocení adresářů a tím nečitelnost diskety. Kdo nevěří, ať si pod SpartaDOSem některé z výše uvedených verzí zkusí následující: Zformátujeme dvě diskety, na každou z nich uložíme na zkoušku několik souborů. Na disketu č.2 umístíme nějakou menší utilitu, která je uložena jako jeden dlouhý segment s vektorem RUN, a umožňuje ukládání dat na disk (například polský ED.COM od Janusze B. Wišniewského). Nyní vypíšeme adresář diekty č.1, vložíme disketu č.2 a okamžitě spustíme (zadáním názvu) naši utilitu. Vrátíme do disketové jednotky disketu č.1 a uložíme na ni nějaká data. Vyskočíme do DOSu a prohlédneme si zničený adresář...
Jedná se o závažnou chybu ve vnitřní stavbě SpartaDOSu. Rutina pro zavádění programových souborů je jednou z interních rutin systému FMS (diskového handleru), což je chyba - tato rutina totiž přímo spouští zaváděné programy přes vektory RUN a INIT (jsou-li definovány), což vede k "ilegálnímu" opuštění systému FMS bez korektního zakončení operace LOAD. V důsledku toho nejsou do příslušných proměnných zaneseny případné změny, které v průběhu operace LOAD nastaly, zejména případná výměna diskety provedená bezprostředně před LOADem (identifikace nové diskety). Pokud pak do disketové jednotky vrátíme původní disketu, jejíž identifikace zůstala v proměnných, je obsah sektorových bufferů považován za platný (žádná výměna diskety), a při zápisu nějakého souboru je po úpravě "vrácen" na disketu - ve skutečnosti ovšem na jinou!!! Tento podivný "sektorový kopírák" obvykle postihuje hlavní adresář, který zůstává v bufferech nejčastěji a na různých disketách většinou souhlasí i jeho umístění.
Prevence je poměrně jednoduchá. Nezbytnou podmínkou pro vznik popsané situace je provedení operace LOAD ihned po výměně diskety - tomu je třeba zabránit. Stačí po výměně diskety například nahlédnout do adresáře.
- Interní povel BASIC ve SpartaDOSu netestuje skutečnou velikost dostupné paměti RAM - pro umístění obrazovky používá konstanty $A000 pro "BASIC ON" a $C000 pro "BASIC OFF". Je-li připojena nějaká cartridge, dojde po "BASIC OFF" ke kolizi obrazové paměti s ROM cartridge, tím ke zhroucení funkce zařízení "E:" a neovladatelnosti systému. Tato situace hrozí zejména při kombinaci cartridge a BOOTu z diskety, jejíž soubor STARTUP.BAT obsahuje "BASIC OFF".
Prevence: Při použití cartridge se přesvědčit, že žádný z použitých dávkových souborů (zejména STARTUP.BAT) neobsahuje povel "BASIC".
- Program CLEANUP.COM vytváří po zápisu oprav na disk předpoklady pro zablokování počítače - pokud je instalován jakýkoliv rezident. Jedná se o hrubou nedbalost autora tohoto programu. Protože CLEANUP zapisuje změny přímo přes SIO, potřebuje nějak zabránit DOSu v použití starých sektorů, které ještě může mít v bufferech. Správně by to měl udělat změnou sekvenčního čísla diskety (DOS by pak identifikoval výměnu diskety), CLEANUP toho však dosahuje vyvoláním procedury DOS-INIT. Jedná se o dosti svérázné řešení (jako vedlejší účinek zastaví dávkový soubor, vyčistí buffer klávesnice atd. atd.), jeho použití je však možné. "Kámen úrazu" je ovšem ve způsobu, jakým CLEANUP tento podprogram volá: Místo správného skoku na adresu uloženou v proměnné DOSINI ($0C), používá CLEANUP ilegální "tvrdý" skok na adresu $7E0! Tato adresa je sice v naprosté většině DOSů začátkem zmíněné inicializační rutiny, nezahrnuje však případné instalované rezidenty. A to je právě ono: CLEANUP inicializuje pouze samotný DOS - bez rezidentů - což vede k nesprávnému nastavení proměnné MEMLO, která pak nechrání rezidenty před přepsáním (např. při kopírování).
Prevence: Ihned po použití programu CLEANUP stisknout klávesu . (Tím proběhne správná inicializace systému, která rizikový stav odstraní.)
- Rutina ZDIVIO, která je určena ke spouštění dávkových souborů a funkce HardCopy, a je uživatelským programům přístupná přes stejnojmenný vektor v tabulce COMTAB, ve SpartaDOSu nesprávně obsluhuje chybové stavy. Pokud dojde při otvírání souboru k chybě (stačí překlep v názvu dávkového souboru), SpartaDOS místo předání chybového kódu volajícímu programu vypíše na obrazovku chybové hlášení a "spadne" do CP. Pokud před tím uživatelský program otevřel nějaké soubory, nemá už šanci je legálně uzavřít - pokud byly otevřeny v IOCB č.3 a vyšším, neuzavře je ani CP...
Prevence: Při psaní programů používajících ZDIVIO je vhodné nenechávat přes volání zmíněného vektoru žádné soubory otevřené.
- Interní buffer, ve kterém funkce čtení formátovaného adresáře sestavuje jednotlivé řádky výpisu, koliduje ve SpartaDOSu s koncem bufferu LBUF (buffer zadaného příkazu v CP). Je-li zadaný řádek dlouhý, dojde při provedení operace OPEN s aux1=6 k přepsání jeho konce, a tím případně i k chybné interpretaci zadaných parametrů.
Prevence: Při psaní externích povelů nejprve převzít všechny parametry, teprve potom otevírat sobory.
- Obslužný program ramdisku RD.COM založený ramdisk nesprávně formátuje. Bitová mapa je generována o jeden bit kratší, což v některých případech (ramdisk 256kB) vede k rozdílu jednoho sektoru na délce bitové mapy a tím k formální kolizi bitové mapy s hlavním adresářem. V praxi se tento problém obvykle nijak neprojevuje, formální nedostatky v bitové mapě však trvají a mohou se stát příčinou chybné funkce některých utilit. Navíc je při formátování chybně nastavena délka hlavního adresáře - to se však opraví samo zápisem libovolného souboru nebo podadresáře.
Prevence: Nepoužívat v ramdisku sektorově orientované utility, nebo nepoužívat RD.COM.
Tím končí první část tohoto článku - seznam chyb SpartaDOSu. Na řadu teď přichází přehled dalších nedostatků tohoto DOSu, které sice nejsou přímo chybami v programu, mohou však programátora nemile překvapit. Jedná se většinou o různá drobná opomenutí autorů SpartaDOSu, kteří některé funkce nedotáhli zcela do konce.
- Ve formátovaných výpisech adresáře jsou některá čísla nevhodně zkrácena. Délka souborů v "dlouhém" výpisu je oříznuta na 6 číslic, což dává nesprávný údaj pro všechny soubory od 1000000 bytů výše. "Krátký" výpis podobným způsobem zkracuje počty sektorů (u souborů, i volné sektory) na 3 číslice - 1000 volných sektorů se tedy zobrazí jako 000, což může některé programy přivést k doměnce, že disketa je plná.
- Příkaz TYPE je ve SpartaDOSu omezen na soubory, které neobsahují řádky delší než 64 znaků (jinak hlásí chybu 137).
- Příkaz COPY nikdy nehlásí chybu 170 (soubor nenalezen) a mění obsah páté stránky paměti (sestavuje zde názvy souborů).
- Program CLEANUP hlásí v ramdisku neexistující chyby. Ramdisky nepotřebují BOOTový zavacěč, a proto mívají bitovou mapu obvykle umístěnu již v sektoru č.2 - to CLEANUP odmítá pochopit. Při výpočtu volných sektorů odečítá sektory 2 a 3 vždy jako BOOTové, v ramdisku pak ještě znovu jako bitové mapy - důsledkem je odlišný počet volných sektorů.
Dále CLEANUP nerozpoznává některé chyby - nekontroluje totiž hlavičky podadresářů (unikne mu chybný odkaz na nadřízený adresář nebo chybný název adresáře).
- Příkaz XINIT nedokáže na většině konfigurovatelných disketových jednotek (včetně XF-551) formátovat rozšířenou hustotu. Pokouší se to totiž provést pomocí povelů 'O' a '!', což na většině jednotek nejde (správný povel je '"'). Dále XINIT při kopírování nezachovává datum a čas DOSového souboru.
- BOOTová rutina, kterou všechny verze SpartaDOSu (včetně cartridge SpartaDOS X) ukládají na formátované diskety, není plně slučitelná s disketovou jednotkou XF-551. Pokud používáme tuto jednotku, podaří se první BOOT z dvojité hustoty až napodruhé, a DOSový soubor nesmí ležet na druhé straně diskety.
- Rezidentní povely dodávané se SpartaDOSem (nejen) se nebrání vícenásobné instalaci (mnohdy pak jednotlivé kopie téhož rezidentu navzájem kolidují), a nelze je odstraňovat z paměti.
- Při zavádění strojového programu - a hlavně při provádění jeho INIT rutin - má být IOCB č.1 otevřen pro čtení z programového souboru. (Toho využívá např. Turbo Basic, který svoji druhou část zavádí sám - přímo pod OS-ROM.) Pod SpartaDOSem tento IOCB otevřen není.
- SpartaDOS se nebrání otevření více formátovaných výpisů adresáře současně, což však nedokáže správně obsloužit. Protože je k dispozici jen jeden řádkový buffer, "prosakují" části obou výpisů do sebe.
- Většina DOSů vrací po přečtení posledního byte v souboru status 3. SpartaDOS nikoliv.
- Přímý přístup k adresářům má pod SpartaDOSem některá nepříjemná omezení. Režim aux1=8+16 (přepsat adresář) se pod SpartaDOSem chová stejně jako 12+16 (aktualizace adresáře) - nedochází ke zrušení starých dat, která mohou při zápisu kratšího adresáře přes delší částečně zůstat na jeho konci. Režim 12+32 (aktualizace podadresáře) je v podstatě nefunkční - pokud totiž podadresář již existuje (proč bychom ho jinak aktualizovali?!?), skončí operace s chybou 151 (nelze přepsat).
Všechny režimy aux1+16 pracují s adresářem určeným jen cestou, název souboru ignorují. Pod SpartaDOSem však musí být i přesto přítomen syntakticky správný název - proto je vhodné za cestu vždy přidávat alespoň "*.*". Použijeme-li režimy aux1+32 k založení nového podadresáře, neprovede SpartaDOS tuto operaci kompletně - založí jen adresářový soubor, aniž by do něj vložil správnou hlavičku podadresáře.
- Obsluha alokačních ukazatelů - pozice 18 a 20 v sektoru 1 - je ve všech dosud známých verzích SpartaDOSu (včetně SpartaDOSu X) značně nedotažená. Tyto ukazatele označují místo na disketě, od kterého se začíná hledat volný sektor při rozšiřování souboru resp. podadresáře. Při zápisu nových souborů a podadresářů se s postupným obsazováním diskety zvyšují, při mazání je třeba tyto ukazatele naopak snižovat. SpartaDOS je při uvolňování každého sektoru vrací na číslo tohoto sektoru, přičemž rozlišení mezi oblastí adresářů a dat se provádí porovnáním s ukazatelem pro přidělování adresářů. Protože se ale obvykle sektory uvolňují ve vzestupně číslovaných skupinách (soubory a adresáře), při mazání adresářů podle této metody bude již druhý sektor nad (novou) hodnotou "adresářového" ukazatele - posunut bude tentokrát ukazatel "datový". Tím se oba ukazatele dostávají na téměř stejnou hodnotu, a přestávají oddělovat adresáře a data do různých oblastí na disketě. Nové sektory adresářů i souborů se začnou přidělovat promíchaně, což po čase vede k "rozházení" adresářů po celé disketě a pomalému přístupu k nim.
- Obsluha zařízení "E:" při práci dávkových souborů je ve SpartaDOSu vyřešena způsobem, který nepřipouští korektní instalaci nových driverů "E:". (Různé urychloače výstupu na obrazovku, které se SpartaDOSem fungují, jsou obvykle řešeny metodou ilegálních zásahů přímo do programu SpartaDOSu - fuj...)
Informace uvedené v tomto článku si v žádném případě nekladou za cíl SpartaDOS nějak "očernit". Jejich účelem je upozornit uživatele na rizikové situace, kterým je lepší se vyhnout, a zvýšit tak bezpečnost a efektivitu jejich práce se SpartaDOSem. Jinou možností je přechod na BW-DOS, který je se SpartaDOSem do značné míry slučitelný a uvedené chyby a nedostatky samozřejmě nemá, v tom případě se však musí uživatel smířit s poněkud menším okruhem dostupných funkcí.
Jiří Bernášek (BEWESOFT)