przerwanie 1c i zegar systemowy

0

Witam.

Dostelem taki temat na projekt:

Przestawić zegar systemowy aby przerwanie 1C było zgłaszane co 1ms a zegar komputera nadal zliczał poprawnie.

Niestety nie mam zielonego pojęcia od czego zacząć, może mnie ktos naprowadzić na odpowiednie tory??
Niestety jestem też noga z assemblera no ale to jakos nadgonie tylko mala pomoc potrzebna.

0

calosc zadania ma tu polegac na przyspieszeniu wywolywania przerwania sprzetowego IRQ0 (przerwanie programowe INT 08h). z tego co wyczytałem jest ono wywoływane co 55ms i za każdym razem przy okazji wywołuje ono INT 1Ch. To by oznaczało że musimy przyspieszyc IRQ0 55 razy i podczas wywołań liczyć ile razy już się wykonało: jeżeli mniej niz 55 razy to musimy samodzielnie wywołać INT 1Ch a jeśli wykonało się 55 razy to musimy wywołać oryginalną procedure IRQ0 (które za nas wywoła INT 1Ch podczas tego 55-ego razu).
Aby przyspieszyc IRQ0 musimy przeprogramowac PIT który to jest tworem odpowiedzialnym za ustalenie czestości generowania IRQ0 (tj.to przez niego musimy przyspieszac). Dostep do tegóż mamy przez porty 43h i 40h
oto źródło za pomocą którego możemy przeprogramować PIT i IRQ0 (tj.: oto gotowiec ;) ). Programik jest stworzony pod NASM i do kompilacji do pliku .COM

[org 100h]
push cs  ;tak na zas kopiujemy cs do ds jakby system tego nie zrobil
pop  ds
jmp entry_point

data:
 faster dw 55 ;ile razy przyspieszamy PIT
 ctimes dw 0 ;ilosc naliczonych wywolan naszego IRQ0
 oldIRQ0 dd 0 ;pierwotny adres IRQ0

;;nasza nowa procedura IRQ0
newIRQ0:
 pushf ;zabezpieczmy FLAGS i AX na stosie - bedziemy uzywac tych rejestrow wiec dobrze by bylo zeby nie zniszczyc ich zawartosci
 push ax
nIRQ0_IRQ: ;wlasciwa procedura przerwania
 inc word [ctimes]
 mov ax, [ctimes]
 xor ax, [faster] ;szybsza forma cmp (jesli sprawdzamy warunek rownosci '=' to nie marnujmy czasu na cmp i uzyjmy szybszego a rownie skutecznego xor)
 jnz nIRQ0_end ;jesli nie rowne to do wyjscia z naszego IRQ0
 mov word [ctimes], 0 ;wyzerujmy licznik wywolan
 ;posprzatajmy po sobie
 pop ax
 popf
 ;wywolajmy domyslna procedure IRQ0
 ;(uzylem rozwiazania ktore zapewni nam, ze domyslne IRQ0 juz zakonczy procedure obslugi przerwania zamiast wracac do naszej)
 push dword [oldIRQ0]
 retf ;skocz do oryginajnego IRQ0 - oryginalne IRQ0 juz tu nie wroci (cos na wzor jmp far ktorego jednak nie wszystkie kompilatory lubia tak jak zauwazylem)
nIRQ0_end:
 int 1Ch ;wywolajmy INT 1Ch
 ;powiedzmy kontrolerowi PIC ze zakonczylismy obsluge przerwania IRQ0
 mov al, 20h
 out 20h, al
 ;posprzatajmy po sobie
 pop ax
 popf
 iret ;koniec przerwania

entry_point:
 ;zainstalujmy nasze przerwanie IRQ0 (po drodze robiac kopie obecnego)
 mov ax, 0
 mov es, ax
 mov di, 8 ;numer przerwania INT 08h, ktore chcemy podmienic
 shl di, 2
 mov eax, [es:di] ;32-bitowe rejestry ale adresowanie 16-bitowe
 mov [oldIRQ0], eax ;zabezpieczamy stary wektor przerwania IRQ0
 ;stworzmy w eax nasz wektor przerwania
 mov ax, cs
 shl eax, 16
 lea ax, [newIRQ0]
 cli ;blokada przerwan (bardzo wazne gdyz poki nie przeprogramujemy PIT nasze przerwanie bedzie zle dzialalo!!!)
 mov [es:di], eax ;wstawiamy nasz wektor przerwania
 ;mamy przerwanie, teraz przeprogramujmy PIT
 mov dx, 1
 mov ax, 0
 div word [faster]
 push ax
 mov al, 0x34
 out 0x43, al ;zaznaczmy ze chcemy przeprogramowac PIT
 pop ax
 out 0x40, ax ;ustawmy nowa wartosc dla PIT
 sti ;PIT dziala juz tak jak chcemy wiec odblokujmy przerwania
main: ;nasz wlasciwy program (tu mozna robic juz co chcemy cieszac sie z predkosci - ja zrobilem po prostu czekanie na dowolny klawisz)
 mov ax, 0x1000
 int 0x16
kill: ;koniec programu - trzeba przywrocic PIT i IRQ0 do stanu pierwotnego
 ;przywracamy IRQ0
 mov ax, 0
 mov es, ax
 mov di, 8
 shl di, 2
 mov eax, [oldIRQ0]
 cli ;blokada przerwan na czas przelaczania PIT
 mov [es:di], eax ;wstawiamy stary wektor przerwania
 ;przywracamy PIT
 mov al, 0x34
 out 0x43, al
 mov ax, 0
 out 0x40, ax
 sti ;odblokowac przerwania
 ;i zakonczyc program
 mov ax, 0x4C00
 int 0x21
 

Zastrzezenia:

  1. Raczej nie uruchamiaj tego pod windowsem - nie wiadomo jak sie windows zachowa
  2. Ja to tworzylem pod DOSa i do trybu rzeczywistego i u mnie dziala idealnie
0

dziekuje bardzo

1 użytkowników online, w tym zalogowanych: 0, gości: 1