   #Start Contents

                       Zarzadzanie zasilaniem komputera

   Jesli zastanawialiscie sie kiedys, jak wylaczac dyski twarde lub
   resetowac komputer uzywajac tylko oprogramowania (nie naciskajac
   zadnych przyciskow), to w tym artykule powinniscie znalezc odpowiedz
   na wszystkie wasze pytania.
     _________________________________________________________________

Wylaczanie monitora

   (przeskocz wylaczanie monitora)

   Zajmijmy sie najpierw teoria. Przerwanie, ktorym najpierw sie
   zajmiemy, to.... int 10h, przerwanie sterownikow karty graficznej. Co
   one maja wspolnego z energia? Otoz, mozna z uzyciem int 10h wylaczyc
   monitor. Zajrzyjmy do RBIL, w opis funkcji numer 4F10h. Uruchomienie
   jej z BL=0 powinno nas upewnic, ze odpowiednie funkcje sa
   zainstalowane (zwroci AL=4Fh):
   (przeskocz sprawdzanie funkcji)
        mov     ax, 4f10h
        mov     bl, 0
        xor     di, di
        mov     es, di          ; przerwanie zada ES:DI = 0
        int     10h

        cmp     al, 4fh
        jne     wychodzimy      ; gdy kleska....

   Teraz, jesli wiemy, ze ta funkcja dziala, to patrzymy na kolejna.
   Wpisujac 1 do BL mozemy zmienic aktualny stan zasilania. W BH
   podajemy, co chcemy zrobic: 0-wlaczyc, 1-przelaczyc w stan
   oczekiwania, 2-zawiesic, 4-wylaczyc monitor. Zanim jednak zaczniecie
   ochoczo pisac, dam wam rade: program nalezy napisac tak, aby po jakims
   czasie monitor wracal jednak do stanu wlaczonego (bez resetowania
   komputera...). Wiem, ze potrafilibyscie cos takiego sami napisac, ale
   podam tutaj gotowe (i sprawdzone - dziala nawet pod Win98)
   rozwiazanie:
   (przeskocz program wylaczajacy monitor)
        ; Program wylacza monitor
        ;
        ; Autor: Bogdan D.
        ; kontakt: bogdandr (at) op (dot) pl
        ;
        ; nasm -O999 -o mon_off.com -f bin mon_off.asm

        org 100h

        start:
                mov ax,4f10h            ; wybranie numeru funkcji
                mov bx,0401h            ; BL=1 - zmien stan. BH=4 - wylacz
                int 10h

                xor ah,ah
                int 16h                 ; poczekaj na nacisniecie klawisza

                mov ax,4f10h
                mov bx,1                ; BL=1 - zmien stan. BH=0 - wlacz
                int 10h

                mov ax,4c00h
                int 21h
     _________________________________________________________________

Wylaczanie twardych dyskow

   (przeskocz wylaczanie twardych dyskow)

   Z dyskami twardymi jest nieco gorzej. Tutaj trzeba sie znac na
   kontrolerze HDD - na jego portach i wysylanych tam komendach. Dlatego
   posluze sie gotowcem. Ma on wylaczyc 2 pierwsze dyski twarde. Dla
   dokladniejszych opisow portow i ich komend spojrzcie do pliku
   "ports.lst" dolaczonego do RBIL. Gotowiec ten jest czescia doskonalego
   programu FDAPM (FreeDOS Advanced Power Management), ktory wraz z kodem
   zrodlowym mozna znalezc na stronach projektu FreeDOS.
   (przeskocz program wylaczajacy dyski)
        mov dx,1f6h     ; pierwszy kontroler IDE (drugi: 176)

        mov al,0a0h     ; bez LBA, dysk nadrzedny (Master)
        out dx,al
        inc dx          ; DX = 1F7
        call miniWait   ; chwila przerwy
        mov al,0e0h     ; e0 = standby, e1 = wlaczony/idle
        out dx,al
        dec dx          ; DX = 1F6
        call miniWait
        mov al,0b0h     ; bez LBA, dysk podrzedny (Slave)
        out dx,al
        inc dx          ; DX = 1F7
        call miniWait
        mov al,0e0h     ; e0 = standby, e1 = wlaczony/idle
        out dx,al

        mov ax,4c00h
        int 21h

        miniWait:       ; bardzo krotki okres przerwy
        xchg ax, bx
        xchg bx, ax
        xchg ax, bx
        xchg bx, ax
        ret

   Po zatrzymaniu twardego dysku mozna go uruchomic wykonujac dowolna
   operacje na systemie plikow (na przyklad wyswietlic zawartosc
   biezacego katalogu).

   Parkowanie glowic twardego dysku jest sprawa prostsza, gdyz w tym
   przypadku pomaga nam BIOS. Aby zaparkowac glowice pierwszego dysku
   twardego, uzyj nastepujacego kodu:
        mov     ah, 19h
        mov     dl, 80h
        int     13h

        jc      blad            ; nie pokazuje bledow pod Windows 98

   Jesli chcecie zaparkowac glowice drugiego dysku, zamiast 80h wpiszcie
   81h, jesli trzeciego - 82h itd.
     _________________________________________________________________

