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