;*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.;
;*****************************************************************************/

;/*************************************************************************
;*                                                                         
;* SOURCE FILE NAME = MACS.INC                                                               
;*                                                                                                     
;* DESCRIPTIVE NAME = Mouse Device Driver Macros.                         
;*                                                                         
;*                                                                         
;* VERSION      V2.0                                                       
;*                                                                         
;* DATE         10/13/91
;*                                                                         
;* DESCRIPTION                                
;*                                                                         
;* FUNCTIONS    none
;*             
;* NOTES        This file contains the macros used by the mouse DD 
;*              code.                                              
;*             
;* STRUCTURES   NONE                                                       
;*                                                                         
;* EXTERNAL REFERENCES                                                     
;*                                                                         
;*              NONE                                                       
;*                                                                         
;* EXTERNAL FUNCTIONS                                                      
;*                                                                         
;*              NONE                                                       
;*                                                                         
;* CHANGE ACTIVITY =                                                       
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION                       
;*   --------  ----------  -----  --------------------------------------   
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx                                  
;**************************************************************************
                                                                    

.xlist
       include iodelay.inc              ; IODELAY MACROS
.list

DrawPointer      MACRO
      MOV  [SI].Screen_Func, 0          ; Specify Function = Draw Pointer
      CALL DWORD PTR [SI].Screen_Entp   ; Invoke Ptr Draw DD Function
                 ENDM


RemovePointer      MACRO
      MOV  [SI].Screen_Func, 1          ; Specify Function = Hide Pointer
      CALL DWORD PTR [SI].Screen_Entp   ; Invoke Ptr Draw DD Function
                   ENDM


CheckModeProtect  MACRO
    MOV  [SI].Screen_Func, 3            ; Specify Function = Check Mode Protect
    CALL DWORD PTR [SI].Screen_Entp     ; Invoke Ptr Draw DD Function
                  ENDM


GenFail          MACRO
        MOV  ES, TempES                        ; LocalVar = Req Blk Selector
        MOV  BX, TempBX                        ; LocalVar = Req Blk Offset
        MOV  ES:[BX].PktStatus, GENERALFAILURE ; Flag General Failure Error
                 ENDM


ParmErr          MACRO
        MOV  ES, TempES                        ; LocalVar = Req Blk Selector
        MOV  BX, TempBX                        ; LocalVar = Req Blk Offset
        MOV  ES:[BX].PktStatus, INVALIDPARMS   ; Flag Invalid Parm Error
                 ENDM



FreePointerMem      MACRO
    MOV  [SI].Screen_Func, 2            ; Specify Function = Free Memory
    CALL DWORD PTR [SI].Screen_Entp     ; Invoke Ptr Draw DD Function
                    ENDM


GetPointerMem      MACRO
    MOV  [SI].Screen_Func, 5            ; Specify Function = Get Ptr Memory
    CALL DWORD PTR [SI].Screen_Entp     ; Invoke Ptr Draw DD Function
                   ENDM


;*
;* Send_Packet - macro to call mouse$ to process packet.  On entry
;*               cx = mouse event, bh= col movement, bl = row movement.
;*

Send_Packet  Macro           ; macro to call MOUSE$ to process int data

       test DevStatus, gREADENABLE        ; see if data reporting enabled
       .if <nz>                           ; if so then send data to mouse$
          and  DevStatus, NOT gREADENABLE ; one event at a time
          push ds                         ; save our ds on stack for restore
          push es                         ; same for es
          push ds                         ; put ds on stack for switch to es
          mov  SInt_Packet.Event, cx      ; move the mouse event          ;emi
          mov  al, bh                     ; get column movement (byte value)
          cbw                             ; convert to word
          mov  SInt_Packet.Col_Mov, ax    ; move colument movement value  ;emi
          mov  al, bl                     ; get row movement (byte value)
          cbw                             ; convert to word
          mov  SInt_Packet.Row_Mov, ax    ; move row movement value (word);emi
          pop  es                         ; put our ds (on stack) in es
          mov  ax, 1
          sti                             ; allow interrupts
          call GIDC_Entry
          cli                             ; hold ints until we're done
          pop  es                         ; restore our es
          pop  ds                         ; restore our ds
          or   DevStatus, gREADENABLE     ; we can process another event
       .endif                             ; end report data test
                EndM

IssueEOI  Macro

       cli                            ; hold ints for call
       mov  al, DeviceData.IRQ
       mov  dl, DevHlp_EOI
       call Device_Help

          EndM

;*
;*     MyIODelay - Perform an IO delay using kernel provided macro
;*                 This macro give the proper amount of delay regardless
;*                 of processor speed.
;*

MyIOdelay MACRO

        push ax
        DevIODelay <ax>              ; Trashes AX reg
        pop  ax

        ENDM

;*
;*     DelayIn - in with IOdelay
;*

DelayIn MACRO   a,b

        MyIOdelay
        in      a,b

        ENDM

;*
;*     DelayOut - out with IOdelay
;*

DelayOut        MACRO   a,b

        MyIOdelay
        out     a,b

                ENDM

;*
;*     ADDRESS
;*
;* This macro is used to change the I/O address contained in DX to a value
;*       relative to the current value in DX.
;*
;* It is meant to be called as
;*
;*       ADDRESS dest FROM src
;*
;*       where dest and src are either absolute I/O addresses or offsets from
;*       a base.
;*
 
address MACRO   dest,dummy,src

;*
;* Check all of the parameters
;*

IFB     <dest>
        .ERR
        %OUT    Missing first parameter!
        EXITM
ENDIF   ;* IFB <dest>

IFDIFI  <dummy>,<from>
        .ERR
        %OUT    Second parameter is not FROM!
        EXITM
ENDIF   ;* IFDIFI <dummy>,<from>

IFB     <src>
        .ERR
        %OUT    Missing third parameter!
        EXITM
ENDIF   ;* IFB <src>

;*
;*  At this point, all the error checking has been done.
;*  
;*  If the dest is the same as the src, do nothing!
;*

IF      dest EQ src
        EXITM
ENDIF   ;* dest EQ src

;* 
;* If the difference between them is 3 or greater, just add on the difference
;*       between the two.
;* 
  
IF      (dest - src GT 2) OR (src - dest GT 2)
        add     dx,-src+dest
        EXITM
ENDIF   ;* (dest - src GT 2) OR (src - dest GT 2)

;*
;* The difference between them is 1 or 2, therefore we will do INCs or DECs.
;*

IF      dest GT src
        inc     dx

IF      dest - src GT 1
        inc     dx
ENDIF   ;* dest - src GT 1

ELSE    ;* NOT (dest GT src)
        dec     dx

IF      src - dest GT 1
        dec     dx
ENDIF   ;* src - dest GT 1

ENDIF   ;* NOT (dest GT src)

        ENDM

;*
;* This macro is used to read serial devices. (serial mice)
;*

ReadAsync  MACRO
local      RXBLOOP

       MOV  DX, PortBase                ; Setup Mouse Input Port Number
       IN   AL, DX                      ; Read incoming Interrupt data Byte

       PUSH AX                          ; Save Data Byte

       ADD  DX, LSR                     ; Check Line Status Reg
       IN   AL, DX                      ; Read Line Status Data
       MOV  BL, AL                      ; Get Error Code in BL

       POP AX                           ; Restore Data Byte

       .IF < BL gt 60H >                ; If an Error occured then
                                        ; Reset DLAB
          MOV  DX, PortBase             ; Get Base Port
          ADD  DX, LCR                  ; Get Line Control Reg
          MOV  AL, 80H                  ; Set DLAB access bit in the LCR
          OUT  DX, AL                   ; to Access div latch regs
          MyIODelay                     ; I/O Delay for Port Access
          SUB  AL, AL                   ; Set 1200 Baud
          ADD  DX, -LCR+LATMSB          ; Get div latch MSB
          OUT  DX, AL                   ; Set div latch MSB to 0
          MyIODelay                     ; I/O Delay for Port Access
          MOV  AL, 60H                  ; 
          ADD  DX, -LATMSB+LATLSB       ; Get div latch LSB
          OUT  DX, AL                   ; Set divisor for 1200 bauds
          MyIODelay                     ; I/O Delay for Port Access
;*
;* Reset DLAB, set NO Parity, 1 Stop Bit, 7 Data Bits
;*

          ADD  DX, -LATLSB+LCR          ; Get Line Control Reg
          MOV  AL, LCRMASK              ; Set 7 data bits, etc. in LCR
          OUT  DX, AL                   ; 
          MyIODelay                     ; I/O Delay for Port Access
;*
;* Set OUT2, RQS, DTR in Modem Control Reg
;*

          ADD  DX, -LCR+MCR             ; Get MCR
          MOV  AL, MCRMASK              ; 
          OUT  DX, AL                   ; 
          MyIODelay                     ; I/O Delay for Port Access
;*
;* Set Data avail in INT Enable Reg
;*

          ADD  DX, -MCR+IER             ; Indicate Interrupts Enabled
          MOV  AL, IERMASK              ; 
          OUT  DX, AL                   ; 
          MyIODelay                     ; I/O Delay for Port Access
                                        ; Read stray data
          ADD  DX, -IER+RXB             ; Get receive buffer
          MOV  CX, 0FFFFH               ; Loop for a while

RXBLOOP:                                ; 
          IN   AL, DX                   ; Read stray data
          MyIODelay                     ; I/O Delay for Port Access
          LOOP RXBLOOP                  ; 

          XOR  AX, AX                   ; Discard     Data Byte
          MOV  ByteCount, ax            ; Discard any Packet Data
       .ENDIF                           ; Data Error Tests
   ENDM
