;*DDK*************************************************************************/
;
; 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.;
;*****************************************************************************/
;**********************************************************************/
;*                                                                    */
;*   File            = EDDHMACR                                       */
;*                                                                    */
;*   Description     = Display Device Driver Macros                   */
;*                                                                    */
;*   Function        =                                                */
;*                                                                    */
;*   Reference       = Device Driver Interface Specification          */
;*                                                                    */
;*                                                                    */
;**********************************************************************/

IF1     ; only include macros on 1st pass

;Simulate 680x0 swap (NB carry flag trashed)
swap    macro   reg
        rol     reg, 10h
        endm

;put the maximum of addr1 and addr2 into reg
max     macro   addr1, addr2, reg
        mov     reg, addr1
        cmp     reg, addr2
        jnc     short @F
        mov     reg, addr2
@@:
        endm

;put the minimum of reg1 and reg2 into reg1
rmin    macro   reg1, reg2
        cmp     reg1, reg2
        jc      short @F
        mov     reg1, reg2
@@:
        endm

;put the maximum of reg1 and reg2 into reg1 (signed)
rmax    macro   reg1, reg2
        cmp     reg1, reg2
        jge     short @F
        mov     reg1, reg2
@@:
        endm

;put the minimum of reg2 and reg3 into reg1 (signed)
smin    macro   reg1, reg2, reg3

        mov     reg1, reg2
        cmp     reg2, reg3
        jle     short @F
        mov     reg1, reg3
@@:
        endm

;put the maximum of reg2 and reg3 into reg1 (signed)
smax    macro   reg1, reg2, reg3

        mov     reg1, reg2
        cmp     reg2, reg3
        jge     short @F
        mov     reg1, reg3
@@:
        endm

;order reg1 and reg2 so that they are reg1=smaller reg2=larger
sorder  macro   reg1, reg2

        cmp     reg1, reg2
        jle     short @F
        xchg    reg1, reg2
@@:
        endm

; It appears that we are not allowed to use the FS register in user space
; code.  For the moment it looks as if we can merely switch to using the
; GS register instead

IFDEF HARD_DRAW
        ; XGA registers are accessed outside of flat model
SEGREG  equ     <gs>
ENDIF ; HARD_DRAW
IFDEF SOFT_DRAW
        ; XGA registers are accessed within flat model
SEGREG  equ     <ds>
ENDIF ; SOFT_DRAW

; Set up access to the xga registers
; For software drawing these are simply accessed via esi
; For hardware drawing these are currently accessed via SEGREG:[esi]
; (we would ideally always like to access then via [ESI])

movxga  macro   address
ifndef  _8514
IFDEF HARD_DRAW
        xor     esi,esi
        lgs     si, dword ptr address
ENDIF ; HARD_DRAW
IFDEF SOFT_DRAW
        mov     esi, dword ptr address
ENDIF ; SOFT_DRAW
else
        mov     esi, dword ptr address
endif
        endm

; To be really nice guys, we need to be able to save and restore the
; segment register used to access the xga registers
pushxga macro
        ; this is a NOP for software drawing
IFNDEF _8514
IFDEF HARD_DRAW
        push    SEGREG
ENDIF ; HARD_DRAW
ENDIF ; NOT _8514
        endm

popxga  macro
        ; this is a NOP for software drawing
IFNDEF _8514
IFDEF HARD_DRAW
        pop     SEGREG
ENDIF ; HARD_DRAW
ENDIF ; NOT _8514
        endm


ifndef   _8514
;Read specified memory mapped I/O register
memregread      macro   inreg,regnum
        mov     inreg,SEGREG:[esi+regnum]
        endm

;Write specified memory mapped I/O register
memregwrite     macro   regnum,outreg
        mov     SEGREG:[esi+regnum],outreg
        endm

else   ;_8514
;Read specified memory mapped I/O register
memregread      macro   inreg,regnum
        mov     inreg,[esi+regnum]
        endm

;Write specified memory mapped I/O register
memregwrite     macro   regnum,outreg
        mov     [esi+regnum],outreg
        endm
endif   ;_8514


ifndef RING0
extrn   _ulPollingDelay      :dword
endif ; ndef RING0

; Wait for the hardware before writing to registers
; Use this if the hardware is probably ready

waitshort       macro
         local  poll_xga
         local  delay_finished
         local  hardware_free
        ; this is a NOP for software drawing
ifndef  _8514
IFDEF RING0
@@:
        test    byte ptr SEGREG:[esi].pi_control,HW_BUSY
        jnz     short @B
ELSE ; RING0
IFDEF HARD_DRAW
        add     si, word ptr _pbHWPollRegister
poll_xga:
        test    byte ptr SEGREG:[si], HW_BUSY
        jz      short hardware_free

        ; Delay loop to give the XGA hardware a chance to finish
        push    ecx
        mov     ecx, [_ulPollingDelay]
        jecxz   short delay_finished
@@:
        loopz   @B
delay_finished:
        pop     ecx
        jmp     poll_xga

hardware_free:
        sub     si, word ptr _pbHWPollRegister
ENDIF ; HARD_DRAW
ENDIF ; RING0
endif ; _8514
        endm

; we need a special version of waitshort for use by the cursor code

waitshortcursor      macro
        local   nowait
ifdef MATROX
        cmp     [edi].cd_adapter_id, MATROX_ID
        je      short nowait
endif; MATROX
        add     si, word ptr [edi].cd_polling_register
@@:
        test    byte ptr SEGREG:[esi], HW_BUSY
        jnz     short @B
        sub     si, word ptr [edi].cd_polling_register
nowait:
        endm

;Write to specified Expressway I/O port
iowrite macro   regnum,outreg
        add     dx,regnum
        out     dx,outreg
        sub     dx,regnum
        endm

;Read from specified Expressway I/O port
ioread  macro   inreg,regnum
        add     dx,regnum
        in      inreg,dx
        sub     dx,regnum
        endm

; a macro to separate i/o instructions by sufficent length of time
iowait  macro
        local nojump
        jmp short nojump
nojump:
        endm

ENDIF ; pass 1
