A Commodore DOS vagy CBM DOS a Commodore 8 bites architektúrájú mikroszámítógépeiben használt, lemezkezelésre képes operációs rendszer (DOS) volt. A legtöbb DOS rendszertől eltérően, melyek lemezről töltődtek be a számítógép saját RAM-jába és onnan futottak, a CBM DOS a számítógépen kívül, a lemezmeghajtó csak olvasható memóriájában (ROM) foglalt helyet, és onnan futtatták a dedikált MOS 6502-es processzorcsalád tagjai. Ezért a Commodore 8 bites számítógépei és lemezmeghajtói közti adatátvitel jobban emlékeztetett egy helyi hálózati összeköttetésre, mint a tipikus diszk/gazdagép átvitelekre.
A CBM DOS verziói Legalább hét különböző számozású Commodore DOS-változatról tudunk, az alábbi lista megadja a verziószámokat és a hozzájuk tartozó lemezes egységeket. Ha külön nem jelezzük, a meghajtók 5¼ hüvelykes formátumúak. Az „lp” kód a „low profile” (alacsony profilú) egységekre utal. A 15-tel kezdődő modellszámú meghajtók a Commodore által egyedileg kifejlesztett CBM-488 soros (TALK/LISTEN) protokollokkal kommunikálnak, az összes többi a párhuzamos IEEE-488-at használja. 1.0 – a 2040 és 3040 floppymeghajtókban 2.0 – a 4040 és 3040 floppymeghajtókban 2.5 – a 8050 floppymeghajtókban 2.6 – a 1540, 1541, a beépített SX-64 floppymeghajtókban, a 1551, 2031 (+"lp"), és 4031 floppymeghajtókban 2.7 – a 8050, 8250 (+"lp") és SFD-1001 floppymeghajtókban 3.0 – a 1570, 1571 és 8280 floppymeghajtókban (8280: 8 hüvelykes), valamint a 9060 és 9090 merevlemezes meghajtókban 3.1 – a C128D/DCR mikroszámítógép beépített 1571 floppymeghajtóiban 10.0 – a 1581-ben (3½ hüvelykes)
A 2.6-os volt a legelterjedtebb és legismertebb DOS-verzió, mivel ezt használták a C64 mikroszámítógéphez tartozó 1541 floppy drive-okban.
Az 1571-esben a relatív fájlok hibás kezelését javító verzió is V3.0 néven futott. Ezért kizárólag a verziószám alapján nem lehet megkülönböztetni a két változatot.
Technikai áttekintés
1541-es könyvtár- és fájltípusok
Az 1541-es Commodore flopilemez legfeljebb 144 fájlt tartalmaz egy lapos névtérben (nincsenek alkönyvtárak); a lemez „tartalomjegyzékét” („directory”) az erre fenntartott 18-as sávon tárolták, ami a 35-sávos egyoldalú lemez középső, a fizikai behatásoktól legvédettebb sávja volt. A fájlnév hosszúsága legfeljebb 16 bájt, elvileg egyedi; a könyvtárhoz való közvetlen hozzáféréssel létre lehet hozni azonos fájlneveket – bár az ilyen fájlok elérése utána problematikus. Az azonos fájlnevek általában semmi más célt nem szolgáltak, mint a tartalomjegyzék listájának informatív vagy trükkös formázását. A The Final Cartridge III által is használt népszerű trükk volt "----------------" névvel és DEL< típussal jelölt fájlok hozzáadása a tartalomjegyzékhez úgy, hogy a vonalak segítségével csoportosítsák a fájlneveket. A játékfejlesztők, warez csoporttagok, demoscene-hackerek stb. további ügyes trükköket is elkövettek a könyvtárbejegyzésekkel.
A fájlnevek tartalmazhatnak shift+space karaktert ($A0), és ha a tartalomjegyzéket BASIC-ből listázzák, a fájlnév $A0 karakteren túli része a többitől idézőjellel elválasztva listázódik, ami miatt a BASIC nem tekinti a fájlnév részeként. Így lehetőség nyílt olyan könyvtárbejegyzések létrehozására, mint SAVE "PROGRAM,8,1:",8,1, ami aztán a listában például így jelenik meg: 32 "PROGRAM",8,1: PRG. Ha a felhasználó a sor elejére vitte a kurzort és felülírta a fájlméretet a LOAD szóval és megnyomta az Entert, a BASIC úgy értelmezte a sort, hogy LOAD "PROGRAM",8,1: ..., ami a program memóriába töltését idézte elő. A kettőspont utáni rész nem kerül végrehajtásra, mivel a LOAD parancs futtatja a programot, és nem tér vissza a parancsértelmezőhöz.
A fájlnévbe ágyazott nullbájt megszakítja a listázást, három nulla bájt pedig nagyon nehézzé teszi a BASIC megoldásaival a listázást, mivel ez a BASIC programok végét jelzi. Egyes gépi kódú programozók szándékosan nulla értékű bájtokat szúrtak bele kódjaikba, megnehezítve a BASIC-programozók számára, hogy belepiszkáljanak azokba.
A C64 BASIC-jében a tartalomjegyzék egyfajta nem futtatható, pszeudo-BASIC programkódként töltődött be – kihasználva, hogy a BASIC-ben a sorok számozása valójában tetszőleges, a kiírási sorrendet nem befolyásolja, azt a láncolt lista adja meg –, a LOAD "$0",8 (vagy LOAD "$1",8 dupla meghajtó esetén), majd a LIST parancs kiadásával. Az első sor sorszáma 0 vagy 1 (a meghajtó számát jelöli), következik inverz („reverse”) videomódban kiírva a lemez neve, azonosítókódja és a formázáshoz használt DOS-verzió kódja (csak az inkompatibilis lemezformátumok miatta DOS-verziók különböztethetők meg, a legtöbb 5.25 inches verzió a "2A"-t használta, a 3.5 inches 1581-es meghajtó a "3D"-t). A további sorok pszeudo-sorszámként kiíratva a fájl méretét tartalmazzák (lemezblokkokban mérve), majd a fájl nevét idézőjelben és a hárombetűs fájltípus-kódot. Az utolsó sor (szintén pszeudo-sorszámként kiíratva) a lemez szabad blokkjainak számát mutatja, melyet a "BLOCKS FREE." felirat követ.
A Commodore 64-en a LOAD "$",8,1 a tartalomjegyzék BASIC RAM-ba való töltése helyett teliszemeteli a képernyőt. Ez azért van, mert a „,1” miatt gépi kódként tölti be a listát, aminek a betöltési címe a $0401 (1025) lesz, ami ugyan a Commodore PET-en a BASIC memóriaterületének eleje, de a C64-en az alapértelmezett képernyőmemória második karakterét adja.
A tartalomjegyzék betöltése a standard LOAD "$",8 paranccsal felülírja a memóriában lévő BASIC programot. A DOS Wedge program és számos, külső cég által fejlesztett cartridge és bővítő, mint az Epyx FastLoad, az Action Replay és a Final Cartridge III lehetővé tették a tartalomjegyzék listázását olyan parancsokkal, melyek a memóriában lévő BASIC program felülírása nélkül, a képernyőmemóriába töltötték be a directoryt. A Commodore 128-on futó BASIC 7.0 tartalmaz DIRECTORY vagy CATALOG parancsot (indításkor az F3 gombhoz bekötve), ami ugyanezt a feladatot látja el.
A következő fájltípusok támogatottak:
SEQ A szekvenciális (soros elérésű) adatfájl lineárisan olvasható az elejétől a végéig. A SEQ fájlokat például szövegszerkesztők dokumentumainak vagy szöveges fájljainak tárolására lehet használni. A szekvenciális fájl hasonló a Linux/UNIX rendszereken ismert simafájl (flat file) szerkezettel, amennyiben nem rendelkezik speciális belső szerkezettel. Nincs arra mód, hogy egy szekvenciális fájl tetszőleges helyére pozicionáljunk, mivel a Commodore DOS-ban nem létezik a Unix-szerű operációs rendszerekben található lseek kernelhívás. PRG A PRG fájlok általában futtatható programkódot tartalmaznak, bár adattárolásra is használhatók. A PRG fájlok első két bájtját a kernalígy hívják a Commodore-terminológiában a kernelt "load file"-rutinja beolvassa, és a betöltési cím meghatározására használja fel (little endian bájtsorrend szerint tárolódik). REL A relatív fájl olyan szekvenciális fájl, amiben egy indexelési mechanizmus „side-sector”-ok (mellérendelt szektorok) segítségével lehetővé teszi a rekord-orientált hozzáférést. A rekordok legfeljebb 254 bájtosak lehetnek és 1-gyel kezdődő sorszámozás alapján lehet hozzájuk férni, így valódi véletlen elérésű fájlokról van szó. USR A felhasználói fájl belső szerkezete megegyezik a szekvenciális fájléval. A Commodore eredeti célja a fájltípussal a DOS-fejlesztés elősegítése volt, mivel a fájl tartalma bemásolható volt a meghajtó pufferjébe, a lemezmeghajtó mikroprocesszora általi későbbi végrehajtásra. Nem ismeretes, hogy bárki használta volna ezt a funkcionalitást. Egyes, nem standard alacsony szintű lemezhozzáférést használó alkalmazások USR formátumban mentettek adatokat, amit a felhasználó számára amolyan „hagyj békén, ne próbálj másolni vagy törölni” jelzésnek szántak. Például a GEOS operációs rendszer "VLIR" fájljai is USR kóddal jelennek meg. DEL Dokumentálatlan, belső felhasználású fájltípus, a szekvenciális fájlhoz hasonló szerkezetű. Ilyen fájlt csak a lemez tartalomjegyzékének közvetlen manipulációjával lehet létrehozni.
A tartalomjegyzékben a fájltípus melletti csillag (*) jelenléte (például *SEQ) a fájl írás utáni szabálytalan lezárására utal. Amikor a lemezegység utasítást kap egy írásra megnyitott fájl lezárására, a hozzárendelt puffer kiíródik a lemezre, és a szabad blokkokat nyilvántartó block availability map (BAM) frissül a felhasznált blokkokkal. Ha egy program lefagyása miatt vagy más okból (például a felhasználó kiveszi a lemezt a fájl bezárása előtt) egy fájl „elárvul” („orphan file”, „poison” vagy „splat” file), a puffer nem íródik ki, ezért a BAM nem pontosan tükrözi vissza a lemezhasználatot, ami adatvesztés veszélyével jár. Az elárvult fájlokat általában nem lehet megnyitni (csak „módosítás – modify” módban), és a DOS scratch parancsával való törlés fájlrendszer-sérülést, például keresztcsatolt fájlokat hozhat létre. A probléma praktikus megoldása a fájl „modify” módban való megnyitása (és javítása) vagy a DOS validate parancsával a lemez helyrehozása; ez a parancs újraépíti a BAM-ot és eltávolítja a sérült fájlokat a tartalomjegyzékből. A hírhedt save-with-replace bug ilyen fájlok létrejöttével járhat.
A *DEL speciális bejegyzés, ami a tartalomjegyzékben a kitörölt fájlokhoz tartozik. Az ilyen fájlok nem látszanak a normál könyvtárlistában, adatblokkjaikat és könyvtárbejegyzésüket pedig a később létrehozandó fájlok felülírják. Egyes segédprogramok lehetővé teszik az ilyen állományok visszaállítását, ha adatblokkjaik és könyvtárbejegyzéseik még nem lettek felülírva. A DEL fájlokat gyakran használták fel bannerek vagy megjegyzés-szekciók a tartalomjegyzékbe való beszúrására.
A fájltípusok, melyek neve mögött < áll (például PRG<) „zárolva vannak” és nem törölhetők, bár olvasásra meg lehet nyitni őket. Nincs olyan Commodore DOS parancs, amivel kifejezetten ezt az állapotot be lehet állítani vagy törölni lehet, bár számos lemezkezelő segédprogram lehetővé teszi ezt. Az ilyen programok általában közvetlen hozzáféréssel beolvassák a tartalomjegyzéket, elvégzik a szükséges módosításokat a nyers adatokon, majd visszaírják a lemezre.
Fájl-hozzáférés A fájlokhoz való hozzáférés a gazdaszámítógép feladata. A számítógép kernal ROM-ja tartalmazza fájlok eléréséhez szükséges alacsony szintű rutinokat, a BASIC ROM pedig a BASIC szintaxissal való eléréshez szükséges magasabb absztrakciós szintet. A DOS szintjén megjelenő komponensek a fájlnevek elemzésével és a másodlagos címekkel foglalkoznak. Az alábbiakban a teljesség kedvéért áttekintést adunk az alapvető BASIC fájlkezelési parancsokról.
A Commodore lemezmeghajtón történő fájlmegnyitás maga után vonja néhány olyan paraméter kezelését, melyek nagyjából megfeleltethetők más környezetek fájlmegnyitási procedúráinak. Mivel a DOS ténylegesen a lemezmeghajtó kontrollerén fut, a fájlmegnyitási műveletnek elegendő információt kell átadnia ahhoz, hogy az egyértelmű interpretáció lehetséges legyen. Egy tipikus BASIC nyelvű parancs egy soros fájl írására a következőképpen nézhet ki:
OPEN 3,8,4,"0:ADDRESSBOOK,S,W"
Az OPEN igét követő paraméterek értelmezése a következő:
3 Ez a paraméter, a „fájl száma” (file number) logikailag azonosítja a megnyitott fájlt a számítógép operációs rendszere számára a megnyitott fájlok között, a Unix-szerű operációs rendszerek fájlleírójához (file descriptor) hasonlóan. Ez a paraméter sosem kerül elküldésre a lemezmeghajtóhoz, így a drive operációs rendszere nem is tud róla. A fájl száma 1–254 között lehet, a programozó végzi a hozzárendelést és egyedinek kell lennie (ha több fájl egyidejű megnyitására van szükség). Miután a fájl megnyitásra került, minden olvasási és írási művelet ezt a fájlszámot használja. Assembly nyelvű programokban erre az értékre gyakran mint „logikai címre” (LA, logical address) hivatkoznak, a fájl számát tároló memóriacímre utaló mnemonik elnevezéséből. 8