;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; 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.;
;*****************************************************************************/
    Page  58,132
    Title   Kbdfilt - Kbd DD Filter Key Support Routines
    Name    Kbdfilt

;/*****************************************************************************
;*
;* SOURCE FILE NAME = KBDFILT
;*
;* DESCRIPTIVE NAME = Keyboard Special Need Support
;*
;*
;* VERSION      V2.0
;*
;* DATE         11/02/92
;*
;* DESCRIPTION  Sepecial Need Support process
;*
;* FUNCTIONS    ProcessFilter()      Process Filter Key
;*              SetFilterTypa        Set Filter Key Typematic Controls
;*              TypaControl_Reset    Typematic Rate/Delay and Acceptance Rate Control
;*              TypaControl_Disable  Typematic Rate/Delay and Acceptance Rate Control
;*
;*
;* NOTES        DEPENDENCIES:  Controller or keyboard must be set to the PC compati-
;*                             ble scan code set.
;*              RESTRICTIONS:  Machine must be a 386 or compatible with a 386.
;*
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*****************************************************************************/
.286p
.sall
.xcref
.xlist
  Include basemaca.inc   ;DOS macros.
  Include osmaca.inc     ;Macro file for OS/2 kernel
  CPUMODE 286
  Include struc.inc      ;Structured assembly macros.
  Include devhlp.inc     ;DevHlp & Signal equates, char queue structure.
  Include devsym.inc     ;Device driver header definitions.
  Include kbdseg.inc     ;Segment definitions.
  Include kbdddr.inc     ;Keyboard Device Driver structures & equates.
  Include kbdaim.inc     ;AIM
.list

;**************************************************************************
;**External Routines
;**************************************************************************
  Extrn SetLocalVar       :Far
  Extrn DD_Entry          :Far
  Extrn KBDBeep1KHz       :Far
  Extrn KBDBeep2KHz       :Far
  Extrn QueryMouse        :Far
  EXTRNFAR Typa_RDCheck


;**************************************************************************
;External Variables
;**************************************************************************

  Extrn FilterFlags            :Byte    ;AIM
  Extrn AIMFlags               :Word    ;AIM
  Extrn PrevKey                :Byte    ;AIM
  Extrn LastKey                :Byte    ;AIM
  Extrn FinalKey               :Byte    ;AIM
  Extrn Shift_Count            :Byte    ;AIM
  Extrn Beep_State             :Byte    ;AIM
  Extrn Bp_Count               :Byte    ;AIM
  Extrn Rep_Count              :Word    ;AIM
  Extrn Acc_Ctrl               :Word    ;AIM
  Extrn Typematic_Ctrl         :Word    ;AIM
  Extrn Delay_Ctrl             :Word    ;AIM
  Extrn Comp_Acc_Ctrl          :Word    ;AIM
  Extrn Comp_Typematic_Ctrl    :Word    ;AIM
  Extrn Comp_Delay_Ctrl        :Word    ;AIM
  Extrn Comp_AIMTimeout        :Word    ;AIM
  Extrn Comp_Rep_Count         :Word    ;AIM
  Extrn AIMTimeOut             :Word    ;AIM
  Extrn Tick_Per_Sec           :Word    ;AIM
  Extrn Filter_Ctrl            :Byte    ;AIM
  Extrn MSEFilterStatus        :Word    ;AIM
  EXtrn StickMakes             :Word
  EXtrn StickBreaks            :Word
  EXtrn Hw_Typa_Rate           :Word
  EXtrn Em_Typa_Rate           :Word
  EXtrn Hw_Typa_Delay          :Word
  EXtrn Em_Typa_Delay          :Word
  EXtrn Hw_Typa_Time           :Word
  Extrn AIMAccept              :DWord   ;AIM
  Extrn AIMRate                :DWord   ;AIM
  Extrn AIMDelay               :DWord   ;AIM
  Extrn DeviceHelp             :DWord

  StkFrameVars                 ;Setup local stack varibles.

AIMCode Segment
Assume  CS:AIMCode,DS:DGROUP,ES:Nothing


BREAK <ProcessFilter routine>
Public ProcessFilter
ProcessFilter Proc Far

