home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------------------------------------------------------
- ;
- ;Timer interrupt routines for AdLib/ROLAND MIDI file player
- ;
- ;--------------------------------------------------------------------------------
- ;Timer hardware equates
- ;--------------------------------------------------------------------------------
-
- TIMER0 equ 40h ; Address of timer 0 - used for 18.2hz interrupt
- TIMERCMD equ 43h ; Address of 8253 timer command register
- ; bit 0 - 0=binary data, 1=BCD
- ; bits 1-3 - mode number, 0-5 (000-101)
- ; bits 4,5 - kind of operation:
- ; 00 = move counter into latch
- ; 01 = read/write low byte only
- ; 10 = read/write high byte only
- ; 11 = read/write low byte, then high
- ; bits 6,7 - timer # to program, 0-2 (00-10)
- SQWAVE equ 00110110b ; square wave mode command
-
- ;--------------------------------------------------------------------------------
- ;These variables declared in code segment
- ;--------------------------------------------------------------------------------
-
- EventDelay dw ? ;delay to calling routine
- InProgress db 0 ;to avoid re-entry
-
- TimerDiv dw ? ;timer divisor
-
- TimerMod dw ? ;modulus
-
- OldInt8 dw ?,? ;old interrupt
-
- ;--------------------------------------------------------------------------------
- ;InstallTimer:
- ;
- ;install timer interrupt
- ;--------------------------------------------------------------------------------
-
- InstallTimer proc near
- mov ax,65535
- call TimerRate
- mov cs:InProgress,0
-
- ;set up interrupt
-
- push ds
- cli
-
- mov di,offset TimerRoutine
- xor ax,ax
- mov ds,ax
- mov ax,ds:[20h] ;get existing timer interrupt
- mov cs:OldInt8,ax ;ip
- mov ax,ds:[22h]
- mov cs:OldInt8+2,ax ;cs
- mov ds:[20h],di
- mov ds:[22h],cs
-
- sti
- pop ds
-
- ret
- InstallTimer endp
-
- ;--------------------------------------------------------------------------------
- ;RemoveTimer:
- ;
- ;de-install timer interrupt
- ;--------------------------------------------------------------------------------
-
- RemoveTimer proc near
- mov ax,65535
- call TimerRate
- push ds
- cli
- xor ax,ax
- mov ds,ax
- mov ax,cs:OldInt8 ;restore old interrupt
- mov ds:[20h],ax
- mov ax,cs:OldInt8+2
- mov ds:[22h],ax
- sti
- pop ds
- ret
- RemoveTimer endp
-
- ;--------------------------------------------------------------------------------
- ;TimerRate:
- ;
- ;set up timer divisor
- ;
- ;inputs:
- ;
- ;ax: count divisor
- ;
- ;--------------------------------------------------------------------------------
-
- TimerRate proc near
- mov cs:TimerDiv,ax
- mov cs:TimerMod,ax
- push ax ;set up timer0 divisor
- mov al,SQWAVE ;square wave mode
- out TIMERCMD,al
- pop ax
- out TIMER0,al
- xchg al,ah
- out TIMER0,al
- xchg al,ah
- ret
- TimerRate endp
-
- ;--------------------------------------------------------------------------------
- ;TimerRoutine:
- ;
- ; this is the interrupt routine
- ;
- ; - calls EventRoutine when EventDelay counts down
- ; - calls OldInt8 at 18.2 Hz
- ; for other rates a different modulus is needed
- ;
- ;--------------------------------------------------------------------------------
-
- TimerRoutine proc near
- push ax
-
- ;check whether to call OldInt8
-
- mov ax,cs:TimerDiv
- add cs:TimerMod,ax ;every 65536/TimerDiv times call OldInt8
- jc DoInt8
-
- mov al,20h
- out 20h,al ;EOI
-
- jmp NoInt8
-
- DoInt8: pushf ;make like an interrupt
- ; push cs ;cs
- ; mov ax,offset NoInt8
- ; push ax ;ip
- ; jmp far ptr cs:OldInt8 ;call it
- call dword ptr cs:OldInt8
-
- NoInt8: dec cs:EventDelay
- jnz EndTimerInt ;don't call yet
-
- cmp cs:InProgress,0 ;avoid re-entrance
- jnz EndTimerInt
-
- push bx
- push cx
- push dx
- push ds
- push es
- push si
- push di
- push bp
-
- mov ax,dseg ;this is my data segment
- mov ds,ax
-
- DoEvnt: inc cs:InProgress
- sti
- call EventRoutine ;returns with ax=new delay
- cli
- dec cs:InProgress
-
- mov bx,cs:EventDelay ;calc new delay
- neg bx
- cmp bx,ax
- jb DelayOK
-
- mov cs:EventDelay,0 ;must call EventRoutine now
- jmp DoEvnt
- DelayOK:
- add cs:EventDelay,ax
-
- sti
-
- pop bp
- pop di
- pop si
- pop es
- pop ds
- pop dx
- pop cx
- pop bx
-
- EndTimerInt:
- pop ax
- iret
- TimerRoutine endp