;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;      /*****************************************************************/
;      /*                                                               */
;      /*                                                               */
;      /*****************************************************************/
;      /******************* START OF SPECIFICATIONS *********************/
;      /*                                                               */
;      /*  SOURCE FILE NAME: TIMER.ASM                                  */
;      /*                                                               */
;      /*  DESCRIPTIVE NAME: Timer services                             */
;      /*                                                               */
;      /*                                                               */
;      /*  STATUS:  Version 1.0                                         */
;      /*                                                               */
;      /*  NOTES: This module provides timer services to the driver.    */
;      /*         The device dependent and device type dependent        */
;      /*         routine is called for each logical device on each     */
;      /*         timer tick.                                           */
;      /*                                                               */
;      /*         A routine is provided to convert milliseconds to      */
;      /*         timer ticks.                                          */
;      /*                                                               */
;      /*  ENTRY POINTS:                                                */
;      /*      See public statements                                    */
;      /*  EXTERNAL REFERENCES:                                         */
;      /*      See extrn statements                                     */
;      /*                                                               */
;      /******************* END  OF  SPECIFICATIONS *********************/
.xlist
  include pensegs.inc
  include pen.inc
  include struc.inc
  include devhlp.inc
  include infoseg.inc
.list

.286p

;------------------------------------------------------------------------------
;declare external variables
;------------------------------------------------------------------------------

extrn Device_Help : dword
extrn DCB_Anchor : word
extrn GDTInfoSeg   : word

;------------------------------------------------------------------------------
;  DOS calls
;------------------------------------------------------------------------------

extrn   DOSGETINFOSEG:far

;------------------------------------------------------------------------------
;  external routines
;------------------------------------------------------------------------------

extrn Trc_Tick : near

;------------------------------------------------------------------------------
; local equates
;------------------------------------------------------------------------------

TICK_INTERVAL equ 1 ; n-tick count for  n-tick device help

;------------------------------------------------------------------------------
; local data declarations
;------------------------------------------------------------------------------

DSEG SEGMENT
public Tim_MsecPerTick
  Tim_MsecPerTick dd 33 ;default, will be updated during init
DSEG ends

;------------------------------------------------------------------------------
; Initialization data
;------------------------------------------------------------------------------

DSEGI segment
ring3_GIS  dw ?   ; ring 3 selector to global info seg
ring3_LIS  dw ?   ; ring 3 selector to local info seg
DSEGI ends

CSEG     SEGMENT
         ASSUME    CS:CGROUP, SS:nothing, ES:nothing, DS:DGROUP
;------------------------------------------------------------------------------
; Timer interrupt handler
;------------------------------------------------------------------------------
public timIntHandler
timIntHandler proc far
  TraceTick

; call all devices that request a timer tick

  mov  bx, DCB_Anchor
  .if <nonzero bx>
     .repeat
       CALL_NZ [bx].dcb_@Dev_DDTick
       CALL_NZ [bx].dcb_@Dev_DTTick
       mov  bx,[bx].dcb_link
     .until <zero bx>
  .endif
  xor ax,ax   ; clear carry
  ret
timIntHandler endp

;------------------------------------------------------------------------------
; convert milliseconds to tick count
;   eax = milliseconds
; returns
;   eax = tick count
;------------------------------------------------------------------------------
.386p
public Tim_Mill2Tick
Tim_Mill2Tick proc
  push edx
  xor  edx,edx
  idiv Tim_MsecPerTick     ;calculate number of ticks
  .if  <nonzero edx>
     inc eax
  .endif
  pop edx
  ret
Tim_Mill2Tick endp
.286p

CSEG ends

;---- INITIALIZATION ROUTINES -------------------------------------------------
;
; note: this code is truncated from the driver after the INIT command returns
;       to OS/2
;------------------------------------------------------------------------------

CSEGI segment

;------------------------------------------------------------------------------
; Initialize timer
;  bx = dcb
;------------------------------------------------------------------------------
public Tim_Init
Tim_Init  proc
  push bx

; call DosGetInfoSeg to get ring3 global info seg

  push ds
  push offset ring3_GIS
  push ds
  push offset ring3_LIS
  call DosGetInfoSeg
  jc tim_exit
  .if  <nonzero ax>
    PANIC PANIC_GETINFO
    stc
    jmp short tim_exit
  .endif
  mov     ax, ring3_GIS

; calculate milliseconds per tick

  push    es
  mov     es, ax

  xor     bx, bx
  mov     ax, es:[bx].SIS_ClkIntrvl
  pop     es

  mov     cx, TICK_INTERVAL
  mul     cx
  mov     cx, 10
  div     cx
  .if     <zero ax>
    inc     ax
  .endif
  mov     word ptr Tim_MsecPerTick,ax

; register a tick handler

  mov  ax, offset timIntHandler
  mov  bx, TICK_INTERVAL
  mov  dl, DevHlp_TickCount
  call Device_Help
  .if c
    PANIC PANIC_DEVHLP3
  .endif
tim_exit:
  pop bx
  ret
Tim_Init  endp


CSEGI ends

end

