DETEKT.ASM

TITLE Detekuje CPU,NPU,HDD,CDROM,mouse,ramdisk,VGA,VESA ...
.8086                               ; Linkuje se pro 80 86
PAGE 67, 130                        ; Stránka 67 zn., délka 130 zn./řádek








COMMENT @
 ===========================================================================

  Název souboru  :   DETEKT.ASM
  Link OBJ & LIB :   DETEKT.ZIP
  Datum úprav    :   01.09.97
  Verze programu :   4.00
  (c) Copyright  :   1993,94,95,96,97 by NST 32 , Medo Zdeněk junior

 ===========================================================================@


Knihovna_NST32  SEGMENT PARA PUBLIC 'CODE' USE16
   ASSUME CS:Knihovna_NST32

   PUBLIC __detect_cpu          ; EXTRN __detect_cpu         :PROC :NEAR
   PUBLIC __detect_npu          ; EXTRN __detect_npu         :PROC :NEAR

   PUBLIC __info_hdd            ; EXTRN __info_hdd           :PROC :NEAR
   PUBLIC __hdd_type            ; EXTRN __hdd_type           :PROC :NEAR
   PUBLIC &__hdd_type           ; EXTRN &__hdd_type          :WORD
   PUBLIC &__hdd_comand_status  ; EXTRN &__hdd_comand_status :WORD
   PUBLIC &__hdd_data_register  ; EXTRN &__hdd_data_register :WORD
   PUBLIC &__hdd_digital_output ; EXTRN &__hdd_digital_output:WORD

   PUBLIC __detect_mouse        ; EXTRN __detect_mouse       :PROC :NEAR
   PUBLIC __detect_cdrom        ; EXTRN __detect_cdrom       :PROC :NEAR
   PUBLIC __detect_ramdisk      ; EXTRN __detect_ramdisk     :PROC :NEAR

   PUBLIC __detect_vga          ; EXTRN __detect_vga         :PROC :NEAR
   PUBLIC __detect_ega          ; EXTRN __detect_ega         :PROC :NEAR
   PUBLIC __detect_vesa         ; EXTRN __detect_vesa        :PROC :NEAR
   PUBLIC __detect_mh_monitor   ; EXTRN __detect_mh_monitor  :PROC :NEAR





;                     -------------------------------------
;                     -              For NPU              -
;                     -------------------------------------

   Control    DW 00
   Maska      EQU 0000111100111111B
   Test_1     EQU 0000001100111111B
   Test_2     EQU (NOT Test_1) AND Maska




;                     -------------------------------------
;                     -       Tabulka parametrů  HDD      -
;                     -------------------------------------

&__hdd_type   DW 00             ; (+00) Konstanta 0A5Ah
              DW 00             ; (+02) Počet cylindrů na disku
              DW 00             ; (+04) Počet odstranitelných cylindrů
              DW 00             ; (+06) Počet hlav
              DW 00             ; (+08) Počet neformátovaných bajtů na stopě
              DW 00             ; (+10) Počet neformátovaných bajtů na sektoru
              DW 00             ; (+12) Počet sektorů na stopě
              DW 00             ; (+14) Počet bajtů v oblasti mezi sektory
              DW 00             ; (+16) Počet bajtů v synchronizačním poli
              DW 00             ; (+18) Konstanta 0000h

              DW 10 dup(0)      ; (+20) Sériové číslo

              DW 00             ; (+40) Typ kontroléry
              DW 00             ; (+42) Velikost vnitřního bufferu v 512-bajtových blocích
              DW 00             ; (+44) Počet bajtů ECC při operaci dlouhého čtení/zápisu

              DW 4 dup (0)      ; (+46) Verze frimwaru kontroléru
              DW 20 dup(0)      ; (+54) Typ pevného disku

              DW 00             ; (+94)  Počet sektorů během interruptu
              DW 00             ; (+96)  Příznak přenosu dvojtých slov

              DW 207 dup(0)     ; (+98) Rezerva

