Ovládání TRDOSu ze strojového kódu

Úvod

Betadisk, resp. jeho systém TRDOS měl oproti ostatním diskovým systémům na počítačích ZX Spectrum jednu zajímavou a rozhodně nezanedbatelnou výhodu. Je od začátku stavěný tak, že se ovládá pomocí služeb s pevně daným rozhraním, které jsou stejné bez ohledu na verzi systému, nebo případné hardwarové odlišnosti. Díky tomu může a také existuje značné množství verzí TRDOSu. Bohužel ne každý programátor toto dodržoval, takže existuje i řada programů, které na jiných verzích TRDOSu nefungují, ale to už není chyba Betadisku, ale autora programu. Ve srovnání s D40, resp. D80, která existuje nejméně ve dvou verzích s různými řadiči a několika modifikacích fandů a která se ovládá ze strojového kódu přímým voláním rutin MDOSu to je výhoda obrovská. Stačí rutiny posunout o jeden byte a je nekompatibilita na světě.

Další zajímavostí je neexistence FAT, resp. filesystém TRDOSu je extrémně jednoduchý a obsahuje prakticky jenom jeden direktorář se jmény a dalšími parametry souborů, několik pomocných sektorů a data. Píšu zajímavostí, protože je sporné jestli se jedná o výhodu, nebo nevýhodu. Výhodné to je kvůli snadnosti a rychlosti zpracování dat, tím spíš, když je CPU pouze osmibitový a dnes už velmi pomalý. Nevýhodné to je při častém zápisu a mazání souborů, protože nelze soubory fragmentovat a je nutno je čas od času "sesypat" příkazem MOVE. Nevýhodné to je i v případě, že na disketě existují vadné sektory, jež nelze nijak obejít (nutno poznamenat, že ze zhruba dvou stovek disket DS DD 5 1/4" 80 stop, které mi prošly rukama byly vadné snad jen dvě, oproti novějším HD 3,5" odcházejícím někdy i v 50 - 100% případů spolehlivost nesrovnatelná, většina starých 5 1/4" disket je čitelná i po mnoha letech archivace).

Zvláštností Betadisku je také absence vlastní RAM (např. D40 má 2kB vyrovnávací paměti na sektory a systémové proměnné), takže veškeré operace, kde je paměť nutná využívají RAM počítače. TRDOS potřebuje pro systémové proměnné 112 bytů o které posouvá Basicový program dolů, případně o dalších 58 (57 bez Betadisku) bytů posune Basic Interface 1 (Microdrive) pokud je používán společně s Betadiskem. Ačkoliv osobně jsem se nikdy s kombinací těchto dvou zařízení nesetkal, měly by se snášet. Krom 112 bytů pro systémové proměnné (do nichž lze zapisovat a s výhodou toho využít) potřebuje TRDOS dalších 256 bytů jako buffer pro právě zpracovávaný sektor (jak čtení souboru, tak CAT, LIST ...). K tomu využívá opět prostor pro Basic, ale tuto paměť po skončení práce zase uvolní. V praxi to znamená, že není rozumné nastavovat RAMTOP výš než 24500 a i tak se do paměti nevejde víc než nejzákladnější basicový zavaděč. Nicméně stačí to k tomu, aby mohl být TRDOS volán ze strojového kódu. Pro srovnání při práci s D40 resp. MDOSem a páskou se často nastavoval RAMTOP na 24200, což činí zbytečné potíže při převodu softwaru z pásky/D40 na Betadisk.

Začátky Basicu pro různé kombinace Betadisk/Interface 1

Adresy začátku Basicu
bez připojeného zařízení23755
pouze Interface I23812
pouze Betadisk23867
Interface I i Betadisk23925

rozhraní TRDOSu pro uživatele

Seznam služeb TRDOSu

číslo
služby
adresa v
ROM 5.03
Popis a funkce služby
03D98hRESTORE - hlava na stopu 0
výstup: BC kód chyby
13DCBhSELECT DRIVE - zvolení mechaniky s níž se bude pracovat
vstup : A číslo mechaniky
výstup : BC kód chyby
23E63hSEEK - posune hlavu na určenou stopu
vstup: A číslo stopy
výstup: BC kód chyby
33F02hSTORE SEKTOR NUMBER - uloží číslo sektoru
vstup: A číslo sektoru
výstup: na 5CFFh číslo sektoru, BC kód chyby
43F06hSTORE BUFFER ADDRESS - uloží adresu bufferu
vstup: HL adresa bufferu
výstup: na 5D00h adresa bufferu, BC kód chyby
51E3DhREAD SECTOR - čtení sektoru z diskety
vstup: HL adresa bufferu, D číslo stopy, E číslo sektoru, B počet sektorů
výstup: obsah sektorů na adrese HL, BC kód chyby
61E4DhWRITE SECTOR - zápis sektoru na disketu
vstup: HL adresa bufferu, D číslo stopy, E číslo sektoru, B počet sektorů, data v bufferu
výstup: sektory na disketě, BC kód chyby
728D8hCAT - výpis katalogu diskety (adresáře)
vstup: A kanál (standardně 2)
výstup: katalog disku v zadaném kanálu (tedy třeba na obrazovce), BC kód chyby
8165ChREAD HEADER - načtení zvolené hlavičky z adresáře
vstup: A pořadí hlavičky v adresáři
výstup: od 5CDDh hlavička, BC kód chyby
91664hWRITE HEADER - zapsání zvolené hlavičky do adresáře
vstup: A pořadí hlavičky v adresáři, od 5CDDh hlavička
výstup: BC kód chyby
101CF0hHEADER INDEX - vrátí pořadové číslo hlavičky v adresáři
vstup: od 5CDDh hlavička
výstup: na 5D0Fh číslo hlavičky, jinak FFh, nebo v C číslo hlavičky, jinak 0 (nález Z, jinak NZ)
1128FBhSAVE BYTES - uloží binární soubor na disketu
vstup: od 5CDDh hlavička (bez umístění na disketě), HL začátek bloku, DE délka bloku
výstup: BC kód chyby
1228F2hSAVE BASIC - uloží basicový program na disketu
vstup: od 5CDDh hlavička, na 5CD1h buď 0, nebo řádek autostartu
výstup: BC kód chyby
1301D3h<< nevyužito>>
14290FhLOAD PROGRAM - načtení programu
vstup: od 5CDDh hlavička
pro A=0 - start a délka podle hlavičky
pro A=3 - HL start, DE délka
výstup: BC kód chyby
1501D3h<< nevyužito>>
1601D3h<< nevyužito>>
1701D3h<< nevyužito>>
182926hERASE FILE - vymazání souboru
vstup: od 5CDDh hlavička
výstup: BC kód chyby
1928E0hMOVE HEADER TO 5CDDh - přenesení hlavičky z adresy v HL na 5CDDh
vstup: v HL adresa bufferu, v bufferu hlavička
výstup: na 5CDDh hlavička
2028E3hMOVE HEADER FROM 5CDDh - přenesení hlavičky z 5CDDh na adresu v HL
vstup: na 5CDDh hlavička, v HL adresa bufferu
výstup: hlavička v bufferu
212739hVERIFY TRACK - verifikace stopy
vstup: D číslo stopy
výstup: na 5CD6h počet chyb, BC kód chyby (např. no disk)
221FEBhSELECT SIDE 0 - volba stopy 0 (kvůli verifikaci ???)
231FF6hSELECT SIDE 1 - volba stopy 1 (kvůli verifikaci ???)
240405hTRDOS INIT - ověření značky TRDOSu a nastavení druhu záznamu podle údajů na disku
výstup: nastavené bity specifikace, BC kód chyby

Adresy služeb v originální ROM TR-DOSu 5.03 uvádím jen pro pořádek a pro potřebu zkoumání. Rozhodně je NEPOUŽÍVEJTE pro volání funkcí programem. Pravděpodobně by program pracoval jenom Vám, protože verzí TR-DOSu se vyskytuje mnohem více než v případě D40! I v emulátorech většinou (např. X128) fungují služby bez problémů narozdíl od přímého volání ROM.

Co se týče vrácené chyby tak já osobně radši používám systémovou proměnnou než registr BC.

Jedna ze systémových proměnných použitelná pro čtení disket MS DOSu, nebo D40 na Betadisku. Tyto proměnné jsou čtyři. Pro každou mechaniku jedna.

  • Drive A - 23752
  • Drive B - 23753
  • Drive C - 23754
  • Drive D - 23755
bitvýznam bitu
0formát diskety 0=40nbsp;tr. 1=80 tr.
1číslo strany diskety 0=side 0, 1=side 1
2-
30=256 bytů na sektor, 1=512 bytů na sektor
(nepoužívat implicitní buffer!)
4-
5-
6-
7drive 0=40 tr., 1=80 tr.
(při formátu 40 tr. a mechanice 80 tr. automaticky dvojitý krok)

Chybové kódy

č. chybyvýznam
0žádná chyba
1soubor nebyl nalezen
2soubor už existuje
3není místo (disk plný ???)
4katalog je plný
5počet záznamů překročen (???)
6v mechanice není disk
7chyba disku
8chyba syntaxe
9---
10proud je již otevřen
11Not Disk File - ???
12proud není otevřen
13chyba verifikace

Tuto tabulku jsem kompletně opsal z Mikrobáze, ale jsem z ní poněkud zmaten. Prý to funguje v syntaxi LET ERR=USR 15619:REM: příkaz. Jenže co ve strojáku. V praxi mi bohatě stačilo, že 0 znamená vše OK, a něco jiného je chyba. Při volání služeb se mi povedlo rozlišit chybu sektor nečitelný a není disk. S ostatními případy jsem se nesetkal, protože jsem vždy pracoval s diskem po sektorech a nikoliv po souborech. V takovém případě totiž není problém ošetřit mnohem více situací vlastním programem, přitom adresář zabírá dohromady 2304 bytů včetně systémového sektoru. Číslo chyby jsem četl z proměnné na adrese 23823 (i když v BC byla stejná), protože mezitím s registrem BC můžu pracovat a nestarat se o jeho obsah, hlavně stejně musíte číslo chyby na adrese 23823 před použitím služby vynulovat, protože to TRDOS nedělá. TRDOS změní na této adrese hodnotu právě a jedině tehdy když chyba nastane.

Příklady

Příklad nejjednoduššího volání služby

restore ld   c,0
        call 15635
        ret

cat     ld   c,7
        ld   a,2
        call 15635
        ret

V C je vždy číslo služby, případná chyba je ignorována, v nejhorším se objeví hlášení Betadisku stejně jako je tomu v BASICu. Je ovšem možné zajistit, aby nedošlo k vrácení do editoru BASICu ani při zvolené možnosti Abort.

Příklad podle manuálu výrobce Technology Research

Příklad uvádím včetně původních komentářů. Odstranil jsem řádek s pseudoinstrukcí org a upravil jsem zápis dat příkazů SAVE a LOAD pro překladač Prometheus. Opravil jsem i adresu volané rutiny z původní hodnoty 15363 na 15619. Původní hodnota se myslím týkala starších verzí TRDOSu a zůstala v manuálu zřejmě nezměněna. Příklad se zdá docela úsporný, data pro LOAD a SAVE je možné sloučit a měnit pouze opcode samotného basicového příkazu, ale není o nic výhodnější než přímé volání služeb (viz. první příklad), protože neodstraňuje výpis chybových hlášení skrze basicový interpreter a je v podstatě stejně náročný.

CHADD	equ	23645		; Location of SOS variable CHADD
	ld	hl,(CHADD)	; Start to save true CHADD
	ld	(TEMP),HL	; Temporary store of true CHADD
	ld	HL,SAVE		; Address of SAVE routine
	ld	(CHADD),HL	; CHADD now points to our routine
	call	15619		; ENTER TRDOS SAVE via chadd
	jp	BACK		; Jump to program point from which the whole routine was called
	ld	HL,(CHADD)

	ld	(TEMP),HL	; The routine for LOAD now repeats
	ld	HL,49500	; the above with just the address
	ld	(CHADD),HL	; changed.
	call	15619
BACK	ld	HL,(TEMP)	; Start to restore CHADD
	ld	(CHADD),HL	; Reload original CHADD
	ret			; Return from where you came
TEMP	defs	2		; Label allocating memory for temporary storage

SAVE	defb	234		; code for REM
	defm	":"
	defb	248		; code for SAVE
	defb	34		; code for "
	defm	"filename"
	defb	34		; code for "
	defb	13

LOAD	defb	234		; code for REM
	defm	":"
	defb	239		; code for SAVE
	defb	34		; code for "
	defm	"filename"
	defb	34		; code for "
	defb	13

Složitější příklad

Následující volání služeb umožňuje přenastavit kanál pro výpis a tím zamezit nevhodným výpisům TRDOSU na obrazovku.

DRIVE_A	ld	a,0		; volby mechaniky A,B,C,D
	jp	DRIVE
DRIVE_B	ld	a,1
	jp	DRIVE
DRIVE_C	ld	a,2
	jp	DRIVE
DRIVE_D	ld	a,3
DRIVE	ld	(AKDRIVE),a	; zápis do proměnné
	ld	c,1
	call	BETA
	ret

BETA	ld	(BETA_A+1),a	; toto je tu proto aby se v ošetření chyb dala snadno 
	ld	(BETA_DE+1),de	; zopakovat poslední akce skokem na BETA_2
	ld	(BETA_BC+1),bc
	ld	(BETABUF+1),hl
	di
BETA_2	xor	a
	push	hl
	ld	(23823),a
	ld	(ERROR),a
	ld	hl,(23613)
	ld	(BETA_1+1),hl
	push	de
	push	bc
	push	hl
	push	ix
	push	iy
	ld	hl,BETA_ER
	push	hl
	ld	(23613),sp
BETABUF	ld	hl,BUFFER
BETA_BC	ld	bc,14*256+5
BETA_DE	ld	de,0
BETA_A	ld	a,0
	call	15635
	pop	hl

BETA_ER	di
	ld	sp,(23613)
	pop	hl
	pop	iy
	pop	ix
	pop	hl
	pop	bc
	pop	de
BETA_1	ld	hl,0
	ld	(23613),hl
	ld	a,4
	out	(254),a
	pop	hl
	ld	a,(23823)
	or	a
	ret	z
;nastala chyba, zpracovat
	ret

CHANNE2	ld	a,2		; inicializace kanálu 2, kvůli výpisu na obrazovku
	call	#1601
	ld	hl,CLSTEXT
	call	TEXTOUT
	ret

CLSTEXT	defb	22,0,0,20,0,21,0,16,0,17,7,18,0,19,0+128

TEXTOUT	ld	a,(hl)
	and	127
	rst	16
	bit	7,(hl)
	inc	hl
	jp	z,TEXTOUT
	ret

AKDRIVE defb 	0
ERROR	defb	0

Update ohledně ruského softwaru

Po světě se šíří spousta více, či méně kvalitního softwaru, který vznikal pro Pentagony a Scorpiony obsahující mimo jiné řadič kompatibilní s Betadiskem. Bohužel tento software velmi často přistupuje přímo na porty řadiče a vůbec všelijak obchází TRDOS ačkoliv to není nutné. Často nefunguje s jinými verzemi TRDOSu. Tento způsob přístupu k řadiči je zavrženíhodný, protože jednak popírá smysl TRDOSových služeb a jednak přináší dost zásadní nekompatibilitu.

Dobře napsaný TRDOS s fungujícími službami může v podstatě ovládat zcela libovolný řadič. Dokonce médiem nemusí být nutně disketa, ale v podstatě cokoliv (HDD, RAMdisk ...). Pokud ovšem hloupý programátor zcela obchází rozhraní určené jako jediné k přístupu ke službám, tak nutně píše software, který nebude fungovat jinde než na jeho a identickém hardwaru.

Zde si můžete přečíst podrobný popis formátu diskety systému TRDOS.

Použitá literatura : Mikrobáze z roku 1989 a k tomu vlastní zkušenosti s provozem i stavbou řadiče.

[ Zpět na hlavní stránku ]

Cygnusova stránka o ZX Spectru a kompatibilních počítačích byla napsána (přepsána) výhradně pomocí svobodného Open Source softwaru. V případě že naleznete chybu, nebo byste rádi cokoliv co se ZX Spectrem souvisí, neváhejte mi napsat na některý z mých emailů, nebo pracovně do zaměstnání. Stručně o mém webu se můžete dočíst zde.