Ovládání Betadisku z jazyka BASIC
Nakouknutí do historie a souvislostí
Tento popis platí především pro TRDOS 5.05cz a s drobnými odlišnostmi ho lze použít i pro poslední originální verzi TRDOS 5.03 (1986) od britské společnosti Technology Research Ltd., která kdysi TRDOS vyvinula. A taktéž pro většinu odvozených TRDOSů pro ruské klony ZX Spectrum (Pentagon, Scorpion... např.).
Starší verze TRDOSu než poslední oficiálně vydanou 5.03 si dovolím ignorovat, dřívější verze 5.0x byly verzí 5.03 brzy nahrazeny a běžně se nevyskytují. S verzí 4.x jsem se ve skutečnosti za desítky let setkal pouze jednou v Jiiirově Betadisku z roku 1984 a o verzi 3 jsem pouze četl. Tyto starší verze nejsou kompatibilní s žádným současným softwarem, který používá volání služeb ze strojového kódu, dají se používat pouze z BASICu a i v BASICu jsou kompatibilní jen částečně, umí pouze základní příkazy a hlavně se liší adresou volání 15360 místo 15616 a 15363 místo 15619.
Pro ZX Spectrum existuje diskových systémů mnoho. U nás byla počátkem 90. let velmi rozšířená disketová jednotka Didaktik 40 / Didaktik 80 se systémem MDOS z v.d. Didaktik Skalica. Ta to řeší tak, že odchytává volání podprogramu pro zpracování chyby (rst 8), která nastala při kontrole syntaxe BASICového příkazu. Pokud tato syntaxe odpovídá příkazu MDOSu, zpracuje se. Pokud to není příkaz MDOSu, ohlásí se chyba obvyklým způsobem. Uživatel to pak z pohledu BASICu vnímá jakoby mu přibyly příkazy a jejich možnosti, což je velmi pohodlné.
Betadisk 5.x vznikl o pár let dříve (dle Wikipedie je Betadisk 128, tj. verze 5.x z roku 1987, dle verze TRDOSu z roku 1986) a kromě toho, že byl navržen jako zařízení konstrukčně velmi levné, bez vlastní paměti RAM, navazoval konstrukčně na předchozí verzi a je zřejmá i určitá snaha o alespoň nějakou kompatibiltu s předchozími verzemi přinejmenším na úrovni souborového systému a stejné syntaxe příkazů.
Logika Betadisku je postavená tak, že odchytává běh programu v oblasti, kde je v ROM ZX Spectra uložen font. To jsou data, která by nikdy neměla být prováděna jako program, ale pokud přesto dojde ke skoku do těchto dat, Betadisk dřív než se načte první instrukce přistránkuje vlastní paměť ROM a program pokračuje v ní, místo aby se zhroutil prováděním nesmyslných instrukcí. Zpátky do Sinclair BASICu se program vrací skokem mimo adresní prostor ROM.
Tento způsob přestránkování na rozdíl od odchytávání téhož na adrese 8 si vynucuje použití příkazu RANDOMIZE USR na příslušnou adresu s rizikem, že když stejný skok nastane bez připojeného Betadisku, provede se nesmyslný program a počítač se pravděpodobně zhroutí / resetuje. Na druhou stranu, dokud nedojde k zavolání Betadisku (alespoň skoku do příkazového řádku TRDOSu), tak je Betadisk zcela neaktivní, nereaguje ani na porty skrz které se komunikuje s čipem řadiče a běžící programy o něm nemusí vědět.
Tady se sluší poznamenat, že verze Betadisku 4.x a starší s adresou 15360 (15363) se mohly aktivovat, pokud byla v počítači upravená Sinclair ROM, která využívala prostor před fontem v originální Sinclair ROM nevyužitý (zaplněný 0xff). A to je v podstatě každá upravená ROM, pokud ty změny nebyly velmi malé. To byl pravděpodobně důvod, proč ke změně adresy došlo.
omezení TRDOSu kvůli absenci vlastní RAM
Dnes můžeme jen spekulovat, co by se stalo, kdyby Betadisk byl zkontruovaný dokonaleji s vlastní RAM na systémové proměnné a prodával se dráž. Možná by se nestal tak populárním, rozšířeným a snadno klonovaným, jak se stal. Fakt je, že Betadisk vlastní RAM (na rozdíl od Didaktik 40/80 a mnoha dalších systémů) do které by si mohl ukládat systémové proměnné a třeba ji použít jako buffer pro čtení sektorů z diskety nemá a z toho plynou omezení.
Pro systémové proměnné TRDOS alokuje celých 112 bytů paměti. O těchto 112 bytů posune BASICový program, své systémové proměnné přidá k systémovým proměnným Sinclair BASICu a o těchto 112 bytů je prodlouží. V těchto přidaných proměnných jsou parametry disketové mechaniky i diskety, čísla sektorů a stopy se kterou se pracuje, jméno právě zpracovávaného souboru a takové věci. Bez těchto systémových proměnných nelze ani skočit do příkazového řádku.
Ale to není všechno. Kromě systémových proměnných potřebuje TRDOS místo na dalších 256 bytů do kterých si načítá obsah sektoru. A některé náročnější příkazy jako LIST, MOVE a COPY potřebují paměti ještě víc. Tuto paměť si TRDOS alokuje dynamicky a po dokončení příkazu ji zas uvolní. Ale musí být k dispozici během provádění příkazu.
Prakticky z toho vyplývá, že pro načtení programu z diskety s velmi jednoduchým BASICovým zaváděčem musí být RAMTOP nastavený nejméně o těchto 112 + 256 bytů výš než by bylo potřeba pro načtení z pásky a protože příkazy TRDOSu jsou delší tak ještě o pár dalších bytů víc, aby se vše do paměti vešlo.
Nutno poznamenat, že stejný princip používá i Sinclair Microdrive a Rotronics Wafadrive. Wafadrive zabírá dokonce víc než 2kB RAM.
Volání TRDOSu z BASICu
Jak už jsem napsal, aby se Betadisk aktivoval a přepnul na ROM s TRDOSem, je nutné, aby procesor Z80 prováděl program v oblasti ROM, kde začíná font. Z BASICu, nepoužíváte-li upravenou variantu Sinclar ROM ISOROM, která TRDOSové příkazy radikálně zjednodušuje, to lze provést pouze funkcí USR, která se nejčastěji s příkazem RANDOMIZE používá ke spouštění programů ve strojovém kódu.
RANDOMIZE USR 15616
Příkazem RANDOMIZE USR 15616 můžete skočit do příkazového řádku TRDOSu. Jeho první vyvolání zároveň zobrazí identifikaci a verzi TRDOSu. Viz screenshoty. Původní verze opravdu má takto nevycentrované titulky a chybí jas barevných ZX Spectrum pruhů, i tento drobný detail je ve verzi 5.05cz opraven. Verze 5.04T pochází z aktuálně používané verze ESXDOSu 0.89, kde je disketová mechanika emulována pomocí obrazu diskety .TRD na úložišti s FAT16/32 filesystémem. Opakovaný vstup do příkazového řádku obrazovku nepřepisuje.
Příkazový řádek usnadňuje zadávání příkazů zvláště chystáte-li se jich použít víc po sobě. Zpět do Sinclair BASICu se vrátíte příkazem RETURN.
*"a:" CAT MOVE SAVE "program" LIST RETURN
BETA 128 v názvu naznačuje kompatibilitu se ZX Spectrum 128k (Betadisk verze 4.x a starší se ZX Spectrum 128k nefunguje), nikoli nutnost. Betadisk 5.x stejně dobře funguje i se ZX Spectrum 48k, ZX Spectrum 48k+ a mnoha klony. Podmínkou je, že uvnitř počítače nesmí být periferie pracující na stejných IO portech (31, 63, 95, 127, 255). S těmi koliduje např. PIO 8255 v Didaktiku Gama. A zároveň počítač musí mít vyvedených 9V pro stabilizátor 7805 uvnitř Betadisku a u Betadisků s řadičem WD1793, který vyžaduje 12V musí být i těch 12V na sběrnici přítomno.
Periferie pracující s kolidujícími porty ale může být připojena za Betadisk. Viz foto. Do ZX Spectrum 48k plus je připojený Betadisk a do něj interface UR-4 obsahující čip 8255 adresovaný na portech 31, 63, 95 a 127. Tato kombinace je zcela bez problémů použitelná a často používaná, protože Betadisk interface UR-4 během své činnosti odpojuje blokováním signálu /IORQ a naopak, když Betadisk nepracuje s disketou a není aktivní, tak jsou jeho porty vypnuté a Z80 může nerušeně komunikovat s čipem 8255 v UR-4. Bez této vlastnosti Betadisku by nebylo možné současně připojit ani Kempston joystick interface.
použití příkazů TRDOSu v programech
Režim příkazového řádku je užitečný pro jednorázové příkazy, ale nepomůže to s vkládáním příkazů do BASICového programu. Pro příkazy vložené do programu se používá druhá ze spouštěcích adres 15619. Příkaz REM následující za RANDOMIZE USR adresa zajišťuje, aby Sinclair BASIC nedetekoval chyby v syntaxi příkazů za REM následujících. Bez toho by nebylo možné sestavit příkazy, kterým standardní Sinclair BASIC nerozumí, které se od jeho syntaxe odlišují. Dvojtečka za REM zajišťuje přepnutí editoru na psaní příkazů, což signalizuje blikající kurzor K (keyword - klíčové slovo). Zároveň je důležité, aby příkaz za REM byl napsaný jako token (keyword). Např. CAT je jeden znak s kódem 207 (extend a ss+9), tak jak běžně v BASICu příkazy píšeme, nikoli tři písmena C A T.
10 RANDOMIZE USR 15619: REM : CAT
Chcete-li zpracovávat i některé chyby, můžete použít následující konstrukci. Ale v praxi to najde uplatnění málokdy, nijak to neřeší přerušení práce s diskem uživatelem pomocí BREAK ani to nepotlačí výpis hlášky "Retry, Abort, Ignore?".
10 LET error = USR 15619: REM : LOAD "filename" CODE 50000 20 IF error = 0 THEN PRINT "ok"
Tady je vhodné připomenout, že USR není příkaz, ale funkce, která vrací hodnotu. Sinclair BASIC neumí tuto funkci použít samostatně, vždy je nutné ji použít jako vstupní hodnotu do jiného příkazu. Následující příklad je špatně a kontrola syntaxe nedovolí takový řádek do programu zadat. Nedávalo by smysl použít funkci, jejíž výsledek je následně zahozen, kromě funkce USR.
Malou výjimkou je ISOROM, kde upravený interpretr BASICu dovolí funkci USR adresa použít jako samostatný příkaz z příkazového řádku, ale ani s ISOROM nelze USR vložit do řádku programu bez přecházejícího příkazu. Podobně se chová editor / interpretr BASICu ZX Spectra 128k, funkce USR může být použita samostatně, ale nesmí jí předcházet číslo řádku. V obou případech se BASIC chová, jakoby funkcím předcházel příkaz PRINT (kromě funkce USR v ISOROM) a po dokončení se vrácená hodnota vypíše na obrazovku. A ani u jedné ROM nelze použít USR bez příkazu v složitější konstrukci s : REM : příkaz TRDOSu.
10 REM ukazka chybne syntaxe na radku 20 20 USR adresa
Funkce USR je zamýšlena jako volání uživatelské funkce - programu ve strojovém kódu, který v registru BC vrací hodnotu a tu hodnotu můžeme použít pro něco dalšího v BASICu. To, že se hodnota vloží do příkazu RANDOMIZE je pouze zvyklost, nikoli nutnost. RANDOMIZE provádí inicializaci generátoru náhodných čísel a na tom většinou před spuštěním programu ve strojovém kódu nijak nezáleží. Ale stejně dobře lze použít i následující konstrukce.
PRINT USR adresa RUN USR adresa GO TO USR adresa CLEAR USR adresa BEEP 0,USR adresa
Problém je, že se vrácená hodnota v příkazu použije. Např. RUN a GO TO následně skočí na řádek vrácený v registru BC, v případě úspěšně provedeného příkazu TRDOSu to bude řádek 0. PRINT hodnotu vytiskne, CLEAR smaže proměnné a ještě nastaví RAMTOP a při hodnotách menších než je délka programu v BASICu ohlásí chybu M RAMTOP no good (tj. vždy když příkaz proběhne bez chyby, protože výsledkem je 0), BEEP pípne, ale protože trvání tónu je nula, k pípnutí vlastně nedojde. To by mohlo být fajn, kdyby tam nebyl druhý parametr taky zabírající místo v paměti. Příkaz RANDOMIZE se ze všech variant ukazuje být nejméně problematický.
Vložení vrácené hodnoty do proměnné příkazem LET je tak jen jednou z možností a prakticky jediná možnost, jak na vrácenou hodnotu reagovat. Použití v příkazu IF nefunguje kvůli syntaxi s REM a příkazem za ním a vkládat do podmínky USR 15616, který po úspěšném provedení příkazu RETURN vrátí vždy 0 nedává smysl.
Nejčastější využití vrácené chyby bývá, když uživatel zadává jméno souboru ručně v INPUT dialogu. Např. při načítání souboru, kdy uživatel jméno souboru opisuje z předtím zobrazeného výpisu adresáře příkazem CAT.
10 INPUT "zadej jmeno ";a$ 20 LET error=USR 15619: REM : LOAD a$ SCREEN$ 30 IF error=0 THEN PAUSE 0: GO TO 9999 40 IF error=1 THEN PRINT "soubor nenalezen": STOP
Analogicky při ukládání souboru, nastane-li neúspěch, bývá vhodné zacyklit program a dovolit uživateli vyměnit disketu za prázdnou, nebo pozměnit název souboru, aby nekolidoval.
10 INPUT "zadej jmeno ";a$ 20 LET error=USR 15619: REM : SAVE a$ SCREEN$ 30 IF error=0 THEN GO TO 9999 40 IF error=2 THEN PRINT "soubor uz existuje" 50 IF error=3 THEN PRINT "plny disk" 60 IF error=4 THEN PRINT "plny adresar" 70 STOP
Tato tabulka chybových kódů vychází z originálního manuálu. Pro LOAD a SAVE se z ní dá použít přinejmenších prvních pět kódů 0 až 4. Nejsem si zcela jistý chybou číslo 5. Chyby 6 a 7 samozřejmě nastat mohou, jen se obtížněji testují v emulátoru a v tuto chvíli netuším, jak by mohla nastat chyba 8. Možná voláním ze strojového kódu s příkazem, který neprošel kontrolou editorem BASICu. Ale BASIC syntaktickou chybu v příkazu TRDOSu ohlašuje chybou "C Nonsense in BASIC", na které se zastaví a k vrácení hodnoty funkcí USR nedojde.
Proudy se na Betadisku téměř nepoužívají, ale přesto se mi chyby číslo 12 podařilo dosáhnout příkazem RANDOMIZE USR 15619: REM : NEXT a$ SCREEN$ když jsem zkoušel, co se dá TRDOSu vnutit aniž by nastal "C Nonsence in BASIC". Ke stejnému výsledku vedlo několik dalších kombinací příkazů i prostý PRINT "string".
| č. chyby | význam |
|---|---|
| 0 | žádná chyba - soubor načten / příkaz proveden |
| 1 | soubor nenalezen - soubor zadaného názvu na disku není |
| 2 | soubor už existuje - po odpovědi nepřepisovat existující soubor |
| 3 | plný disk - málo volných sektorů, ukládaný soubor se nevejde |
| 4 | katalog je plný - při pokusu uložit 129. soubor včetně smazaných |
| 5 | počet záznamů překročen - při pokusu o přístup k sektoru mimo rozsah |
| 6 | v mechanice není disk |
| 7 | chyba disku - nečitelný sektor, chybějící značka TRDOSu... |
| 8 | chyba syntaxe |
| 9 | --- |
| 10 | proud je již otevřen |
| 11 | Not Disk File - může nastat při pokusu o uzavření kanálu 0 až 3 |
| 12 | proud není otevřen |
| 13 | chyba verifikace |
Poznámka: TRDOSový příkaz, ať už v jakékoli formě zápisu, musí být poslední na BASICovém řádku. Za RANDOMIZE USR 15619: REM : příkaz nelze psát cokoli dalšího. Pokud např. při konverzi programu za páskovou operací řádek pokračoval, při konverzi na TRDOS je nutné takový řádek rozdělit na dva.
formátování diskety
Zde si dovolím předpokládat, že máte k Betadisku připojenou oboustrannou 80 stopou disketovou mechaniku, nebo používáte emulátor (příp. ESXDOS). Např. Fuse emulátor, kde je v menu funkce Media -> Disk -> Beta -> Drive n -> Insert New, ta vytvoří prázdný 640kB obraz diskety. Už v 90. letech se s Betadiskem běžně používaly oboustranné 80 stopé mechaniky, používat pouze 40 stopou 5,25" mechaniku je trochu plýtvání kapacitou diskety a s 3,5" jednostrannou jsem se nikdy nesetkal a 80 stopé snad byly všechny. I jednostranné 5,25" mechaniky byly spíš doménou Commodore C64, 8bit Atari, Apple... u Sinclairů byly raritní, nejspíš proto, že k většímu rozšíření disketových řadičů došlo později. Kdo mohl, jednostranné i 40 stopé mechaniky nahradil lepšími.
Stejně jako čerstvě rozbalenou a do disketové mechaniky vloženou disketu je nutné zformátovat, taktéž image diskety bývá "vložen" bez vytvořené struktury adresáře a systémového sektoru s informacemi o disketě. O disketě recyklované, pocházející z jiného počítače, kterou chceme smazat, ani nemluvě.
RANDOMIZE USR 15616 FORMAT "diskname"
RANDOMIZE USR 15619: REM : FORMAT "diskname"
Příkaz FORMAT nejprve na disketě vytvoří strukturu sektorů a stop, sektory vymaže (vyplní nulami) a ověří jejich čitelnost. Z této struktury my uživatelé vidíme jen obsah sektorů, ale kromě 256 bytů dat jsou na magnetickém médiu i mezisektorové mezery, synchronizační blok, číslo sektoru a kontrolní součet obsahu sektoru. To jsou informace pro čip řadiče a s ním komunikující část kódu v TRDOSu. Z pohledu našeho programu se jimi nemusíme zabývat. Nakonec TRDOS zapíše systémový sektor s informacemi o disketě a jménem diskety zadaným v příkazu FORMAT. Toto jméno lze později změnit, formát (kapacitu) diskety nikoli. Za běžných okolností s 80 stopou disketovou mechanikou nebývá potřeba dělat víc.
Pokud jsou během formátování nalezeny chybné sektory, zobrazí se jako na následujícím snímku. Tato konkrétní disketa obsahovala pět vadných sektorů, které neprošly verifikací. První inverzí zvýrazněné číslo tedy ukazuje počet sektorů, které se podařilo naformátovat, druhé kolik jich mělo být. Jsou-li čísla odlišná, TRDOS na to takto upozorní. A protože TRDOS neumí na rozdíl od systémů s FAT chybné sektory označit a později se jim vyhýbat, je lepší takovou disketu nepoužívat. Výjimkou mohou být snad jedině diskety s chybnými sektory na úplně posledních stopách a k nimž se zapsané soubory ani nepřiblíží. Ale i tak je dobré si takovou disketu viditelně označit a příliš na ní nespoléhat.
Pokud byste chtěli používat mechaniky jednostranné, lze disketu jako jednostrannou naformátovat přidáním znaku $ na začátek názvu diskety. Příkazem 40 lze aktuální (80 stopou) disketovou jednotku přepnout do režimu 40 stop a naopak příkazem 80 zpět do režimu 80 stop. Příkazem 40 se zapne dvojité krokování, což je potřeba k čtení disket zapsaných na 40 stopých disketových mechanikách pomocí 80 stopé. A zároveň to dovolí naformátovat disketu v 80 stopé mechanice jako 40 stopou. Ale protože 80 stopá mechanika má hlavu s užší štěrbinou, aby mohla zapisovat užší stopy, kterých se vejde na stejnou magnetickou vrstvu dvojnásobek, tak záznam takto zapsaný na 80 stopé mechanice není zcela kompatibilní. 40 stopá disketová mechanika bude z takto zapsané diskety číst nejenom stopy zapsané 80 stopou mechanikou, ale zároveň i tu část magnetické vrstvy, kde zůstal předchozí záznam, což způsobí chyby. Lépe nemíchat dohromady a nikdy na 40 stopou disketu pomocí 80 stopé disketové mechaniky nezapisovat. Znovu zdůrazňuji, že příkaz 40 slouží ke čtení disket zapsaných na 40 stopé disketové mechanice pomocí 80 stopé.
Zde je také dobré připomenout, že TRDOS 5.05cz po resetu neověřuje počet stop. U starších verzí TRDOS přejel hlavičkou za stopu 40 (43?) a ověřoval, jestli hlavička narazí, nebo může stopu na 40 stopé mechanice nedosažitelnou dosáhnout. Tím si zjistil parametry disketové mechaniky a tyto až do resetu uchovával ve svých systémových proměnných. Na jednu stranu to dovolovalo používat všechny druhy mechanik, ale zároveň to bylo hlučné a zdržující. TRDOS 5.05cz předpokládá, že jsou všechny připojené disketové mechaniky 80 stopé.
Více o formátech disket, stopách, a dalších detailech na Wikipedii, ovšem obecně, nikoli z pohledu Betadisku.
rychlé smazání diskety
Původní TRDOS 5.03 dovoluje pouze formátovat celou disketu, nebo mazat soubory jednotlivě. TRDOS 5.05cz rozumí příkazu ERASE "*", který vymaže celý adresář a prakticky provede "rychlý formát" diskety. Může být užitečné v případě, že jste si jistí bezchybností diskety a chcete pouze vymazat obsah bez zbytečného čekání na přepsání všech stop.
RANDOMIZE USR 15616 ERASE "*"
RANDOMIZE USR 15619: REM : ERASE "*"
Pozor na to, že z takto smazané diskety nelze snadno obnovit soubory i když jejich obsah ve stopách zůstal. Adresář bude kompletně vynulován na rozdíl od mazání jednotlivých souborů při kterém dochází pouze k náhradě prvního znaku názvu kódem 0, nebo 1.
přejmenování diskety
S TRDOS 5.05cz lze použít rozšířený příkaz NEW i k přejmenování diskety. Bez parametru příkaz NEW zavolaný v TRDOSu nefunguje, jeho použití vede k chybě "C Nonsense in BASIC", nikoli ke smazání BASICového programu. S názvem diskety v uvozovkách provede přejmenování diskety, přičemž TRDOS 5.05cz umí názvy disket až 10 znaků dlouhé na rozdíl od mnoha ostatních verzí, které umí názvy jen 8 znakové i když v systémovém sektoru jsou za názvem dva nevyužité byty navíc.
RANDOMIZE USR 15616 NEW "diskname"
RANDOMIZE USR 15619: REM : NEW "diskname"
Možná vás napadlo, co se stane, když do názvu diskety dáme $, povede k přepnutí diskety na jednostrannou? Nepovede (ověřil jsem). Disketa jednoduše bude mít v názvu $ a ani následné smazání obsahu příkazem ERASE "*" na tom nic nezmění, $ má význam pouze v názvu příkazu FORMAT. Informace o "kapacitě" diskety je uložena v systémovém sektoru na jiném místě.
volba disketové mechaniky
K Betadisku lze připojit až čtyři disketové mechaniky (disketové jednotky). TRDOS proto poskytuje příkaz pro jejich přepínání. Viz příklad.
RANDOMIZE USR 15619: REM :*"a:" RANDOMIZE USR 15619: REM :*"b:"
TRDOS 5.05cz tyto příkazy zjednodušuje na prostou hvězdičku a písmeno jednotky, což je ideální pro časté používání v příkazovém řádku, ale nemělo by být použito v programu, pokud hrozí, že program bude používán i s jinou verzí TRDOSu.
RANDOMIZE USR 15616 *a *b
RANDOMIZE USR 15619: REM :*a RANDOMIZE USR 15619: REM :*b
Písmeno jednotky oddělené dvojtečkou lze přidávat i na začátek názvů souborů, ale to se používá většinou jen v příkazu COPY. Přidání k názvu v programu by mohlo být problematické. Správněji by každý program měl být napsaný tak, aby byl schopen pracovat z kterékoli disketové jednotky, kdekoli ho uživatel spustí. Tu a tam se stává, že na to programátoři zapomenou a setkal jsem se s programy (hrami), které fungovaly pouze z disketové jednotky A.
RANDOMIZE USR 15619: REM : LOAD "a:filename"
načtení a uložení souboru
Nyní, když už máme připravanou disketu, chceme na ní i něco zapsat a pak to z té diskety přečíst. K tomu stejně jako v Sinclair BASICu pro práci s páskou slouží příkazy LOAD, SAVE, MERGE a VERIFY. Na rozdíl od pásky, kde jsou soubory uložené sekvenčně jeden za druhým u diskety musíme zadávat správné jméno. Nelze uložit soubor beze jména a nelze přečíst soubor beze jména s výjimkou programu "boot.B". Existují systémy (BSDOS), které umí ukládat soubory sekvenčně, nebo do TAP souboru emulujícího pásku (ESXDOS) a ty dovolují uložit i bezhlavičkové datové bloky, ale TRDOS nic takového neumí. Další rozdíl oproti ukládání na pásku je, že TRDOS mezi příkazy pro načtení souboru přidává i příkaz RUN s parametrem, který soubor načte a zároveň spustí.
Začněměž uložením souboru. Viz nejčastěji používané varianty. První dva uloží program v BASICu, přičemž LINE určuje řádek odkud se má BASIC automaticky spustit po načtení. Druhé dva příklady uloží binární data (Bytes). SCREEN$ je v podstatě ekvivalentní CODE 16384,6912, ale zabírá v paměti pouze jeden token, nikoli token plus prostor pro dva číselné parametry a čárku mezi nimi. Program v BASICu a CODE se mohou jmenovat stejně, odlišují se příponou.
Na rozdíl od pásky mohou mít soubory pouze 8 znaků v názvu. Zjevně to je důsledek snahy o extrémní úspornost položky v adresáři, která zabírá pouhých 16 bytů celkem a dvě šestnáctibitové hodnoty, které jsou k dispozici u každého soubory mají různý význam pro BASIC, CODE i DATA.
RANDOMIZE USR 15619: REM : SAVE "filename" RANDOMIZE USR 15619: REM : SAVE "filename" LINE 10 RANDOMIZE USR 15619: REM : SAVE "filename"CODE 0,16384 RANDOMIZE USR 15619: REM : SAVE "filename"SCREEN$ RANDOMIZE USR 15619: REM : SAVE "str data" DATA a$() RANDOMIZE USR 15619: REM : SAVE "num data" DATA n()
Místo a$(), nebo n() si doplňte název své řetězcové proměnné, nebo číselného pole.
Analogicky načtení takto uložených souborů můžeme provést, viz příklad. Stejně jako při načítání z pásky se neuvádí spouštěcí řádek, nebo délka binárního souboru, stačí adresa, kam mají být binární data uložena, chceme-li je uložit jinam než je adresa v hlavičce souboru. Stejně jako při načítání z pásky by pro binární data měl být předem nastavený správný RAMTOP.
RANDOMIZE USR 15619: REM : LOAD "filename" RANDOMIZE USR 15619: REM : LOAD "filename"CODE 32768 RANDOMIZE USR 15619: REM : LOAD "filename"CODE RANDOMIZE USR 15619: REM : LOAD "filename"SCREEN$ RANDOMIZE USR 15619: REM : LOAD "str data" DATA a$() RANDOMIZE USR 15619: REM : LOAD "num data" DATA n()
Dojde-li při čtení souboru k chybě, pokusí se TRDOS čtení opakovat a když ani potom sektor není přečten správně se správným kontrolním součtem, zobrazí TRDOS dotaz, aby uživatel rozhodl, jak dál postupovat. Po odpovědi Retry se znovu několikrát pokusí sektor přečíst, po odpovědi Ignore ignoruje chybu a ponechá v paměti počítače chybná data a Abort přeruší čtení a ukončí provádění příkazu LOAD (ale i CAT a LIST..., je-li např. chybný sektor v adresáři).
Riziko zklamání ze ztráty cenných dat můžeme snížit kromě zálohování i ověřením zapsaných souborů příkazem VERIFY. Verifikace probíhá podobně jako u souborů uložených na pásku. Viz příklady. Když jsem testoval správnost syntaxe, TRDOS 5.03 mi nezobrazoval dialog s dotazem na přepsání souboru, ani chybu verifikace, tipnul bych si spíš na chybu emulace, nevzpomínám si, že by se takto choval TRDOS 5.03 i na reálném hardwaru. TRDOS 5.05cz fungoval dle očekávání správně v emulátoru i na skutečném počítači. V TRDOSu 5.05cz byla verifikace rozšířena o zobrazování adresy, kde byla odlišnost nalezena a také původní a z diskety načtené hodnoty bytu.
RANDOMIZE USR 15619: REM : VERIFY "filename" RANDOMIZE USR 15619: REM : VERIFY "filename"CODE 32768 RANDOMIZE USR 15619: REM : VERIFY "filename"CODE RANDOMIZE USR 15619: REM : VERIFY "filename"SCREEN$ RANDOMIZE USR 15619: REM : VERIFY "str data" DATA a$() RANDOMIZE USR 15619: REM : VERIFY "num data" DATA n()
Příkaz MERGE má smysl jen u BASICových programů, slouží ke složení programu s programem již načteným v paměti. Pokud se čísla řádků překrývají, dojde k nahrazení dřívějších řádků nově načtenými. Je třeba vědět předem, co se bude skládat s čím. Častěji se příkaz MERGE používá k načtení BASICového programu, který nechceme automaticky spustit. Což lze, není-li proti tomu program chráněný. Pokus o MERGE binárního souboru vede k chybě "C Nonsense in BASIC".
RANDOMIZE USR 15619: REM : MERGE "filename"
Příkaz RUN jsem si nechal nakonec. Tento příkaz šikovně použitý v zaváděči má potenciál částečně kompenzovat potřebu TRDOSu využívat paměť ZX Spectra pro sebe, protože s vhodně připravenými binárkami odstraňuje potřebu používat RANDOMIZE USR k dekompresi a spouštění kódu programů v binárních souborech. Ušetří se tím jen několik málo bytů, ale v kritických situacích je každý byte dobrý.
RUN se používá nejčastěji pro načítání binárních souborů a v podstatě funguje jako kombinace příkazů LOAD "filename"CODE: RANDOMIZE USR startovní adresa. Lze jím načíst i program v BASICU, pak je ekvivalentní LOAD "filename": RUN.
RANDOMIZE USR 15619: REM : RUN "filename" RANDOMIZE USR 15619: REM : RUN "filename"CODE 32768 RANDOMIZE USR 15619: REM : RUN "filename"CODE
Často se také používá zcela bez parametrů v příkazovém řádku TRDOSu ke spuštění programu "boot.B" nebyl-li spuštěn automaticky hned po resetu.
RANDOMIZE USR 15616 RUN
Bohužel v původním TRDOS 5.03 a mnoha odvozených verzích je chyba, která způsobí po použití příkazu RUN "filename"CODE v BASICovém programu chybu "C Nonsense in BASIC" a tím přerušení běhu programu i když se příkaz provede, viz dále v kapitole o psaní zaváděče (loaderu) programu / hry. V TRDOS 5.05cz i v TRDOS 5.04T v ESXDOSu je tato chyba opravena.
zobrazení obsahu diskety
TRDOS poskytuje dva příkazy. Rychlejší a stručnější CAT (katalog) vypisující jména souborů do dvou sloupců pouze s délkou v sektorech a pomalejší LIST vypisující jména souborů se všemi detaily včetně startovacího řádku BASICových programů, která není součásti hlavíčky v adresáři, ale TRDOS pro číslo řádku musí sahat do posledního sektoru uloženého souboru, viz formát TRDOSové diskety.
RANDOMIZE USR 15619: REM : CAT RANDOMIZE USR 15619: REM : CAT "a:" RANDOMIZE USR 15619: REM : LIST RANDOMIZE USR 15619: REM : LIST "a:"
I v tomto se TRDOS 5.05cz maličko liší od originálního TRDOS 5.03, z výpisu příkazu CAT bylo odstraněno písmeno jednotky zcela zbytečně vypisované na začátku každého řádku a dvojtečka mezi sloupci. Výsledný výpis je přehlednější, viz screenshot vlevo.
I příkaz LIST byl v TRDOS 5.05cz opraven, nevypisuje hlavičku s informacemi o disketě na každou obrazovku, ale pouze na začátku na první obrazovku. Tím se výpis o něco zrychlil, protože zbylo více řádků pro jména souborů. Hlavička s informacemi o disketě je přehlednější a lépe srozumitelná.
Pro srovnání viz výpis obsahu stejné diskety na TRDOS 5.03.
Pozitivním důsledkem obou drobných změn v příkazech CAT a LIST je i to, že s pomocí TRDOS 5.05cz se dá výpis obsahu diskety vytisknout na případně nainstalované tiskárně, pokud je ovladač nastavený na tisk přes kanál 3, aby fungovaly příkazy LPRINT a LLIST. Resp. vytisknutý obsah diskety pak dává větší smysl i na papíru. Občas mi u 5,25" disket přišlo vhod vložit do papírové obálky diskety lístek s výpisem obsahu.
RANDOMIZE USR 15619: REM : CAT #3 RANDOMIZE USR 15619: REM : LIST #3
V originálním manuálu je dokonce zmínka o tisku přes sériový port Interface 1. Osobně neznám nikoho, kdo by někdy zkoušel Betadisk s Interface 1 připojovat současně, ale údajně to technicky možné bylo. Já sám jsem Interface 1 provozoval jen velmi krátce (test po opravě pro někoho jiného) a domnívám se, že krátkodobá kombinace obou zařízení mohla mít smysl jen pro přenesení souborů z Microdrive na disketu.
mazání souborů
Soubory lze mazat příkazem ERASE. Název souboru musí být zadán přesně, TRDOS neumí hromadné mazání, neumí regulární výrazy, ani prosté nahrazení části názvu jiným znakem, třeba hvězdičkou. Zároveň musí být zadán typ souboru, viz příklady. Výjimkou je výše zmíněný příkaz ERASE "*" kde hvězdička místo názvu vede ke smazání celé diskety (soubor by proto nikdy neměl mít název obsahující pouze jednu hvězdičku).
RANDOMIZE USR 15619: REM : ERASE "filename" RANDOMIZE USR 15619: REM : ERASE "a:filename" RANDOMIZE USR 15619: REM : ERASE "filename"CODE RANDOMIZE USR 15619: REM : ERASE "filename" DATA RANDOMIZE USR 15619: REM : ERASE "filename"#
Nesprávně zadané jméno mazaného souboru vede k chybě "S No file".
ERASE "filename"SCREEN$ nefunguje ani na TRDOS 5.05cz, nutno použít CODE.
kopírování a přejmenování souborů
Abychom si udrželi v souborech pořádek, je občas nutné něco někam zkopírovat, nebo soubory přejmenovat. Dnes máme několik pěkných správců souborů, např. velmi jednoduchý a mimořádně efektivní KCopy+ nebo pomalejší, ale pěkně propracovaný TR-DOS Navigator. A mnoho dalších. Dobrý filemanager je nenahraditelný a určitě mnohem pohodlnější. Ale i TRDOS sám poskytuje nástroje pro správu souborů v podobě příkazů COPY, NEW a už zmíněný ERASE.
Příkazem COPY lze kopírovat soubor odněkud někam. Dneska jsme zvyklí, že zdrojový soubor bývá uváděn první. U TRDOSu je tomu z nějakého důvodu naopak, první je cíl, druhý v pořadí zdroj. Pokud se kopírují binární data (Bytes), je třeba přidat klíčové slovo CODE, pokud soubor s uloženými daty pak klíčové slovo DATA, nebo # pro stream.
RANDOMIZE USR 15619: REM : COPY "target","source" RANDOMIZE USR 15619: REM : COPY "target","source"CODE RANDOMIZE USR 15619: REM : COPY "target","source" DATA RANDOMIZE USR 15619: REM : COPY "target","source"#
Pokud nechcete jen duplikovat soubor pod novým názvem na stejné disketě jako v předchozím případě a máte víc disketových mechanik, je vhodné spolu se jménem souboru určit i z jaké na jakou disketovou mechaniku (jednotku) se má soubor zkopírovat.
RANDOMIZE USR 15619: REM : COPY "b:target","a:source" RANDOMIZE USR 15619: REM : COPY "b:target","a:source"CODE RANDOMIZE USR 15619: REM : COPY "b:target","a:source" DATA RANDOMIZE USR 15619: REM : COPY "b:target","a:source"#
Pro kopírování všech souborů na prázdnou diskety lze také použít příkaz COPY s hvězdičkami místo názvu souborů. Opět pozor na to, že cíl je první. Pro jistotu je dobré mít zdrojovou disketu chráněnou proti zápisu. Takto použitý příkaz COPY v podstatě kopíruje soubor po souboru z jedné diskety na druhou, ale bude proveden pro všechny nesmazané soubory na zdrojové disketě. Smazané soubory budou vynechány, duplicitní soubory se pokusí přepsat (zeptá se).
Hvězdička v řetězci bohužel nelze použít jen pro část názvu, ani nelze zkopírovat jen soubory jednoho typu a jiné ignorovat. Příkazem TRDOSu lze zkopírovat buď vše bez rozdílu, nebo jména souborů zadávat jednotlivě.
RANDOMIZE USR 15619: REM : COPY "b:*","a:*"
Pro kopírování mezi dvěma disketami na jedné disketové mechanice má TRDOS zvláštní syntaxi s písmenem s jako "single drive". Když jsem při psaní článku ověřoval správnost příkladů, proběhlo kopírování 156 sektorů dlouhého souboru (39762 bytů) s RAMTOP nastaveným 65367 (41376 bytů volných) na jednu výměnu diskety. Nemusel jsem vložit zdrojovou disketu podruhé. Očividně TRDOS k přenosu souboru využívá dostupnou paměť alokovatelnou pro proměnné v BASICu, aniž by došlo k narušení programu, nebo binárních dat nad RAMTOP.
RANDOMIZE USR 15619: REM : COPY s"filename" RANDOMIZE USR 15619: REM : COPY s"filename"CODE RANDOMIZE USR 15619: REM : COPY s"filename" DATA RANDOMIZE USR 15619: REM : COPY s"filename"#
Programy pro správu souborů, jako zmíněný KCOPY+ jdou samozřejmě ještě o kousek dál. KCOPY+ umí využívat rozšířenou paměť 128kB ZX Spectra a skupinu označených souborů KCOPY+ kopíruje najednou, ne po jednotlivých souborech. Co se vejde do paměti to přenese. Ale vložit zdrojovou disketu zpět požaduje vždy i když se mu povede zkopírovat označené soubory napoprvé a ze zdrojové diskety si jen načte adresář (katalog).
Poslední varianta příkazu COPY je použití s písmenem b jako backup k zálohování obsahu diskety.
RANDOMIZE USR 15616 COPY b""
RANDOMIZE USR 15619: REM : COPY b""
Tato varianta příkazu COPY je určena k vytvoření duplikátu diskety na jedné disketové mechanice. Příkaz COPY zkopíruje celý adresář a celou obsazenou část diskety od prvního souboru po poslední nesmazaný včetně souborů smazaných, které jsou v adresáři mezi nesmazanými a tedy potenciálně obnovitelné. I obsah smazaných souborů mezi nesmazanými je zachován na cílové disketě. Obsah smazaných na konci adresáře nikoli, pouze jejich jména zůstanou v adresáři s kódem 0x00 místo prvního znaku názvu. Tyto soubory by mohly být obnovitelné po smazání, dřív než na disketu bylo zapsáno něco dalšího, ale obecně to neplatí.
V manuálu není evedeno, že by řetězec v uvozovkách za příkazem COPY b měl mít nějaký vliv a experimentálně se zdá, že je ignorován včetně pokusů o určení disketové jednotky. Tu lze zvolit před zadáním příkazu COPY b a volba bude respektována, ale nikoli v uvozovkách za příkazem COPY b.
POZOR na to, že příkaz COPY b"" přepíše zcela obsah cílové diskety obsahem zdrojové. Na přepsání duplicitních souborů se neptá ani je nerozlišuje.
K přejmenování slouží příkaz NEW. Vždy je nutné zadat oba názvy, původní i nový, pokud by byl zadán jen jeden řetězec, příkaz NEW na TRDOS 5.05cz by se pokusil ho použít k přejmenování diskety.
RANDOMIZE USR 15619: REM : NEW "novy","stary" RANDOMIZE USR 15619: REM : NEW "novy","stary"CODE RANDOMIZE USR 15619: REM : NEW "novy","stary" DATA RANDOMIZE USR 15619: REM : NEW "novy","stary"#
Součástí názvu souboru může být i písmeno disketové jednotky, ale protože soubor je před přejmenováním i po přejmenování na stejné disketě, bývá praktičtější disketovou jednotku přepnout předem a do názvů písmeno jednotky neuvádět.
setřesení diskety
Z vlastností filesystému, tj. ze způsobu jak jsou soubory organizované v sektorech na disketě vyplývá jedna méně příjemná vlastnost TRDOSu. TRDOSová disketa nemá žádnou souborovou alokační tabulku (FAT), jen seznam souborů, které jsou uložené popořadě, jeden za druhým. Když dojde ke smazání souboru na konci tohoto seznamu souborů v adresáři jsou jím zabrané sektory okamžitě k dispozici pro další soubor na disketu zapsaný. Pokud je smazaný soubor umístěný mezi jinými soubory, tak už to tak jednoduché není a jím zabrané místo zůstává i nadále zabrané, jen se soubor přestane vypisovat ve výpisu příkazů CAT a LIST. Místo nelze využít nově zapsaným souborem, leda by ten nově zapsaný soubor zabíral přesně stejný počet sektorů jako volné místo mezi soubory, což TRDOS neumí rozhodnout, místo nechává volné, dokud nedojde k "setřesení" příkazem MOVE.
Příkaz MOVE postupně prochází soubory od začátku a pokud je mezi soubory nějaký smazaný (více smazaných souborů), tak nejbližší další nesmazané soubory posune na toto místo blíž k začátku diskety a prostor tím uvolní. Posouvá se nejenom položka v adresáři, ale i data souboru. Proto celá operace může trvat i docela dlouho, podle toho, jak velký objem dat je nutné takto přesouvat z jednoho místa diskety na druhé.
RANDOMIZE USR 15616 MOVE
RANDOMIZE USR 15619: REM : MOVE
Doporučuji tuto operaci provádět pokud možno hned po resetu počítače s čistou pamětí a čerstvě inicializovaným TRDOSem (pro jistotu) a rozhodně jen a pouze na spolehlivém počítači. Kdyby došlo k nějaké poruše, nebo resetu během přesouvání souborů blíž k začátku diskety, tak byste mohli přijít o soubor, se kterým MOVE v tu chvíli pracoval. Na mém počítači s příkazem MOVE nikdy nebyl problém pokud byla disketa bez chybných sektorů, ale i tak je jistá opatrnost na místě.
To, že by mohlo mít smysl provést setřesení naznačuje číslo "Del. File(s)" ve výpisu obsahu diskety příkaz CAT a LIST. Je-li tam nula, není co přesouvat a setřásat.
Používáte-li Betadisk převážně ke spouštění her, je klidně možné, že na toto narazíte jen vzácně, jestli vůbec někdy.
kanály / sekvenční data
Nechci zabíhat příliš do detailů, jak kanály v Sinclair BASICu fungují, to je na samostatný článek, ale velmi zjednodušeně. Sinclair BASIC umožňuje skrz kanály odesílat a přijímat data. První tři 0, 1 a 2 jsou vyhrazené pro výpis na obrazovku a pro vstup z klávesnice od uživatele. Kanál 3 je určen pro tisk na tiskárnu, tisknout lze speciálními příkazy LPRINT a LLIST, což ve skutečnosti není nic jiného než PRINT #3 a LIST #3. Další kanály od čísla 4 včetně do 15 lze použít s TRDOSem pro přesměrování dat do souboru, nebo čtení ze souboru.
Nejprve je kanál nutné otevřít. Musí být zadáno číslo, jméno souboru a režim - pro čtení R, nebo pro zápis W. Pokus o otevření kanálu 0 až 3 vede k chybě "Q Parameter error" a tuto chybu nelze odchytit pomocí LET error = USR 15619, je to chyba Sinclair BASICu ne TRDOSu.
Pokus o odeslání, nebo příjem dat z neotevřeného kanálu vede k chybě "O Invalid stream", také toto je chyba ohlášená Sinclair BASICem, ne TRDOSem. A nakonec, pokus o čtení dat z kanálu, ze kterého bylo už vše přečteno končí hláškou "8 End of file".
Následující příklad otevře kanál #4, přesměruje ho do souboru pro zápis a zapíše do něj několik řádků. Potom zas kanál uzavře. Opatrně na uzavírání neotevřeného kanálu, v dřívějších verzích to mohlo vést ke zhroucení BASICu.
14 RANDOMIZE USR 15619: REM : OPEN #4,"filename",w 20 FOR n=1 TO 8: PRINT #4;"hello world ";n: NEXT n 30 RANDOMIZE USR 15619: REM : CLOSE #4
Nabízí se myšlenka, jestli by se to nedalo použít pro výpis programu do souboru. Ale to tak úplně nefunguje. Zápis příkazem LIST #4 proběhne. Řádky se pak ale načíst nedají, příkaz INPUT bude selhávat na každém řádku, který obsahuje uvozovky. A zároveň příkaz LIST odesílá tokeny, nikoli příkazy jako prostý text. To je úspornější, ale zároveň takto uložená data vyžadují další zpracování. Pro tisk se lépe hodí sériový port.
10 RANDOMIZE USR 15619: REM : OPEN #4,"filename",w 20 LIST #4 30 RANDOMIZE USR 15619: REM : CLOSE #4
Čtení jednoho, nebo více řádků se provádí příkazem INPUT.
10 RANDOMIZE USR 15619: REM : OPEN #4,"filename",r 20 INPUT #4,a$ 30 PRINT a$ 40 RANDOMIZE USR 15619: REM : CLOSE #4
10 RANDOMIZE USR 15619: REM : OPEN #4,"filename",r 20 FOR n=1 TO 8: INPUT #4,a$: PRINT a$: NEXT n 30 RANDOMIZE USR 15619: REM : CLOSE #4
Zapsaných dat může být teoreticky tolik, kolik se vejde na disketu. Každých zapsaných 4096 bytů se uloží do nového souboru a jeho startovní adresa bude 8192 + index souboru číslováno od 0. Objem dat tedy není omezen pouze 16 bitovou délkou souboru. Existující soubor / stream s daty lze otevřít opakovaně a přidávat do něj další data. Prakticky jsem ale při pokusu o zaplnění diskety dosáhl poškození adresáře, je možné, že je v TRDOS 5.05cz chyba, která dovolí zapisovat i když je disk plný.
V následujícím příkladu jsem zkusil na disketu zapsat 10000 řádků a toto byl výsledek. K zaplnění diskety nedošlo, vše bylo zapsáno korektně dle očekávání. Tento druh zápisu by mohl mít smysl třeba při dlouhodobějším sběru údajů, nějakém měření, které probíhá řádově hodiny a je třeba zapsat pár znaků po několika sekundách.
Zapisovat a číst data skrze kanály lze nejenom sekvenčně, ale i náhodně. V tomto případě je kromě způsobu přístupu nutné určit i velikost zapisovaného bloku. Kanál lze otevřít příkazem OPEN #, místo znaku R nebo W následuje token RND a za čárkou počet znaků určující délku jednoho záznamu, řetězce s pevnou délkou. Při pokusu o zápis delšího řetězce bude tento zkrácen na zadanou délku.
Zápis se provádí podobně jako v předchozích případech příkazem PRINT # číslo_kanálu. Trik je v tom, že za číslem kanálu musí následovat středník a za číslem záznamu (v příkladu proměnná n) je čárkou oddělený řetězec a dále platí stejna pravidla pro syntaxi jako platí pro příkaz PRINT v jiných situacích.
10 REM ** otevrit kanal ** 20 RANDOMIZE USR 15619: REM : OPEN #4,"filename",RND,14 30 STOP 50 REM **zavrit kanal ** 60 RANDOMIZE USR 15619: REM : CLOSE #4 70 STOP 100 REM **zapsat data ** 110 FOR n=1 TO 20 120 PRINT #4;n,"Hellorld! ";n;"..." 130 NEXT n 140 STOP 200 REM **precist data ** 210 FOR n=1 TO 20 220 INPUT #4;(n),a$ 230 PRINT a$ 240 NEXT n 250 STOP
I toto může být zajímavý způsob, jak využívat prostor na disketě pro data. I toto jsem ověřil na reálném ZX Spectrum 128k +2 s ISO ROM a Betadiskem s TRDOS 5.05cz. Původně se zdálo, že proměnnou v příkazu INPUT nelze zadat. Teprve později jsem zjistil, že lze, ale proměnná na rozdíl od číselné konstanty musí být v závorkách. Pokus o zadání proměnné bez závorek vedl k chybě "C Nonsense in BASIC". Velikost záznamu na konci příkazu OPEN # pro náhodný přístup je nutné uvádět vždy, nejenom když chcete zapisovat, ale i když chcete data jen číst.
přímé čtení a zápis sektorů souboru
Ke čtení sektorů konkrétního souboru slouží příkaz PEEK. Čte vždy jeden sektor, číslováno od 1. Pokus o čtení sektoru mimo rozsah by měl vést k chybě. Ale když jsem s tímto experimentovat, narazil jsem na zvláštní nekonzistenci. S vykřičníkem ISOROM místo RANDOMIZE USR 15619: REM : pokus o čtení neexistujícího souboru vedl k chybě "S No file" a pokus o čtení neexistujícího sektoru k "T Error in TRDOS". V případě, že jsem použil syntaxi s RANDOMIZE USR 15619: REM : byla chyba potlačena, chybně zadaný příkaz se neprovedl a do BASICu se to vrátilo s "0 O.K.". Ale když jsem zkusil použít PRINT USR 15619, ukázalo se, že chyba nastala. Pro neexistující soubor to byla chyba 1 a pro sektor mimo rozsah chyba 5, viz tabulka uvedená výše.
RANDOMIZE USR 15619: REM :PEEK "filename"adresa,pořadí_sektoru RANDOMIZE USR 15619: REM :PEEK "filename"CODE adresa,pořadí_sektoru RANDOMIZE USR 15619: REM :PEEK "filename" DATA adresa,pořadí_sektoru RANDOMIZE USR 15619: REM :PEEK "filename"#adresa,pořadí_sektoru
Zdá se být vhodnější používat kombinaci volání s LET USR, viz příklad.
10 INPUT "zadej jmeno ";a$ 20 INPUT "zadej sektor ";s 30 LET error=USR 15619: REM :PEEK a$CODE 16384,s 40 IF error=0 THEN GO TO 9999 50 IF error=1 THEN PRINT "soubor nenalezen" 60 IF error=5 THEN PRINT "sektor mimo rozsah" 70 STOP
Pro zápis sektoru z paměti počítače do souboru slouží příkaz POKE. Uvádět všechny varianty se asi zbytečné, syntaxe je stejná jako u příkazu PEEK včetně zpracování chyb.
RANDOMIZE USR 15619: REM : POKE "filename"CODE adresa,pořadí_sektoru
POZOR na to, do kterého souboru zapisujete, tento příkaz má potenciál být skrytě destruktivní a zápis chybných dat, nebo zápis do nesprávného souboru snadno může vést ke ztrátě dat v tom souboru. Musím přiznat, že za celou dobu používání Betadisku jsem se s používáním těchto příkazů nepotkal a přemýšlím v jaké situaci by mohl najít uplatnění - napadá mě opakované ukládání tabulky hiscore, nebo pozice ve hře do stále stejného souboru, aniž bychom museli řešit jeho přepisování a kolizi jmen v adresáři. Určitě půjde o malá data, protože POKE neposkytuje možnost zápisu více sektorů naráz a zápis více sektorů po jednom bude výrazně pomalejší.
magické tlačítko - snapshot
Původní manuál zmiňuje, že toto tlačítko lze použít k uložení programu na disketu, který by jinak s Betadiskem nepracoval. Často lze. Je to snadné a může to být užitečné. Ale není to považováno za dobrý způsob a takto uložený program by měl sloužit jen pro osobní potřebu, nikdy by neměl být dál šířen. Zvláště ne v dnešní době, kdy už bylo na Betadisk zkonvertováno skoro vše a máme lepší způsoby, jak konverzi provést.
Snapshot tlačítko lze také použít k uložení pozice hry, resp. obecně k uložení stavu programu. Bohužel uložení snapshotu není vždy spolehlivé. Pokud program (hra) intenzivně používá přerušení a zásobník, může se přihodit cokoli. Absence RAM v Betadisku zároveň vede k nutnosti použít k odložení zásobníku a obsahu registrů obrazovku, což TRDOS později obnoví kromě dvou bytů v pravém dolním rohu obrazovky.
Nutno podotknout, že určitou mírou nespolehlivosti trpí i ekvivalentní SNAP na D40, nebo NMI a uložení snapshotu v NMI menu ESXDOSu. Jsou situace, které se oproti emulátorům zpracovávají obtížně Z80 na které zároveň takto ukládaný program běží. Ale většinou to funguje.
Beta 128, resp. TRDOS 5.0x umí uložit snapshot i s obsahem rozšířené paměti ZX Spectra 128, které ukládá do samostatných souborů, nejsou-li stránky vyplněné pouze nulami. První soubor bude stejně jako na ZX Spectrum 48k obsahovat paměť v rozsahu 16384 až 65535, bude pojmenovaný "@" a dlouhý 192 sektorů. Po něm mohou následovat paměťové stránky veliké 64 sektorů a tuto sekvenci zakončí souborem "@8". Tyto soubory je pak možné přejmenovat, kromě číselného indexu se musí jmenovat stejně.
Následující snímky obrazovky ukazují různé druhy snapshotů. První soubor s výchozím jménem "#.C" přejmenovaný na "scrnshot.C" je snímek obrazovky. Dá se ho dosáhnout držením libovolného tlačítka těsně před stisknutím Magic Button tlačítka na Betadisku. Druhý snapshot přejmenovaný na "aa.C" a "aa8.C" je snapshot programu běžícího na ZX Spectrum 128k, který ale stránky rozšířené paměti nevyužívá. TRDOS 5.05cz prázdné stránky neukládá, uloží pouze informační soubor. Snapshot přejmenovaný na "48k.C" je také snapshot programu běžícího jen v základní paměti, ale v situaci, kdy je zakázáno stránkování na portu 32765 (0x7ffd), nebo počítač vůbec rozšířenou RAM nemá, tj. na základním ZX Spectrum 48k. V takové situaci Betadisk uloží jen jeden soubor dlouhý 192 sektorů (49152 bytů). Poslední příklad na snímku obrazovky je snapshot programu, který rozšířenou paměť využívá. Ve výpisu zdánlivě chybí obsah stránek 2 a 5, to proto, že jejich obsah, stejně jako obsah stránky 0, už je v základním 48kB bloku.
Byl-li snapshot uložen s běžícím přerušením IM2, musí název začínat znakem $, aby TRDOS IM2 opět zapnul po načtení snapshotu. Protože se snapshot uloží vždy s výchozím názvem, bude nutné takový snapshot před načtením přejmenovat. Každý snapshot, kromě snímku obrazovky, se načítá příkazem GO TO "jméno"CODE a z každého snapshotu lze zobrazit obsah obrazovky v okamžiku pořízení prostým LOAD "jméno"SCREEN$.
RANDOMIZE USR 15616 GO TO "@"CODE
RANDOMIZE USR 15619: REM : GO TO "@"CODE RANDOMIZE USR 15619: REM : GO TO "filename"CODE
Píšeme BASICový zaváděč (loader)
Většina programů na ZX Spectru je napsaná ve strojovém kódu. Před načtením je obvykle potřeba provést několik málo kroků - nastavit barvy, nastavit RAMTOP a případně vypsat i nějaké stručné informace. U her předchází spuštění hry úvodní obrázek, někdy bývá součástí zaváděče možnost nastavit si nekonečné životy, někdy se hra skládá z více souborů a ne vždy se hra spouští od stejné adresy jako binární soubor CODE (Bytes) v paměti začíná. To vše by měl obsloužit krátký program v BASICu, říkejme mu třeba zaváděč.
Na rozdíl od ruského softwaru u nás bývalo zvykem počítat s tím, že program / hra nemá celou disketu pro sebe a může sdílet prostor skoro s čímkoli jiným, zvláště pokud zabírá jen malou část kapacity diskety. To v první řadě znamená, že všechny soubory takového programu by měly mít jasně identifikovatelný název, pokud možno nezaměnitelný s jiným programem. To není vždy snadné, protože množství variací v pouhých 8 znacích názvu je omezené, ale snažíme se o to.
Každý program na TRDOSové disketě by měl být napsaný tak, aby ho bylo možné spustit libovolným "boot.B" spouštěčem. Jeho název by měl být ideálně jednoduše opsatelný v příkazovém řádku TRDOSu, to znamená pokud možno jen malými písmeny. Tak aby případné ruční zadávání uživatelem nebylo zbytečně otravné. Abychom rozlišili, co je spustitelné, tak se u nás obvykle ostatní soubory pojmenovávaly velkými písmeny. Ale už jen to, že to jsou skoro vždy soubory typu CODE stačí k odfiltrování v "boot.B".
Moje osobní preference také je zcela se vyhnout jakémukoli přidanému intru, cractru... je to zdržující a většinou zcela zbytečné.
příklad zaváděče programu - naivní
Předpokládejme, že chceme zaváděč k jednoduché hře. Ta sestává z úvodního obrázku, jednoho binárního bloku a vyžaduje relativně nízký RAMTOP. Intuitivně nejjednodušší program by pak vypadal asi takto. Nastavíme barvy, načteme soubory, spustíme hru a je hotovo.
10 BORDER 7: PAPER 7: INK 0: CLEAR 24499: RANDOMIZE USR 15619: REM : LOAD "GAME-A_1"SCREEN$ 20 RANDOMIZE USR 15619: REM : LOAD "GAME-A_2"CODE 30 RANDOMIZE USR 24500
V zásadě na takovém zaváděči není technicky nic špatně. Je syntakticky správně, je funkční. V paměti zbývá 413 bytů prostoru pro provedení příkazu. Ale pokud bychom chtěli ještě nižší RAMTOP, třeba jen o pouhých 100 bytů na 24399, tak už se dostáváme za hranici, kdy fungovat nebude. Pro provedení TRDOSového příkazu potřebujeme nejméně 256 bytů na sektor + nějaký prostor, pro data samotného Sinclair BASICu. Zhruba 340 bytů je minimum volné paměti (při použití ISOROM, se standardní Sinclair ROM je minimum okolo 300 bytů), abychom mohli použít TRDOSový příkaz LOAD. Přičemž mnoho her vyžaduje RAMTOP mnohem níž, velmi často hry s Pressorovým počítadlem z Proximy mají RAMTOP nastavený na 24199. To je hodně nízko, ale není to extrém pro načítání z pásky. Zároveň jsme u naivního zaváděče načetli obrázek jako nekomprimovaný obsah obrazovky, který se jednak načítá o chvilku déle a zároveň zabírá na disketě víc místa než by bylo nutné. A pokud tento zaváděč zkusíte spustit na TRDOSu 5.03, tak zjistíte, že nebude fungovat načtení obrázku pomocí LOAD "GAME-A_1"SCREEN$. Ale tento poslední detail snadno vyřešíme nahrazením SCREEN$ za CODE pokud je počáteční adresa obrázku opravdu 16384, aby se načetl na správné místo.
10 BORDER 7: PAPER 7: INK 0: CLEAR 24499: RANDOMIZE USR 15619: REM : LOAD "GAME-A_1"CODE 20 RANDOMIZE USR 15619: REM : LOAD "GAME-A_2"CODE 30 RANDOMIZE USR 24500
Při zkoušení mi tento jednoduchý zaváděč z nějakého důvodu nefungoval ve Fuse emulátoru na Pentagonu 128k s TRDOS 5.03. Problém byl po návratu ze spuštěného programu, hroutilo se to jakoby nebyl správně nastavený zásobník. V emulátoru na ZX Spectrum 128k s TRDOS 5.05cz žádný problém nebyl, na reálném ZX Spectrum 128k a TRDOS 5.05cz taky ne a to ani v případě, že jsem načítal program ze 128k editoru BASICu. V emulátoru jsem zkusil i kombinaci ZX Spectrum 128k s TRDOS 5.03, stejným TRDOSem jako u toho Pentagonu 128k a spustit ze 128k editoru BASICu, taktéž na Pentagonu 128k ale v USR 0 režimu bez 128k editoru, vše fungovalo perfektně. Pouze Pentagon 128k ve 128k editoru byl problematický, přičemž soubor napodobující kód hry je velmi jednoduchý, jen effekt v BORDERu s čekáním na stisk klávesy. Nepracuje se zásobníkem, kromě RET na konci, nepoužívá IX, IY, ani HL z druhé sady registrů. Na Pentagonu 512k s Gluk Boot také vše fungovalo správně.
Jediný všeobecně přítomný problém 128k editoru byl s překladem příkazů za REM na tokeny. 128k editor to neprovede a ponechává v příkazovém řádku TRDOSové příkazy jako text. K jejich překladu na tokeny došlo až při interpretaci. Teprve pak lze program napsaný ve 128k editoru uložit na disketu.
příklad zaváděče programu - základní optimalizace
Začněme úspornějším zápisem čísel. Sinclair BASIC velmi zjednodušeně ukládá čísla napsaná v programu tak, že se skládají z cifer a z pěti bytové hodnoty. Např. příkaz CLEAR 24499 se uloží do paměti takto.
10 CLEAR 24499 db 0x00,0x0a ; číslo řádku 10 db 0x0d,0x00 ; délka řádku 13 db 0xfd ; token příkazu CLEAR db 0x32,0x34,0x34,0x39,0x39 ; ASCII cifry 24499 db 0x0e db 0x00,0x00,0xb3,0x5f,0x00 ; číslo 24499 (0x5fb3) db 0x0d ; konec řádku CR
Z příkladu je vidět, že se číslo, kromě cifer uloží ještě jednou. První z šesti bytů interpretru oznamuje, že následuje číslo a dalších 5 bytů obsahuje 40 bitový zápis čísla s pevnou desetinnou čárkou. Celočíselnou 16 bitovou hodnotu můžeme snadno vidět jako #5fb3 = 24499. Celý řádek zabírá včetně čísla a délky řádku 17 bytů. Zkusme číslo ukrýt do funkce VAL, která zabrání duplicitnímu uložení hodnoty a zajistí vyhodnocení cifer až při běhu programu.
10 CLEAR VAL "24499" db 0x00,0x0a ; číslo řádku 10 db 0x0a,0x00 ; délka řádku 10 db 0xfd ; token příkazu CLEAR db 0xb0 ; token funkce VAL db 0x22 ; uvozovky db 0x32,0x34,0x34,0x39,0x39 ; ASCII cifry 24499 db 0x22 ; uvozovky db 0x0d ; konec řádku CR
Tentokrát řádek zabírá 14 bytů, oproti předchozímu zápisu jsme 3 byty ušetřili navzdory přidanému tokenu funkce a uvozovkám. To je důvod, proč se v zaváděčích, kde na rychlosti interpretace hodnot použitých jen jednou příliš nezáleží, skoro vždy snažíme nahradit čísla zapsaná přímo nějakým jiným způsobem. Funkce VAL je nejjednodušší, použitelná pro všechny hodnoty, ale pro některé hodnoty existují ještě kratší způsoby, jak číslo zapsat. Viz typické nastavení barev vyskytující se v mnoha programech.
10 BORDER 0: PAPER 0: INK 7
Tradičně zapsaný řádek zabírá 29 bytů vč. čísla řádku, zatímco varianta s čísly nahrazenými úspornějším zápisem zabírá 18 bytů vč. čísla řádku, viz příklad, úspora 11 bytů.
10 BORDER NOT PI: PAPER NOT PI: INK VAL "7" db 0x00,0x0a ; číslo řádku 10 db 0x0e,0x00 ; délka řádku 14 db 0xe7 ; příkaz BORDER db 0xc3,0xa7 ; hodnota NOT PI = 0 db 0x3a ; dvojtečka db 0xda ; příkaz PAPER db 0xc3,0xa7 ; hodnota NOT PI = 0 db 0x3a ; dvojtečka db 0xd9 ; příkaz INK db 0xb0 ; token funkce VAL db 0x22 ; uvozovky db 0x37 ; cifra 7 db 0x22 ; uvozovky db 0x0d ; konec řádku CR
Celý zaváděč s úpravami, aby zabíral méně mísa v paměti pak může vypadat takto.
10 BORDER "7": PAPER "7": INK NOT PI: CLEAR VAL "24499": RANDOMIZE USR VAL "15619": REM : LOAD "GAME-A_1"CODE 20 RANDOMIZE USR VAL "15619": REM : LOAD "GAME-A_2"CODE 30 RANDOMIZE USR VAL "24500"
Nebo ještě lépe s použitím příkazu RUN místo LOAD a následujícího RANDOMIZE USR. V této poslední variantě už je možné snížit RAMTOP na 24399, přičemž zbude volných 353 bytů a to s bezpečně stačí k provedení TRDOSových příkazů LOAD a RUN.
10 BORDER "7": PAPER "7": INK NOT PI: CLEAR VAL "24499": RANDOMIZE USR VAL "15619": REM : LOAD "GAME-A_1"CODE 20 RANDOMIZE USR VAL "15619": REM : RUN "GAME-A_2"CODE
Pokud obrázek zkomprimujeme Pressorem, takže z něj bude samorozbalující se spustitelný blok CODE, nabízí se možnost nahradit i první LOAD příkazem RUN. S TRDOS 5.05cz to samozřejmě funguje parádně.
10 BORDER "7": PAPER "7": INK NOT PI: CLEAR VAL "24499": RANDOMIZE USR VAL "15619": REM : RUN "GAME-A_1"CODE 20 RANDOMIZE USR VAL "15619": REM : RUN "GAME-A_2"CODE
A tady narazíme na ošklivou chybu TRDOSu 5.03 a z něj odvozených TRDOSů, které tuto chybu nemají opravenou. Výše uvedený pěkně krátký program totiž na takových TRDOSech vede k chybě "C Nonsense in BASIC" po načtení a zobrazení obrázku. Vyzkoušel jsem to na TRDOS 5.03, 5.04T (Pentagon 512 s Gluk ROM). Tyto obě verze mají stejnou hloupou chybu! Chcete-li, aby zaváděč programu byl kompatibilní úplně se všemi verzemi, nezbývá než rezignovat a použít následující verzi. Osobně bych se ale přikláněl k opravě chybných verzí TRDOSu. ESXDOS 5.04T, který je součástí ESXDOSu opravený je a s příkazem RUN nemá problém.
Pokud bychom rezignovali a chtěli napsat zaváděč zcela kompatibilní se všemi verzemi TRDOS, pak by vypadal jako následující příklad - museli bychom přidat dvojí RANDOMIZE USR a tím se samozřejmě program prodlouží, budeme muset RAMTOP opět posunout o pár bytů výš na adresu 24410.
10 BORDER "7": PAPER "7": INK NOT PI: CLEAR VAL "24410": RANDOMIZE USR VAL "15619": REM : LOAD "GAME-A_1"CODE 20 RANDOMIZE USR VAL "43e3": RANDOMIZE USR VAL "15619": REM : LOAD "GAME-A_2"CODE 30 RANDOMIZE USR VAL "24500"
Nebo takto - s tím že příkaz RUN je na posledním řádku programu a program se už ze strojového kódu do BASICu nebude vracet. Návrat by vedl k chybě "C Nonsense in BASIC" místo "0 O.K.", ale když k návratu nedojde, nikomu to vadit nebude, chyba se nezobrazí, RAMTOP může zůstat na nízké adrese 24399.
10 BORDER "7": PAPER "7": INK NOT PI: CLEAR VAL "24399": RANDOMIZE USR VAL "15619": REM : LOAD "GAME-A_1"CODE 20 RANDOMIZE USR VAL "43e3": RANDOMIZE USR VAL "15619": REM : RUN "GAME-A_2"CODE
odepnutí TRDOSu v případě nedostatku RAM
Myslím, že zde je dobré místo na malou vsuvku. Mnoho programů, typicky hry, aby mohly být spuštěny, vyžaduje RAMTOP níž než je nezbytné pro provoz TRDOSu. Lze to řešit tak, že se po načtení posledního souboru před finálním rozbalením načtených souborů, uvolní vše, co si TRDOS alokoval pro sebe včetně těch 112 bytů systémových proměnných o které TRDOS posunul program v BASICu.
Krátký kód, který se k posunutí BASICového programu zpět používá se obvykle vkládá za příkaz REM do BASICového řádku, zabírá 10 bytů (plus číslo řádku a příkaz REM) a záměrně je upravený tak, aby se zobrazoval jen jako znaky a tokeny, aby neobsahoval kódy znaků, které by mohly dělat potíže při zobrazení BASICového programu. S inicializovaným TRDOSem po načtení z diskety bude jeho spouštěcí adresa 23872. Jak kód ve výpisu BASICu vypadá viz screenshot.
A následující výpisy ukazují tentýž program, pouhé čtyři instrukce Z80.
ld hl,23755 ; do HL cíl, kam posunout BASIC ex de,hl ; cílovou adresu do DE ld (hl),23635 ; do HL současnou adresu BASICu jp 6629 ; podprogram v ROM pro přesun
Hexadecimální výpis téhož programu včetně dat BASICového řádku okolo.
db 0x00,0x0a ; číslo řádku 10 db 0x0c,0x00 ; délka řádku 12 db 0xea ; příkaz REM db 0x21,0xcb,0x5c ; jp jl,23755 db 0xeb ; ex de,hl db 0x2a,0x53,0x5c ; ld (hl),23635 db 0xc3,0xe5,0x19 ; jp 6629 db 0x0d ; konec řádku CR
Celkem tento posouvací podprogram stojí 16 bytů plus dalších 10 bytů za příkaz RANDOMIZE USR, kterým se spouští. Ale odstraněním 112 bytů systémových proměnných TRDOSu a tím, že se už nebude TRDOS znovu volat ušetříme nejméně 256+112 bytů a můžeme posunout RAMTOP z 24499 třeba na 24199.
RANDOMIZE USR VAL "23872"
Výše uvedené volání poprogramu v ROM samozřejmě nemusí být jen součástí BASICového řádku, může být i součástí některého z načtených souborů a pak odpadá omezení na instrukce, které nepůsobí potíže při zobrazení BASICového řádku. Stejně tak součástí některého ze souborů bývají dekompresní podprogramy, podprogramy pro přesuny bloků dat v paměti na správná místa a do stránek rozšířené paměti atd...
jak zaváděč napsali jiní - příklad ze hry Manic Miner
Toto je příklad jednoduchého zaváděče. Žádné nekonečné životy, žádné dohrávky, prostoru pro BASIC pod RAMTOP dostatek. Hra je na disketě uložená pouze ve třech souborech.
filename sec start length line -------------------------------------------- manic <B> 1 123 123 10 MANIC_1 <C> 3 43000 557 MANIC_2 <C> 71 32768 17971
10 PAPER NOT PI: BORDER NOT PI: CLEAR VAL "32767" 20 RANDOMIZE USR VAL "15619": REM : LOAD "MANIC_1"CODE 30 RANDOMIZE USR VAL "4e4" 40 RANDOMIZE USR VAL "15619": REM : LOAD "MANIC_2"CODE 50 RANDOMIZE USR VAL "32768" 60 RANDOMIZE USR VAL "33792"
jak zaváděč napsali jiní - příklad ze hry Driller
Hra Driller se skládá z více souborů a umožňuje zvolit cheat před finálním spuštěním. Tentokrát se načítají obrázky dva, nejprve úvodní obrázek, který se zobrazuje po dobu načítání dalších 3 souborů a nakonec menu hry, přes které se vypíše dotaz "T-training". Všimněte si, že jsou soubory opět pojmenované tak, aby bylo snadné zadání jména v příkazovém řádku a aby bylo zřejmé, které soubory patří k sobě při kopírování na jinou disketu.
filename sec start length line -------------------------------------------- driller <B> 2 419 419 10 DRILL_1 <B> 27 16384 6912 DRILL_2 <B> 1 27000 145 DRILL_3 <B> 8 50000 1940 DRILL_4 <B> 149 27410 38125 DRILL_5 <B> 27 16384 6912
10 PAPER NOT PI: INK VAL "7": BORDER NOT PI: CLEAR VAL "26999" 20 LET mem=PEEK 23388=16 25 LET a=VAL "15619" 30 POKE 23739,111 40 RANDOMIZE USR a: REM : LOAD "DRILL_1"CODE 50 RANDOMIZE USR a: REM : LOAD "DRILL_2"CODE 60 POKE 23388,22 70 RANDOMIZE USR a: REM : LOAD "DRILL_3"CODE 75 POKE 23388,16 80 RANDOMIZE USR a: REM : LOAD "DRILL_4"CODE 88 RANDOMIZE USR a: REM : LOAD "DRILL_5"CODE 95 PRINT #1;"T-training" 100 PAUSE NOT PI: IF INKEY$="t" OR INKEY$="T" THEN POKE VAL "47904", NOT PI: POKE VAL "49021",NOT PI: POKE VAL "49022",NOT PI: POKE VAL "49424",NOT PI: POKE VAL "49425",NOT PI 110 IF mem THEN RANDOMIZE USR 27000 120 RANDOMIZE USR VAL "38820"
jak zaváděč napsali jiní - příklad ze hry F-16
Další namátkou vybranou variantou budiž zaváděč ze hry F-16. Hra je opět složená z více souborů, které se postupně rozbalují do rozšířené paměti ZX Spectra 128k.
filename sec start length line -------------------------------------------- f 16 <B> 2 332 332 1 F16_0 <C> 14 40000 3449 F16_1 <C> 135 25000 34356 F16_2 <C> 87 25000 22063 F16_3 <C> 109 30000 27900
1 CLEAR VAL "24999": PRINT ,AT VAL "8",VAL "6"; " F16 COMBAT PILOT " ''" TURBO LOADER CRACKED BY CID'91" ''"128 ONLY VERSION BY MATASOFT '91" ''"PRESSED BY MATASOFT AND KAMIL'91" ''" REPACKED BY TORASOFT '93" 2 RANDOMIZE USR VAL "15619": REM : RUN "F16_0"CODE 3 BORDER VAL "5": RANDOMIZE USR VAL "15619": REM : RUN "F16_1"CODE 4 RANDOMIZE USR VAL "15619": REM : RUN "F16_2"CODE 5 RANDOMIZE USR VAL "15619": REM : LOAD "F16_3"CODE 6 INK VAL "5": PAPER VAL "5": CLS : RANDOMIZE USR VAL "57880"
jak zaváděč napsali jiní - příklad z programu Desnaper
Program Desnaper je určený ke zkoumání snapshotů her. Nejprve dá na výběr disketovou jednotku, další část napsaná ve strojovém kódu zobrazí na disketě nalezené snapshoty ze kterých si uživatel vybere a Desnaper načte. Po načtení se přepne do obrazovkového monitoru / disassembleru Devast. Tím pak lze hru zkoumat, případně se z něj i vrátit do BASICu nejsou-li poškozené systémové proměnné Sinclair BASICu, některé hry i tuto oblast paměti mohou využít pro sebe. Desnaper může pomoct s crackováním her. V době před schopnými emulátory to byl velmi užitečný nástroj.
filename sec start length line -------------------------------------------- desnaper <B> 2 301 307 1 DESNAP_1 <C> 37 37295 9285
1 CLEAR VAL "25080": LET X=VAL "15619": RANDOMIZE USR X: REM : LOAD "DESNAP_1"CODE 3 INK NOT PI: PAPER VAL "7": BORDER VAL "7": CLS : PRINT AT PI+PI,PI;" DESNAPER VERSION 1.1. "'''''''TAB VAL "5";"SELECT DRIVE: A,B,C,D" 5 PAUSE NOT PI: LET K=CODE INKEY$: IF K=VAL "65" OR K=VAL "97" THEN RANDOMIZE USR X: REM :*"A" 7 IF K=VAL "66" OR K=VAL "98" THEN RANDOMIZE USR X: REM :*"B" 9 IF K=VAL "67" OR K=VAL "99" THEN RANDOMIZE USR X: REM :*"C" 11 IF K=VAL "68" OR K=VAL "100" THEN RANDOMIZE USR X: REM :*"D" 95 RANDOMIZE USR VAL "37295": GO TO PI
jak zaváděč napsali jiní - příklad z programu AYdriver
V tomto zaváděči je použitý výše uvedený způsob posunutí BASICu zpět a odstranění systémových proměnných TRDOSu. Na rozdíl od umístění do řádku s komentářem je použitý zápis do řetězce jako DATA a adresa umístění těchto dat se zjišťuje příkazem RESTORE 1488, který do systémových proměnných BASICu uloží adresu dat na zadaném řádku a tu lze pak přečíst dvěma příkazy PEEK v následujícím RANDOMIZE USR VAL. Tento způsob je odolnější v případě, že by BASIC byl posunutý jinam, ne o 112 bytů, jako to dělá TRDOS opět za cenu pár bytů navíc.
filename sec start length line -------------------------------------------- aydriver <B> 2 270 270 1 AYDRIVER <C> 84 25000 21330
10 BORDER NOT PI: INK VAL "7": PAPER NOT PI: CLEAR VAL "24999" 20 PRINT AT VAL "5",VAL "9";"AY driver 2.1"; AT VAL "7",VAL "5";"(mouse kompaktdebile)" 30 PRINT AT VAL "10",VAL "6";"Program: Tritolsoft" 50 RANDOMIZE USR VAL "15619": REM : LOAD "AYDRIVER"CODE 1488 DATA "! THEN \ FOR *S\NOT RESTORE " 1489 RESTORE 1488 1490 RANDOMIZE USR VAL "PEEK 23639+256*PEEK 23640+7" 1500 CLEAR VAL "24199" 1600 RANDOMIZE USR VAL "25e3" 6000 RANDOMIZE USR VAL "24200"
Dalších příkladů by se daly najít stovky. Zajímavé a jednoduché řešení dohrávání většího množství dalších souborů je v zaváděčí MQM 5 dema a ještě několika dalších s mnoha částmi. Dohrávání souborů ve hrách se ale nejčastěji řeší ve strojovém kódu.
poznámka k zaváděčům na závěr
Nemám rád zbytečnou obfuskaci a uzavřenost programů. Příkladem úplně zbytečné obfuskace budiž program Betatools od LadinekSOFT, kde autor přepsal všechna zobrazovaná čísla v příkazech, pozměnil barvy... Stejně tak mnohý ruský software je napsaný tak, aby případné zásahy byly obtížné. Nemám ani příliš v oblibě, když se autor snaží nacpat program do jednoho bloku spolu s BASICem. To má podle mého názoru smysl pouze u "boot.b", který by se měl načíst rychle po resetu. Zaváděč běžného programu by naopak měl být napsaný tak, aby se dal snadno upravit pro libovolný diskový systém. To znamená pro páskové programy nechat pár stovek bytů rezervu pro režii TRDOSu a naopak pro Betadiskové programy nekomplikovat odstranění RANDOMIZE USR 15619... pro přenos zpět na pásku, MDOS, nebo cokoli jiného, zvláště pokud se takový program načte jednou a znovu na úložiště nesahá, nebo v případě, že sice potřebuje z diskety dohrávat data, ale toto dohrávání se dá zvládnout v BASICu.
Všelijaké frajerské zaváděče, třeba zrychlené turbo z pásky, počítadlo nebo animace během nahrávání byly zajímavým zpestřením, ale vždy sebou nesou nějakou nekompatibilitu a komplikaci. Někdy je to nudné a nejobyčejnější řešení nejméně problematické, dlouhodobě snadno udržitelné, přenositelné a tím vlastně nejlepší.
zjednodušení příkazů pomocí ISOROM
ISOROM je upravený Sinclair BASIC s opravenými chybami, různými drobnými vylepšeními a hlavně s podporou Betadisku pomocí zjednodušené syntaxe TRDOSových příkazů. Místo RANDOMIZE USR 15619: REM : stačí napsat jeden vykřičník. Jedna z variant ISOROM je ISOROM 128 což je rozšíření, které v sobě sdružuje nejenom upravenou Sinclair ROM, ale i menu a podpůrné aplikace v druhé stránce ROM pro ZX Spectrum 128k a zároveň 32kB RAM do které se dá zapsat jakákoli další "ROM".
V kombinaci s ISOROM se Betadisk pohodlím použití přibližuje ostatním systémům, např. MDOSu na Didaktik 40 / Didaktik 80 s hvězdičkovou syntaxí LOAD * "filename". Viz několik příkladů:
10 !CAT 20 !LOAD "filename"SCREEN$ 30 !RUN "filename"CODE 4e4 40 !SAVE "filename"CODE 16384,6144
Do příkazového řádku se s pomocí ISOROM dostanete zadáním jediného vykřičníku místo 15616 a do Devastu se lze z BASICu kdykoli dostat dvěma vykřičníky. Už jen tyto dvě vlastnosti mi ušetřily obrovské množství stisků kláves psaním RANDOMIZE USR... a neustále mi tato drobnost chybí v ESXDOSu.
! !!
Jen pozor na použití příkazů využívajících ISOROM v programech. Takové programy bude potřeba opět upravit, aby fungovaly i na počítačích bez ISOROM. Ale stejný problém je se všemi rozšířeními. Pokud se rozhodnete využívat výhod pozdějších vylepšení, je vhodné v programu uvést, že toto vylepšení vyžaduje a nenechat ho jen selhat a nechat uživatele marně pátrat po příčině pokud využité rozšíření nezná. Ale protože ISOROM není masově rozšířená a zvláště na systémech s ESXDOSem nejspíš nikdy nebude, je jistější nevkládat syntaxi s vykřičníkem do žádného programu, který by měl být šířen.
Stručný seznam příkazů TRDOS 5.05cz
Tato tabulka by měla být jen velmi stručnou referencí nejčastěji používaných příkazů TRDOSu. Detaily hledejte v textu výše.
| č. | příkaz | příklad | stručný popis funkce |
|---|---|---|---|
| 01 | CAT | CAT | Vypíše stručně adresář diskety v aktuální disketové jednotce. |
| CAT "a:" | Vypíše stručně adresář diskety v disketové jednotce A. | ||
| CAT #3 | Vytiskne adresář diskety v aktuálně zvolené disketové jednotce na tiskárnu. | ||
| 02 | * | *"a:" | Přepne na disk. jednotku A, syntaxe funkční na všech verzích TRDOSu. |
| *"b:" | Přepne na disk. jednotku B, syntaxe funkční na všech verzích TRDOSu. | ||
| *a | Přepne na disk. jednotku A, funkční jen na TRDOS 5.05cz. | ||
| 03 | FORMAT | FORMAT "jmeno" | Naformátuje vloženou disketu. |
| FORMAT "$jmeno" | Naformátuje vloženou disketu jednostranně. | ||
| FORMAT "b:jmeno" | Naformátuje vloženou disketu v jednotce B. | ||
| 04 | MOVE | MOVE | Setřese disk, uvolní místo po smazaných souborech mezi nesmazanými. |
| 05 | NEW | NEW "nove-jme","stare-jm" | Přejmenuje BASICový program z "stare-jm" na "nove-jme". |
| NEW "nove-jme","stare-jm"CODE | Přejmenuje binární soubor CODE (Bytes) z "stare-jm" na "nove-jme". | ||
| NEW "nove-jme","stare-jm" DATA | Přejmenuje datový soubor z "stare-jm" na "nove-jme". | ||
| NEW "jmenodisku" | Přejmenuje disketu na zadané jméno, umí jen TRDOS 5.05cz. | ||
| NEW "b:jmenodisku" | Přejmenuje disketu v disketové jednotce B, jen TRDOS 5.05cz. | ||
| 06 | ERASE | ERASE "jmeno" | Smaže BASICový program zadaného jména z diskety. |
| ERASE "b:jmeno" | Smaže BASICový program zadaného jména z diskety v jednotce B. | ||
| ERASE "jmeno"CODE | Smaže z diskety soubor typu CODE (Bytes). | ||
| ERASE "jmeno" DATA | Smaže z diskety soubor typu DATA. | ||
| ERASE "jmeno"# | Smaže z diskety soubor typu stream. | ||
| ERASE "*" | Smaže obsah celé diskety v aktuální disketové jednotce. Jen TRDOS 5.05cz. | ||
| ERASE "b:*" | Smaže obsah celé diskety v disketové jednotce B. Jen TRDOS 5.05cz. | ||
| 07 | LOAD | LOAD | Pokusí se načíst program "boot.b", není-li vypíše katalog. |
| LOAD "jmeno" | Načte BASICový program "jmeno" a spustí ho, byl-li zadán startovní řádek. | ||
| LOAD "b:jmeno" | Stejně jako předchozí, ale dočasně přepne na disketovou jednotku B. | ||
| LOAD "jmeno"CODE | Načte soubor typu CODE na adresu v paměti, která je uvedena v adresáři. | ||
| LOAD "jmeno"CODE adresa | Načte soubor typu CODE na zadanou adresu v paměti. | ||
| LOAD "jmeno"CODE adresa,delka | Načte soubor typu CODE na zadanou adresu v paměti a omezí jeho délku. | ||
| LOAD "jmeno"SCREEN$ | Načte soubor typu CODE na adresu 16384 a omezí jeho délku na 6912 bytů. | ||
| LOAD "jmeno" DATA a$() | Načte data - řetězcové pole ze souboru do proměnné a$. | ||
| LOAD "jmeno" DATA n() | Načte data - numerické pole ze souboru do proměnné n. | ||
| 08 | SAVE | SAVE "jmeno" | Uloží BASICový program. |
| SAVE "jmeno" LINE n | Uloží BASICový program a nastaví řádek n od kterého se po načtení spustí. | ||
| SAVE "jmeno"SCREEN$ | Uloží 6912 bytů z RAM od 16384 do souboru typu CODE. | ||
| SAVE "jmeno"CODE adresa,delka | Uloží počet bytů daných délkou od adresy adresa do souboru typu CODE. | ||
| SAVE "b:jmeno"CODE adresa,delka | Stejně jako předchozí, ale dočasně přepne na disketovou jednotku B | ||
| SAVE "jmeno" DATA a$() | Uloží řetězcové pole a$ do souboru typu DATA. | ||
| SAVE "jmeno" DATA n() | Uloží numerické pole n do souboru typu DATA. | ||
| 09 | RETURN | RETURN | Provede návrat z příkazového řádku TRDOSu do editoru Sinclair BASICu. |
| 10 | PEEK | PEEK "jmeno" adresa,sektor | Přečte n-tý sektor ze souboru do paměti počítače na zadanou adresu. |
| 11 | POKE | POKE "jmeno" adresa,sektor | Zapíše 256 bytů z paměti od zadané adresy do n-tého sektoru v souboru. U příkazů PEEK i POKE je "sektor" pořadí sektoru, číslováno od 1, ne od 0. |
| 12 | MERGE | MERGE "jmeno" | Načte BASICový program a složí ho s programem v paměti počítače. Merge lze použít i k načtení programů do prázdné RAM bez spuštění. |
| 13 | RUN | RUN | Načte a spustí "boot.B", je-li na disketě, není-li vypíše katalog. |
| RUN "jmeno" | Načte a spustí BASICový prog. od prvního řádku, nebo určeného při uložení. | ||
| RUN "b:jmeno" | Stejně jako předchozí, ale dočasně přepne na disketovou jednotku B. | ||
| RUN "jmeno"CODE | Načte a spustí soubor typu CODE od adresy v hlavičce souboru. | ||
| RUN "jmeno"CODE adresa | Načte a spustí soubor typu CODE od adresy adresa. | ||
| RUN "jmeno"SCREEN$ | Načte a spustí soubor typu CODE od adresy 16384. Užitečné pro spouštění obrazovkových utilit. |
||
| 14 | OPEN # | OPEN #n,"jméno",W | Otevře kanál n pro sekvenční zápis. |
| PRINT #n;"retezec" | Zapíše řetězec / řádek "retezec" skrz kanál n do streamu na disk. | ||
| OPEN #n,"jméno",R | Otevře kanál n pro sekvenční čtení. | ||
| INPUT #n;a$ | Přečte řetězec / řádek ze streamu skrz kanál n do proměnné a$. | ||
| OPEN #n,"jméno",RND,delka | Otevře kanál n pro náhodný přístup k blokům dlouhým "delka" znaků. | ||
| PRINT #n;b,"retezec" | zapíše řetězec blok číslo b do souboru s náhodným přístupem skrz kanál n. | ||
| INPUT #n;(blok),a$ | Přečte blok b ze souboru s náhodným přístupem do prom. a$ skrz kanál n. | ||
| 15 | CLOSE # | CLOSE #n | Uzavře kanál n, vyprázdní buffer a zbývající data z něj zapíše na disk. |
| 16 | COPY | COPY "cil","zdroj" | Vytvoří kopii BASICového programu na stejné disketě, jako je nyní. |
| COPY "b:cil","a:zdroj" | Zkopíruje BASICový program z diskety v jednotce A na B. | ||
| COPY "b:cil","a:zdroj"CODE | Zkopíruje soubor typu CODE z diskety v jednotce A na B. | ||
| COPY "b:cil","a:zdroj" DATA | Zkopíruje soubor typu DATA z diskety v jednotce A na B. | ||
| COPY "b:cil","a:zdroj"# | Zkopíruje soubor typu stream z diskety v jednotce A na B. | ||
| COPY "b:*","a:*" | Zkopíruje všechny soubory z diskety v jednotce A na disketu v jedn. B. | ||
| COPY s"jmeno" | Zkopíruje BASICový program s použitím pouze jedné akt. disk. mechaniky. | ||
| COPY s"jmeno"CODE | Zkopíruje soubor CODE s použitím pouze jedné aktuální disk. mechaniky. | ||
| COPY s"jmeno" DATA | Zkopíruje soubor DATA s použitím pouze jedné aktuální disk. mechaniky. | ||
| COPY s"jmeno"# | Zkopíruje stream s použitím pouze jedné aktuální disk. mechaniky. | ||
| COPY b"" | Zduplikuje obsah diskety s použitím pouze jedné akt. disk. mechaniky. | ||
| 17 | 40 | 40 | Přepne aktuální 80 stopou disketovou jednotku na dvojitý krok, použitelné pro čtení disket zapsaných na 40 stopé disketové mechanice. |
| 18 | GOTO | GOTO "jmeno"CODE | Načte a spustí snapshot včetně všech souborů, co k němu dle jména patří. |
| 19 | 80 | 80 | Přepne aktuální disketovou jednotku do režimu 80 stop, je-li 80 stopá. Resp. vrátí výchozí chování 80 disketové jednotky zpět po použití příkazu 40. |
| 20 | LIST | LIST | Zobrazí podrobný výpis obsahu diskety v aktuální disketové jednotce. |
| LIST "b:" | Zobrazí podrobný výpis z diskety v disketové jednotce B. | ||
| LIST #3 | Vytiskne podrobný výpis diskety v aktuální disketové jednotce skrz kanál 3. | ||
| 21 | VERIFY | VERIFY "jmeno" | Porovná BASICový program uložený v souboru s programem v paměti. |
| VERIFY "jmeno"CODE | Porovná binární data v souboru s daty na stejné adrese v paměti. | ||
| VERIFY "jmeno"CODE adresa | Porovná binární data v souboru s daty v paměti od adresy "adresa". | ||
| VERIFY "jmeno"SCREEN$ | Porovná 6912 bytů v souboru s daty v paměti od adresy 16384. | ||
| VERIFY "jmeno" DATA a$() | Porovná data v souboru s daty v proměnné a$() s obsahem souboru. |
Přehled rozšíření a změn TRDOSu 5.04 (a taky 5.05) oproti verzi 5.03
TRDOS verze 5.03 od Kamilsoft je téměř shodná s původní 5.03
- Je vyřazeno testování mechanik po každém resetu (způsobující nepříjemné zvuky a zdržení). Toto nastavení je natvrdo naprogramováno v EPROM (obvykle 80 stop - nezáleží jestli 5 1/4 nebo 3 1/2).
- Je zabudován monitor Devast, který se spouští příkazem "!" z dialogového řádku TRDOSu.
- U příkazu LIST byl odstraněn opakovaný výpis hlavičky.
- Program "boot" je spouštěn libovolným příkazem pro čtení pokud není zadáno jméno souboru, tedy nejenom RUN, ale i LOAD, MERGE, PEEK.
- Není-li "boot" nalezen je vypsán katalog.
- Je zlepšena spolupráce se ZX 128kB, systém vytváří přídavné systémové proměnné.
- Je upravena obsluha tlačítka Magic Button, takže nedochází k přepisu adres 23552 a 23553, ale RET se ukládá na adresu 22527 do obrazovky.
- Při pokusu o zápis souboru se stejným jménem jako má jiný soubor na disketě lze stiskem klávesy "Y" starý soubor přepsat.
Další úpravy od autora BetaPolák
- Umožněn zápis na 40 stopou disketu v 80 stopé mechanice.
- Při nenalezení sektoru, není před novým najetím na stopu snížena krokovací rychlost.
- Volání monitoru Devast je upraveno na "!!".
Další úpravy TRDOSu 5.04 - autor neuveden
- Je zkráceno klávesové echo podle ISOROM.
- Je zrychlena komunikace s diskem díky zkrácení časových smyček a zvýšení rychlosti krokování v příkazech.
- Je tokenizován i příkaz RETURN, kvůli LECROM.
- Je akceptován i příkaz LOAD "jméno" SCREEN$.
- Z monitoru Devast je odstraněn trojský kůň (ochrana firmy Proxima) a rozšíření znaků je provedeno vlevo, kvůli čitelnosti na počítačích Didaktik i Didaktik.
- Je zastaven motor a zrušen select pokud není přítomen disk.
- Při nenalezení sektoru je proveden návrat na 0 pouze jednou, v dalších pokusech je prováděn jen 1 krok zpět (resp. 1 krok vpřed jedná-li se o nečitelný sektor na stopě 0 nebo 1).
- Při chybě "DISK ERROR" je vypsáno skutečné číslo sektoru. Stane-li se tak při použití CAT, nebo LIST dojde k obnovení původního čísla kanálu pro výpis.
- Byla opravena chyba služby číslo 7 (výpis katalogu), takže nyní ji lze použít pro libovolnou mechaniku.
- Příkaz LIST po dokončení výpisu vrátí hlavu mechaniky na stopu 0 a vytiskne kód CR, kvůli možnému tisku na tiskárnách. Pokud totiž tiskárně nepošlete kód CR nevytiskne obsah bufferu (tj. např. poslední řádek).
- Příkaz LIST potřebuje o 32 bytů méně paměti a po provedení je použitá paměť opět uvolněna, takže lze tento příkaz zadávat opakovaně bez obav z hlášení "Out of RAM" (pokud nastane tak vždy a ne až po několikátém LISTu).
- Příkaz VERIFY umožňuje porovnávat obsah celého souboru s obsahem paměti, při neshodě vytiskne:
Kde xxxxx je adresa v paměti, yyy je obsah adresy xxxxx, a zzz je byte v souboru na disku s nímž se paměť neshoduje. Klávesou A lze porovnávání ukončit, klávesou I lze pokračovat na další adrese.
Verify ERROR xxxxx/yyy/zzz Abort,Ignore ?
- Na adresu 15607 byla umístěna sekvence IN a,(c) a RET což umožňuje číst registry řadiče při jeho přímém ovládání. Sekvence OUT (c),a a RET je umístěna jinde. Díky tomu není potřeba hardwarově upravovat desku DOSu.
- Při formátování je vypisováno skutečné číslo formátované stopy (bez ohledu na stranu).
- Jsou umožněny multisektorové operace se sektorem o velikosti 512 bytů (což umožňuje snadněji pracovat s disketami formátu MS-DOS, M-DOS (D40), CP/M ) pomocí služeb 5 a 6. Za tím účelem je využit bit 3 systémové proměnné pro zvolenou mechaniku (drive A - 23752 až drive D - 23755) a to tak že 0=256 bytů, 1=512 bytů na sektor.
| bit | význam |
|---|---|
| 0 | formát diskety 0=40 stop, 1=80 stop |
| 1 | počet stran 0=jednostranně, 1=oboustranně |
| 2 | ---- |
| 3 | délka sektorů 0=256bytů, 1=512 bytů |
| 4 | ---- |
| 5 | ---- |
| 6 | ---- |
| 7 | typ mechaniky 0=40stop, 1=80stop |
Standardní TRDOS umí číst i sektory 128 nebo 1024 bytů dlouhé, ale nikoliv více najednou, pouze po jednom a navíc je nutno měnit programově (nestará se o to DOS) adresu bufferu kam se sektor uloží/ odkud se zapíše.
Bity 0,1,2 jsou ovlivňovány službou 24 (inicializace), která je volána při každém příkazu DOSu (netýká se služeb pro přímou práci se sektorem).
Bit 7 je ovlivňován pouze příkazem 40, nebo příkazem 80. Toto nastavení je pevně naprogramováno v EPROM na adrese 12210 pro mechaniku A, C a na adrese 12211 pro mechaniku B, D. 80h znamená 80 stopou mechaniku, 00h znamená mechaniku 40 stopou. Hodnoty je pochopitelně nutné zadat před programováním EPROM.
- Jsou odstraněny všechny chyby příkazů PEEK a POKE (později doplním podrobnosti)
- Příkaz ERASE byl rozšířen o možnost smazat úplně všechny soubory na disketě (ERASE "*"). Jedná se víceméně o rychlý formát diskety, protože adresář je zaplněn hodnotou 0 a tím je prakticky znemožněno obnovení souborů.
- Příkaz NEW byl rozšířen o možnost přejmenovat i disketu (nejenom soubor) a to v případě je-li zadánou pouze jedno jméno.
- Změnu mechaniky je možné provést příkazem *b: ačkoliv funguje starší verze *"b:"
Tak to je asi vše. Jestli TRDOS 5.04 přece jen obsahoval nějaké chyby, tak ty byly jistě opraveny ve verzi 5.05. Stáhnete-li si z této stránky (viz. všemožné ROMky) nějaký TRDOS určitě ho budete moct použít v emulátoru X128.
Download
- TR-DOS_Manual.txt - do prostého textu převedená příručka k TR-DOSu
- TR-DOS_Variables.txt - systémové proměnné TRDOSu (těch 112 bytů, které přidává k sys. proměnným Sinclair BASICu)
- TR-DOS_programming_reference_list_of_services.txt - seznam a popis služeb pro volání ze strojového kódu
- TR-DOS_для_профессионалов_и_любителей.pdf - výborná příručka k TRDOSu (Ю. Поморцев, Львов v roce 1994)
Související odkazy
- článek o využití TRDOSu ze strojového kódu
- článek o struktuře dat a formátu diskety
- schémata zapojení
- článek o ISOROM 128 a novější variantě zapojení ISOROM 128
- místní výběr obsahů ROM ke stažení
- místní výběr programů ke stažení (zastaralé)
- archiv časopisů Mikrobáze včetně ročníku 1989 - kde je seriál článků o stavbě Betadisku, který napsal Daniel Meca
- sam.speccy.cz/olddocs/beta_128_disk_man_cz.pdf - sborník č. 23 Karolinka, český překlad návodu a popis fungování desky Betadisku (Ing. Petr Zapletal)
- sam.speccy.cz/olddocs/beta_128_disk_man_schemata.pdf - příloha sborníku č. 23, první nedokonalá schémata Betadisku
Historie změn článku
- 2004-2007 - zveřejněno, článek vycházel z článků Mikrobáze ročník 1989, návodu k TR DOSu 5.04 od Betaklubu v Brně a z vlastní zkušenosti
- 2008-05-24 - přepracování HTML po přenosu na doménu cygnus.speccy.cz
- 2015-12-29 - drobné korekce, převážně překlepy a formátování, žádné velké změny obsahu
- 2025-11-23 - článek přepsán, rozšířen, zpřesněn, doplněno víc příkladů, obarvena syntaxe příkazů, lépe otestovány a popsány rozdíly mezi TRDOS 5.03 s TRDOS 5.05cz...





