;************************************************************************
;*
;* FUNCTION NAME = ProcessFilter
;*
;* DESCRIPTION   = Handle Filter Key function in Special Need Support
;*
;* NOTES         =
;*              When AIM is active, this routine is always called
;*              by KBDInt.  KBD DD starts emulation of the keyboard
;*              speed which was set before AIM is activated.  This
;*              emulation was done because the default system keyboard
;*              speed could be slower than AIM support condition
;*              requires.  When AIM is activated, the keybaord speed
;*              is set to FAST which is 33 characters/sec of typematic
;*              rate and 250 milliseconds of typematic delay.
;*
;*
;*  Actual Hardware     |  Keyboard DD         |   User
;*                      |                      |
;*  --------------------|----------------------|--------------------
;*                      |                      |
;*  Default Speed       |  AIM not active      | Normal usage
;*   NORMAL             |                      | Normal speed
;*                      |      |               |
;*                      |      V               |
;*  Change keyboard  <--|- AIM active      <-----Activate AIM
;*  to FAST speed       |      |               |
;*                      |      V               |
;*                      |  Emulate NORMAL speed| Normal speed
;*                      |      |               |
;*                      |      V               |
;*                      |  Filter Key active<----Activate Filter Key
;*                      |  AIM specified KBD   | Specified Filter Key
;*                      |  speed               | speed
;*                      |      |               |
;*                      |      |               |
;*                      |      V               |
;*                      |  Filter Key inactive<--Deactivate Filter Key
;*                      |      |               |
;*                      |      V               |
;*                      |  Emulate NORMAL speed| Normal speed
;*                      |      |               |
;*                      |      V               |
;*  Change keyboard  <--|- AIM inactive    <-----Deactivate AIM
;*  to NORMAL speed     |                      | Normal usage
;*                      |                      | Normal speed
;*                      |                      |
;*
;*
;*    ENTRY POINT: FilterProcess
;*
;*    LINKAGE:  NEAR
;*
;*
;*
;*    REGISTERS:
;*
;*            AL = Scan code
;*
;* INPUT = NONE
;*
;* OUTPUT = NONE
;*
;* RETURN-NORMAL = Return to System Initialization
;*
;* RETURN-ERROR  =  see NORMAL above.
;*
;*
;*
;* INTERNAL REFERENCES:
;*    ROUTINES:
;*      PDDCMD_Entry - Physical Keyboard Device Driver IDC Interface
;*                     Entry Point.
;*      KbdBeep1KH  - Beep with 1000 Hz for 500 milliseconds
;*      QueryMouse   - query mouse status
;*
;*
;*      DEVHELPS: DevHlp_TickCount
;*
;*
;*
;* PSUEDOCODE =
;*
;*   If FILTER_ACTIVE bit in FilterFlags is off
;*
;*      If the scan code is Make Key for Right or Left Shift
;*
;*         Call QueryMouse to initialize MouseStatus
;*         Call QueryMouse to initialize MouseStatus surely
;*
;*         If the scan code is different from last scan code
;*            Save the new scan code in LastKey
;*            Set Shift_Count to Filter_Ctrl
;*         Else
;*            Call QueryMouse to get current MouseStatus
;*            If MouseStatus is not equal to 0
;*               Turn on TYP_ACC bit in FilterFlags
;*            Endif
;*            If TYP_ACC bit in FilterFlags is off
;*               Decrement Shift_Count
;*            Endif
;*            If Shift_Count is 0
;*
;*               Set Beep_State to 4
;*
;*               Save the scan code to FinalKey
;*
;*               /* Reset Sticky Key Counters */
;*               Set StckMakes to 0
;*               Set StickBreaks to 0
;*
;*               Call DevHlp_TickCount with 1 tick count for
;*               KbdBeep1KHz
;*
;*               Turn on Filter Timeout bit in FilterFlags
;*
;*            Endif
;*         Endif
;*
;*         Turn off TYP_ACC bit in FilterFlags
;*
;*      Endif
;*   Endif
;*
;*   Turn off Filter Timeout bit in FilterFlags
;*
;*   If AIMActive bit in AIMFlags is on
;*
;*      If the scan code is Extended Key E0h
;*         Turn on Exteded Key Mode bit in FilterFlags
;*         Jump to Normal_Process
;*      Endif
;*
;*      If Bypass Count is not 0
;*         Decrement Bypass Count
;*         Jump to Normal_Process
;*      Endif
;*
;*      If the scan code is E1h (Print Screen)
;*         Set Bypass Count to 5
;*         Jump to Normal_Process
;*      Endif
;*
;*      If Extended Key mode bit is on in FilterFlags and the scan
;*         code is 2Ah (Pause Key)
;*         Turn off Extended Key Mode bit in FilterFlags
;*         Jump to Normal_Process
;*      Endif
;*
;*      If the scan code is different from last scan code
;*
;*         Save the new scan code in LastKey
;*
;*         If Acc_Ctrl is 0
;*            Jump to Normal_Process
;*         Endif
;*
;*         Set Repeat_Count to Acc_Ctrl
;*         Turn on Typmatic Delay mode bit in FilterFlags
;*
;*         If the scan code is not BREAK Key
;*            Turn on Repeat mode bit in FilterFlags
;*         Else
;*            Turn off Repeat mode bit in FilterFlags
;*            Turn off Extended Key Mode bit in FilterFlags
;*            Turn off Typematic Disbale bit in FilterFlags
;*            Set Shift_Count to 0
;*         Endif
;*      Else   /* Last scan code is the same as the current one */
;*         If Repeat_Count is 0
;*
;*            Turn off Repeat mode bit in FilterFlags
;*
;*            If Typematic Delay mode bit is on
;*
;*               If Typematic_Ctrl is 0
;*                  Jump to Normal_Process
;*               Endif
;*
;*               Set Repeat_Count to Typematic_Ctrl
;*            Else
;*               If Delay_Ctrl is DELAY_DISABLED
;*                  Turn on Typematic Disbale bit in FilterFlags
;*               Else
;*                  Turn off Typematic Delay mode bit in FilterFlags
;*
;*                  If Typematic_Ctrl is 0
;*                     Jump to Normal_Process
;*                  Endif
;*
;*                  Set Repeat_Count to Delay_Ctrl
;*               Endif
;*            Endif
;*         Else                       /* Repeat Count is not 0 */
;*            If Typematic Disbale bit in FilterFlags is off
;*               Turn on Repeat mode bit in FilterFlags
;*               If Repeat_Count is DELAY_DISABLED - 1
;*                  Jump to Skip_Process
;*               Endif
;*               Decrement Repeat_Count
;*            Endif
;*         Endif
;*      Endif
;*   Endif
;*
;*   If Repeat mode bit in FilterFlags is on
;*      Jump to Skip_Process
;*   Endif
;*
;*
;* Normal_Process:
;*   Set Carry flag off
;*   Return to the caller
;*
;* Skip_Process:
;*   Set Carry flag on
;*   Return to the caller
;*
;*********************************************************************



   Test  FilterFlags,FILTER_ACTIVE
   .If <z>
      .If <AL eq R_SHIFT> OR                    ; If right or
      .If <AL eq L_SHIFT>                       ; left shift key
         .If <LastKey ne AL>
             Mov   LastKey,AL                   ; Save the new key
             Mov   CL,Filter_Ctrl
             Mov   Shift_Count,CL
             Mov   CX, FilterQuery
             Call  QueryMouse                   ; Set up initial Mouse status
             Call  QueryMouse                   ; Set up initial Mouse status
         .Else
             Mov   CX, FilterQuery
             Call  QueryMouse
            .If <MSEFilterStatus ne 0>
               Or  FilterFlags,TYP_ACC
            .Endif
             Test  FilterFlags,TYP_ACC
            .If <z>
               Dec Shift_Count
            .Endif
            .If <Shift_Count eq 0>

               Mov Beep_State,ENABLE_BEEP
               Mov FinalKey,AL

               Mov StickMakes,0
               Mov StickBreaks,0

               Push AX

               Mov AX, Offset KbdCode:KBDBeep1KHz

               Mov BX, IMMEDIATE_TICK
               Mov DL, DevHlp_TickCount
               Call [DeviceHelp]

               Pop AX

            .Endif
         .Endif
      .Else
          Mov   LastKey,0
          And   FilterFlags,NOT TYP_ACC
      .Endif
   .Endif

    And   FilterFlags,NOT TIMEOUT            ; Set for timeout
   .If <AL eq OtherKey>                      ; Extended Key E0
       Or   FilterFlags,ExtKey_Mode          ; Set to Exteded Key Mode
       Jmp  Normal_Process                   ; Process normally
   .Endif                                    ; 
                                             ; 
   .If <Bp_Count ne 0>                       ; If Bypass Count is not 0
       Dec  Bp_Count                         ; Decrement Bypass Count
       Jmp  Normal_Process                   ; Process normally
   .Endif                                    ; 
                                             ; 
   .If <AL eq OtherKey2>                     ; If E1 (Print Screen) <- this is Pause not print screen
       Mov  Bp_Count,5                       ; Set Bypass Count to 5
       Jmp  Normal_Process                   ; Process normally
   .Endif                                    ; 
                                             ; 
    Test  FilterFlags,ExtKey_Mode            ; 
   .If <nz> AND                              ; If Extended Key mode
   .If <AL eq 42>                            ; and 2Ah (Pause Key)  <- this is Print Screen not pause
       And  FilterFlags,NOT ExtKey_Mode      ; Remove Extended Key Mode
       Jmp  Normal_Process                   ; Process normally
   .Endif                                    ; 
                                             ; 
   .If <PrevKey ne AL>                       ; If different from last key
       Mov   PrevKey,AL                      ; Save the new key
       Mov   CX,Acc_Ctrl                     ; Set # of Int for Acc Rate
       Mov   Rep_Count,CX                    ; 
       Or    FilterFlags,TYP_DELAY           ; Turn on Delay switch too

      .If <CX eq 0>
          Mov  CX,Delay_Ctrl                 ; Set # of Int for
          Mov  Rep_Count,CX                  ; Typematic Delay
         .If <CX ne DELAY_DISABLED>          ; 
             And  FilterFlags,NOT TYP_DELAY  ; Remove Delay flag
         .Endif                              ; 

          Jmp  Normal_Process                ; Process normally
      .Endif                                 ; 

       Test AL,80h                           ; If not BREAK Key Int
      .If <z>                                ; 
         Or   FilterFlags,TYP_REP            ; It must be typa repeat
      .Else                                  ; Else
         And  FilterFlags,NOT TYP_REP        ; Forget about typa repeat
         And  FilterFlags,NOT ExtKey_Mode    ; Forget about Extended Key
      .Endif                                 ; 
   .Else                                     ; Last Key is the same one
      .If <Rep_Count eq 0>                   ; If Repeat Count is 0

         And  FilterFlags,NOT TYP_REP        ; Don't repeat any more but
         Test FilterFlags,TYP_DELAY          ; check if Delay was done
         .If <z>                             ; If so
             Mov  CX,Typematic_Ctrl          ; Set # of Int for
             Mov  Rep_Count,CX               ; Typematic Rate

            .If <CX eq 0>
                Jmp  Normal_Process          ; Process normally
            .Endif                           ; 

         .Else                               ; else
             Mov  CX,Delay_Ctrl              ; Set # of Int for
             Mov  Rep_Count,CX               ; Typematic Delay

            .If <CX ne DELAY_DISABLED>
                And  FilterFlags,NOT TYP_DELAY     ; Remove Delay flag
            .Endif

            .If <Acc_Ctrl ne 0>
                KbdBeep TimedBeep,KeyFreq,KeyDuration
            .Endif

            .If <CX eq 0>
                Jmp  Normal_Process          ; Process normally
            .Endif                           ; 

         .Endif                              ; 
      .Else                                  ; Repeat Count is not 0
         Or   FilterFlags,TYP_REP            ; Set flag to repeat
        .If <Rep_Count eq DELAY_DISABLED-1>  ; 
            Jmp  Skip_Process                ; 
        .Endif                               ; 
         Dec  Rep_Count                      ; Decrement Repeat Count
      .Endif                                 ; 
   .Endif                                    ; 
                                             ; 
    Test FilterFlags,TYP_REP                 ; If Repeat Flag is on
   .If <nz>                                  ; 
       Jmp  Skip_Process                     ; Jump to the end
   .Endif                                    ; 


