>>> Egy olyan interruptot szeretnek installalni, ami x masodpercenkent
>>> meghivodik. Melyik ez? Lehet allitani, hogy milyen gyakran hivodjon
>>0x1C kb 18* hivodik masodpercenkent. Ha ennel surubbet akarsz,
>>lehet azt is, de fejbol nem tudom. Mar csinaltam. Tomor asm....
>>Elsore annyira emlexem, hogy at kell programozni a 8253 timer ic
>>valamelyik csatornajat. Meg at kell venni az egesz
>Egyszeru:
>TR_LOW equ 0ffh
>TR_HIGH equ 003h
>cli
>mov al,036h
>out 043h,al
>jmp $+2 ; ha jol emlekszem csak 8086-nak kell ez
>mov al,TR_LOW
>out 040h,al
>jmp $+2
>mov al,TR_HIGH
>out 040h,al
>jmp $+2
>; .. es atvenni a int 8-et a sajat hadler-rel !!
>; getvector ... setvector ...
>sti
>Az eredeti ertekek : TR_LOW es TR_HIGH mindketto 0ffh
>igy a timer interrupt 1193180/65536 -szor tortenik minden mp-be (~18.2)
>Ha gyorsabban akarod akkor meg kell valtoztatni a TR_HIGH es TR_LOW
>szamokat.
>Pelda: ha 64-szer gyorsabban akarod a megszakitast, akkor
>0ffffh/040h = 03ffh, TR_HIGH = 003h, TR_LOW = 0ffh
>igy az int 8 1193180/1280 szor tortenik, kb 932.2 szer (minden 1.073 ms)
>Tobb problemak ott vannak hogy az eredeti int 8 fuggveny neked
>MUSZAJ az eredeti idobe hivni, igy szamolni kell es minden
>64-edszer hivni kell. Es el nem felejteni a sajat handler vegen
>a PIC-nak megmondani hogy vege van a megszakitasnak
>mov al,020h
>out 020h,al
>Na es ha vege van a programnak akkor mindent vissza kell allitani
>eredetire!!
Hello!
Bocs, de a timer interrupthoz egy kis pontositas:
Az eredeti TR_LOW es TR_HIGH egyarant 0 es nem 0ffh, azaz a szamlalo
specifikacio szerint 65536 es nem 65535, igy az eredeti visszaallitasa:
cli ; Disable interrupts
mov al,36h
out 43h,al ; port 43h, 8253 timer control
out 0ebh,al
xor al,al ; Zero register
out 40h,al ; port 40h, 8253 timer 0 clock
out 0ebh,al
out 40h,al ; port 40h, 8253 timer 0 clock
Hasonloan:
TR_HIGH = 003h, TR_LOW = 0ffh helyett:
TR_HIGH = 004h, TR_LOW = 0 a pontos.
A portra valo iras/olvasas muveletek kozott mindig ajanlatos egy kis
kesleltetes, mert az alaplapok es BIOS beallitasok kulonbozosege miatt
elofordulhatnak problemak. jmp $+2 vagy nop Pentiumtol folfele nemigen
kesleltet, ezert van a fenti kodban out 0ebh,al , ami egy ures, nem letezo
portra valo kiiras es egyben hatekony kesleltetes (ld. AWARD BIOS).
Elvileg Win NT alatt a szamlalot nem lehet ilyen egyszeruen atprogramozni,
sot, meg Win9x alatt sem (ld. TSS I/O map).
A legfinomabb idozitest a CMOS real-time ora interrupt (int 70h - IRQ 8)
felhasznalasaval lehet elerni: masodpercenkent 1024 idozito interrupt. Ez
komplikaltabb, mert a CMOS oranak is meg kell parancsolni, hogy adjon IRQ-t
a procinak, stb.
Ha csak idomeresre kell, kvazi millisec pontossagot ad. Egy (elnagyolt)
pelda:
Count_Set: ;a szamlalo inicializalasa BIOS-on keresztul (ez most
TENYLEG 0ffffffffh [cx:dx])
stc
push ds
sbb dx,dx
pop es
mov ax,8300h
sbb cx,cx
mov bx,offset watch_flag ;szamlalas kb. 2^12 sec (jo oraig) ideig
visszafele,
int 15h ;a szamlalo 40:9ch alatt 4 byte-on,
microsec-ben, 1/1024 sec felbontassal
jnc Count_OK
mov ax,8301h ;ha nem megy, lodd le az elozo szamlalast.
Ugyanez mehet a progi vegere is!
int 15h
jmp Count_Set ;probald ujra (jobb lenne a carry flag detect, ha
ez sem megy [pl. NT DOS ablak])
Count_OK:
...
ha pedig most msec pontossagu meres kell:
Num_1000 dd 1000
...
Get_Time proc near ;ezt hivjuk idomereskor
push 40h
pop gs
mov eax,gs:[9ch] ;kiolvassuk a microsec szamlalot
xor edx,edx
neg eax ;novekvo idoertekek kellenek
div Num_1000 ;legyen a microsecbol millisec
push eax ;a msec-t eax reg.-ben vagy dx:ax reg.-ben kapjuk
vissza (16/32 bites izles szerint :-))
pop ax
pop dx
retn
Get_Time endp
Tovabbi ajanlott irodalom: Ralf Brown interrupt list file (pl. Chip CD)
Udv:
PlyR
|