Čvn 212006
 

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)”

  1. 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).

  2. 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.

  3. Xor, su vůl, teď vidím podmínku – djnz – jasně, pokračuje se jen se z, netřeba nastavovat… aaachjo !

Je nám líto, ale formulář pro přidávání komentářů je momentálně uzavřen.