Normal_Process:
    Clc
    Ret

Skip_Process:
    Stc
    Ret

ProcessFilter endp



BREAK <SetFilterTypa subroutine>
Public SetFilterTypa
Procedure SetFilterTypa , HYBRID

;/***************************************************************************
;*
;* FUNCTION NAME = SetFilterTypa
;*
;* DESCRIPTION   = Set up Acc_Ctrl, Delay_Ctrl, and Typematic_Ctrl to
;*                 control Acceptance Rate, Typematic Delay, and
;*                 Typematic Rate.  This routine also turns off
;*                 Filter Active mode bit in FilterFlags.
;*
;*
;* NOTES:       This routine is called by SetTypa routine.
;*              Always called in protect mode.
;*
;* ENTRY POINT: SetFilterTypa
;*
;*    LINKAGE : NEAR
;*
;* INPUT         =
;*
;*            AX = Delay Value ( 0000h - 1482h ) or ( 0 - 5250 )
;*            SI = Typematic Rate Value ( 0002h - 001Eh ) or ( 2 - 30 )
;*
;*
;* OUTPUT        = Changes Acc_Ctrl, Delay_Ctrl, and Typematic_Ctrl
;*                 variables.
;*
;*
;* RETURN-NORMAL = Return to the caller
;* RETURN-ERROR  = None
;*
;* PSEUDOCODE:
;*    If AIMActive bit in AIMFlags is off
;*
;*       Set Hw_Typa_Rate to AX
;*       Set Hw_Typa_Delay to SI
;*
;*    Endif
;*
;*    Set Em_Typa_Rate to AX
;*    Set Em_Typa_Delay to SI
;*
;*    Return to the caller
;*
;*
;*********************************************************************

       Push    AX
       Shr     AX,8
       Inc     AX
       Imul    AX,250
       Mov     Em_Typa_Rate, SI
       Mov     Em_Typa_Delay, AX

       Pop     AX

       Ret

SetFilterTypa endp


BREAK <TypaControl_Reset routine>
Public TypaControl_Reset
Procedure TypaControl_Reset  , HYBRID


;/***************************************************************************
;*
;* FUNCTION NAME = TypaControl_Reset
;*
;* DESCRIPTION   = Set up Acc_Ctrl, Delay_Ctrl, and Typematic_Ctrl to
;*                 control Acceptance Rate, Typematic Delay, and
;*                 Typematic Rate.  This routine also turns off
;*                 Filter Active mode bit in FilterFlags.
;*
;* NOTES        =  This routine is called by SGController routine when
;*                 AIM is activated.  This routine is also called by
;*                 Sticky Key  and Timeout logic when Filter Key is
;*                 deactivated.
;*                 Always called in protect mode.
;*
;*
;* INPUT         = Delay Value ( 0000h - 1482h ) or ( 0 - 5250 )
;*                 Typematic Rate Value ( 0002h - 001Eh ) or ( 2 - 30 )
;*                 Timeout Value (?)
;*
;*
;* OUTPUT        = Changes Acc_Ctrl, Delay_Ctrl, and Typematic_Ctrl
;*                 variables.
;*
;* RETURN-NORMAL = Return to the caller
;* RETURN-ERROR  = NONE
;*
;*
;* PSEUDOCODE    =
;*       Turn off Filter Active bit of FilterFlags
;*
;*       Set Acc_Ctrl to zero
;*
;*       Set Hw_Typa_Time to 1000/Hw_Typa_Rate
;*
;*       If KBD_CONTROL bit of FilterFlags is off
;*
;*          Call Device Independent Entry Point to set Typamatic
;*          Rate/Delay to 30 chars/sec and 250 millisec.
;*
;*          Turn on KBD_CONTROL bit of FilterFlags
;*
;*       Endif
;*
;*       Set Filter_Ctrl to (FIVESEC - Hw_Typa_Delay) / Hw_Typa_Time
;*
;*       /* Set Faking Typematic Rate and Delay Controls       */
;*
;*       Set Acc_Ctrl to zero
;*
;*       If Em_Typa_Delay - Hw_Typa_Delay is equal to zero
;*
;*          Set Delay_Ctrl to zero
;*
;*       Else
;*
;*          Set Delay_Ctrl to
;*          (Em_Typa_Delay - Hw_Typa_Delay) / Hw_Typa_Time
;*
;*       Endif
;*
;*       If Hw_Typa_Rate - Em_Typa_Rate is less than 5
;*
;*          Set Typematic_Ctrl zero
;*
;*       Else
;*
;*          Set Typematic_Ctrl to Hw_Typa_Rate / Em_Typa_Rate
;*
;*       Endif
;*
;*       /* Compute Filter Typematic Rate and Delay Controls   */
;*
;*       If AimAccept is zero
;*
;*          Set Comp_Acc_Ctrl to zero
;*
;*       Else
;*
;*          If AimAccept - Hw_Typa_Delay is equal to zero
;*
;*             Set Comp_Acc_Ctrl to 1
;*
;*          Else
;*
;*             Set Comp_Acc_Ctrl to
;*             (AimAccept - Hw_Typa_Delay) / Hw_Typa_Time
;*
;*          Endif
;*
;*       Endif
;*
;*
;*       If AimRate is zero
;*
;*          Set Comp_Typematic_Ctrl to zero
;*
;*       Else
;*
;*          Set Comp_Typematic_Ctrl to AimRate / Hw_Typa_Time
;*
;*       Endif
;*
;*
;*       If AimDelay is zero
;*
;*          Set Comp_Delay_Cntrl to DELAY_DISBALED
;*
;*       Else
;*
;*          If AimDelay is equal to KBD_FAST_DELAY  OR
;*             AimAccept is greater or eqaul to AimDelay
;*
;*             Set Comp_Delay_Cntrl to zero
;*
;*          Else
;*
;*             Set Comp_Delay_Ctrl to AimDelay / Hw_Typa_Time
;*
;*          Endif
;*
;*       Endif
;*
;*       Set Comp_AIMTimeout to AIMTimeout * 18
;*
;*
;*    Return to the caller
;*
;*********************************************************************


