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 !