&__hdd_comand_status    DW 01F7h     ; Příznakové a stavový registr disku

; bit.      00000000                 ; Při čtení registru '_comand_status'
;           ||||||||
;           ||||||||---> Chyba předešlé operace                       - ERR
;           |||||||----> Bit. je ve stavu H, po každé otáčce          - IDX
;           ||||||-----> Při operaci s daty došlo k opravitelné chybě - CORR
;           |||||------> Disk je připraven k přenosu dat              - DRQ
;           ||||-------> Operace hledání dokončena                    - DRQ
;           |||--------> Chyba zápisu dat                             - DWF
;           ||---------> Disk připraven k operaci                     - DRDY
;           |----------> Disk provádí nějaku činost                   - BSY

&__hdd_data_register    DW 01F0h     ; Datový registr disku

&__hdd_digital_output   DW 03F6h     ; Digitální výstupní registr

; bit.      00000000            ; Při čtení registru '&__digital_output'
;           ||||||||
;           ||||||||----> nepoužito
;           |||||||-----> Povolení přerušení (irq 14)                  - ien
;           ||||||------> Reset disku                                  - SRST
;           |||||-------> nepoužito
;           ||||--------> nepoužito
;           |||---------> nepoužito
;           ||----------> nepoužito
;           |-----------> nepoužito




;                     -------------------------------------
;                     -         Tabulka VESA-BIOS         -
;                     -------------------------------------

    VESA_INFO   DB 257 dup (0)   ; Informace o VESA ...







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje typ procesoru.
;  --------------
;
;  Volání(např.) :   call    __detect_cpu            ; Test typu procesoru
;  --------------
;
;  Výstup        :   AX    = 00                      ; Je to 8086
;  --------------    AX    = 01                      ; neobsazeno (pro 186)
;                    AX    = 02                      ; Je to 80 286
;                    AX    = 03                      ; Je to 80 386
;                    AX    = 04                      ; Je to 80 486 (a vyšší)
;                    AX    = 05                      ; neobsazeno (pro PENTIUM)
;
;  Mění registry :   AX,   Flags, BX, DX, BP
;  --------------
;
;---------------------------------------------------------------------------

__detect_cpu PROC  NEAR

    xor     dx, dx                          ; Číslo procesoru
    mov     bp, sp                          ; Ulož aktuální hodnotu zásobníku
    sub     sp, 10                          ; Simulace vložení deseti bajtů
                                            ;  (kůli zarovnávání při testu 486)

;           ------------ Test na CPU 8086 -------------
;       'Podle programátorské perličky BAJT 12/93 str. 139'
    pushf                                   ; Ulož FLAGs
    pop     ax                              ;   - do AX
    mov     bx, ax                          ; Uschovej pro test 80286

    and     ax, 0FFFH                       ; Vynuluj bity 12-15
    push    ax
    popf                                    ; AX do Flags

    pushf                                   ; Znovu přečti příznaky
    pop     ax
    and     ax, 0F000H                      ; Testuj, zda jsou
    cmp     ax, 0F000H                      ; - bity 12-15 nastaveny
    je      CPU_OK                          ; Je to XT 8086 ...

;           ------------ Test na CPU 80 186 -------------
    inc     dx                              ; Číslo procesoru 80186

;           ------------ Test na CPU 80 286 -------------
    inc     dx                              ; Číslo procesoru 80286
    or      bx, 0F000H                      ; Nastav bity 12-15
    push    bx
    popf                                    ; BX do Flags

    pushf
    pop     bx
    test    bx, 0F000H                      ; Testuj, zda jsou bity 12-15 nastaveny
    jz      CPU_OK                          ; Je to AT 80286 ...

