;       SCCSID = @(#)timirpt.asm        6.2 91/04/29
;      SCCSID = @(#)timirpt.asm 6.2 91/04/29
;
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
;
        PAGE    60,132

;** Modification History

; @WWM  8/21/87 Removed CLI's and STI's from first part of Tick_Handler
;               for PTM7131
;
; @L    10/2/87 Added check for empty q in try_async_q. PTM 781
;
; @TARNG 2/12/88 Changed position of CLI's and STI's for PTM 1863
;               (performance problems)
;
; @SUDEEP 08-Feb-1990 Removed TIMER APIs related code
;
; RAR    12/15/92 Reorganized to allow most common cases (no servicing, and
;                 protected-mode servicing) to have as jump-free a path as
;                 possible 59308
;
;.286c
.LIST
;*
;*           SOURCE MODULE    TIMIRPT
;*
;******* START OF SOURCE FILE SPECIFICATIONS ********************
;*
;* SOURCE FILE NAME:    Timirpt
;*
;* DESCRIPTIVE NAME:    Timer Tick handler
;*
;* COPYRIGHT:   (TOP MODULE ONLY)
;*
;*  STATUS:     RELEASE 1 LEVEL 0
;*
;* NOTES:
;*    DEPENDENCIES:
;*    RESTRICTIONS
;*    PATCH LABEL:      (TOP MODULE ONLY)
;*
;* ENTRY POINTS EXTERNAL TO COMPONENT TIMER SERVICES
;*
;*      Tick_handler
;*
;* ENTRY POINTS EXTERNAL TO MODULE TIMIRPT
;*
;* OTHER SUBROUTINES CONTAINED IN THIS MODULE
;*
;*      none
;*
;* EXTERNAL TIMER SERVICES (COMPONENT) REFERENCES:
;*
;*
;* EXTERNAL TIMIRPT (MODULE) REFERENCES:
;*
;*
;************ END OF SOURCE FILE SPECIFICATIONS *****************
.XLIST
.SALL
;
;  INCLUDED LIBRARIES
;
include         dosseg.inc
include         basemaca.inc
include         osmaca.inc
include         timlib.inc

.LIST
.XALL

;
;       PUBLIC  PROCEDURES
;
        public  Tick_Handler


;
; EXTRN VARIABLES
;

ReferGlobal     handler_list,BYTE
ReferGlobal     handler_max,WORD
ReferGlobal     semaphore,BYTE

        FARCODE LOW
CODE    SEGMENT

page
;********************** START OF SPECIFICATIONS *****************
;*
;* SUBROUTINE NAME:     Tick_handler
;*
;* DESCRIPTIVE NAME:    Timer Tick handler
;*
;* FUNCTION:
;*      This procedure when called will 1st, check various
;*      queues and determine if any threads need notification
;*      (i.e. - their timeout values have expired) and two,
;*      will send control to anyone who has requested it via
;*      DevHlp_SetTimer.
;*
;* NOTES:
;*      This Procedure is called by SchedClock
;*      once every system timer tick (post-EOI).
;*
;* ENTRY POINT: Tick_handler
;*    LINKAGE:
;*
;* INPUT:       AX - milliseconds since last called
;*
;* EXIT-NORMAL: return to caller
;*
;* EXIT-ERROR:  return to caller
;*
;* EFFECTS:     none
;*
;* INTERNAL REFERENCES:
;*    ROUTINES:
;*
;*      none
;*
;* EXTERNAL REFERENCES:
;*    ROUTINES:
;*
;*
;*********************** END OF SPECIFICATIONS *********************
page
;**********************START OF PSEUDO CODE ************************
;
; for i = 1 to handler_max
;     if entry status == active
;        disable interrupts
;        if ticks_left == 1 (means handler needs servicing)
;           enable interrupts
;           call handler
;           disable interrupts
;           reset ticks_left = ntick (max ticks)
;        else
;           ticks_left--
;     enable interrupts
;
; semaphore = 0
; enable interrupts
; return
;
;*********************** END OF PSEUDO CODE ************************
page
Procedure   Tick_Handler
        ASSUME  DS:NOTHING, ES:NOTHING, FS:NOTHING, GS:NOTHING, SS:NOTHING

        DosContext es
.386p
        bts     semaphore,1     ; > if an interrupt occurs while still in the <
.286p
        jc      irpovr          ; > DD Tick handler routines then skip this   <
                                ; > interrupt.  (non-critical)                <

        lea     di,handler_list
        mov     cx,handler_max

dolist: dec     es:[di].ticksleft               ; reduce ticks until service
        jz      dosvc                           ; Handler needs servicing...
inact:  add     di,SIZE handler
        loop    dolist
        mov     semaphore,0

irpovr: sti                                     ; enable all interrupts
        ret

dosvc:  cmp     es:[di].status,0                ; is entry inactive?
        je      inact                           ; ignore this service then...
        push    es
        push    cx
        push    di

        smsw    ax                               ; see what mode we're in
        test    ax,protect_mode                  ; is machine in protect mode?
        jz      real_mode                        ; no then jump to real_mode

        mov     ds,es:word ptr[di].protectds     ; get protect mode DS
        call    es:dword ptr[di].virtprotect_off ; call the handler

rstcnt: pop     di
        pop     cx
        pop     es

        cli                                      ; Avoid window
        mov     ax,es:[di].ntick
        mov     es:[di].ticksleft,ax             ; reset counter to max
        sti
        jmp short inact

real_mode:
        mov     ds,es:word ptr[di].realds
        call    es:dword ptr[di].virtreal_off
        jmp     short   rstcnt

EndProc Tick_Handler


CODE    ENDS
        END
