TITLE "PC_HW" Procedury přistupující na HW počítače ...
.8086 ; Linkuje se pro 80 86
PAGE 67, 130 ; Stránka 67 zn., délka 130 zn./řádek
COMMENT @
===========================================================================
Název souboru : PC_HW.ASM
Link OBJ & LIB : PC_HW.ZIP
Datum úprav : 01.09.97
Verze programu : 4.00
(c) Copyright : 1992,97 by NST 32 , Medo Zdeněk junior
===========================================================================@
Knihovna_NST32 SEGMENT BYTE PUBLIC 'CODE' USE16
ASSUME CS:Knihovna_NST32
PUBLIC __new_speed_irq_0 ; EXTRN __new_speed_irq_0 :PROC :NEAR
PUBLIC __read_speed_irq_0 ; EXTRN __read_speed_irq_0 :PROC :NEAR
PUBLIC __irq_off_m ; EXTRN __irq_off_m :PROC :NEAR
PUBLIC __irq_on_m ; EXTRN __irq_on_m :PROC :NEAR
PUBLIC __irq_eof_m ; EXTRN __irq_eof_m :PROC :NEAR
PUBLIC __irq_off_s ; EXTRN __irq_off_s :PROC :NEAR
PUBLIC __irq_on_s ; EXTRN __irq_on_s :PROC :NEAR
PUBLIC __irq_eof_s ; EXTRN __irq_eof_s :PROC :NEAR
PUBLIC __cmos_read ; EXTRN __cmos_read :PROC :NEAR
PUBLIC __cmos_write ; EXTRN __cmos_write :PROC :NEAR
PUBLIC __pause_ms_hw ; EXTRN __pause_ms_hw :PROC :NEAR
PUBLIC __cpu_pause ; EXTRN __cpu_pause :PROC :NEAR
PUBLIC __read_cmos ; EXTRN __read_cmos :PROC :NEAR
PUBLIC __write_cmos ; EXTRN __write_cmos :PROC :NEAR
; -------------------------------------
; - Tabulka parametrů CMOS -
; -------------------------------------
; ------------ Reálný čas -------------
; 00 h - Sekundy reálných hodin
; 01 h - Sekundy budíku
; 02 h - Minuty reálného času
; 03 h - Minuty budíku
; 04 h - Hodiny reálného času
; 05 h - Hodiny budíku
;
; 06 h - Den reálného času v týdnu (1=Neděle)
; 07 h - Den reálného času v měsíci
; 08 h - Měsíc reálného času
; 09 h - Rok reálného času
;
; 0A h - 10100110B 'Stavový registr A hodin reálného času
; ||-||--|
; | | |---> Dělící činitel (0110) pro děličku kmitočtu generátoru
; | | impulsů (0110 určuje frekvenci 1024 kHz a přerušovací
; | | čas 976,562 mikrosekund.
; | |
; | |-------> 22-stupňová dělička (010) nastavuje základní frekvenci
; | čítače hodin reálného času (010 je 32,768 kHz základna)
; |
; |----------> Interní blokování (0=povolen přístup k hodinám)
;
; 0B h - 00000110B 'Stavový registr B hodin reálného času
; ||||||||
; ||||||||---> Změna na letní čas (počáteční nastavení 0=standartní
; ||||||| čas - bez změny na letní čas, 1=přechod na letní čas -
; ||||||| poslední neděli v dubnu dojde k posunu času z 1:59 na
; ||||||| 3:00 a poslední neděli v říjnu přejde čas z 1:59 na 1:00)
; |||||||
; |||||||----> 12-hodinový nebo 24-hodinový cyklus (počáteční
; |||||| nastavení je 1=24hod.cyklus)
; ||||||
; ||||||-----> BCD kód (počáteční nastavení 1=BCD)
; |||||
; |||||------> Generátor impulsů (počáteční nastavení 0=vypnuto)
; ||||
; ||||-------> Generace přerušení při zápisu auktalizovaného
; ||| času (počáteční nastavení 0=vypnuto)
; |||
; |||--------> Přerušení od budíku (počáteční nastavení 0=vypnuto)
; ||
; ||---------> Periodické přerušení (počáteční nastavení 0=vypnuto),
; | frekvence přerušení je nastavitelná v registru A, bity.0-3
; |
; |----------> Interní blokování (počáteční nastavení 0=povolen
; přístup k hodnotám)
;
; 0C h - 00000000B 'Stavový registr C hodin reálného času
; |---||-|
; | |---> Nevyužito
; |
; |------> Jednotlivá návěstí pro přerušení (IRQF - přerušení
; povoleno, PF-pčerušení od čítače, AF-přerušení od
; budíku, UF-přerušení po modifikaci)
;
;
; 0D h - 10000000B 'Stavový registr D hodin reálného času
; ||-----|
; | |---> Nevyužito
; |
; |----------> Informace RTC jsou platné (stav 1), stav 0 indikuje
; poruchu v napájení RTC
; ------------- Konfigurační informace -------------
; 0E h - 00000000B 'POST (Power On Self Test) diagnostická informace
; ||||||-|
; |||||| |---> Nevyužito
; ||||||
; ||||||-----> POST kontrola generátoru reálného času:
; ||||| 0 - Reálný čas je platný
; ||||| 1 - Reálný čas je neplatný
; |||||
; |||||------> Kontrola inicializace pevného disku:
; |||| 0 - Inicializace proběhla správně
; |||| 1 - Inicializace neproběhla správně
; ||||
; ||||-------> Změna velikosti paměti při POST:
; ||| 0 - velikost paměti souhlasí s nastavenou hodnotou
; ||| 1 - velikost paměti nesouhlasí s nastavenou hodnotou
; |||
; |||--------> Platnost nastavení konfigurace:
; || 0 - POST proběhl správně
; || 1 - POST neproběhl správně
; ||
; ||---------> Kontrolní součet CMOS RAM:
; | 0 - kontrolní součet je platný
; | 1 - kontrolní součet je neplatný
; |
; |----------> Kontrola napájení RTC:
; 0 - RTC je napájen
; 1 - výpadek napájení RTC
; 0F h - Diagnostika pro Reset (ShutDown), jednotlivé informační bity
; tvoří hodnotu, která definuje důvod restartu a následnou činnost:
; 0 - Teplý restart systému (Ctrl-Alt-Del), POST se neprovede
; 1 - Restart po definování velikosti paměti
; 2 - Restert po provedení testu paměti
; 3 - Restart po chybě parity (parita 1 nebo 2)
; 4 - Restart s požadavkem startu Loaderu
; 5 - Restart s interní kontrolou a dlouhým skokem na adr. 0467h
; 6,7,8 - Restart po provedení testu chráněného režimu procesoru
; 9 - Restart po provedení blokového přenosu z Extended paměti, resp.
; do Extended paměti
; 10 - Restart po návratu z chráněného režimu, přímý dlouhý skok
; na adresu 0467h
; ------------- Disketové jednotky -------------
; 10 h - 00000000B Typ instalovaných disketových jednotek
; |--||--|
; | |---> Typ druhé disketové jednotky (tab.disket 1)
; |
; |-------> Typ první disketové jednotky (tab.disket 1)
; tab.disket 1: 0000 Jednotka není instalována
; 0001 48 TPI, 2 str., 40 stop, 9 sekt., 360 KB
; 0010 96 TPI, 2 str., 80 stop, 15 sekt., 1,2 MB
; 0011 96 TPI, 2 str., 80 stop, 9 sekt., 720 KB
; 0100 135 TPI, 2 str., 80 stop, 18 sekt., 1,44 MB
; 0101-1111 Rezervováno
; ------------- Harddisky -------------
; 11 h - Rezervováno
; 12 h - 00000000B Typ pevného disku
; |--||--|
; | |---> Typ prvního pevného disku (tab.hdd 1)
; |
; |-------> Typ druhého pevného disku (tab.hdd 1)
; Poznámka: Tabulka byla porvrzena později, proto může nastat
; situace,že některé typy ROM BIOS mají tabulku disků
; dosti odlišnou. Tato tabulka je firemní IBM.
; (PC/AT Technical Reference, 1984)
; Byty Typ Stop Hlav WRPc Land Kapacita
; tab.hdd 1: 0000 --- Disk není instalován ---
; 0001 1 306 4 128 305 10.6 MB
; 0010 2 615 4 300 615 21.4 MB
; 0011 3 515 6 300 615 32.1 MB
; 0100 4 940 8 512 940 65.4 MB
; 0101 5 940 6 512 940 49.0 MB
; 0110 6 615 4 --- 615 21.4 MB
; 0111 7 462 8 256 511 32.1 MB
; 1000 8 733 5 --- 733 31.9 MB
; 1001 9 900 15 --- 901 117.5 MB
; 1010 10 820 3 --- 820 21.4 MB
; 1011 11 855 5 --- 855 37.2 MB
; 1100 12 855 7 --- 855 52.0 MB
; 1101 13 306 8 128 319 21.3 MB
; 1110 14 733 7 --- 733 44.4 MB
; 1111 15 - Odkaz na další typy disků -
; ------------- Informace o instalovaném vybavení -------------
; 13 h - Rezervováno
; 14 h - 00000000B 'Informace o instalovaném vybavení
; -|-|-|||
; | | |||----> Bit přítomnosti disketových jednotek
; | | || 0 - jednotky nejsou instalovány
; | | || 1 - jednotky jsou instalovány
; | | ||
; | | ||-----> Bit přítomnosti matematického koprocesoru
; | | | 0 - koprocesor není instalován
; | | | 1 - koprocesor je instalován
; | | |
; | | |------> Nevyužito
; | |
; | |
; | |
; | |--------> Primární VIDEO-adaptér
; | 00 - Rezervováno (grafické adaptéry s mapováním
; | video-paměti, EGA,PGA,VGA atd.)
; | 01 - CGA v textovém režimu 40x25
; | 10 - CGA v textovém režimu 80x25
; | 11 - MDA (monochrom nebo Hercules)
; |
; |----------> Počet instalovaných disketových jednotek
; 00 - Je instalována jedna mechanika
; 01 - Jsou instalovány dvě mechaniky
; 11 - rezervováno
; ------------- Velikost paměti -------------
; 15 h - Vel.základní operační paměti (LO bajt)
; 16 h - Vel.základní operační paměti (HI bajt)
; Poznámka: Platné jsou pouze tyto velikosti paměti:
; 0100h - 256 KB systémové paměti
; 0200h - 512 KB systémové paměti
; 0280h - 640 KB systémové paměti
; 17 h - Vel.rozšířující paměti (LO bajt)
; 18 h - Vel.rozšířující paměti (HI bajt)
; Poznámka: Platné jsou pouze náaobky 512KB
; ------------- Harddisky -------------
; 19 h - 00000000B Typ pevného disku čílo I - vyšší než 14 (Tabulka II.)
; ... volné
; 1A h - 00000000B Typ pevného disku čílo II - vyšší než 14 (Tabulka II.)
; Bajt Typ Stop Hlav WRPc Land Kapacita
; tab.hdd 2: 00h 16 612 4 --- 633 20.3 MB
; 01h 17 612 5 300 977 40.5 MB
; 02h 18 977 7 --- 977 56.7 MB
; 03h 19 1024 7 512 1023 59.5 MB
; 04h 20 733 5 300 732 30.4 MB
; 05h 21 733 7 300 732 42.5 MB
; 06h 22 733 5 300 733 30.4 MB
; 07h 23 306 4 0 336 10.1 MB
; Poznámka: Tato tabulka byla dodávána s ROM BIOSem dodáváným k
; 15.11.1985. Další doplňky již nejsou standartní pro PC/AT,
; ale byly dodávány s prvnímy modely IBM PS/2.
; ------------- Pomocné záznamy -------------
; 1B h až 2D h - Rezervováno
; 2E h - Kontrolní součet (word) adr.10h-20h (HI bajt)
; 2F h - Kontrolní součet (word) adr.10h-20h (LO bajt)
; 30 h - (LO) Fyzicky nalezená velikost rozšiřující paměti v POST -
; 31 h - (HI) - s touto velikosí počítají všechny funkce BIOSu (INT 15)
; 32 h - BCD datum století pro čtení a zápis pomocí funkce BIOS
; 33 h - 00000000B ' Dodatečné informace
; ||-----|
; | |--> Použito pro SETUP proceduru
; |
; |---------> Instalováno rozšíření IBM 128 KB RAM
; 0 - Rozšíření neinstalováno
; 1 - Rozšíření instalováno
; 34 h až 3F h - Nevyužito IBM, u jiných výrobců BIOSu využíváno
; pro zápis hesla
;-----------------------------------------------------------------------------
;
; Popis funkce : Nastav rytchlost IRQ 0 - Timer INT 8
; ---------------- Procedura změní rychlost pro HW generování IRQ 0
;
; Volání (např.) : mov ax, SPEED ; 1 193 182 Hz / AX = xxx Hz
; ---------------- call __new_speed_irq_0 ; Nastav novou rychlost INT 8
;
; Mění registry : AX
; ----------------
;
;-----------------------------------------------------------------------------
__new_speed_irq_0 PROC NEAR
pushf ; Ulož Flags
cli ; Zakaž externí přerušení
push ax ; Ulož reg.
mov al, 11111111B ; Všechna IRQ
call __irq_off_m ; Vypni vybraná IRQ [AT Master]
mov al, 34h ; Nastavení děliče Timeru 0
out 43h, al
call __cpu_pause ; Časová prodleva CPU (5x JMP $+2)
pop ax ; LO dělitel frekvence
out 40h, al
call __cpu_pause ; Časová prodleva CPU (5x JMP $+2)
xchg ah, al ; HI dělitel frekvence
out 40h, al
call __cpu_pause ; Časová prodleva CPU (5x JMP $+2)
call __irq_on_m ; Obnov původní masku IRQ [AT Master]
call __irq_eof_m ; Konec IRQ [AT Master]
popf
retn ; Návrat NEAR
__new_speed_irq_0 ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Přečti rychlost generování IRQ 0 na HW časovači ...
; ---------------- POZOR ! výsledek není přesný !!!
;
; Volání (nař.) : call __read_speed_irq_0 ; Čti stvající rychlost INT 8
; ---------------- mov ax, SPEED ; 1 193 182 Hz / AX = xxx Hz (+/- 1%)
;
; Mění registry : AX CX DX
; ----------------
;
;-----------------------------------------------------------------------------
__read_speed_irq_0 PROC NEAR
pushf ; Ulož Flags
cli ; Zakaž externí přerušení
mov al, 11111111B ; Všechna IRQ
call __irq_off_m ; Vypni vybraná IRQ [AT Master]
xor dx, dx
xor cx, cx
mov al, 00000110B ; Nastavení děliče Timeru 0
out 43h, al
Cti_IRQ_0:
in al, 40h ; Čti LO bajt
mov ah, al
in al, 40h ; Čti HI bajt
cmp ax, dx ; Je AX <= DX ?
jbe SM_OK ; Ano, skoč ...
xchg dx, ax ; Nastav novou (vyšší hodnotu časovače)
SM_OK:
loop Cti_IRQ_0
mov ax, dx ; Hodnota časovače do AX
xchg ah, al
call __irq_on_m ; Obnov původní masku IRQ [AT Master]
call __irq_eof_m ; Konec IRQ [AT Master]
popf
retn ; Návrat NEAR
__read_speed_irq_0 ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Vypne genrování vybranśch IRQ
; ----------------
;
; Volání (např.) : mov al, 00000000B ; Maska IRQ (AT Master)
; ---------------- ||||||||
; |||||||+> IRQ 0 = Systémový časovač
; ||||||+-> IRQ 1 = Klávesnice
; |||||+--> IRQ 2 = Druhý řadič IRQ (AT Slave)
; ||||+---> IRQ 3 = COM 2
; |||+----> IRQ 4 = COM 1
; ||+-----> IRQ 5 = LPT 2
; |+------> IRQ 6 = Flopy Disk
; +-------> IRQ 7 = LPT 1
;
; call __irq_off_m ; Vypni vybraná IRQ [AT Master]
;
; Výstup : BL = Původní maska
; ----------------
;
; Mění registry : BX
; ----------------
;
;-----------------------------------------------------------------------------
__irq_off_m PROC NEAR
pushf ; Ulož Flags
push ax
in al, 21h ; Načti IRQ masku
mov bl, al ; Ulož masku
cli ; Zakaž externí přerušení
pop ax
out 21h, al ; Vybraná IRQ
call __irq_eof_m ; Konec IRQ [AT Master]
popf ; Obnov Flags
retn ; Návrat NEAR
__irq_off_m ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Zapne IRQ vypnuté předešlou funkcí __irq_irq_off_m.
; ----------------
;
; Volání (např.) : mov bl, 00000000B ; Maska IRQ (AT Master)
; ---------------- ||||||||
; |||||||+--------> IRQ 0 = Systémový časovač
; ||||||+---------> IRQ 1 = Klávesnice
; |||||+----------> IRQ 2 = Dryhý řadič IRQ (AT Slave)
; ||||+-----------> IRQ 3 = COM 2
; |||+------------> IRQ 4 = COM 1
; ||+-------------> IRQ 5 = LPT 2
; |+--------------> IRQ 6 = Flopy Disk
; +---------------> IRQ 7 = LPT 1
; call __irq_on_m ; Zapni vybraná IRQ [AT Master]
;
;-----------------------------------------------------------------------------
__irq_on_m PROC NEAR
pushf ; Ulož Flags
cli ; Zakaž externí přerušení
push ax
mov al, bl ; Nová (původní) maska
out 21h, al ; Zapni IRQ
call __irq_eof_m ; Konec IRQ [AT Master]
pop ax
popf ; Ovnov Flags
ret ; Návrat
__irq_on_m ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Vyšle signál na řadič IRQ o připravenosti na další
; ---------------- IRQ.
;
; Volání (např.) : call __irq_eof_m ; Konec IRQ [AT Master]
; ----------------
;
;-----------------------------------------------------------------------------
__irq_eof_m PROC NEAR
push ax
mov al, 20h ; Resetuj řadič ...
out 20h, al
pop ax
retn ; Návrat NEAR
__irq_eof_m ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Vypne genrování vybraných IRQ (z druhého řadiče)
; ----------------
;
; Volání (např.) : mov al, 00000000B ; Maska IRQ (AT Slave)
; ---------------- ||||||||
; |||||||+--------> IRQ 8 = Real-Time Clock
; ||||||+---------> IRQ 9 = Redirected to INT 0Ah
; |||||+----------> IRQ A = Reserved
; ||||+-----------> IRQ B = Reserved
; |||+------------> IRQ C = Reserved
; ||+-------------> IRQ D = Math Coprocessor
; |+--------------> IRQ E = Hard Disk Controller
; +---------------> IRQ F = Reserved
; call __irq_off_s ; Vypni vybraná IRQ (z druhého řadiče)
;
; Výstup : BL = Původní maska
; ----------------
;
; Mění registry : BX
; ----------------
;
;-----------------------------------------------------------------------------
__irq_off_s PROC NEAR
pushf ; Ulož Flags
push ax
in al, 0A1h ; Načti IRQ masku
mov bl, al ; Ulož masku
cli ; Zakaž externí přerušení
pop ax
out 0A1h, al ; Vybraná IRQ
call __irq_eof_s ; Konec IRQ [AT Slave]
popf ; Obnov Flags
retn ; Návrat NEAR
__irq_off_s ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Zapne IRQ (druhého řadiče) vypnuté předešlou
; ---------------- funkcí __irq_irq_off_s.
;
; Volání (např.) : mov bl, 00000000B ; Maska IRQ (AT Slave)
; ---------------- ||||||||
; |||||||+--------> IRQ 8 = Real-Time Clock
; ||||||+---------> IRQ 9 = Redirected to INT 0Ah
; |||||+----------> IRQ A = Reserved
; ||||+-----------> IRQ B = Reserved
; |||+------------> IRQ C = Reserved
; ||+-------------> IRQ D = Math Coprocessor
; |+--------------> IRQ E = Hard Disk Controller
; +---------------> IRQ F = Reserved
; call __irq_on_s ; Zapni vybraná IRQ (z druhého řadiče)
;
;-----------------------------------------------------------------------------
__irq_on_s PROC NEAR
pushf ; Ulož Flags
cli ; Zakaž externí přerušení
push ax
mov al, bl ; Nová (původní) maska
out 0A1h, al ; Zapni IRQ
call __irq_eof_s ; Konec IRQ [AT Slave]
pop ax
popf ; Ovnov Flags
ret ; Návrat
__irq_on_s ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Vyšle signál na řadič IRQ (druhého řadiče) o
; ---------------- připravenosti.
;
; Volání (např.) : call __irq_eof_s ; Konec IRQ (druhého řadiče)
; ----------------
;
;-----------------------------------------------------------------------------
__irq_eof_s PROC NEAR
push ax
mov al, 020h ; Resetuj řadič ...
out 0A0h, al
pop ax
retn ; Návrat NEAR
__irq_eof_s ENDP
;---------------------------------------------------------------------------
;
; Popis funkce : Tato procedura přečte vybraný bajt z CMOS paměti
; --------------
;
; Volání(např.) : mov al, Adr. ; Adr.v CMOS pro výběr bajtu
; -------------- call __read_cmos ; Přečti data z CMOS
;
; Výstup : AL = Obsah vloženého paměťového místa
; --------------
;
; Mění registry : Flags, AX
; --------------
;
;---------------------------------------------------------------------------
__read_cmos PROC NEAR
out 70h, al ; Vyber adresu v AL
call __cpu_pause ; Časová prodleva CPU (5x JMP $+2)
in al, 71h ; Načti do AL z bajt z CMOSky
retn ; Návrat NEAR
__read_cmos ENDP
;---------------------------------------------------------------------------
;
; Popis funkce : Tato procedura zapíše vybraný bajt z CMOS paměti
; --------------
;
; Volání(např.) : mov ah, Bajt ; Nový parametr pro CMOS
; -------------- mov al, Adr. ; Adr.v CMOS pro uložení bajtu
; call __write_cmos ; Ulož data do CMOS
;
; Mění registry : Flags, AX
; --------------
;
;---------------------------------------------------------------------------
__write_cmos PROC NEAR
out 70h, al ; Vyber adresu v AL
call __cpu_pause ; Časová prodleva CPU (5x JMP $+2)
xchg ah, al ; Prohoď reg.
out 71h, al ; Ulož bajt do CMOS
retn ; Návrat NEAR
__write_cmos ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Procedura zajistí čekání po danou dobu pomocí HW.
; ----------------
;
; Volání (např.) : mov cx, 510 ; Počet časových intervalů (jeden
; ---------------- ; interval trvá 15.085 737
; ; mikrosekundy). Délka intervalu je
; ; daná vybavovací dobou RAM pamětí.
; call __pause_ms_hw ; Čekej CX x (15.085 737 ms)
;
; Mění registry : Flags
; ----------------
;
;-----------------------------------------------------------------------------
__pause_ms_hw PROC NEAR
push ax cx ; Ulož reg.
in al, 61H ; Načtení stavu portu B
and al, 00010000B ; Maska pro vybavení
mov ah, al ; Uložení nového stavu
Cekej:
in al, 61H ; Načtení stavu portu B
and al, 00010000B ; Maska pro vybavení
cmp al, ah ; Došlo ke změně ?
je Cekej ; Ne, skoč ...
mov ah, al ; Uložení nového stavu
loop Cekej ; Smyčka pro další interval
pop cx ax ; Obnov reg.
retn ; Návrat NEAR
__pause_ms_hw ENDP
;-----------------------------------------------------------------------------
;
; Popis funkce : Procedura zajistí čekání přes instrukci JMP $+2
; ---------------- a to pětkrát.
;
; Volání (např.) : call __cpu_pause ; Časová prodleva CPU (5x JMP $+2)
; ----------------
;
;-----------------------------------------------------------------------------
__cpu_pause PROC NEAR
DB 2Eh ; Zpomal CPU ... [CS:]
jmp $+2 ; Časová prodleva
jmp $+2 ; Časová prodleva
DB 2Eh ; Zpomal CPU ... [CS:]
jmp $+2 ; Časová prodleva
jmp $+2 ; Časová prodleva
DB 2Eh ; Zpomal CPU ... [CS:]
retn ; Návrat NEAR
__cpu_pause ENDP
Knihovna_NST32 ENDS
END