;           ------------ Test na CPU 80 386 -------------
    .386                                    ; Linkuje se pro i80386
    inc     dx                              ; Číslo procesoru 80386
    and     sp, not 3                       ; Zarovnej SP, aby nedošlo k chybě AC
    push    eax ecx                         ; Ulož reg.

    pushfd                                  ; Ulož EFlags do EAX
    pop     eax
    mov     ecx, eax                        ; Uschovej EFlags pro porovnání
    xor     eax, 40000H                     ; Neguj bit 18 (AC)
    push    eax
    popfd
    pushfd
    pop     eax
    cmp     eax, ecx                        ; Testuj, zda byl bit 18 změněn
    pop     ecx eax                         ; Obnov reg.
    je      CPU_OK                          ; Je to AT 80386 ...

;           ------------ Test na CPU 80 486 a vyšší -------------
    inc     dx                              ; Číslo procesoru 80486

;                   ------------ CPU OK -------------
 CPU_OK:
    .8086                                   ; Linkuje se pro i8086
    mov     sp, bp                          ; Obnov původní SP (změnil-li jej test)
    mov     ax, dx                          ; Číslo procesoru
    retn                                    ; Návrat NEAR

__detect_cpu  ENDP








;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost koprocesoru.
;  --------------    Pro detekci používá jak BIOS, tak i vlastní detekci ...
;
;  Volání(např.) :   call    __detect_npu            ; Test na přítomnost koprocesoru
;  --------------
;
;  Výstup        :   CF = 1  Je instalován koprocesor
;  --------------    CF = 0  Není instalován
;
;  Mění registry :   Flags, AX
;  --------------
;
;---------------------------------------------------------------------------

__detect_npu  PROC  NEAR

    int     11h                             ; Načti konfiguraci počítače
    test    ax, 0000000000000010B           ; 1=je instalován
    jnz     NPU_1                           ; Ano, skoč ...
 No_NPU:
    clc                                     ; CF = 0
    retn                                    ; Návrat NEAR

;             ------------ Test NPU -------------
 NPU_1:
    fninit                                  ; Inicializace koprocesoru
    fstcw   word ptr cs:[Control]           ; Uložení stav.slova NK do RAM
    fwait                                   ; Synchronizace
    mov     ax, word ptr cs:[Control]
    and     ax, Maska                       ; Vynulování nedefinovaných bitů
    cmp     ax, Test_1                      ; Test inicializační hodnoty
    jne     No_NPU                          ; Nesouhlasí, skoč ...

    not     ax                              ; Negace bitů stav. slova NK
    mov     word ptr cs:[Control], ax
    fldcw   word ptr cs:[Control]           ; Vložení hodnoty do stav.slova NK
    fstcw   word ptr cs:[Control]           ; Uložení stav.slova NK do RAM
    fwait                                   ; Synchronizace
    mov     ax, word ptr cs:[Control]
    and     ax, Maska                       ; Vynulování nedefinovaných bitů
    cmp     ax, Test_2                      ; Test hodnoty
    jne     No_NPU                          ; Nesouhlasí, skoč ...

    or      ax, 1000000000000000B           ; Nastav identifikační bit.

;             ------------ NPU OK -------------
 NPU_OK:
    stc                                     ; CF = 1
    retn                                    ; Návrat NEAR

__detect_npu   ENDP








;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura zjistí pomocí služeb BIOSu
;  --------------    základní informace o HDD.
;
;  Volání(např.) :   mov     dl, 80h                 ; HDD 'C:'
;  --------------    call    __info_hdd              ; Základní informace o HDD
;
;  Výstup        :   CH = Max. číslo stopy (10.bit.hodnota, horní dva bity v CL)
;  --------------    CL = Max. číslo sektoru
;                    DH = Max. číslo hlavičky
;                    DL = Počet připojených pevných disků na prvním řadiči
;
;                    Je-li CF=1, pak nastala chyba
;                    AH = Stav operace
;
;  Mění registry :   Flags, AX, CX
;  --------------
;
;---------------------------------------------------------------------------

