Nyní si naprogramujeme hlavní smyčku programu, která bude umět najít první disk na aktuální patišně a postupně projít celý oddíl a všechny diskety vypsat. Zatím bez jakékoliv úpravy.
Hnedka zkraje je třeba se přestránkovat do stínové rom D80, odkud je možné volat služby MDOS3. Hned první službu, kterou zavoláme bude GET VER, který zjistí, jestli je MDOS3 incializován. Pokud ne, vrací se do Basicu s chybovou hláškou.
Další službu, kterou zavoláme bude GET AKTPAR, který nám vrátí adresu tabulku s údaji o aktuální partišně, tuto adresu si uložíme. Pokud bychom chtěli patchovat na jiném oddíle, museli bychom vyrobit vybírátko, údaje o všech oddílech jsou k dispozici po zavolání služby GET PART_TABLE.
Program pak vstupuje do rutiny FIRST DISK, který podle údajů z oddílu vypočte LBA adresu prvního sektoru první diskety. Protože je oddíl aktuální, je jisté, že první sektor toho oddílu ukazuje na první infosektor. Pokud by se o výběr partišny staralo nějaké vybírátko, muselo by se ještě zjistit, jestli jde o oddíly s číslem 252,253, které nejsou najeté na první disketu. Pak by se musel načítat sektor po sektoru a hledat značku infosektoru. Takhle je to prostě jednodušší.
FIRST_DISK taky zjistí, jde-li o zařízení master nebo slave, a podle toho upraví 4. bit registru B, který indikuje master/slave. LBA sektor první diskety je uložen.
Pak teprve vstupujeme do vlastní smyčky. Je třeba zkontrolovat, jde-li o platný disk. Může se stát, že bude mít infosektor nabouraný a tudíž další data nejsou platná. A tady už využijeme službu, která čte data z HDD. Naplníme „čtyřregistr“ BCDE LBA adresou (a nestaráme se o to, jestli to disk umí nebo ne), do HL dáme adresu dat, a pak zavoláme službu READHDD. Otestujeme chyby a pokud nějaká nastala, prostě skončíme. Zatím neřešíme nějaké problémy. Chyby by nastat neměly, leda bychom měli v programu chybu.
Otestujeme přítomnost značky SDOS a nastavíme příznak, podle kterého v hlavní smyčce rozhodneme, zda program pustíme dále, nebo skočíme na NEXT DISK. Pak název diskety vytiskneme na obrazovku.
Dále by měl program načíst obsah adresáře a FAT, najít run.P načíst určené sektory z něj a patchnout a uložit zpět. To zatím němáme, program pokračuje nalezením další diskety.
Do „čtyřregistru“ BCDE dáme LBA sektor diskety, do IX pak údaje o oddíle a zavoláme službu NEXTDISK. Aby služba poznala, kde je konec oddílu, opravdu je třeba to IX nastavit. Pokud je oddíl překročen, je nastaveno carry a program končí. Pokud není oddíl překročen, BCDE je posunuto na další disketu, to je třeba uložit a jít zpět na začátek kolotoče.
Příště už jenom doplníme program o chybějící část a dokončíme jej.
obsah souboru patchrun.a80, který minule chyběl:
;program na prepracovani outu 145 a 153 u FileManageru, protoze koliduje
;se strankovanim na 128 a pak nefunguje na neupravenych 128
;program bude mit za ukol projit aktualni partition a na vsech nalezenych
;disketach najit soubor run.P a "opatchovat" novymi hodnotami.
;ovsem, jen ty, ktere jsou opravdu filemanagerem zname verze.
cpu z80undoc
relaxed on
shared START,RAMTOP ;navesti k exportu
SERVICE: equ $24
org 25000 ;za programem budeme potrebovat
;prostor pro nactenou disketu
START:
RAMTOP: equ START-1
di
ld (RETURN + 1),sp ;uloz si hodnotu zasobniku
STARTX: call SHADE ;prestrankuje do ROM MDOS3
call GET_VER ;zjisti informace o MDOS3
call CLS ;smaz obr. tiskni hlasku
call GET_AKTPAR ;nacti udaje o aktualni partition
call FIRST_DISK ;do BCDE prvi sektor prvni diskety
MAINLOOP:
call VALID_DISK ;otestuje platnou disketu (z=OK)
jr nz,NEXT_DISK ;jinak skoc na dalsi
ld de,16384+64+4
ld (POS),de ;nastav pozici
xor a
ld (COL),a
ld (ROLL),a
ld hl,INFOSEKTOR+4 ;vytiskni nazev diskety
call PRINT32 ;presne 32 znaku
;zde bude program pokracovat nactenim a patchem
NEXT_DISK:
ld ix,DISKETA
call BCDE_IX ;uakazatel na disketu
ld ix,(AKTPAR) ;ukazatel na udaje o partition
ld a,16 ;NEXTDISK
call SERVICE
jr c,RETURN ;HOTOVO, dalsi disketa neni
ld ix,DISKETA ;nezapomen si to ulozit
call IX_BCDE
call KEYBREAK ;nc=BREAK
jr c,MAINLOOP ;jinak smyckuj
RETURN: ld sp,0 ;pouzivej vzdy jen tento
call ZXROM
ei ;navrat zpet do BASICu.
ret
VALID_DISK: ld ix,DISKETA
call BCDE_IX ;BCDE = infosektor diskety
ld hl,INFOSEKTOR ;na adresu
ld a,25 ;READHDD
call SERVICE ;nacti
inc c
dec c ;byla nejaka chyba?
jp nz,ERROR
ld hl,ZNACKA ;kontroluje, jestli je v infosektoru
ld de,INFOSEKTOR ;nase znacka
ld b,4 ;ktera rika, ze je to disketa
COMPARE: ld a,(de) ;porovnava B znaku
cp (hl) ;z adresy DE a HL
ret nz ;Z = stejne
inc de
inc hl
djnz COMPARE
xor a
ret
ZNACKA: db "SDOS"
FIRST_DISK: ld a,(hl) ;typ partition
inc hl ;posun se
ld e,(hl) ;a postupne nacti udaje do bcde
inc hl
ld d,(hl)
inc hl
ld c,(hl)
inc hl
ld b,(hl)
cp 255
jr z,+ ;slave=skok
cp 5
jr c,++
/ set 4,b ;slave
/ ld ix,DISKETA
;uloz udaje o diskete
IX_BCDE: ld (ix+0),e ;ulozi BCDE na (IX)
ld (ix+1),d
ld (ix+2),c
ld (ix+3),b
ret
BCDE_IX: ld e,(ix+0)
ld d,(ix+1)
ld c,(ix+2)
ld b,(ix+3)
ret
GET_AKTPAR: ld a,3 ;GET_AKTPAR
call SERVICE ;hl=aktpar
ld (AKTPAR),hl
ld a,(hl) ;musime zkontrolovat
or a ;jestli je vubec nejaka
ret nz ;partition vybrana
ld de,16384+64+4
ld hl,T_NONPART ;chyba
jr REPEAT
GET_VER: xor a ;zjisti inicializaci MDOS3
call SERVICE ;sluzbou GET_VER
ret nz ;navrat = OK
pop hl ;zrus navrat adresu
ld de,16384+64+4 ;pozice
ld hl,T_INIT ;tiskni hlasku
REPEAT: call PRINT
call INKEY ;cekej na klapku
call ZXROM ;prestrankuj do ZXROM
call $66 ;zavolej NMI
jp STARTX ;a pak spust program znovu
CLS: ld hl,16384 ;smaz obrazovku
ld de,16385
ld bc,6144
ld (hl),0
ldir
ld (hl),7 ;nastav bila na cerne
ld bc,767
ldir
ld de,16387
ld hl,T_WELCOME ;vytiskni uvitaci text
call PRINT
ret
;jednuduche osetreni chyb.
ERROR: ld de,16384+64+4 ;pozice
ld hl,T_ERROR ;tiskni hlasku
call PRINT
jp RETURN ;a skonci
;Promenne
AKTPAR: dw 0
DISKETA: db 0,0,0,0
;TEXTY
T_INIT: db "MDOS3 neni inicializova",'n'+128
T_WELCOME: db "Vitejte v PATCHRU",'N'+128
T_NONPART: db "Neni nastavena zadna partitio",'n'+128
T_ERROR: db "Chyba pri cteni/zapis",'u'+128
;includovane knihovny
include include/shade.a80
include include/print.a80
include include/inkey.a80
;pracovni prostor
INFOSEKTOR: ds 512
stažení:
3 komentáre na “Programujeme pro MDOS3 (2)”
Je nám líto, ale formulář pro přidávání komentářů je momentálně uzavřen.
Pekneee. Uz ked som cital tvoj dokument popisujuci sluzby MDOS3, tak som vedel, ze takto sa k MDOSu mali postavit v Skalici. Je vidiet, ako jednoducha myslienka znacne sprehladni a zjednodusi vysledny kod. Uz mi chyba iba divIDE (alebo emulator, ktory ho regulerne podporuje :-), aby som sa vytesoval este viac.
Dovolim si ale dve poznamky, ktore usetria 2 byty 🙂 Podprogram CLS moze byt ukonceny ‚jp PRINT‘.
Podprogram COMPARE nepotrebuje na konci instrukciu ‚xor a‘, kedze instrukcie ‚inc de‘, ‚inc hl‘ a ‚djnz COMPARE‘ nemenia priznak Z (ak teda nie je potrebene mat v registri A nulu, samozrejme).
Tuhle poznámku jsem nepochopil – xor a na konci COMPARE je nutnost. jedna věc je ret nz (vrací se při nz) a druhá věc je xor a, ret, která se vrací se z. Nutné je právě proto, že incy nemění z.
To s tim CLS je ale pravda.
Xor, su vůl, teď vidím podmínku – djnz – jasně, pokračuje se jen se z, netřeba nastavovat… aaachjo !