Timer systemowy
Timer systemowy zawarty w każdym komputerze PC, generuje standardowo 18,2 razy na sekunde
przerwanie programowe 1CH. Aby je praktycznie wykorzystać (np: w grze), musimy się pod nie
podpiąć zamieniając oryginalny adres procedury przerwania 1CH na adres naszej procedurki.
Aby to zrobić możemy użyć funkcji DOS'a: 25H i 35H. Pierwsza z nich umożliwia zapis wektora
(adresu) procedury przerwania w tablicy przerwań, druga umożliwa odczyt tego adresu.
Ponieważ po zakończeniu programu który przejąłby przerwanie, ustawione przez niego procedury
przerwan nadal działają (co doprowadza do zawieszenia komputera), musimy pod koniec pracy
programu przywrócic adres oryginalnej procedury obsługi przerwania 1CH. Dlatego też ogólny
schemat działania programu wygląda następująco:
1) pobierz adres oryginalnej procedury obsługi przerwania 1CH
2) podepnij nową procedure
3) wykonuj program
4) przywróc starą procedure
Uwaga ! Jeżeli w procedurze obsługi dowolnego przerwania zamierzasz korzystać ze zmiennych
dostępnych dla całego programu wtedy musisz sie do nich odwołać przez rejestr CS, np:
MOV BYTE [CS:zmienna],10
To będzie na tyle teori, oto przykładowy kod (NASM). Program po uruchomieniu będzie wkołko
wyświetlał napis Timer co taki sam odcinek czasu.
przerwanie programowe 1CH. Aby je praktycznie wykorzystać (np: w grze), musimy się pod nie
podpiąć zamieniając oryginalny adres procedury przerwania 1CH na adres naszej procedurki.
Aby to zrobić możemy użyć funkcji DOS'a: 25H i 35H. Pierwsza z nich umożliwia zapis wektora
(adresu) procedury przerwania w tablicy przerwań, druga umożliwa odczyt tego adresu.
Ponieważ po zakończeniu programu który przejąłby przerwanie, ustawione przez niego procedury
przerwan nadal działają (co doprowadza do zawieszenia komputera), musimy pod koniec pracy
programu przywrócic adres oryginalnej procedury obsługi przerwania 1CH. Dlatego też ogólny
schemat działania programu wygląda następująco:
1) pobierz adres oryginalnej procedury obsługi przerwania 1CH
2) podepnij nową procedure
3) wykonuj program
4) przywróc starą procedure
Uwaga ! Jeżeli w procedurze obsługi dowolnego przerwania zamierzasz korzystać ze zmiennych
dostępnych dla całego programu wtedy musisz sie do nich odwołać przez rejestr CS, np:
MOV BYTE [CS:zmienna],10
To będzie na tyle teori, oto przykładowy kod (NASM). Program po uruchomieniu będzie wkołko
wyświetlał napis Timer co taki sam odcinek czasu.
;------- CPU 186 BITS 16 ORG 100H JMP main timer_int: ; procedura obslugi przerwania 1CH STI MOV BYTE [CS:can_print],1 ; ustaw zmienna can_print na 1 CLI IRET install_timer: MOV AX,351CH ; pobierz adres starej procedury INT 21H ; przerwania 1CH i wrzuc go do MOV [CS:old_timer_int],BX ; zmiennej old_timer_int (ES:BX) MOV [CS:old_timer_int + 2],ES MOV AX,251CH ; ustaw nowa procedure MOV DX,timer_int ; laduj jej adres do DS:DX PUSH DS PUSH CS POP DS INT 21H POP DS RET remove_timer: MOV AX,251CH ; przywroc stara procedure LDS DX,[CS:old_timer_int] INT 21H RET main: CALL install_timer ; instaluj timer main_loop: CMP BYTE [can_print],1 ; jezeli can_print = 1 JNE main_loop ; to wyswietl napis "Timer" MOV BYTE [can_print],0 PUSH DS PUSH CS POP DS MOV DX,timer_text MOV AH,09H INT 21H POP DS JMP main_loop exit: CALL remove_timer ; usun timer (tu nie dojdzie nigdy) MOV AX,4C00H INT 21H old_timer_int DD 0 timer_text DB 'Timer',10,13,'$' can_print DB 0 ;-------
Kategoria: Z pogranicza
3 komentarze
a co jeśli podczas wykonywania programu wystąpi błąd krytyczny i się on wyłączy. Czy wtedy system zawiesi się całkiem, czy przywróci może właściwe "ustawienia" timera ??
to zalezy pewnie od tego co będzie zawierała procedurka timera, jak nie bedzie operowac na duzych zmiennych itp, to pewnie nic sie nie stanie, a w przeciwnym wypadku to reset i po klopocie , zreszta problem dotyczy tylko czystego dosa :P
Dodałem kolorowanie składni :-)