.386c
     SaveReg<EAX,EBX,EDX,ESI,ECX>             

        Test    FilterFlags, Filter_Active
       .If <nz>

           Mov   Beep_State,DISABLE_BEEP
           Mov   AX, Offset KbdCode:KBDBeep2KHz
           Mov   BX, IMMEDIATE_TICK
           Mov   DL, DevHlp_TickCount
           Call  [DeviceHelp]
       .Endif

        And     FilterFlags, NOT Filter_Active

        Mov     Acc_Ctrl,0

        Mov     Hw_Typa_Rate,KBD_FAST_RATE
        Mov     Hw_Typa_Delay,KBD_FAST_DELAY

        Xor     EAX,EAX
        Xor     EDX,EDX
        Mov     AX,1000d
        Div     Hw_Typa_Rate
        Mov     Hw_Typa_Time,AX

.286c
        Test    FilterFlags,KBD_CONTROL
       .If <z>
           Or   AIMFlags,TYPACONTROL_CALLING
           Xor  DX,DX
           Xor  AX,AX               ; 30 char/sec + 500 millisec
           Push 2222h               ; Var2 (Not used for this call)
           Push AX                  ; Var1 (Rate and Delay)
           Push DD_Cmd_Typematic    ; Function
           Call DD_Entry        ; Device Independent Entry Point
           And  AIMFlags,NOT TYPACONTROL_CALLING
           Or   FilterFlags,KBD_CONTROL
       .Endif
