Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
7.7 KiB

  1. PAGE 60,150
  2. ;***************************************************************************
  3. ;* TIMER.ASM
  4. ;*
  5. ;* Routines used to give a cleaner interface to the VTD.
  6. ;* This interface also works on a 286 by calling GetTickCount() in
  7. ;* this case.
  8. ;*
  9. ;***************************************************************************
  10. INCLUDE TOOLPRIV.INC
  11. INCLUDE WINDOWS.INC
  12. ;** Symbols
  13. SI_CRITICAL EQU 1
  14. DI_CRITICAL EQU 2
  15. ;** Imports
  16. externA __WinFlags
  17. externFP GetTickCount
  18. sBegin DATA
  19. dwLastTimeReturned dd 0
  20. wLastCountDown dw 0
  21. sEnd
  22. sBegin CODE
  23. assumes CS,CODE
  24. assumes DS,DATA
  25. ; TimerCount
  26. ; Returns the count from either the virtual timer device or from the
  27. ; Windows function GetTickCount() depending on the processor.
  28. ; Prototype:
  29. ; BOOL FAR PASCAL TimerCount(
  30. ; TIMERINFO FAR *lpTimer)
  31. ;
  32. cProc TimerCount, <FAR,PUBLIC>, <si,di,ds>
  33. parmD lpTimer
  34. localD dwJumpAddr
  35. cBegin
  36. mov ax, _DATA ;Get our data segment
  37. mov es, ax
  38. ;** Point to the structure
  39. lds si,lpTimer ;Point to the structure
  40. ;** Make sure the size is correct
  41. xor ax,ax ;FALSE
  42. cmp WORD PTR [si].ti_dwSize[2],0 ;High word must be zero
  43. je @F
  44. jmp TC_End
  45. @@: cmp WORD PTR [si].ti_dwSize[0],SIZE TIMERINFO ;Low word must match
  46. je @F
  47. jmp TC_End
  48. @@:
  49. ifndef WOW
  50. ;** If we are in standard mode, always use Windows entry point
  51. mov ax,__WinFlags ;Get the flags
  52. test ax,WF_STANDARD ;Standard mode?
  53. jnz TC_TryMMSys ;Yes, don't even try VTD
  54. .386p
  55. ;** Try to get the VTD entry point
  56. mov ax,1684h ;Get device entry point
  57. mov bx,5 ;VTD device number
  58. int 2fh ;Win386 entry point
  59. mov ax,es ;Did we get a value?
  60. or ax,di ; (zero means no device)
  61. jz SHORT TC_UseWinAPI ;No VTD--use Win API
  62. ;** Get the VTD values
  63. mov WORD PTR dwJumpAddr[0],di ;Save the address
  64. mov WORD PTR dwJumpAddr[2],es ;Save the address
  65. mov ax,0101h ;VTD: ms since start of Win386
  66. call DWORD PTR dwJumpAddr ;Call the VTD
  67. jc SHORT TC_UseWinAPI ;Carry set means error
  68. mov [si].ti_dwmsSinceStart,eax ;Save in structure
  69. mov ax,0102h ;VTD: ms in this VM
  70. call DWORD PTR dwJumpAddr ;Call the VTD
  71. jc SHORT TC_UseWinAPI ;Carry set means VTD error
  72. mov [si].ti_dwmsThisVM,eax ;Save value in structure
  73. jmp TC_ReturnOK ;We're done
  74. .286p
  75. ;** See if mmsystem timer is installed
  76. TC_TryMMSys:
  77. cmp WORD PTR es:[lpfntimeGetTime][2], 0 ;Installed?
  78. je TC_UseWinAPI ;No, do this the hard way
  79. call DWORD PTR es:lpfntimeGetTime
  80. ;** Fill the structure with this information
  81. mov WORD PTR [si].ti_dwmsSinceStart[0],ax
  82. mov WORD PTR [si].ti_dwmsSinceStart[2],dx
  83. mov WORD PTR [si].ti_dwmsThisVM[0],ax
  84. mov WORD PTR [si].ti_dwmsThisVM[2],dx
  85. jmp TC_ReturnOK
  86. endif ; ndef WOW
  87. ;** Use the Windows API
  88. TC_UseWinAPI:
  89. cCall GetTickCount ;Call the Windows API
  90. mov WORD PTR [si].ti_dwmsSinceStart[0],ax ;Save the value for now
  91. mov WORD PTR [si].ti_dwmsSinceStart[2],dx
  92. ;** Read the countdown timer. Note that the timer starts at 54 * 1193
  93. ;** and counts down to zero. Each count is 1193 ms.
  94. ifdef NEC_98
  95. ; timer i/o access change
  96. push ds
  97. mov ax,40h ; 40:101 ;921006
  98. mov ds,ax
  99. test byte ptr ds:[101h],80h ; system clock check ;921006
  100. pop ds
  101. mov cx,2457 ; 2.5MHz
  102. jz @f
  103. mov cx,1996 ; 2MHz
  104. @@:
  105. push cx
  106. xor al,al ;Prepare to read tick count
  107. out 77h,al ;Send to timer ;921006
  108. in al,dx ;Get the low byte
  109. mov ah,al ;Save in AH
  110. in al,dx ;Get the high byte
  111. xchg ah,al
  112. pop cx
  113. mov dx,0ffffh ;Get total countdown amount
  114. sub dx,ax ;Get number of counts expired
  115. mov ax,dx ;Get the number in AX for div
  116. xor dx,dx ;Zero the high word
  117. else ; NEC_98
  118. xor al,al ;Prepare to read tick count
  119. out 43h,al ;Send to timer
  120. in al,40h ;Get the low byte
  121. mov ah,al ;Save in AH
  122. in al,40h ;Get the high byte
  123. xchg ah,al
  124. mov dx,0ffffh ;Get total countdown amount
  125. sub dx,ax ;Get number of counts expired
  126. mov ax,dx ;Get the number in AX for div
  127. xor dx,dx ;Zero the high word
  128. mov cx,1193 ;Divide to get ms
  129. endif ; NEC_98
  130. div cx ;Divide it
  131. mov cx, ax ;cx == saved Curr count
  132. ;** Now fill the structure. Note that the 'ThisVM' entry is the
  133. ;** same as the 'SinceStart' entry in standard mode.
  134. xor dx, dx
  135. add ax, WORD PTR [si].ti_dwmsSinceStart[0] ;Add this count in
  136. adc dx, WORD PTR [si].ti_dwmsSinceStart[2]
  137. ;** Check to make sure we didn't mess up. If we did (if the timer
  138. ;** was reset right in the middle of us reading it). If we
  139. ;** messed up, do it again until we get it right.
  140. mov bx, _DATA ;Get our data segment
  141. mov es, bx
  142. cmp dx, WORD PTR es:dwLastTimeReturned[2]
  143. jne TC_TimeOK
  144. cmp ax, WORD PTR es:dwLastTimeReturned[0]
  145. jae TC_TimeOK
  146. ; New time is less than the old time so estimate the curr time
  147. ; using LastTimeReturned as the base
  148. mov ax, WORD PTR es:dwLastTimeReturned[0]
  149. mov dx, WORD PTR es:dwLastTimeReturned[2]
  150. xor bx, bx ;check for wrap
  151. cmp cx, word ptr es:wLastCountDown
  152. jae TC_NoWrap ;if wrap
  153. add ax, cx ; += curr count
  154. adc dx, 0
  155. jmp short TC_TimeOK
  156. TC_NoWrap: ;else no wrap
  157. mov bx, cx ; += Curr - LastCountDown
  158. sub bx, word ptr es:wLastCountDown
  159. add ax, bx
  160. adc dx, 0
  161. TC_TimeOK:
  162. mov word ptr es:wLastCountDown, cx
  163. mov WORD PTR es:dwLastTimeReturned[0], ax
  164. mov WORD PTR es:dwLastTimeReturned[2], dx
  165. mov WORD PTR [si].ti_dwmsSinceStart[0], ax ;Save good count
  166. mov WORD PTR [si].ti_dwmsSinceStart[2], dx
  167. mov WORD PTR [si].ti_dwmsThisVM[0],ax ;Save in structure
  168. mov WORD PTR [si].ti_dwmsThisVM[2],dx ;Save in structure
  169. TC_ReturnOK:
  170. mov ax,1 ;Return TRUE
  171. TC_End:
  172. cEnd
  173. sEnd
  174. END