e20 ;*************************************************************************** ; Routines for programming the 8253 Programmable Interval Timer (PIT) ; ; void prog_timer(unsigned int Hzfreq); ; void rest_timer(void); ; void newdelay(unsigned int delval); ;*************************************************************************** OPTION PROC:PRIVATE .DOSSEG .MODEL SMALL .386 .DATA? old_int8_vect dword ? .DATA PUBLIC _user_timer_rte, _timerticks _user_timer_rte dword 0 _timerticks dword 0 orig_cntr word 0 tmr_count word 0FFFFH hz18 word 18 .CODE PUBLIC _prog_timer, _rest_timer, _newdelay timer_isr PROC FAR ASSUME CS:_TEXT, DS:@data push ds push ax push dx push @data pop ds inc _timerticks ;Update tick value cmp _user_timer_rte, 0 ;User routine installed? jz no_rte ;No pusha ;Yes, call it push es call _user_timer_rte pop es popa no_rte: mov ax, tmr_count ;Time to call orig ISR? add orig_cntr, ax jnc end_of_ISR ;No pushf call old_int8_vect ;Call original timer ISR jmp skip_EOI end_of_ISR: mov al, 20h ;Signal End of Interrupt out 20h, al skip_EOI: pop dx pop ax pop ds iret timer_isr ENDP ;======================================================================== _prog_timer PROC push bp mov bp, sp push cx push es mov ax, 3508h ;H„mta vektorn till INT 08h int 21h mov word ptr[old_int8_vect], bx ;Org_Rutinens OFFSET h„mtas mov word ptr[old_int8_vect+2], es ;Segment sparas push ds mov ax, 2508h ;Install TIMER ISR push cs pop ds mov dx, offset timer_isr int 21h pop ds mov ax, 34DCh ;Divide 1193180 by frequency mov dx, 12h ;to get count value for timer div word ptr[bp+4] mov cx, ax ;Count value -> CX xor dx, dx ;Wait for system timer to tick mov es, dx ;for synchronization mov dx, word ptr es:[46Ch] wait_tick1: cmp word ptr es:[46Ch], dx jz short wait_tick1 cli mov tmr_count, cx ;Store count value mov orig_cntr, 0 ;Zero counter mov dx, 43h ;Re-program system timer to mov al, 36h ;new resolution out dx, al mov dx, 40h ;Load new count value mov al, cl ;LSB out dx, al mov al, ch ;MSB out dx, al sti pop es pop cx pop bp ret _prog_timer ENDP ;------------------------------------------------------------------------ _rest_timer PROC push si push es xor dx, dx ;Wait for system timer to tick mov es, dx ;for synchronization mov dx, word ptr es:[46Ch] wait_tick2: cmp word ptr es:[46Ch], dx jz short wait_tick2 cli mov dx, 43h mov al, 36h out dx, al mov dx, 40h ;Restore timer 0 frequency mov al, 0h out dx, al mov al, 0h out dx, al push ds ;Restore old INT 8 mov ax, 2508h mov dx, word ptr[old_int8_vect] mov ds, word ptr[old_int8_vect+2] int 21h pop ds sti pop es pop si ret _rest_timer ENDP ;-------------------------------------------------------------------------- _newdelay PROC push bp mov bp, sp push bx xor ebx, ebx mov bx, [bp + 4] ;Delay value -> BX mov eax, _timerticks ;Timer reference start value delay_lp: mov edx, _timerticks ;Current tick value sub edx, eax ;Current val - reference val cmp edx, ebx ;Delay time elapsed? jnz delay_lp ;No, loop pop bx pop bp ret _newdelay ENDP END . 0