.386c
;Typematic Rate/Delay and Acceptance Rate Control
;****** Set Filter_Cntrl **********************************

        Xor     EAX,EAX
        Xor     EDX,EDX
        Mov     AX,FIVESEC
        Mov     BX,Hw_Typa_Delay
        Sub     AX,BX
        Div     Hw_Typa_Time
        Mov     Filter_Ctrl, AL

;****** Set Faking Typematic Rate and Delay Controls *******

        Mov     Acc_Ctrl,0
        Mov     AX,Em_Typa_Delay
        Sub     AX,BX
       .if <AX eq 0>
           Mov          Delay_Ctrl,0
       .Else
           Xor          EDX,EDX
           Div          Hw_Typa_Time
           Mov          Delay_Ctrl,AX
       .Endif

        Mov     AX,Hw_Typa_Rate
        Mov     BX,Em_Typa_Rate
        Sub     AX,BX
       .If <AX lt 5>
           Mov          Typematic_Ctrl,0
       .Else
           Xor          EAX,EAX
           Xor          EDX,EDX
           Mov          AX,Hw_Typa_Rate
           Div          Em_Typa_Rate
           Mov          Typematic_Ctrl,AX
       .Endif

;****** Compute Filter Typematic Rate and Delay Controls ******-

        Mov     EAX,AIMAccept
       .If <AX eq 0>
                Mov     Comp_Acc_Ctrl,0
       .Else
                Sub     AX,Hw_Typa_Delay
               .If <AX eq 0>
                        Mov     Comp_Acc_Ctrl,1
               .Else
                        Xor     EDX,EDX
                        Div     Hw_Typa_Time
                        Mov     Comp_Acc_Ctrl, AX
                        Mov     Comp_Rep_Count,AX
               .Endif
       .Endif

        Mov     EAX,AIMRate
       .If <AX eq 0>
                Mov     Comp_Typematic_Ctrl,0
       .Else
                Xor     EDX,EDX
                Div     Hw_Typa_Time
                Mov     Comp_Typematic_Ctrl, AX
       .Endif

        Mov     EAX,AIMDelay
       .If <AX eq 0>
                Mov     Comp_Delay_Ctrl,DELAY_DISABLED
       .Else
                Xor     ECX,ECX
                Mov     CX,Hw_Typa_Delay

               .If <AIMAccept eq 0>
                        Sub     EAX,ECX
               .Endif

            ;*
            ;*  .If <AX eq Hw_Typa_Delay> OR
            ;* .If <EAX ge AimAccept>
            ;*  .If <AimAccept ge EAX>
            ;*           Mov     Comp_Delay_Ctrl,0
            ;*  .Else
            ;*

                        Xor     EDX,EDX
                        Div     Hw_Typa_Time
                        Mov     Comp_Delay_Ctrl, AX
            ;  .Endif
       .Endif

        Xor     EAX,EAX
        Mov     AX,AIMTimeout
        Mul     Tick_Per_Sec
        Mov     Comp_AIMTimeout,AX

     RestoreReg<ECX,ESI,EDX,EBX,EAX>             
