
;/*************************************************************************
;*
;* SOURCE FILE NAME = VISION.ASM
;*
;* DESCRIPTIVE NAME = VisiOn mouse interrupt handler
;*
;* COPYRIGHT    COPYRIGHT IBM CORPORATION, 1991, 1992
;*              Copyright Microsoft Corporation, 1990
;*              LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
;*              REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
;*              RESTRICTED MATERIALS OF IBM
;*              IBM CONFIDENTIAL
;*
;* VERSION      V2.0
;*
;* DATE         07/08/91
;*
;* DESCRIPTION  Vision mouse interrupt handler
;*
;* FUNCTIONS    Interrupt_Handler       Mouse device Interrupt Handler.
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;**************************************************************************



.xlist
       include pmode.inc
       include devsym.inc
       include devhlp.inc
       include struc.inc
       include dddd.inc
       include devhlpP.inc            ;76711
.list

.286p

;*
;*    External Mouse Module Data References
;*

       extrn MEvent              : byte
       extrn Disable_8259        : byte
       extrn Enable_8259         : byte
       extrn DeviceData          : byte
       extrn MseDD               : byte

       extrn First_Port          : word
       extrn ByteCount           : word
       extrn DevStatus           : word
       extrn IntPacketOff        : word

       extrn Device_Help         : dword

       extrn ENDDATA             : near
       extrn Disable_Device      : near
       extrn Enable_Device       : near


CSEG     SEGMENT   WORD  PUBLIC  'CODE'
         ASSUME    CS:CSEG, SS:nothing, ES:nothing, DS:nothing

;*
;*    Module Procs made Public for other Mouse Modules
;*

       public  Interrupt_Handler


;*******************************************************************
;*
;*  FUNCTION NAME :  Interrupt_Handler
;*
;*  DESCRIPTION   :  Mouse device Interrupt Handler.
;*
;*                   Reads mouse interrupts, translates to common
;*                   format, and sends them to the independent DD.
;*
;*  ENTRY POINT   :  Interrupt_Handler   LINKAGE:  CALL FAR
;*
;*  INPUT         :  None, except data from mouse device
;*
;*  RETURN-NORMAL :  Always, carry clear -- our interrupt.
;*
;*  RETURN-ERROR  :  N/A.
;*
;*  EFFECTS       :  Stack is clean on return.  AX, CX, DX, SI, and DI
;*                   registers are changed.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES:  None.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*     DevHlps:  See individual support routines.
;*
;********************************************************************
;*
;*
;* The Visi On Mouse returns a 5 byte packet whenever the hardware
;* changes state (movement, button press, button release).
;*
;*        Byte 1:  B7 : 1 = Sync byte.  Marks 1st byte of packet
;*                 B6-B3 : 0
;*                 B2 : Button 1 status (0 = depressed)
;*                 B1 : 0
;*                 B0 : Button 2 status (0 = depressed)
;*
;*        Byte 2:  Delta X1            The value for Delta-X
;*        Byte 3:  Delta Y1            is formed by adding
;*        Byte 4:  Delta X2            Delta-X1 and Delta-X2.
;*        Byte 5:  Delta Y2            Ditto for Delta-Y.
;*
;***********************************************************************

Interrupt_Handler  Proc  Far

       ;*
       ;* issue the EOI and disable the IRQ
       ;*

       call Disable_Device            ; disable the device 1st
     ; IssueEOI                       ; issue the EOI       Remove 76711
       cli                                     ;            Add    76711
       DevEOI    <DeviceData.IRQ>,Device_Help  ;            Add    76711
       sti

;*
;* Check the read packet first, then check initialization request blocks.
;*

       ReadAsync                       ; read interrupt data
       mov  ah, 0f0h                   ; sync bit mask
       and  ah, al                     ; mask off possible button stats

;*
;* If we get a Sync Byte in the middle of building an interrupt packet
;* without an error we have encountered the 16550 data error.  Latching
;* generates a RCV interrupt which is lost.  The error is generated
;* on the next data byte.
;*

       .if <ah eq SYNCBIT> AND         ; if 1st byte of packet
       .if <ByteCount eq 0>            ; and we need to start a packet
          inc  ByteCount               ; show that we have started
          mov  Mevent[0], al           ; save button data
       .elseif <ByteCount ne 0> NEAR   ; if a packet has started
          mov  di, ByteCount           ; get byte count for index
          mov  Mevent[di], al          ; save this byte
          inc  ByteCount
          .if <ByteCount eq PACKETSIZE>  NEAR ; if packet complete
             mov  ByteCount, 0         ; clear counter

;*
;* Button event is in this format:  Sxxxx102 where 0=depressed.
;* The event mask is built using this byte.  Each button status is rotated
;* into the carry flag.  If the carry flag is 0 then the corresponding
;* button event for button pressed with motion is set in cx.  After all
;* buttons have been checked the motion counters are calculated.  If there
;* was no motion and there was a button depressed then cx is shifted to
;* put the button events in the without motion format.
;*

             xor  cx, cx              ; clear register to build event
             mov  ah, MEvent[0]       ; get button event
             shr  ah, 1               ; Put butt 3 stat in cy flag
             jc   b2up                ; if cy is set button 2 is up
b2down:      or   cx, 0008h           ; but 2 is down so set event bit
b2up:        shr  ah, 2               ; put but 1 stat in cy flag
             jc   b1up                ; if cy is set button 1 is up
b1down:      or   cx, 0002h           ; but 1 is down so set event bit
b1up:        mov  bh, byte ptr MEvent[1] ; get 1st column movement byte
             add  bh, byte ptr MEvent[3] ; add resid col movement byte
             mov  bl, byte ptr MEvent[2] ; get 1st row movement byte
             add  bl, byte ptr MEvent[4] ; add resid row movement byte
             neg  bl                  ; make downward mvmnt positive
             cmp  bx, 0               ; see if no column movement
             jne  movement            ; skip if there was
nomove:      shl  cx, 1               ; no mvmnt, cnvrt to w/o format
             jmp  ser1                ; continue (exit if structure)
movement:    cmp  cx, 0               ; there was mvmnt, any buts down?
             jne  ser1                ; if so then continue
             inc  cx                  ; no buts dwn, motion only event
ser1:        Process_Packet           ; macro to process int data
          .endif
       .endif

       call Enable_Device              ; make sure to enable the IRQ level

       clc                             ; our interrupt

       ret                             ; return to intr hndlr

Interrupt_Handler  EndP

CSEG     ENDS
         END