Resetowanie i wylaczanie komputera

   Teraz ciekawsze sprawy - resetowanie komputera lub wylaczanie go. Na
   poczatek "grzecznie" posluzymy sie przerwaniem - bedzie to int15h,
   numery funkcji 5300h i 5307h (po szczegolowe opisy tych funkcji
   posylam oczywiscie do RBIL). Najpierw sprawdzmy w ogole, czy Advanced
   Power Management (APM) - bo o nim mowa - jest zainstalowane:
   (przeskocz sprawdzanie APM)
        mov     ax, 5300h
        xor     bx, bx          ; numer urzadzenia = 0 = BIOS
        int     15h

        jc      niestety   ; gdy cos poszlo nie tak (na przyklad brak APM), to
CF=1

   Teraz sprobujmy wylaczyc system:
   (przeskocz wylaczanie zasilania)
        mov     ax, 5307h       ; funkcja APM
        mov     cx, 3           ; wylacz system. CX=2 - zawies system, CX=1 -
                                ; przelacz system w stan oczekiwania stand-by
        mov     bx, 1           ; wszystkie urzadzenia
        int     15h             ; sprobujemy wylaczyc...

   Jesli istnieje mozliwosc wylaczenia pradu w systemie, to powyzszy kod
   powinien to zalatwic.

   Teraz przejdziemy do innych "grzecznych" sposobow na zresetowanie
   komputera. W RBIL znalazlem:
   (przeskocz opis przerwan do resetowania)
        INT 16 - AMI BIOS - BIOS-FLASH Interface - GENERATE CPU RESET
                AX = E0FFh

        INT 14 - FOSSIL - REBOOT SYSTEM
        AH = 17h
        AL = method
            00h = cold boot
            01h = warm boot

   Jak widac, nie wyglada to skomplikowanie. Niestety, zaden z powyzszych
   sposobow nie dziala u mnie pod "czystym" DOS-em, a pod Windows98
   dziala jedynie sposob z APM (int15h).

   A teraz pokaze kilka "niegrzecznych" (ale za to sprawdzonych przeze
   mnie i dzialajacych bez pudla) sposobow na zresetowanie komputera.

   Pierwszym takim sposobem jest dlugi skok pod adres FFFF:0000 (tam
   znajduje sie czesc BIOSu odpowiedzialna za operacje wykonywane przy
   starcie komputera). Wczesniej do segmentu danych BIOSu (segment 40h),
   pod adres 72h nalezy wpisac 0, gdy chcemy zimny reset (taki, co
   obejmuje testy pamieci i wszystko inne), a 1234h, gdy chcemy goracy
   reset.

   Odpowiednie kawalki kodu wygladaja tak (przypominam, ze adres
   0040h:0072h = 0000:0472h - patrz czesc 2 mojego kursu):
   (przeskocz kod do recznego resetowania)
        ; zimny reset:

        mov     ax, 40h
        mov     ds, ax                  ; DS = 40h
        mov     word [ds:72h], 0        ; zimny reset

        ; niektore kompilatory (na przyklad TASM) nie lubia instrukcji w stylu
        ; jmp 0FFFFh:0000h, wiec zakoduje ja recznie
        db      0eah            ; kod instrukcji wziety z podrecznikow Intela
        dw      0               ; offset
        dw      0ffffh          ; segment


        ; goracy reset:

        xor     ax, ax
        mov     ds, ax                  ; DS = 0
        mov     word [ds:472h], 1234h   ; goracy reset

        db      0eah            ; kod instrukcji wziety z podrecznikow Intela
        dw      0               ; offset
        dw      0ffffh          ; segment

   Drugim (i prostszym) sposobem jest zapisanie do jednego z portow
   klawiatury (64h) jednego z bajtow od F0 do FE, ktory ma bit0 = 0 (jest
   takich oczywiscie kilka, najczesciej stosuje sie FEh), chociaz ten
   sposob nie jest zalecany.
   Kod jest wyjatkowo prosty i wyglada tak:
        mov     al, 0feh
        out     64h, al

   Celowo nie wspominam tutaj o jednym: o przerwaniu int19h, ktore sluzy
   do ponownego przeczytania bootsektorow i przeladowania systemu od
   nowa. Gdy wkladacie niesystemowa dyskietke do stacji i resetujecie
   komputer, to (o ile macie mozliwosc uruchomienia systemu z dyskietki)
   pojawia sie napis informujacy o nieprawidlowym dysku systemowym. Po
   nacisnieciu Entera uruchamiane jest wlasnie int19h, ktore nie wykonuje
   zadnych resetow, tylko czyta bootsektory od nowa.

   Nie wspominalem o int19h, gdyz jest ono niebezpieczne. Jezeli
   jakikolwiek program przejal przerwanie na przyklad zegara, to int19h
   nie przywroci poprzedniej procedury, co jest nieprzewidywalne w
   skutkach!
     _________________________________________________________________

   Sposoby na wylaczanie urzadzen moga sie Wam przydac, gdy na przyklad
   bedziecie pisac wlasny wygaszacz ekranu, a mozliwosc zresetowania
   komputera przyda sie, gdy Wasze oprogramowanie zostanie zainstalowane
   i musi zmienic na przyklad zawartosc pliku "autoexec.bat".
   Informacje, ktore tutaj podalem moga sie Wam tez przydac przy pisaniu
   boot-sektorow do wlasnych "mini-systemow operacyjnych".

   Spis tresci off-line (klawisz dostepu 1)
   Spis tresci on-line (klawisz dostepu 2)
   Ulatwienia dla niepelnosprawnych (klawisz dostepu 0)
