home *** CD-ROM | disk | FTP | other *** search
/ Dave Lowe: PCPandemonium Copy Sent To Programmer / Lowe_PCPandemoniumCopySentToProgrammer_1992.09.30.img / ADTIMER.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-11-07  |  4.1 KB  |  194 lines

  1. ;--------------------------------------------------------------------------------
  2. ;
  3. ;Timer interrupt routines for AdLib/ROLAND MIDI file player
  4. ;
  5. ;--------------------------------------------------------------------------------
  6. ;Timer hardware equates
  7. ;--------------------------------------------------------------------------------
  8.  
  9. TIMER0      equ    40h    ; Address of timer 0 - used for 18.2hz interrupt
  10. TIMERCMD  equ    43h    ; Address of 8253 timer command register
  11.             ;   bit      0  - 0=binary data, 1=BCD  
  12.             ;   bits 1-3 - mode number, 0-5 (000-101)
  13.             ;   bits 4,5 - kind of operation:
  14.             ;        00 = move counter into latch
  15.             ;     01 = read/write low byte only
  16.             ;     10 = read/write high byte only
  17.             ;     11 = read/write low byte, then high
  18.             ;   bits 6,7 - timer # to program, 0-2 (00-10)
  19. SQWAVE    equ 00110110b    ; square wave mode command
  20.  
  21. ;--------------------------------------------------------------------------------
  22. ;These variables declared in code segment
  23. ;--------------------------------------------------------------------------------
  24.  
  25. EventDelay    dw ?    ;delay to calling routine
  26. InProgress    db 0    ;to avoid re-entry
  27.  
  28. TimerDiv    dw ?    ;timer divisor
  29.  
  30. TimerMod    dw ?    ;modulus
  31.  
  32. OldInt8        dw ?,?    ;old interrupt
  33.  
  34. ;--------------------------------------------------------------------------------
  35. ;InstallTimer:
  36. ;
  37. ;install timer interrupt
  38. ;--------------------------------------------------------------------------------
  39.  
  40. InstallTimer proc near
  41.     mov    ax,65535
  42.     call    TimerRate
  43.     mov    cs:InProgress,0
  44.  
  45. ;set up interrupt
  46.  
  47.     push    ds
  48.     cli              
  49.     
  50.     mov    di,offset TimerRoutine
  51.     xor    ax,ax          
  52.     mov    ds,ax          
  53.     mov    ax,ds:[20h]          ;get existing timer interrupt
  54.     mov    cs:OldInt8,ax    ;ip
  55.     mov    ax,ds:[22h]
  56.     mov    cs:OldInt8+2,ax    ;cs
  57.     mov    ds:[20h],di
  58.     mov    ds:[22h],cs
  59.  
  60.     sti      
  61.     pop    ds
  62.  
  63.     ret
  64. InstallTimer endp
  65.  
  66. ;--------------------------------------------------------------------------------
  67. ;RemoveTimer:
  68. ;
  69. ;de-install timer interrupt
  70. ;--------------------------------------------------------------------------------
  71.  
  72. RemoveTimer proc near
  73.     mov    ax,65535
  74.     call    TimerRate
  75.     push    ds
  76.     cli
  77.     xor    ax,ax
  78.     mov    ds,ax
  79.     mov    ax,cs:OldInt8        ;restore old interrupt
  80.     mov    ds:[20h],ax
  81.     mov    ax,cs:OldInt8+2
  82.     mov    ds:[22h],ax
  83.     sti
  84.     pop    ds
  85.     ret
  86. RemoveTimer endp
  87.  
  88. ;--------------------------------------------------------------------------------
  89. ;TimerRate:
  90. ;
  91. ;set up timer divisor
  92. ;
  93. ;inputs:
  94. ;
  95. ;ax:    count divisor
  96. ;
  97. ;--------------------------------------------------------------------------------
  98.  
  99. TimerRate proc near
  100.     mov    cs:TimerDiv,ax
  101.     mov    cs:TimerMod,ax
  102.     push    ax        ;set up timer0 divisor
  103.     mov    al,SQWAVE    ;square wave mode
  104.     out    TIMERCMD,al
  105.     pop    ax          
  106.     out       TIMER0,al      
  107.     xchg    al,ah
  108.     out    TIMER0,al
  109.     xchg    al,ah
  110.     ret
  111. TimerRate endp
  112.  
  113. ;--------------------------------------------------------------------------------
  114. ;TimerRoutine:
  115. ;
  116. ; this is the interrupt routine
  117. ;
  118. ; - calls EventRoutine when EventDelay counts down
  119. ; - calls OldInt8 at 18.2 Hz
  120. ;   for other rates a different modulus is needed
  121. ;
  122. ;--------------------------------------------------------------------------------
  123.  
  124. TimerRoutine proc near
  125.     push    ax
  126.  
  127. ;check whether to call OldInt8
  128.  
  129.     mov    ax,cs:TimerDiv
  130.     add    cs:TimerMod,ax    ;every 65536/TimerDiv times call OldInt8
  131.     jc    DoInt8
  132.  
  133.     mov    al,20h
  134.     out    20h,al        ;EOI
  135.  
  136.     jmp    NoInt8
  137.  
  138. DoInt8:    pushf               ;make like an interrupt
  139. ;    push    cs           ;cs
  140. ;    mov    ax,offset NoInt8
  141. ;    push    ax           ;ip
  142. ;    jmp    far ptr cs:OldInt8       ;call it
  143.     call    dword ptr cs:OldInt8
  144.  
  145. NoInt8:    dec    cs:EventDelay
  146.     jnz    EndTimerInt    ;don't call yet
  147.  
  148.     cmp    cs:InProgress,0    ;avoid re-entrance
  149.     jnz    EndTimerInt
  150.  
  151.     push    bx
  152.     push    cx
  153.     push    dx
  154.     push    ds
  155.     push    es
  156.     push    si
  157.     push    di
  158.     push    bp
  159.  
  160.     mov    ax,dseg        ;this is my data segment
  161.     mov    ds,ax
  162.  
  163. DoEvnt:    inc    cs:InProgress
  164.     sti
  165.     call    EventRoutine    ;returns with ax=new delay
  166.     cli
  167.     dec    cs:InProgress
  168.  
  169.     mov    bx,cs:EventDelay    ;calc new delay
  170.     neg    bx
  171.     cmp    bx,ax
  172.     jb    DelayOK
  173.  
  174.     mov    cs:EventDelay,0    ;must call EventRoutine now
  175.     jmp    DoEvnt
  176. DelayOK:
  177.     add    cs:EventDelay,ax
  178.  
  179.     sti
  180.  
  181.     pop     bp
  182.     pop     di
  183.     pop     si
  184.     pop     es
  185.     pop     ds
  186.     pop     dx
  187.     pop     cx
  188.     pop     bx
  189.  
  190. EndTimerInt:
  191.     pop    ax
  192.     iret
  193. TimerRoutine endp
  194.