Programová jednotka Dos obsahuje příkazy, které usnadňují spolupráci s operačním systémem (Dnes je ovšem aktuálnější jednotka WinDos, která umožňuje spolupráci s operačním systémem Windows). Jednotka Overlay umožňuje využívat překryvné moduly a maximálně tak šetřit pamětí (v dnešní době se již nepoužívá, pár kilobytů nehraje dneska tak zásadní roli).
type FileRec = record {Držadlo pro soubory, obsahuje potřebné informace} Handle : word; {Držadlo} Mode : word; {Mód, ve kterém je soubor otevřen, viz módy přístupu} RecSize : word; {Velikost položky v bytech} Private : array[1..26] of byte; {Vnitřní data} UserData: array[1..16] of byte; {Data přístupná uživateli} Name : array[0..79] of char; {Jméno (celá cesta) k souboru} end;
TexBuf = array[0..127] of char; {Tyto typy slouží pro práci s textovými soubory} TextRec = record Handle : word; {Držadlo} Mode : word; {Mód přístupu, viz módy přístupu} BufSize : word; {Velikost textového bufferu} Private : word; {??} BufPos : word; {Aktuální pozice v bufferu} BufEnd : word; {Konec bufferu} BufPtr : ^TextBuf; {Ukazatel na buffer} OpenProc :pointer; {Procedura pro otevření souboru} InOutProc:pointer; {Procedura pro čtení/zápis} FlushProc:pointer; {Procedura pro vyprázdnění bufferu} CloseProc:pointer; {Procedura pro uzavření} UserData :array[1..16] of byte; {Uživatelská data} Name : array[0..79] of char; {Jméno souboru - celá cesta} Buffer : TextBuf; {Buffer} end;
Proměnná typu soubor musí obsahovat veškeré výše uvedené položky. Ty však nejsou "veřejně" přístupné, chceme-li se k nim dostat, musíme provést přetypování. Je tedy možná následující konstrukce:
if FileRec(fout).Mode=fmClosed then Writeln('Soubor zatím není otevřen');
FileRec(fout) zde tedy neznamená funkci, ale pouhou typovou změnu (type-casting) proměnné.
Tyto řetězcové typy se používají především při práci s procedurou FSplit.
type PathStr = string[79]; {Celé jméno, včetně cesty a přípony} DirStr = string[67]; {Cesta} NameStr = string[8]; {Jméno bez přípony} ExtStr = string[4]; {Přípona}
type SearchRec = record Fill : array[1..21] of byte; {Data operačního systému, neměnit} Attr : byte; {Atribut souboru - viz konstanty atributů} Time : longint;{Zhuštěný údaj o datu vytvoření souboru, "zčitelnit" lze pomocí procedury UnPackTime} Size : longint;{Velikost souboru v bytech} Name : string[12];{Jméno souboru} end;
type DateTime = record Year, Month, Day, Hour, Min, Sec : word; end;
Anglicky snad umíte, že... Povolené hodnoty pro rok jsou 1980 až 2099, pro měsíce a dny jsou jasné...
Povolené časové hodnoty
Tento typ slouží pro potřeby procedur Intr a MsDos. Přistupovat lze buď k šestnáctibitovým registrům, či k osmibitovým. (Architekturu procesoru doufám znáte).
type Registers = record case integer of 0: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags:word); 1: (AL,AH,BL,BH,CL,CH,DL,DH : byte;) end;
Jednotka Dos vlastně definuje jedinou svou proměnnou :
var DosError : integer;
Tato proměnná obsahuje číslo chybového stavu (či nulu, nenastala-li chyba.) Kódy chyb jsou shodné s kódy v systému MS-DOS :
Kód | Popis | Anglicky |
---|---|---|
0 | Bez chyby | No error |
2 | Soubor nenalezen | File not found |
3 | Cesta nenalezena | Path not found |
5 | Přístup odepřen | Access denied |
6 | Špatné manipulační číslo ( = držadlo z FileRec) | Invalid handle |
8 | Nedostatek paměti | Not enough memory |
10 | Špatné prostředí procesu | Invalid environment |
11 | Špatný formát | Invalid format |
18 | Více souborů není | No more files |
Číslo 18 se používá v souvislosti s FindFirst a FindNext.
Předpokládám, že znáte význam význam registru příznaků (Flags) a jeho
jednotlivých složek.
Uvedené konstanty zjednodušují zjištění nastavených příznaků. Např. R.Flags
and FCarry <> 0 je true, pokud je nastaven příznak Carry (při poslední operaci
došlo k přenosu ...).
const FCarry = $0001; FParity = $0004; FAuxiliary = $0010; FZero = $0040; FSign = $0080; FOverflow = $0800;
const fmClosed = $D7B0; {Soubor je uzavřen} fmInput = $D7B1; {Soubor je otevřen pro zápis} fmOutput = $D7B2; {Soubor je otevřen pro čtení} fmInOut = $D7B3; {Soubor je otevřen pro čtení i zápis}
const ReadOnly = $01; Hidden = $02; SysFile = $03; VolumeID = $04; Directory = $10; Archive = $20; AnyFile = $3F;
Pořadí | Příkaz | Význam |
---|---|---|
1 | Diskfree(Drive : Word):Longint; | Velikost volného místa na disku v bytech |
2 | DiskSize(Drive: Word) : Longint; | Celková velikost disku v bytech |
Pořadí | Příkaz | Význam |
---|---|---|
1 | FindFirst(Path:string;Attr:byte;var S:SearchRec); | Najde první soubor vyhovující kritériím (lze použít hvězdičková konvence), výsledek zapíše do S |
2 | FindNext(var S:SearchRec); | Najde další výskyt požadovaného souboru |
3 | FExpand(Path:PathStr) : string; | Rozvine jméno souboru na úplné (včetně disku a celé cesty) |
4 | FSearch(Path:PathStr;DirList : string) : string; | Hledá v seznamu adresářů DirList soubor s názvem Path, vrátí celou cestu, nejčastěji se používá spolu s DirList=GetEnv('PATH'); - s aktuálním nastavením cest... |
5 | GetFAttr(var f; var Attr : word); | Vrátí atributy daného souboru, jednotlivé atributy viz konstanty atributů |
6 | SetFAttr(var f; Attr : word); | Nastaví atributy daného souboru |
Pořadí | Příkaz | Význam |
---|---|---|
1 | GetDate(var Year,Month,Day,DayOfWeek : word); | Vrátí aktuální datum |
2 | GetTime(var Hour, Minute, Second, Sec100 : word); | Vrátí aktuální čas |
3 | SetDate(Year, Month, Day : word); | Nastaví nové aktuální datum |
4 | SetTime(Hour, Minute, Second, Sec100 : word); | Nastaví nový aktuální čas |
5 | GetFTime(var f; var Time : longint); | Vrátí datum a čas poslední aktualizace daného souboru (ve zhuštěné formě) |
6 | SetFTime(var f; Time : longint); | Nastaví čas poslední aktualizace souboru |
7 | PackTime(var DT : DateTime; var Time:longint); | Zabalí normální datum a čas(DT) do zhuštěné podoby Time |
8 | UnpackTime(Time : longint; var DT : DateTime); | Rozbalí zhuštěné datum a čas (Time) do čitelné podoby (DT) |
Pořadí | Příkaz | Význam |
---|---|---|
1 | GetIntVec(IntNo : byte; var Vector : pointer); | Do Vector uloží ukazatel na obslužnou rutinu přerušení číslo IntNo |
2 | SetIntVec(IntNo : byte; Vector : pointer); | Nastaví obslužnou rutinu přerušení na danou adresu |
3 | Intr(IntNo : byte; var Regs : Registers); | Spustí přerušení IntNo s příslušnými registry - viz Registry |
4 | MsDos(var Regs: Registers); | Spustí přerušení $21 - služby MS-Dosu s příslušnými registry - viz Registry |
5 | SwapVectors; | rohodí současné vektory přerušení s hodnotami umístěnými v SaveIntnn. Nejčastěji se používá před zavoláním procedury Exec. Zavoláním SwapVectors zajistíme, že spuštěný proces se nebude "vrtat" v přerušených našeho programu a naopak. |
Raději si to ukážeme na příkladu :
SwapVectors; {Prohodíme vektory přerušení na původní systémové hodnoty} Exec(...); {Spouštíme nějaký externí proces, ten nebude mít ponětí, že je spuštěn z našeho programu} SwapVectors; {Prohodíme vektory zpět, na naše "programové" hodnoty}
Pořadí | Příkaz | Význam |
---|---|---|
1 | DosExitCode : word; | Vrací ukončovací kód podřazeného procesu (0..normální ukončení, 1..ukončení pomocí Ctrl-C,2..ukončení po chybě, 3..ukončení pomocí Keep - rezidentní programy) |
2 | DosVersion : word; | Číslo verze MS-Dosu Lo(DosVersion) je první hodnota a Hi(DosVersion) je druhá hodnota (ta za tečkou) |
3 | Exec(Path, CmdLine : string); | Spustí proces (prostě nějaký EXE nebo COM soubor, chceme-li spustit příkaz MS-DOSu, použijeme "COMMAND.COM /C ...") |
4 | EnvCount : integer; | Počet proměnných nastavených v daném prostředí (taková proměnná je např. PATH, ...) |
5 | GetEnv(EnvVar : string) : string; | Vrátí danou hodnotu určené proměnné |
6 | EnvStr(Index : integer) : string; | Vrátí specifikovaný řetězec (proměnnou), která je definována v prostředí na Index-tém místě |
7 | GetCBreak(var Break: boolean); | Vrátí-li true, Ctrl-Break ukončuje program |
8 | SetCBreak(var Break : boolean); | Nastaví, jestli Ctrl-Break ukončuje program |
9 | GetVerify(var Verify : boolean); | Vrátí, zde zápis na disk ověřuje |
10 | SetVerify(Verify : boolean); | Nastaví, zda se zápis na disk bude ověřovat |
11 | Keep(ExitCode : word); | Ukončí program, ale ponechá ho v paměti (rezidentní), ExitCode je kód ukončení, v paměti zůstává vše, je nutné správně nastavit alokování paměti pomocí {$M}, rezidentní program musí být navázán na nějaké přerušení (pokud se jedná o důležité přerušení, nezapomeňte zavolat i původní obslužnou rutinu, jinak zbortíte počítač) |
Jednotka Overlay se dá použít pouze v reálném režimu procesoru (dnes skoro vše běhá v režimu chráněném). Chceme-li ji použít, je nutné, aby jednotky, které chceme použít jako překryvné byly přeloženy s direktivami překladače {$F+} a {$O+}. Hlavní program pak musí být přeložen s direktivou {$F+}. Dále je nutné, aby překryvné jednotky byly v uses uvedeny až za jednotkou Overlay. Pokud mají nějakou inicializační část, je nutné, aby před zavoláním této inicializační části byla zavolána procedura OvrInit; (ta musí být tedy uvedena v inicializační části nějaké jednotky, která následuje za Overlay a přitom je před překryvnými jednotkami, nejčastěji se tedy vytvoří samostatná jednotka MyInit, která pouze zavolá ve své inicializační části OvrInit a jinak nic nedělá).
Ze standardních programových jednotek lze jako překryvnou použít pouze jednotku Dos. Dále nelze jako překryvné použít ty jednotky, které do paměti nahrávají grafický driver či obsahují interrupt funkce či procedury.
Pro svou práci definuje jednotka Overlay jediný speciální typ proměnné.
type OvrReadFunc = function(OvrSeg : word) : integer;
Tyto konstanty slouží ke zjištění výsledku dané operace (výsledná hodnota je uložena v OvrResult)
const ovrOK = 0; {Operace proběhla bez chyby} ovrError =-1; {Chyba správce překryvných jednotek} ovrNotFound =-2; {Překryvný soubor nenalezen} ovrNoMemory =-3; {Nedostatek paměti} ovrIOError =-4; {I/O chyba} ovrNoEMSDriver=-5; {EMS není k dispozice} ovrNOEMSMemory=-6; {Nedostatek paměti pro EMS}
Inicializované proměnné obsahují informace o nastavení manažeru překryvných jednotek. Jejich změnou lze dosáhnout změny nastavení. Většina těchto proměnných je definována již v jednotce System, pouze pět zde uvedených je definováno přímo v jednotce Overlay. Většinu z těchto proměnných není důvod měnit, programátor s nimi prakticky nepřijde do styku, k nastavení parametrů se totiž používá spíše uvedených procedur a funkcí.
Pořadí | Proměnná:Typ | Význam |
---|---|---|
1 | OvrCodeList : word; | Code segment, za žádných okolností bychom ji neměli měnit |
2 | OvrDebugPtr : pointer; | Ukazatel pro potřeby debuggingu |
3 | OvrDosHandle : word; | Správce překryvných jednotek |
4 | OvrEmsHandle : word; | Správce EMS |
5 | OvrFileMode : byte; | Druh přístupu k překryvnému souboru, standardně = 0 (Read-Only), může být změněna (např. při práci v síti) |
6 | OvrHeapEnd : word; | Konec paměti pro překryvné moduly, hodnota nastavena pomocí OvrInit; uživatel ať ji nemění |
7 | OvrHeapOrg : word; | Začátek paměti pro překryvné moduly, nastaveno pomocí OvrInit, uživatel ať se v tom nehrabe |
8 | OvrHeapPtr : word; | Současná pozice v paměti, uživatel ať to raději nechá na pokoji |
9 | OvrHeapSize : word; | Velikost paměti vyhrazené pro překryvné jednotky, 0 znamená, že Overlay nejsou použity. Uživatel tuto hodnotu nesmí měnit |
10 | OvrLoadCount : word; | Aktuální počet natahovaných překryvných modulů |
11 | OvrLoadList : word; | Seznam natažených překryvných modulů, slouží manažeru, raději ji neměňte |
12 | OvrReadBuf : OvrReadFunc; | Kontrolní funkce, která je volána po každém načtení překryvného modulu z disku, výsledná hodnota 0 znamená bezproblémový návrat, jinak se generuje chyba 209 (Overlay file read error). Tato proměnná slouží k vlastní obsluze chyb. Parametr OvrSeg slouží pouze k předání hodnoty původní funkci, která by měla vždy být volána. |
13 | OvrResult : integer; | Tady je kód, který vrací procedury a funkce jednotky Overlay podle své úspěšnosti (viz konstanty) |
14 | OvrTrapCount : word; | Počet přístupů na disk (do odstavné oblasti) kvůli překryvným jednotkám, také ji neměňte |
Pořadí | Příkaz | Význam |
---|---|---|
1 | OvrInit(FileName:string); | Inicializuje ovladač překryvných jednotek, FileName je jméno souboru, kde jsou tyto jednotky uloženy; standardně je to NazevProgramu.ovr |
2 | OvrInitEMS; | Překryvné jednotky budou využívat EMS (což program značně zrychlí). Nepovede-li se (např. není-li EMS není přítomna), vrací chybu, ale program pokračuje dál, jako by se nic nestalo |
3 | OvrGetBuf:longint; | Vrací současnou velikost paměti vyhrazené pro překryvné jednotky |
4 | OvrGetRetry:longint; | Vrací velikost odstavné paměti (to je ta část paměti, kde jsou jednotky, než jsou zapsány na disk) |
5 | OvrSetBuf(Size:longint); | Umožní zvětšit velikost paměti vyhrazené pro překryvné jednotky (Size musí být větší než původní vyhrazené místo a menší nebo rovna MemAvail) |
6 | OvrSetRetry(Size: longint); | Umožní nastavit velikost odkládací oblasti (na počátku je tato hodnota nulová) |
7 | OvrClearBuf; | Smaže obsah "překryvné" paměti (vše se bude znovu natahovat z disku) - jenom zpomaluje program |