__info_hdd PROC  NEAR

    mov     ah, 08h                         ; Načti parametry HDD
    int     13h
    retn                                    ; Návrat NEAR

__info_hdd ENDP








;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje typ HDD.
;  --------------    Předpokladem je, že je disk na AT Busu (IDE).
;                    Počet bajtů na sektoru je standartně 512.
;                    Výpočet fyzické velikosti disku (počet neformátovaných
;                    bajtů na cylindru + neformátovaných bajtů na sektoru +
;                    synchronizační bajty + adr. + CRC součty atd. ...)
;                    Podle Programátorské Perličky BAJT 10/92 str.132
;
;                    Cylindry * Hlavy * Sektory na Cylindru * Bajty na stopu = Kapacita HDD disku
;
;  Volání(např.) :   call    __hdd_type              ; Test na přítomnost HDD
;  --------------
;
;  Výstup        :   ES:DI = Tabulka parametrů HDD
;  --------------
;
;  Mění registry :   AX, CX, DX, DI, ES
;  --------------
;
;---------------------------------------------------------------------------

 __hdd_type  PROC  NEAR

     pushf                                   ; Ulož FLAGs
     push    ds                              ; Ulož reg.
     cli                                     ; Zakaž Externí přerušení
     mov     ax, cs
     mov     ds, ax                          ; DS <= CS
     mov     es, ax                          ; ES <= CS

     mov     al, 00000100B                   ; Příkaz pro RESET disku
     mov     dx, word ptr [&__hdd_digital_output]    ; Reg.   pro RESET disku
     out     dx, al                          ; RESET disku
     xor     al, al                          ; Příkaz pro shození RESETu
     out     dx, al                          ; odRESETování disku

     mov     dx, word ptr [&__hdd_comand_status]     ; Adr. řadiče-COMMAND/STATUS port
 Test_Busy:
     in      al, dx                          ; Čtení STATUSu po RESETu disku
     test    al, 10000000B                   ; Test, zda-li je disk BUSY
     jnz     Test_Busy                       ; Pokud je disk BUSY, skoč ...

     cld                                     ; Směr plnění řetězce
     mov     di, OFFSET &__hdd_type          ; Adr.kam budou ukládány data HDD
     push    di                              ; Ulož adr. Tabulky HDD
     mov     cx, 0080h                       ; Velikost tabulky
     mov     dx, word ptr [&__hdd_comand_status]     ; Adr. řadiče-COMMAND/STATUS port
     mov     al, 0ECh                        ; Řídící bajt pro získání parametrů
     out     dx, al                          ; Zapsání příkazu do portu

 Test_DRQ:
     in      al, dx                          ; Čtení STATUSU
     test    al, 00001000B                   ; Test na připravenost dat - DRQ
     jz      Test_DRQ                        ; Pokud nejsou data připravena, skoč ...
     push    dx                              ; Ulož reg.
     mov     dx, word ptr [&__hdd_data_register]     ; Adr. DATA portu
     in      ax, dx                          ; Přečtení dat z portu
     pop     dx                              ; Obnova reg. DX
     stosw                                   ; Ulož parametr do tabulky
     loop    Test_DRQ                        ; Naplň celou tabulku

     mov     al, 00000100B                   ; Příkaz pro RESET disku
     mov     dx, word ptr [&__hdd_digital_output]    ; Reg.   pro RESET disku
     out     dx, al                          ; RESET disku
     xor     al, al                          ; Příkaz pro shození RESETu
     out     dx, al                          ; odRESETování disku

     pop     di                              ; Obnov adr. Tabulky HDD
     pop     ds                              ; Obnov reg.
     popf                                    ; Obnov FLAGs
     retn                                    ; Návrt NEAR

 __hdd_type ENDP







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost MOUSE. Je-li instalována,
;  --------------    nastaví její souřadnice na řádek a sloupec č.1.
;
;  Volání(např.) :   call    __detect_mouse          ; Test na přítomnost mouse
;
;  Výstup        :   CF = 1  Je instalován ovladač MOUSE
;  --------------    CF = 0  Není instalován ovladač ...
;                    BX =    Počet tlačítek v GM
;
;  Mění registry :   Flags, AX, BX, CX, DX, ES
;  --------------
;
;-----------------------------------------------------------------------------

 __detect_mouse  PROC  NEAR

     mov     ax, 3533h                       ; Zjisti adresy INT 33h
     int     21h
     mov     ax, es
     or      ax, bx                          ; Je výsledek nula ?
     jz      No_MOUSE                        ; Ano, skoč ...

     xor     ax, ax                          ; RESET MOUSE
     int     33h
     or      ax, bx                          ; Je výsledek nula ?
     jz      No_MOUSE                        ; Ano, skoč ...

     mov     ax, 04h                         ; Nastav Mouse na novou souřadnici
     xor     cx, cx                          ; Sloupec
     mov     dx, cx                          ; Řádek
     int     33h
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 No_MOUSE:
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 __detect_mouse  ENDP







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost CR-ROM jednotky.
;  --------------    Program je napsán podle Progromátorské Perličky v
;                    časopise BAJT Leden 1994, str. 139
;
;  Volání(např.) :   mov     cl, 'E'                 ; Jméno testovaného disku
;  --------------    call    __detect_cdrom          ; Test na přítomnost CR-ROM
;
;  Výstup        :   CF = 1  Testovaný disk je CD-ROM
;  --------------    CF = 0  Testovaný disk není CD-ROM
;
;  Mění registry :   Flags, AX, BX, CX
;  --------------
;
;---------------------------------------------------------------------------

 __detect_cdrom  PROC  NEAR

     xor     bx, bx                          ; Připrav návratovou hodnotu
     mov     ax, 1500h                       ; Je přítomen MSCDEX nebo jeho ekvivalent ?
     int     2Fh                             ; Volej obslužné přerušení
     mov     ax, bx                          ; Ulož návratový kód
     or      ax, ax                          ; Pokud BX = 0 není MSCDEX instalován
     jz      No_CDROM                        ; Konec ...

     mov     ax, 150Bh                       ; API pro MSCDEX: check drive
     sub     cl, 'A'                         ; CL vstup.hodnota. Jméno disku A-Z
     mov     ch, 0                           ; Požadované je binární jméno A:=0, B:=1, ...
     int     2Fh                             ; Volej obslužné přerušení
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 No_CDROM:
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 __detect_cdrom  ENDP







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost RAMdisku.
;  --------------    Program je napsán podle Progromátorské Perličky v
;                    časopise BAJT Leden 1994, str. 139
;
;  Volání(např.) :   mov     cl, 'E'                 ; Jméno testovaného disku
;  --------------    call    __detect_ramdisk        ; Test na přítomnost RAMdisku
;
;  Výstup        :   CF = 1  Testovaný disk je RAM-DISK
;  --------------    CF = 0  Testovaný disk není RAM-DISK
;
;  Mění registry :   Flags, AX, BX, CX, DX
;  --------------
;
;---------------------------------------------------------------------------

 __detect_ramdisk   PROC  NEAR

     push    ds                              ; Ulož reg.
     mov     ah, 32h                         ; Nedokumentovaná funkce
     mov     dl, cl                          ; Jméno disku ve tvaru A-Z
     sub     dl, 'A'-1                       ; Binární jméno (1='A')
     int     21h                             ; Volej složby DOSu
     xor     ax, ax                          ; Připrav návratovou hodnotu
     cmp     byte ptr [bx+08], 1             ; Testuj počet FAT tabulek.
                                             ; DS je vrácen z volání DOSu
     je      No_RAMdisk                      ; Pokud je jen jedna tab.skoč
     pop     ds                              ; Obnov reg.
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 No_RAMdisk:
     pop     ds                              ; Obnov reg.
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 __detect_ramdisk  ENDP







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost VGA adaptéru.
;  --------------
;
;  Volání(např.) :   call    __detect_vga            ; Test na přítomnost VGA
;  --------------
;
;  Výstup        :   CF = 1  VIDEO-karta je kompatibilní s VGA
;  --------------    CF = 0  VIDEO-karta není kompatibilní s VGA
;
;  Mění registry :   Flags, AX
;  --------------
;
;---------------------------------------------------------------------------

 __detect_vga   PROC  NEAR

     jnz     Test_Busy                       ; Pokud je disk BUSY, skoč ...
     mov     ax, 1A00h                       ; Načti kombinaci adaptér/monitor
      int     10h

     cmp     al, 1Ah                         ; Je služba podporována
     jne     No_VGA                          ; Ne, skoč ...
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 No_VGA:
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 __detect_vga  ENDP







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost EGA adaptéru.
;  --------------
;
;  Volání(např.) :   call    __detect_ega            ; Test na přítomnost EGA
;  --------------
;
;  Výstup        :   CF = 1  Je instalováno EGA nebo komtatibilní
;  --------------    CF = 0  Není podporováno EGA
;
;  Mění registry :   Flags, AX, BX
;  --------------
;
;---------------------------------------------------------------------------

 __detect_ega  PROC  NEAR

     mov     ah, 12h
     mov     bl, 10h
     int     10h

     cmp     bl, 3
     jbe     OK_EGA
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 OK_EGA:
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 __detect_ega  ENDP