.286c

        Ret

TypaControl_Reset  endp


BREAK <TypaControl_Disable routine>
Public TypaControl_Disable
TypaControl_Disable  Proc Far

;/***************************************************************************
;*
;* FUNCTION NAME = TypaControl_Disable
;*
;* DESCRIPTION   = Set up Acc_Ctrl, Delay_Ctrl, and Typematic_Ctrl to
;*                 control Acceptance Rate, Typematic Delay, and
;*                 Typematic Rate.  This routine also turns off
;*                 Filter Active mode bit in FilterFlags.
;*
;* NOTES         = This routine is called by SGController routine when
;*                 AIM is deactivated.
;*                 Always called in protect mode.
;*
;*
;* INPUT         = NONE
;* OUTPUT        = Changes Acc_Ctrl, Delay_Ctrl, and Typematic_Ctrl
;*                 variables.
;*
;* RETURN-NORMAL = Return to the caller
;* RETURN-ERROR  = NONE
;*
;*
;* PSEUDOCODE    =
;*                                                                    *
;*    Turn off Filter Active mode bit of FilterFlags                  *
;*                                                                    *
;*    Set AX to Em_Typa_Delay                                         *
;*    Set SI to Em_Typa_Rate                                          *
;*                                                                    *
;*    Call Typa_RDCheck to set AX bits                                *
;*                                                                    *
;*    Call DD_Cmd_Entry with DD_Cmd_Typematic function to set         *
;*    keybaord hardware typematic rate and delay                      *
;*                                                                    *
;*    Thurn off KBD_CONTROL bit in FilterFlags                        *
;*                                                                    *
;*    Return to the caller                                            *
;*                                                                    *
;********************************************************************** !

     SaveReg<AX,BX,DX,SI>

        Test    FilterFlags, Filter_Active
       .If <nz>

           Mov   Beep_State,DISABLE_BEEP

           Mov   AX, Offset KbdCode:KBDBeep2KHz

           Mov   BX, IMMEDIATE_TICK
           Mov   DL, DevHlp_TickCount
           Call  [DeviceHelp]

       .Endif

        And FilterFlags,NOT Filter_Active

        Mov  AX,Em_Typa_Delay
        Mov  SI,Em_Typa_Rate

        CALLFAR Typa_RDCheck     ; Returns with AX bits set

        Push 2222h               ; Var2 (Not used for this call)
        Push AX                  ; Var1 (Rate and Delay)
        Push DD_Cmd_Typematic    ; Function
        Call DD_Entry        ; Device Independent Entry Point

        And  FilterFlags, NOT KBD_CONTROL

     RestoreReg<SI,DX,BX,AX>

        Ret


TypaControl_Disable endp

public  End_AIMCode
End_AIMCode     label   byte

AIMCode Ends
     End
