home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH17 / TIMER.ASM < prev   
Encoding:
Assembly Source File  |  1994-07-13  |  2.4 KB  |  114 lines

  1. ; This program demonstrates how to patch into the int 1Ch timer interrupt
  2. ; vector and create an interrupt chain.
  3.  
  4.         .xlist
  5.         .286
  6.         include     stdlib.a
  7.         includelib    stdlib.lib
  8.         .list
  9.  
  10. dseg        segment    para public 'data'
  11.  
  12. ; The TIMERISR will update the following two variables.
  13. ; It will update the MSEC variable every 55 ms.
  14. ; It will update the TIMER variable every second.
  15.  
  16. MSEC        word    0
  17. TIMER        word    0
  18.  
  19. dseg        ends
  20.  
  21.  
  22. cseg        segment    para public 'code'
  23.         assume    cs:cseg, ds:dseg
  24.  
  25. ; The OldInt1C variable must be in the code segment because of the
  26. ; way TimerISR transfers control to the next ISR in the int 1Ch chain.
  27.  
  28. OldInt1C    dword    ?
  29.  
  30.  
  31. TimerISR    proc    near
  32.         push    ds
  33.         push    ax
  34.         mov    ax, dseg
  35.         mov    ds, ax
  36.  
  37.         mov    ax, MSEC
  38.         add    ax, 55        ;Interrupt every 55 msec.
  39.         cmp    ax, 1000
  40.         jb    SetMSEC
  41.         inc    Timer        ;A second just passed.
  42.         sub    ax, 1000    ;Adjust MSEC value.
  43. SetMSEC:    mov    MSEC, ax
  44.         pop    ax
  45.         pop    ds
  46.         jmp    cseg:OldInt1C
  47. TimerISR    endp
  48.  
  49.  
  50.  
  51. Main        proc
  52.         mov    ax, dseg
  53.         mov    ds, ax
  54.         meminit
  55.  
  56. ; Begin by patching in the address of our ISR into int 1ch's vector.
  57. ; Note that we must turn off the interrupts while actually patching
  58. ; the interrupt vector and we must ensure that interrupts are turned
  59. ; back on afterwards;  hence the cli and sti instructions.  These are
  60. ; required because a timer interrupt could come along between the two
  61. ; instructions that write to the int 1Ch interrupt vector.  This would
  62. ; be a big mess.
  63.  
  64.         mov    ax, 0
  65.         mov    es, ax
  66.         mov    ax, es:[1ch*4]
  67.         mov    word ptr OldInt1C, ax
  68.         mov    ax, es:[1ch*4 + 2]
  69.         mov    word ptr OldInt1C+2, ax
  70.  
  71.         cli
  72.         mov    word ptr es:[1Ch*4], offset TimerISR
  73.         mov    es:[1Ch*4 + 2], cs
  74.         sti
  75.  
  76. ; Okay, the ISR updates the TIMER variable every second.
  77. ; Continuously print this value until ten seconds have
  78. ; elapsed.  Then quit.
  79.  
  80.         mov    Timer, 0
  81. TimerLoop:    printf
  82.         byte    "Timer = %d\n",0
  83.         dword    Timer
  84.         cmp    Timer, 10
  85.         jbe    TimerLoop
  86.  
  87.  
  88.  
  89. ; Okay, restore the interrupt vector.  We need the interrupts off
  90. ; here for the same reason as above.
  91.  
  92.         mov    ax, 0
  93.         mov    es, ax
  94.         cli
  95.         mov    ax, word ptr OldInt1C
  96.         mov    es:[1Ch*4], ax
  97.         mov    ax, word ptr OldInt1C+2
  98.         mov    es:[1Ch*4+2], ax
  99.         sti
  100.  
  101. Quit:        ExitPgm            ;DOS macro to quit program.
  102. Main        endp
  103.  
  104. cseg        ends
  105.  
  106. sseg        segment    para stack 'stack'
  107. stk        db    1024 dup ("stack   ")
  108. sseg        ends
  109.  
  110. zzzzzzseg    segment    para public 'zzzzzz'
  111. LastBytes    db    16 dup (?)
  112. zzzzzzseg    ends
  113.         end    Main
  114.