home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / MOUSE / PDI.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  37KB  |  1,153 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT (C) Microsoft Corporation, 1989
  4. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  5. ;
  6. ;    The following IBM OS/2 WARP source code is provided to you solely for
  7. ;    the purpose of assisting you in your development of OS/2 WARP device
  8. ;    drivers. You may use this code in accordance with the IBM License
  9. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  10. ;    Copyright statement may not be removed.;
  11. ;*****************************************************************************/
  12. ;/*************************************************************************
  13. ;*
  14. ;* SOURCE FILE NAME = PDI.ASM
  15. ;*
  16. ;* DESCRIPTIVE NAME = Pointing Device Interface (PDI) code
  17. ;*
  18. ;*
  19. ;* VERSION      V2.0
  20. ;*
  21. ;* DATE         03/19/92
  22. ;*
  23. ;* DESCRIPTION  This file contains the PDI specific routines used
  24. ;*              by the generic pointing device driver.
  25. ;*
  26. ;*              Currently known and supported PDI devices are;
  27. ;*
  28. ;*              IBM PS/2 Mouse
  29. ;*              MS PS/2 Mouse
  30. ;*              Logitech PS/2 Mouse
  31. ;*              Kensington Expert Mouse (really trackball device)
  32. ;*
  33. ;* FUNCTIONS    CheckforPDIDevice
  34. ;*              Enable_Ints        -Enable keyboard Interface
  35. ;*              ResetMouse         -Reset PS/2 mouse.
  36. ;*              IsScrnKeypad       -Determine if a ScreenReader 18-key
  37. ;*                                   keypad is plugged into PDI port
  38. ;*              ResetPrescott      -Reset prescott display
  39. ;*              WriteInputBuffer   -Send a byte of data to 8042 (port 60h).
  40. ;*              SendToMouse        -Send command to auxillary device
  41. ;*              Read8042Data       -Wait until there is data in the output
  42. ;*                                  buffer and return it in AL.
  43. ;*              GetMouseData       -Read a byte of data to auxillary device
  44. ;*              SetSampleRate      -Send the SetSampleRate Command (0f3h)
  45. ;*                                   to the Aux device
  46. ;*              SetScaling         -Send the SetScaling 2:1 Command (0E7h)
  47. ;*              SetResolution      -Send the SetResolution Command (0e8h)
  48. ;*                                   to the Aux device.
  49. ;*              EnablePDI          -Enable the Aux Device
  50. ;*              ClearAuxPort       -Read all Aux port data
  51. ;*            WriteControlRegister -Send a command byte to the
  52. ;*                                   8042's control register (64h)
  53. ;*              PDIInit            -Gets the PDI LID if on ABIOS system
  54. ;*
  55. ;*
  56. ;*
  57. ;*
  58. ;* STRUCTURES   NONE
  59. ;*
  60. ;* EXTERNAL REFERENCES
  61. ;*
  62. ;*              NONE
  63. ;*
  64. ;* EXTERNAL FUNCTIONS
  65. ;*
  66. ;*              NONE
  67. ;*
  68. ;* CHANGE ACTIVITY =
  69. ;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
  70. ;*   --------  ----------  -----  --------------------------------------
  71. ;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
  72. ;*   04/04/93              53232  Add support for Logitech middle button
  73. ;**************************************************************************
  74.  
  75.  
  76.  
  77. .xlist
  78.        include basemaca.inc
  79.        include mouse.inc
  80. .list
  81.  
  82. .386p
  83.  
  84. ;*
  85. ;*    External Mouse Module Data References
  86. ;*
  87.  
  88.        extrn TranslateMode       : byte
  89.        extrn AUXPortExists       : byte
  90.        extrn DeviceData          : byte
  91.        extrn ABIOS_Mch           : byte
  92.        extrn PrescottDsp         : byte
  93.        extrn ScreenKeypad        : byte
  94.        extrn Init_Time           : byte
  95.  
  96.        extrn Int_Packet          : word
  97.        extrn SynchFlag           : word                ;           
  98.  
  99.        extrn HotPlugHandle       : dword
  100.        extrn Device_Help         : dword
  101.  
  102.        extrn SetupForWait        : near
  103.        extrn IsWaitOver          : near
  104.        extrn HookHotPlugPDI      : far
  105.  
  106.        extrn  WriteControlRegister : near
  107.  
  108.        extrn  _RM_MSE_AllocPorts   : far
  109.        extrn  _RM_MSE_AllocPort2   : far
  110.        extrn  _RM_MSE_DeallocPorts : far
  111.        extrn  _RM_MSE_DeallocPort2 : far
  112.  
  113. CSEG     SEGMENT   WORD  PUBLIC  USE16  'CODE'
  114.          ASSUME    CS:CSEG, SS:nothing, ES:nothing, DS:nothing
  115.  
  116.        public  CheckforPDIDevice
  117.        public  Enable_Ints
  118.        public  ResetMouse
  119.        public  ResetPrescott
  120.        public  WriteInputBuffer
  121.        public  SendToMouse
  122.        public  Read8042Data
  123.        public  GetMouseData
  124.        public  SetSampleRate
  125.        public  SetScaling
  126.        public  SetResolution
  127.        public  EnablePDI
  128.        public  ClearAuxPort
  129.        public  PDIInit
  130.        public  EnableKbdInt
  131.        public  DisableKbdInt
  132.        public  Find3ButtonMouse                      ;           
  133.  
  134. ;************************************************************************
  135. ;*
  136. ;*  FUNCTION NAME  :  CheckforPDIDevice
  137. ;*
  138. ;*  DESCRIPTION    :  This routine firsts issues the Disable Keyboard
  139. ;*                    Interface (ADh) to the controller. It then issues
  140. ;*                    a Write Controller Ram (60h) command. It writes
  141. ;*                    a 54h to the controller where the bits are
  142. ;*                    defined below.
  143. ;*
  144. ;*  We need to disable interrupts for both keyboard and mouse
  145. ;*  during this init routine. There are various controller
  146. ;*  commands that would cause an IRQ 1. The keyboard DD would
  147. ;*  probably think the interrupt was a scan code and get
  148. ;*  confused. The mouse does not register its interrupt handler
  149. ;*  until the end of the init routine which makes sense. Why
  150. ;*  complicate the interrupt handler when the only thing
  151. ;*  needed after init time is mouse event handling
  152. ;*
  153. ;*
  154. ;*  ENTRY POINT   : CheckforPDIDevice   LINKAGE:  CALL NEAR
  155. ;*
  156. ;*  INPUT         :  N/A
  157. ;*
  158. ;*  RETURN-NORMAL : Carry Flag clear
  159. ;*
  160. ;*  RETURN-ERROR  :  Carry Flag Set
  161. ;*
  162. ;*  EFFECTS       :  Changes ES
  163. ;*
  164. ;*  INTERNAL REFERENCES:
  165. ;*     ROUTINES:  None.
  166. ;*
  167. ;*  EXTERNAL REFERENCES:
  168. ;*     ROUTINES:  NONE.
  169. ;*     DevHlps:  None.
  170. ;*
  171. ;*            This routine firsts issues the Disable Keyboard
  172. ;*            Interface (ADh) to the controller. It then issues
  173. ;*            a Write Controller Ram (60h) command. It writes
  174. ;*            a 54h to the controller where the bits are
  175. ;*            defined below;
  176. ;*
  177. ;*************************************************************************
  178.  
  179. CheckforPDIDevice  proc  near
  180.  
  181. ;*************************************************************************
  182. ;* WARNING 10/24/91:
  183. ;*
  184. ;* It is necessary to first check if POST has found a pointing device
  185. ;* plugged into the AUX (PS/2) port. Some clones were responding to the
  186. ;* test AUX interface command (0a9h) as if they had a system mouse port
  187. ;* when in fact they did not. When the preceeding AUX commands were sent
  188. ;* to the controller the 8042 clone chip was leaving the keyboard in a
  189. ;* disabled state. The word at 40h:10h is defined as the Equipment flags
  190. ;* word. This word can also be retrieved via an Int 11h call. Bit 2 of
  191. ;* this word is the Pointing device installed bit. POST will attempt to
  192. ;* do a reset (0ffh) command to the AUX device. If the AUX device responds
  193. ;* with an 0aah (POR complete) this bit is turned ON. This is supposed to
  194. ;* be an industry standard and every system seems to set this bit correctly
  195. ;* to date.
  196. ;**************************************************************************
  197.  
  198.        push 40h
  199.        pop  es
  200.        mov  ax, word ptr es:[10h]     ; Equipment flags
  201.        test ax, 4                     ; Bit 2 - Pointing device installed
  202.        jnz  pdi_ok
  203.        cmp  ABIOS_Mch,TRUE            ; ABIOS machines ALWAYS have PDI port
  204.        jz   pdi_ok
  205.        stc
  206.        jmp  pdi_return
  207.  
  208. pdi_ok:
  209.        mov al, Init_Time
  210.        .if <al ne 0>
  211.           pusha
  212.           push es
  213.           push 60h
  214.           call _RM_MSE_AllocPorts
  215.           pop dx
  216.           or ax, ax
  217.           jnz short PortPDIClaimed
  218.           push 64h
  219.           call _RM_MSE_AllocPort2
  220.           or ax, ax
  221.           pop ax
  222. PortPDIClaimed:
  223.           pop es
  224.           popa
  225.           jnz  pdi_claimed
  226.        .endif
  227.  
  228.        call DisableKbdInt             ; disable keyboard interrupt
  229.  
  230.        mov  al, 0adh                  ; Disable the keyboard.
  231.        call WriteControlRegister      ; send command to controller (64h)
  232.        jc   pdi_error
  233.  
  234.        mov  al, 20h                   ; Tell 8042 that we want to read the
  235.        call WriteControlRegister      ; controller command byte from (60h)
  236.        jc   pdi_error
  237.  
  238.        call Read8042Data              ; read the controller command byte.
  239.        jc   pdi_error
  240.  
  241.        and  al, 40h
  242.        mov  TranslateMode, al         ; save keyboard translate mode
  243.  
  244.        mov  al, 60h                   ; Tell 8042 that we want to write the
  245.        call WriteControlRegister      ; controller command byte from (60h).
  246.        jc  pdi_error
  247.  
  248.  
  249. ;**************************************************************************
  250. ;* The bit definitions for the controller command byte on any system that
  251. ;* has an AUX port are listed below;
  252. ;*
  253. ;*      Bit   Function
  254. ;*
  255. ;*  0  7 -  Reserved (Always set to 0)
  256. ;*  1  6 -  IBM Keyboard Translate Mode
  257. ;*  0  5 -  Disable AUX Device  (0 = Enabled state, 1 = disabled state)
  258. ;*  1  4 -  Disable Keyboard    (0 = Enabled state, 1 = disabled state)
  259. ;*  0  3 -  Reserved (Always set to 0)
  260. ;*  1  2 -  System Flag (Always set to 1)
  261. ;*  0  1 -  Enable Auxiliary Interrupt (0 = No Aux Ints, 1 = AUX ints enabled)
  262. ;*  0  0 -  Enable Keyboard Interrupt  (0 = No Kbd Ints, 1 = Kbd ints enabled)
  263. ;*
  264. ;* NOTE: I have noticed that this byte is initially set to 65h on systems
  265. ;*       with an AUX port and 45h on systems without an AUX port.
  266. ;*
  267. ;* WARNING!!! On family1 systems without an AUX port the AUX related
  268. ;*            bits (1 and 5) should always be set to zero.
  269. ;**************************************************************************
  270.  
  271.        mov  al, 54h                   ; Write the command byte to controller
  272.        call WriteInputBuffer          ; Send it to 8042 port (60h).
  273.        jc  pdi_error
  274.  
  275. ;*
  276. ;* We will now issue the 8042 command to test the auxiliary interface.
  277. ;* This command only exists on 8042s that support an auxiliary device. If
  278. ;* the test succeeds, a 00h will be placed in the 8042's output buffer.
  279. ;* If no output appears in the 8042's output buffer, it is assumed that the
  280. ;* 8042 does not support an auxiliary device.
  281. ;*
  282.  
  283. ;*
  284. ;* WARNING: The testing of the auxiliary interface will more than likely
  285. ;*       up an auxiliary device attached to it. Therefore, the auxiliary
  286. ;* device should be initialized after calling this procedure.
  287. ;*
  288.        mov  al, 0a9h                  ; Command to test the auxiliary
  289.        call WriteControlRegister      ; device.
  290.        jc   pdi_error                 ; Leave if error.
  291.  
  292.        call Read8042Data              ; Read test results from port (60h)
  293.        jc   pdi_error                 ; No auxiliary device.
  294.  
  295. ;*
  296. ;* WARNING - On certain clones I have noticed that we consistantly
  297. ;* get back a 01 from the 0xA9 command. This means that the AUX device
  298. ;* clock line is stuck low. If we ignore this error and continue on
  299. ;* everything works ok. The reset command follows so it is sufficient
  300. ;* to say that if we get data back from the 8042 then we have an AUX
  301. ;* port. The rest of the code will ensure that a functional pointing
  302. ;* device is attached to the system.  (3/4/92)
  303. ;*
  304.  
  305. ;***   .if <ZERO al>                  ; Was the byte we got 0?
  306.           mov  AUXPortExists, TRUE    ; It was initialized to FALSE
  307. ;**  .else
  308. ;**     jmp  pdi_error
  309. ;**  .endif
  310.  
  311.        call IsScrnKeypad              ; is it a screen reader keypad?
  312.        jc   notpres
  313.  
  314.        call ResetPrescott
  315. notpres:
  316.  
  317.        call ResetMouse
  318.        jc  pdi_error
  319.  
  320.        call Find3ButtonMouse          ;           
  321.  
  322.        call SetSampleRate
  323.        jc  pdi_error
  324.  
  325.        call SetResolution
  326.        jc  pdi_error
  327.  
  328.        call SetScaling
  329.        jc  pdi_error
  330.  
  331.        call EnablePDI
  332.        jc  pdi_error
  333.  
  334. ;*
  335. ;* Now enable the keyboard and aux interfaces and the aux interrupts.
  336. ;*
  337.        mov  bl, 07h                   ; both kbd and aux
  338.        or   bl, TranslateMode
  339.        call Enable_Ints
  340.        .if  <nc>
  341.           mov  DeviceData.IRQ,12      ; set IRQ level (system defined)
  342.           jmp  pdi_exit
  343.        .endif
  344.  
  345. pdi_error:
  346.        .if <AUXPortExists eq TRUE>
  347.           mov  bl, 25h                ; We have an AUX port
  348.           or   bl, TranslateMode
  349.           call Enable_Ints
  350.           mov  al, 0a7h               ; Disable Auxilary Device Interface
  351.           call WriteControlRegister
  352.           call ClearAuxPort           ; clear the aux port
  353.        .else
  354.           mov  bl, 05h                ; No AUX port, bits are slightly different
  355.           or   bl, TranslateMode
  356.           call Enable_Ints
  357.        .endif
  358.  
  359.        mov al, Init_Time
  360.        .if <al ne 0>
  361.           pusha
  362.           push es
  363.           call _RM_MSE_DeallocPorts
  364.           call _RM_MSE_DeallocPort2
  365.           pop es
  366.           popa
  367.        .endif
  368.  
  369. pdi_claimed:
  370.        stc
  371.  
  372. pdi_exit:
  373.        call EnableKbdInt              ; enable keyboard interrupt
  374. pdi_return:
  375.        ret
  376.  
  377. CheckforPDIDevice  endp
  378.  
  379.  
  380. ;****************************************************************
  381. ;*
  382. ;*  FUNCTION NAME  :  Enable_Ints
  383. ;*
  384. ;*  DESCRIPTION    :  Enable keyboard interface
  385. ;*
  386. ;*                    This routine firsts issues an Enable Keyboard
  387. ;*                    Interface (AEh) to the controller. It then issues
  388. ;*                    a Write Controller Ram (60h) command. It writes
  389. ;*                    the caller's value to the controller RAM.
  390. ;*
  391. ;*  ENTRY POINT   :  Enable_Ints       LINKAGE:  CALL NEAR
  392. ;*
  393. ;*  INPUT         :  BL = value to write to controller RAM
  394. ;*
  395. ;*  RETURN-NORMAL :  Keyboard enabled and IRQ 1 activated.
  396. ;*
  397. ;*  RETURN-ERROR  :  N/A.
  398. ;*
  399. ;*  EFFECTS       :  None
  400. ;*
  401. ;*
  402. ;****************************************************************
  403.  
  404. Enable_Ints  proc  near
  405.  
  406.         mov  al, 0aeh                  ; Enable the keyboard.
  407.         call WriteControlRegister      ; send command to controller (64h)
  408.         jc   ei_exit
  409.  
  410.         mov  al, 60h                   ; Tell 8042 that we want to write the
  411.         call WriteControlRegister      ; command byte.
  412.         jc   ei_exit                   ; Leave if we have an error.
  413.  
  414.         mov  al, bl                    ; Write callers value
  415.         call WriteInputBuffer          ; Send it to 8042.
  416.  
  417. ei_exit:
  418.         ret
  419.  
  420. Enable_Ints  endp
  421.  
  422.  
  423. ;****************************************************************
  424. ;*
  425. ;*  FUNCTION NAME :  ResetMouse
  426. ;*
  427. ;*  DESCRIPTION   : This procedure attempts to reset a PS/2
  428. ;*                    mouse. It does this by sending a reset
  429. ;*                    command to the mouse and checking to
  430. ;*                    ensure that it passed its diagnostics.
  431. ;*
  432. ;*   INPUT        :  Mouse interrupts disabled.
  433. ;*
  434. ;*   OUTPUT       :   Carry clear     Mouse has been reset correctly
  435. ;*                     AL              ID Code
  436. ;*
  437. ;*   RETURN-ERROR :  Carry set  Error condition.
  438. ;*
  439. ;*   ALTERS       : AX, CX
  440. ;*
  441. ;*   CALLS        : SendToMouse, GetMouseData
  442. ;*
  443. ;****************************************************************
  444.  
  445. ResetMouse  proc  near
  446.  
  447.         mov   al, 0ffh                ; Send the reset command to the mouse.
  448.         call  SendToMouse
  449.         jc   rm_exit
  450.         call GetMouseData             ; Get response from the mouse
  451.         .if <al ne 0fah>
  452.            stc
  453.            jmp  rm_exit
  454.         .endif
  455.  
  456.         call GetMouseData             ; Get response from the mouse
  457.         .if <al ne 0aah>
  458.            stc
  459.            jmp  rm_exit
  460.         .endif
  461.  
  462.         call GetMouseData             ; Get response from the mouse
  463.         .if <ZERO al>
  464.            clc
  465.         .else
  466.            stc
  467.         .endif
  468.  
  469. rm_exit:
  470.         ret
  471.  
  472. ResetMouse  endp
  473.  
  474.  
  475. ;****************************************************************
  476. ;*
  477. ;*  FUNCTION NAME :  IsScrnKeypad
  478. ;*
  479. ;*  DESCRIPTION   :  This procedure attempts to determine
  480. ;*                   if a ScreenReader 18-key keypad is
  481. ;*                   plugged into the PDI port
  482. ;*
  483. ;*  INPUT         :  This routine must be called after the 8042 has
  484. ;*                   been put in disable mode.
  485. ;*
  486. ;*  OUTPUT        :  Carry clear     No keypad attached
  487. ;*                   Carry set       Keypad attached
  488. ;*
  489. ;****************************************************************
  490.  
  491. IsScrnKeypad proc  near
  492.         mov   al, 0f2h                ; Read the device type attached
  493.         call  SendToMouse
  494.         jc   ik_exit
  495.  
  496.         call GetMouseData             ; Get response (should be ACK x'FA')
  497.         cmp  al,0FAh
  498.         jne  ik_exit
  499.  
  500.         call GetMouseData             ; Get ID (should be x'01' for pad)
  501.         cmp  al,01
  502.         jne  ik_exit
  503.         mov  ScreenKeypad,TRUE
  504.         stc
  505.         ret
  506. ik_exit:
  507.         clc
  508.         ret
  509.  
  510. IsScrnKeypad endp
  511.  
  512.  
  513. ;****************************************************************
  514. ;*
  515. ;*  FUNCTION NAME  : ResetPrescott
  516. ;*
  517. ;*  DESCRIPTION    : This procedure attempts to reset a
  518. ;*                    Prescott display by sending a reset
  519. ;*                    command to the device and checking to
  520. ;*                    ensure that it passed its diagnostics.
  521. ;*
  522. ;*   INPUT         : Mouse interrupts disabled.
  523. ;*
  524. ;*   OUTPUT        : Carry clear     Mouse has been reset correctly
  525. ;*                     AL              ID Code
  526. ;*
  527. ;*   EXIT ERROR    : Carry set  Error condition.
  528. ;*
  529. ;*   ALTERS        : AX, CX
  530. ;*
  531. ;*   CALLS         : SendToMouse, GetMouseData
  532. ;*
  533. ;****************************************************************
  534.  
  535. ResetPrescott proc  near
  536.  
  537.         mov   al, 0bbh                ; Send the reset command to the
  538.         call  SendToMouse             ; 8516 Touch Display
  539.         jc   rp_exit
  540.  
  541.         call GetMouseData             ; Get response from the 8516 display
  542.         .if <al ne 0cah>
  543.            stc
  544.            jmp  rp_exit
  545.         .endif
  546.  
  547.         mov  dx, 99
  548. rp_loop:
  549.         mov  cx, 100                  ; Wait for 100 millisecs
  550.         call SetupForWait
  551.         .repeat
  552.            call IsWaitOver
  553.         .until <c>
  554.  
  555.         in   al, 64h                 ; Get current 8042 status.
  556.         and  al, 21h                 ; We're only interested in Aux OBF bits
  557.         cmp  al, 21h                 ; If OBF and Aux data then
  558.         jz   rp_data                 ; It's OK to proceed
  559.         dec  dx
  560.         jnz  rp_loop
  561.         stc
  562.         jmp  rp_exit
  563.  
  564. rp_data:                             ; There is mouse data to be read.
  565.  
  566.         in   al, 60h                 ; Read byte of data from Prescott
  567.         mov  bl, al
  568.         in   al, 64h
  569.         test al, 0c0h                ; Parity Error + General Time-Out bits
  570.         jnz  rp_loop                 ; should be off
  571.  
  572.         .if <bl ne 0abh> AND
  573.         .if <bl ne 0cdh>
  574.            stc
  575.            jmp  rp_exit
  576.         .endif
  577.  
  578.         call GetMouseData             ; Get response from the mouse
  579.         .if <al eq 2>
  580.            mov  PrescottDsp, TRUE
  581.            clc
  582.         .else
  583.            stc
  584.         .endif
  585.  
  586. rp_exit:
  587.         ret
  588.  
  589. ResetPrescott  endp
  590.  
  591.  
  592. ;****************************************************************
  593. ;*
  594. ;*  FUNCTION NAME :  WriteInputBuffer
  595. ;*
  596. ;*  DESCRIPTION   : This procedure will send a byte of data to the
  597. ;*                  8042 (port 60h).
  598. ;*
  599. ;*  NOTES         : Before the data is sent to the 8042 both the input
  600. ;*                  buffer full and output buffer full bits of the status
  601. ;*                  register must be off.
  602. ;*
  603. ;*               This procedure sends a byte of data to the 8042's
  604. ;*               input buffer. It should not be called unless the
  605. ;*               8042 has already been set up to expect this byte of data.
  606. ;*
  607. ;*               Only 64K attempts will be made before timing out.
  608. ;*
  609. ;*   INPUT        : AL - Data byte to be sent.
  610. ;*
  611. ;*   OUTPUT       : Carry clear - Data sent sucessfully
  612. ;*                  Carry set   - Data not sent, error condition.
  613. ;*
  614. ;*   ALTERS       : CX register
  615. ;*
  616. ;****************************************************************
  617.  
  618. WriteInputBuffer  proc  near
  619.  
  620. ;*
  621. ;* Upon entry, it is assumed that a command has just been sent to the
  622. ;*  8042. Therefore, we will wait until the 8042 has removed the command
  623. ;*  byte from its input buffer before doing anything else.
  624. ;*
  625.  
  626.         push ax                      ; Save callers value to be written
  627.         xor  cx, cx                  ; Loop counter
  628.  
  629. wib_retry:
  630.         in   al, 64h                 ; Get 8042's current status.
  631.         test al, 03h                 ; Is the in/out buffer still full?
  632.         jz   wib_ok                  ; It's OK to proceed
  633.         loop wib_retry               ; Try again.
  634.         stc                          ; Error condition
  635.         pop  ax                      ; Callers value on top of stack
  636.         jmp  short wib_exit          ; Return with failure.
  637.  
  638. wib_ok:                              ; Input and output buffers are empty.
  639.         pop  ax                      ; Get saved data byte.
  640.         out  60h, al                 ; Send data byte.
  641.         clc                          ; Show success.
  642.  
  643. wib_exit:
  644.         ret
  645.  
  646. WriteInputBuffer  endp
  647.  
  648.  
  649. ;****************************************************************
  650. ;*
  651. ;*  FUNCTION NAME : SendToMouse
  652. ;*
  653. ;*  DESCRIPTION   : This procedure will send a command to the
  654. ;*                  auxiliary device
  655. ;*
  656. ;*  NOTES         : The routine first sends a Write to Auxiliary Device
  657. ;*                  (D4h) command to the controller. It then sends the
  658. ;*                  callers command which was passed in (AL register)
  659. ;*                  to port 60h which is the Aux device at this time.
  660. ;*
  661. ;*   INPUT        :  AL - Command to be sent.
  662. ;*
  663. ;*   OUTPUT       :  Carry clear - Command sent sucessfully
  664. ;*                   Carry set   - Command not sent, error condition.
  665. ;*
  666. ;****************************************************************
  667.  
  668. SendToMouse  proc  near
  669.  
  670.         push ax                      ; Save command/data byte.
  671.         mov  al, 0d4h                ; Tell 8042 we want to send a byte to
  672.         call WriteControlRegister    ; the auxiliary device.
  673.         pop  ax                      ; Get saved command/data byte.
  674.         jc   stm_exit                ; Leave if error.
  675.         call WriteInputBuffer        ; Send data/command to aux dev.
  676. stm_exit:
  677.         ret
  678.  
  679. SendToMouse  endp
  680.  
  681.  
  682. ;****************************************************************
  683. ;*
  684. ;*  FUNCTION NAME  :  Read8042Data
  685. ;*
  686. ;*  DESCRIPTION    : This procedure will wait until there is data
  687. ;*                   in the output buffer and return it in AL.
  688. ;*
  689. ;*  NOTE: Before the data is read the output buffer full bit
  690. ;*        must be on in the 8042 Controller Status Register.
  691. ;*
  692. ;*        Only 64K attempts will be made before timing out.
  693. ;*
  694. ;*  INPUT         : N/A
  695. ;*
  696. ;*  OUTPUT        :  Carry clear - AL holds the data byte
  697. ;*                   Carry set   - Error condition.
  698. ;*
  699. ;****************************************************************
  700.  
  701. Read8042Data  Proc  Near
  702.  
  703.         xor  cx,cx
  704.  
  705. rd_retry:
  706.         in   al, 64h              ; Read status port of 8042
  707.         test al, 01h              ; Is the output buffer full
  708.         jnz  rd_ok                ; If so, it's OK to proceed
  709.         loop rd_retry             ; try again
  710.         stc                       ; Error condition
  711.         jmp  rd_exit
  712.  
  713. rd_ok:
  714.         in  al, 60h               ; get data
  715.         clc                       ; clear carry for no error
  716.  
  717. rd_exit:
  718.         ret
  719.  
  720. Read8042Data  endp
  721.  
  722.  
  723. ;****************************************************************
  724. ;*
  725. ;*  FUNCTION NAME :  GetMouseData
  726. ;*
  727. ;*  DESCRIPTION   : This procedure will try to read a byte of
  728. ;*                  data from the auxiliary device.
  729. ;*
  730. ;*  NOTE: Only 15*64K attempts will be made before timing out.
  731. ;*
  732. ;*        I have seen instances where 64K times is not
  733. ;*        enough time for the AUX output buffer full bit to
  734. ;*        turn on. This happened on the reset mouse command.
  735. ;*        It seems that 15*64K is enough for all systems to
  736. ;*        date. (WARNING - 8/15/90)
  737. ;*
  738. ;*   INPUT        :  N/A
  739. ;*
  740. ;*   OUTPUT       : Carry clear     Read was successfully
  741. ;*                  AL              The byte of data that was read
  742. ;*
  743. ;*                  Carry set       The byte of data could not be read
  744. ;*
  745. ;*   ALTERS       : CX and AX registers
  746. ;****************************************************************
  747.  
  748. GetMouseData  Proc  Near
  749.  
  750.  
  751.         mov  ah, 15                  ; Outer loop counter is 15
  752. gmd_outer:
  753.         xor  cx,cx                   ; Inner loop counter is 64K
  754. gmd_inner:
  755.         in   al, 64h                 ; Get current 8042 status.
  756.         and  al, 21h                 ; We're only interested in Aux OBF bits
  757.         cmp  al, 21h                 ; If OBF and Aux data then
  758.         jz   gmd_ok                  ; It's OK to proceed
  759.         loop gmd_inner               ; Keep trying the desired number of
  760.         dec  ah
  761.         jnz  gmd_outer
  762.         xor  al,al
  763.         stc
  764.         jmp  gmd_exit
  765.  
  766. gmd_ok:                              ; There is mouse data to be read.
  767.         in   al, 60h                 ; Read byte of data from mouse.
  768.         clc
  769.  
  770. gmd_exit:
  771.         ret
  772.  
  773. GetMouseData  endp
  774.  
  775.  
  776. ;****************************************************************
  777. ;*
  778. ;*  FUNCTION NAME  :  SetSampleRate
  779. ;*
  780. ;*  DESCRIPTION    :  Send the SetSampleRate Command (0f3h)
  781. ;*                     to the Aux device.
  782. ;*
  783. ;*  NOTES: The sample rate was previously set to 100 reports
  784. ;*         per second by the Reset command. We will set it to
  785. ;*         60 reports per second.
  786. ;*
  787. ;*  ENTRY POINT   :          LINKAGE:  CALL NEAR
  788. ;*
  789. ;*  INPUT         :  N/A
  790. ;*
  791. ;*  RETURN-NORMAL :  Carry Flag clear.
  792. ;*
  793. ;*  RETURN-ERROR  :  Carry Flag set.
  794. ;*
  795. ;*
  796. ;****************************************************************
  797.  
  798. SetSampleRate  proc  near
  799.  
  800.        mov  al, 0f3h          ; set sample rate command
  801.        call SendToMouse       ; send command to mouse
  802.        jc   ssr_exit
  803.  
  804.        call GetMouseData      ; wait for response
  805.        .if <c> or
  806.        .if <al ne 0fah>
  807.            stc
  808.           jmp  ssr_exit
  809.        .endif
  810.  
  811.        mov  al, PDI_SAMPLERATE ; sample rate of 60/sec (was 40/sec)
  812.        call SendToMouse       ; send command to mouse
  813.        jc   ssr_exit
  814.  
  815.        call GetMouseData
  816.        .if <c> or
  817.        .if <al ne 0fah>
  818.           stc
  819.           jmp  ssr_exit
  820.        .endif
  821.  
  822. ssr_exit:
  823.        ret
  824.  
  825. SetSampleRate endp
  826.  
  827. ;****************************************************************
  828. ;*
  829. ;*  FUNCTION NAME :  SetScaling
  830. ;*
  831. ;*  DESCRIPTION   :  Send the SetScaling 2:1 Command (0E7h)
  832. ;*
  833. ;*  NOTES         : The scaling rate was previously set to 1:1
  834. ;*
  835. ;*
  836. ;*  INPUT         :  N/A
  837. ;*
  838. ;*  RETURN-NORMAL :  Carry Flag clear.
  839. ;*
  840. ;*  RETURN-ERROR  :  Carry Flag set.
  841. ;*
  842. ;*
  843. ;****************************************************************
  844.  
  845. SetScaling  proc  near
  846.  
  847.        mov  al, 0e7h          ; set sample rate command
  848.        call SendToMouse       ; send command to mouse
  849.  
  850.        call GetMouseData      ; wait for response
  851.        .if <c> or
  852.        .if <al ne 0fah>
  853.            stc
  854.        .endif
  855.  
  856.        ret
  857.  
  858. SetScaling endp
  859.  
  860. ;****************************************************************
  861. ;*
  862. ;*  FUNCTION NAME :  SetResolution
  863. ;*
  864. ;*  DESCRIPTION   :  Send the SetResolution Command (0e8h)
  865. ;*                     to the Aux device.
  866. ;*
  867. ;*  NOTES: The resolution was previously set to 4 counts per mm
  868. ;*         (100 ppi) by the Reset command. We use this call
  869. ;*         to set the resolution to 8 counts per mm or 200ppi.
  870. ;*
  871. ;*  INPUT         :  N/A
  872. ;*
  873. ;*  RETURN-NORMAL :  Carry Flag clear.
  874. ;*
  875. ;*  RETURN-ERROR  :  Carry Flag set.
  876. ;*
  877. ;*
  878. ;****************************************************************
  879.  
  880. SetResolution  proc  near
  881.  
  882.           mov  al, 0e8h          ; set resolution
  883.           call SendToMouse       ; send command to mouse
  884.           jc   sr_exit           ; error, exit init bad
  885.  
  886.           call GetMouseData
  887.           .if <c> or
  888.           .if <al ne 0fah>
  889.              stc
  890.              jmp  sr_exit
  891.           .endif
  892.  
  893.           mov  al, PDI_RESOLUTION ; resolution of 8 counts/mm
  894.           call SendToMouse       ; send command to mouse
  895.           jc   sr_exit           ; error, exit init bad
  896.  
  897.           call GetMouseData
  898.           .if <al ne 0fah>
  899.              stc
  900.           .else
  901.              mov  DeviceData.NumMics, 80  ; 80 mickeys/cm
  902.           .endif
  903. sr_exit:
  904.           ret
  905.  
  906. SetResolution  endp
  907.  
  908. ;****************************************************************
  909. ;*
  910. ;*  FUNCTION NAME  :  EnablePDI
  911. ;*
  912. ;*  DESCRIPTION    :  Enable the Aux Device.
  913. ;*
  914. ;*                   This routine sends the Enable command (0f4h) to
  915. ;*                   the auxiliary device.
  916. ;*
  917. ;*  INPUT         :  N/A
  918. ;*
  919. ;*  RETURN-NORMAL :  Carry Flag clear.
  920. ;*
  921. ;*  RETURN-ERROR  :  Carry Flag set.
  922. ;*
  923. ;*
  924. ;****************************************************************
  925.  
  926. EnablePDI  proc  near
  927.  
  928.        mov  al, 0f4h          ; enable pointing device
  929.        call SendToMouse       ; send command to mouse
  930.        .if <nc>
  931.           call GetMouseData      ; wait for response
  932.           .if <al ne 0fah>
  933.              stc
  934.           .endif
  935.        .endif
  936.        ret
  937.  
  938. EnablePDI  endp
  939.  
  940.  
  941. ;****************************************************************
  942. ;*
  943. ;*  FUNCTION NAME :  ClearAuxPort
  944. ;*
  945. ;*  DESCRIPTION   : This procedure will read all the aux port data
  946. ;*                  until the controller status register's bits
  947. ;*                  indicate that there is no more aux data to
  948. ;*                  be read.
  949. ;*
  950. ;*  NOTE: This routine will only exit when the Output Buffer
  951. ;*        Full and Auxiliary Output Full bits are OFF in the
  952. ;*        controller status register (port 64h).
  953. ;****************************************************************
  954.  
  955. ClearAuxPort  Proc  Near
  956.  
  957.        in   al, 64h              ; read status port of 8042
  958.        and  al, 21h              ; get AOBF and OBF bits only
  959.  
  960.        .while <al eq 21h>        ; While AUX data is in output buffer
  961.           in   al, 60h           ; read aux data
  962.           MyIODelay              ; Generate delay between I/O instructions
  963.           in   al, 64h           ; read status port of 8042
  964.           and  al, 21h           ; get AOBF and OBF bits only
  965.        .endwhile
  966.  
  967.        ret
  968.  
  969. ClearAuxPort  EndP
  970.  
  971.  
  972. ;****************************************************************
  973. ;*
  974. ;*  FUNCTION NAME  :  PDIInit
  975. ;*
  976. ;*  DESCRIPTION    :  Gets the PDI LID if on ABIOS system
  977. ;*
  978. ;*                   This routine will check to see if we are on an
  979. ;*                   ABIOS system. If so, it will obtain the LID for
  980. ;*                   the PDP device.
  981. ;*
  982. ;*  NOTE          :  This routine is only called if we have detected
  983. ;*                   a PDP device.
  984. ;*
  985. ;*  ENTRY POINT   :  PDIInit           LINKAGE:  CALL NEAR
  986. ;*
  987. ;*  INPUT         :  DS = Base data selector
  988. ;*
  989. ;*  RETURN-NORMAL :  Always, mouse LID obtained
  990. ;*
  991. ;*  RETURN-ERROR  :  N/A.
  992. ;*
  993. ;*  EFFECTS       : Stack is clean on return.  AX, CX, DX, SI, and DI
  994. ;*                  registers are changed.
  995. ;****************************************************************
  996.  
  997. PDIInit  proc  near
  998.  
  999.        .if <ABIOS_Mch eq TRUE>
  1000.           mov  al, 0bh                      ; APD Device ID
  1001.           mov  bl, 1                        ; Get 1st LID
  1002.           xor  dh, dh                       ; reserved, must be 0
  1003.           mov  dl, DevHlp_GetLIDEntry       ; ABIOS function
  1004.           call Device_Help                  ; invoke Dev Help
  1005.        .endif
  1006.  
  1007.        lea   eax, HookHotPlugPDI            ; 16 bit offset to Hot Plug handler
  1008.        mov   ebx, 0FFFFFFFFh                ; RESERVED
  1009.        mov   dl, DevHlp_AllocateCtxHook
  1010.        call  Device_Help
  1011.  
  1012.        .if <nc>
  1013.           mov   HotPlugHandle,  eax
  1014.        .endif
  1015.  
  1016.         ret
  1017.  
  1018. PDIInit  endp
  1019.  
  1020. KBD_INT_MASK    equ     02h
  1021.  
  1022. EnableKbdInt    proc near
  1023.         pushf
  1024.         cli
  1025.         push    ax
  1026.         in      al, 21h              ; read current status
  1027.         and     al, not KBD_INT_MASK ; unmask KBD
  1028.         out     21h, al              ; out new value
  1029.         MyIODelay
  1030.         pop     ax
  1031.         sti
  1032.         popf
  1033.         ret
  1034. EnableKbdInt    endp
  1035.  
  1036. DisableKbdInt   proc near
  1037.         pushf
  1038.         cli
  1039.         push    ax
  1040.         in      al, 21h              ; read current status
  1041.         or      al, KBD_INT_MASK     ; mask KBD
  1042.         out     21h, al              ; out new value
  1043.         MyIODelay
  1044.         pop     ax
  1045.         sti
  1046.         popf
  1047.         ret
  1048. DisableKbdInt   endp
  1049.  
  1050. ;*********************************************************************
  1051. ;*
  1052. ;*  FUNCTION NAME :  Find3ButtonMouse                ;           
  1053. ;*
  1054. ;*  DESCRIPTION   :  Send the SetResolution Command (0e8h), 1 count/mm
  1055. ;*                   to the Aux device followed by three SetScaling
  1056. ;*                   Commands (0e6h).  This is followed by a read of the
  1057. ;*                   status register.
  1058. ;*
  1059. ;*  NOTES: The algorithym was supplied by Logitech for detecting and
  1060. ;*         supporting their three button mice on the PDI port.
  1061. ;*
  1062. ;*  INPUT         :  N/A
  1063. ;*
  1064. ;*  RETURN-NORMAL :  Carry Flag clear.   DeviceData.NumButt updated.
  1065. ;*
  1066. ;*  RETURN-ERROR  :  Carry Flag set.
  1067. ;*
  1068. ;*
  1069. ;****************************************************************
  1070.  
  1071. Find3ButtonMouse proc  near
  1072.  
  1073.        mov  al, 0e8h                 ; set resolution
  1074.        call SendToMouse              ; send command to mouse
  1075.        jc   fb_exit                  ; error, exit init bad
  1076.  
  1077.        call GetMouseData             ; verify set resolution worked
  1078.        .if <c> or
  1079.        .if <al ne 0fah>
  1080.           stc
  1081.           jmp  fb_exit
  1082.        .endif
  1083.  
  1084.        mov  al, 00h                  ; set resolution to 1 count per mm
  1085.        call SendToMouse              ; send command to mouse
  1086.        jc   fb_exit                  ; error, exit init bad
  1087.  
  1088.        call GetMouseData             ; verify set resolution worked again
  1089.        .if <al ne 0fah>
  1090.           stc
  1091.        .else
  1092.  
  1093.           mov  al, 0e6h              ; set scaling = 1:1
  1094.           call SendToMouse           ; send command to mouse
  1095.           jc   fb_exit
  1096.  
  1097.           call GetMouseData          ; verify set scaling worked
  1098.           jc   fb_exit
  1099.           cmp  al, 0fah
  1100.           jnz  fb_exit
  1101.  
  1102.           mov  al, 0e6h              ; set scaling = 1:1
  1103.           call SendToMouse           ; send command to mouse
  1104.           jc   fb_exit
  1105.  
  1106.           call GetMouseData          ; verify set scaling worked
  1107.           jc   fb_exit
  1108.           cmp  al, 0fah
  1109.           jnz  fb_exit
  1110.  
  1111.           mov  al, 0e6h              ; set scaling = 1:1
  1112.           call SendToMouse           ; send command to mouse
  1113.           jc   fb_exit
  1114.  
  1115.           call GetMouseData          ; verify set scaling worked
  1116.           jc   fb_exit
  1117.           cmp  al, 0fah
  1118.           jnz  fb_exit
  1119.  
  1120.           mov  al, 0e9h              ; status request (will generate 3 bytes)
  1121.           call SendToMouse           ; send command to mouse
  1122.           jc   fb_exit
  1123.                                      ; We must clear all three bytes from data
  1124.                                      ; port.
  1125.  
  1126.           call GetMouseData          ; Verify status request worked
  1127.           jc   fb_exit
  1128.           cmp  al, 0fah
  1129.           jnz  fb_exit
  1130.  
  1131.           call GetMouseData          ; Throw away Standard status info
  1132.           jc   fb_exit               ; BYTE 1
  1133.  
  1134.           call GetMouseData          ; Logitech Number of mouse buttons
  1135.           jc   fb_exit               ; BYTE 2
  1136.  
  1137.           .if <al eq 3>              ; Three buttons reported?
  1138.              mov DeviceData.NumButt, al
  1139.           .endif
  1140.  
  1141.           call GetMouseData          ; Throw away firmware revision number
  1142.                                      ; BYTE 3
  1143.        .endif
  1144.  
  1145. fb_exit:
  1146.         clc                          ; Never return an error
  1147.         ret
  1148.  
  1149. Find3ButtonMouse endp
  1150.  
  1151. CSEG     ENDS
  1152.          END
  1153.