;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje přítomnost VESA BIOSu.
;  --------------
;
;  Volání(např.) :   call    __detect_vesa           ; Test na přítomnost VESA BIOS
;  --------------
;
;  Výstup        :   CF = 1  BIOS podporuje standart VESA
;  --------------    CF = 0  VESA BIOS není podporován
;                    ES:DI   Informační blok o VESA BIOSu (256 bajtů)
;
;  Mění registry :   Flags, AX, CX, DI, ES
;  --------------
;
;---------------------------------------------------------------------------

 __detect_vesa  PROC  NEAR

     mov     cx, 3                           ; 3x opakuj pokus

 INIT_VESA:
     mov     di, OFFSET VESA_INFO
     mov     ax, cs
     mov     es, ax                          ; ES <= CS

     mov     ax, 4F00h                       ; Načti informační blok
     int     10h
     cmp     al, 4Fh                         ; Je funkce podporována ?
     je      OK_VESA                         ; Ano, skoč ...
     loop    INIT_VESA                       ; Skus to znova
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 OK_VESA:
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 __detect_vesa  ENDP






;---------------------------------------------------------------------------
;
;  Popis funkce  :   Tato procedura testuje, zda-li je instalován Monochrom
;  --------------    (nebo Hercules) monitor.
;
;  Volání(např.) :   call    __detect_mh_monitor     ; Test na Monochrom & Hercules
;  --------------
;
;  Výstup        :   CF = 1  Je instalován Monochrom nebo Hercules
;  --------------    CF = 0  Není Hercules ani Monochrom
;
;  Mění registry :   Flags, AX
;  --------------
;
;---------------------------------------------------------------------------

 __detect_mh_monitor    PROC  NEAR

;           --- Test na Monochrom nebo Hercules pomocí INT 11h ---
     int    11h                              ; Zjisti konfiguraci systému
     and    ax, 0000000000110000B
     cmp    ax, 0000000000110000B            ; Je režim MONOCHROM nebo Herc. ?
     je     Ok_Herc                          ; Ano, skoč ...

;           ------------ Konec - Výstupní hlášení -------------
     clc                                     ; CF = 0
     retn                                    ; Návrt NEAR

 Ok_Herc:
     stc                                     ; CF = 1
     retn                                    ; Návrt NEAR

 __detect_mh_monitor  ENDP




Knihovna_NST32  ENDS
END
		



© Copyright 1992-2008 by Zdeněk MEDO jr.