;*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.;
;*****************************************************************************/
        PAGE     55,132
        TITLE    Escape
        SUBTITLE Header
;/*****************************************************************************
;*
;* SOURCE FILE NAME = ESCAPE.ASM
;*
;* DESCRIPTIVE NAME = DevEscape function
;*
;*
;* VERSION      V2.0
;*
;* DATE         10/04/91
;*
;* DESCRIPTION  This file contains the DevEscape function.
;*
;*
;* FUNCTIONS    Escape
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   10/04/91                     KEZ  Original
;*   09/18/92              DCR96  Multi-Media Support
;*****************************************************************************/

;/*
;** Model and processor selection
;*/

        .386P
        .MODEL FLAT,SYSCALL

;/*
;**            Start
;*/

        .DATA

pfnSetBankSelect          DWORD 0
pfnQueryApertureInfo      DWORD 0

;/*
;**            End
;*/

        .CODE

;/*
;** Include files
;*/

INCL_DDICOMFLAGS   EQU 1
INCL_DEV           EQU 1
INCL_GPIERRORS     EQU 1
INCL_GPIPRIMITIVES EQU 1
INCL_GRE_DEVICE    EQU 1
OS2_NOBASEAPI      EQU 1
        INCLUDE PMGRE.INC

DINCL_BITMAP       EQU 1
DINCL_ENABLE       EQU 1
        INCLUDE DRIVER.INC
        INCLUDE EXTERN.INC
        INCLUDE PROTOS.INC

;/*
;** Local equates
;*/

;/*
;**            Start
;*/

QUERYSETBANKADDR MACRO
        LOCAL done
        INVOKE  DosQueryProcAddr,
                _hModuleDev,
                6000,
                0,
                ADDR pfnSetBankSelect
        cmp     pfnSetBankSelect,0
        jz      done
        push    esi
        mov     esi,pfnSetBankSelect
        mov     esi,[esi]
        mov     pfnSetBankSelect,esi
        pop     esi
done:
ENDM

QUERYAPERTUREADDR MACRO
        INVOKE  DosQueryProcAddr,
                _hModuleDev,
                6001,
                0,
                ADDR pfnQueryApertureInfo
ENDM

;/*
;**            End
;*/

BytesPerDwordShift  EQU 2 ; Number of bits to shift a value to convert from
                          ; BYTEs to DWORDs
BytesPerQwordShift  EQU 3 ; Number of bits to shift a value to convert from
                          ; BYTEs to QWORDs
DwordsPerQwordShift EQU 1 ; Number of bits to shift a value to convert from
                          ; DWORDs to QWORDs
OutCountBreak       EQU 1 ; Break point for number of DWORDs passed in
                          ; pcOutCount that determines action taken

;/*
;** Public functions
;*/

        SUBTITLE Escape Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = Escape
;*
;* DESCRIPTION   = The only escape function supported by the driver is the
;*                 QueryEscapeSupport function.
;*
;*                 C Prototype:                                                               *
;*                                                                                            *
;*                   GreEscape (HDC   hdc,                                                    *
;*                              LONG  lEscape,                                                *
;*                              LONG  cInCount,                                               *
;*                              PBYTE pInData,                                                *
;*                              PLONG pcOutCount,                                             *
;*                              PLONG pOutData, ,                                             *
;*                              PVOID pInstance,                                              *
;*                              ULONG lFunction);                                             *
;*                                                                                            *
;*                    where:                                                                  *
;*                      hdc        is device context handle                                   *
;*                      lEscape    is escape code                                             *
;*                      cInCount   is number of bytes pointed to by pInData                   *
;*                      pInData    is pointer to input data structure                         *
;*                      pcOutCount is pointer to the number of bytes in output data structure *
;*                      pOutData   is pointer to output data structure                        *
;*                      pInstance  is pointer to instance data                                *
;*                      lFunction  is function code                                           *
;*
;*                 Registers Preserved:
;*                       SI,DI,BP,DS
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,ES,FLAGS
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = DEV_OK                = Successful
;* RETURN-ERROR  = DEVESC_NOTIMPLEMENTED = Escape not implemented for specified code
;*                 DEVESC_ERROR          = Error
;*
;**************************************************************************/

ALIGN 4
Escape  PROC SYSCALL PUBLIC USES EBX EDI ESI,
                hdc       :HDC,
                lEscape   :LONG,
                cInCount  :LONG,
                pInData   :PBYTE,
                pcOutCount:PLONG,
                pOutData  :PLONG,
                pInstance :PVOID,
                lFunction :ULONG

;/*
;** See if it is one of the few escapes the driver supports
;*/

        XOR     EAX,EAX                    ; EAX = 0 : used below
        errnz   DEVESC_NOTIMPLEMENTED
        CMP     WORD ptr lEscape+SIZEOF(WORD),AX
        JNE     EscExit

        MOV     DX,WORD ptr lEscape        ; DX = escape

;/*
;**            Start
;*/
        cmp     dx,DEVESC_GETAPERTURE
        jz      EscQueryApertureSize
        cmp     dx,DEVESC_ACQUIREFB
        jz      EscReserveAdapter
        cmp     dx,DEVESC_DEACQUIREFB
        jz      EscReleaseAdapter
        cmp     dx,DEVESC_SWITCHBANK
        jz      EscSelectBank

;/*
;**            End
;*/

        CMP     DX,DEVESC_QUERYVIOCELLSIZES
        JE      EscVioCellSizes
        CMP     DX,DEVESC_QUERYESCSUPPORT
        JNE     EscExit

;/*
;** DEVESC_QUERYESCSUPPORT
;*/

        CMP     WORD ptr cInCount+SIZEOF(WORD),AX
        JNE     EscLogError
        CMP     WORD ptr cInCount,SIZE_DWORD
        JB      EscLogError
        errnz   DEVESC_NOTIMPLEMENTED
        MOV     EBX,pInData                ; EBX = pInData
        CMP     WORD ptr [EBX+SIZEOF(WORD)],DEVESC_QUERYESCSUPPORT
        JNE     EscSupportExit
        MOV     DX,[EBX]                   ; DX = escape
;/*
;**            Start
;*/
        cmp     dx,DEVESC_GETAPERTURE      ;Check if supported by
        jnz     @f                         ; querying for the proc address
        cmp     pfnQueryApertureInfo,0     ;If initialized,assume supported
        jnz     EscSupportedExit           ; 
        QUERYAPERTUREADDR                  ;If no error, assume supported
        or      eax,eax                    ;Check return code
        mov     eax,0                      ;Not supported
        jnz     EscSupportExit             ; 
        jmp     EscSupportedExit           ; 
@@:                                        ; 

        cmp     dx,DEVESC_SWITCHBANK       ;Check if supported by
        jnz     @f                         ; querying for the proc address
        cmp     pfnSetBankSelect,0         ; 
        jnz     EscSupportedExit           ; 
        QUERYSETBANKADDR                   ;If no error, assume supported
        or      eax,eax                    ;Check return code
        mov     eax,0                      ;Not supported
        jnz     EscSupportExit             ; 
        jmp     EscSupportedExit           ; 
@@:                                        ; 

        cmp     dx,DEVESC_ACQUIREFB        ;Check if supported by
        jnz     @f                         ; querying for the proc address
        cmp     pfnQueryApertureInfo,0     ; 
        jnz     EscSupportedExit           ; 
        QUERYAPERTUREADDR                  ;If no error, assume supported
        or      eax,eax                    ;Check return code
        mov     eax,0                      ;Not supported
        jnz     EscSupportExit             ; 
        jmp     EscSupportedExit           ; 
@@:                                        ; 

        cmp     dx,DEVESC_DEACQUIREFB      ;Check if supported by
        jnz     @f                         ; querying for the proc address
        cmp     pfnQueryApertureInfo,0     ; 
        jnz     EscSupportedExit           ; 
        QUERYAPERTUREADDR                  ;If no error, assume supported
        or      eax,eax                    ;Check return code
        mov     eax,0                      ;Not supported
        jnz     EscSupportExit             ; 
        jmp     EscSupportedExit           ; 
@@:                                        ; 
;/*
;**            End
;*/
        CMP     DX,DEVESC_QUERYVIOCELLSIZES
        JE      EscSupportedExit
        CMP     DX,DEVESC_QUERYESCSUPPORT
        JNE     EscSupportExit
EscSupportedExit:
        INC     EAX                        ;Show supported
EscSupportExit:
        JMP     EscExit
ALIGN 4

;/***************************************************************************
;*
;* FUNCTION NAME = QueryVioCellSizes
;*
;* DESCRIPTION   = Process QueryVioCellSizes
;*
;* INPUT         = NONE
;* OUTPUT        = Return following structure in OutData -
;*                   struct {
;*                     LONG maxcount
;*                     LONG count
;*                    }
;*                 followed by count copies of
;*                   struct VIOFONTCELLSIZE {
;*                     LONG xwidth
;*                     LONG ywidth
;*                    }
;*
;*                 - if outcount < Size_Dword, return no data
;*                 - if outcount = Size_Dword, set maxcount to number of cell
;*                   sizes supported
;*                 - if outcount > Size_Dword, set maxcount as above, count to
;*                   the number of cell sizes actually returned, and count copies
;*                   of VIOFONTCELLSIZE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

EscVioCellSizes:

        MOV     EBX,pcOutCount
        MOV     EAX,[EBX]            ; EAX = received outcount
        CMP     EAX, 4
        JGE     Esc_Cnt_required

;/*
;** pcbOut is less than size (LONG), just update this to zero
;*/

        XOR     EAX,EAX
        MOV     [EBX],EAX            ; return zero in pcbOut
        INC     EAX                     ; return one in AX
        JMP     EscExit
ALIGN 4
Esc_Cnt_required:
        CMP     EAX,8
        JGE     Esc_Data_required
;/*
;** Just room for the count of cells, so output length is four
;*/

        MOV     DWORD ptr [EBX],4    ; Return four in pcbOut
        MOV     EDI,pOutData
        MOV     eax,cDevVioCells
        MOV     DWORD ptr [EDI],eax
        MOV     EAX,1                ; Return one in EAX
        JMP     EscExit
ALIGN 4
Esc_Data_required:

;/*
;** pcBout is greater than size (LONG), so return full information
;** but only as much as there is room in the output buffer
;**
;** Output buffer can take (cbOut - 8)/8 structures
;*/

        SHR     EAX,3
        DEC     EAX                  ; EAX is room in buffer for structure
        MOV     ECX,cDevVioCells     ; ECX is maximum cell structures
        CMP     EAX,ECX              ; Make EAX the smallest of these
        JLE     Esc_Do_copy
        MOV     EAX,ECX              ; Less data than cell structures
Esc_Do_copy:

;/*
;** Write outcount back in bytes
;*/

        MOV     ECX,EAX              ; Save number of cell structures
        INC     EAX
        SHL     EAX,3
        MOV     [EBX],EAX

;/*
;** Write the header data into the output buffer
;*/

        MOV     EDI,pOutData        ; Address output buffer
        MOV     EAX,cDevVioCells     ; Store count of sizes available
        STOSD
        MOV     EAX,ECX              ; Store count of sizes returned
        STOSD
        MOV     ESI,offset adDevVioCells     ; Start size copying loop

        JECXZ   Esc_Q_done                   ; Stop if none to do
Esc_Next_size:
        MOVSD                        ; Copy the width
        MOVSD                        ; Copy the height
        ADD     ESI,4                ; Move to next record (skip font ptr)
        LOOP    Esc_Next_size
Esc_Q_done:
        MOV     EAX,1                ; Return one in EAX
        JMP     EscExit
ALIGN 4

;/*
;**            Start
;*/

;/*
;** QueryApertureSize
;**
;**   Function: Query physical address of the aperture.
;**             Query size of aperture.
;**             Query size of a scanline.
;**             Query screen coordinates.
;**   Input: struct
;**          {
;**             ULONG physical address of the aperture                                                |
;**             ULONG size of aperture
;**             ULONG size of scanline
;**             RECTL screen coordinates
;**          }
;**   Output:   Return code in eax, 1 = success
;*/

EscQueryApertureSize:
        cmp     pfnQueryApertureInfo,0 ;If pointer to QueryApertureInfo is not
        jnz     @f                     ; initialized, initialize it
        QUERYAPERTUREADDR              ;If no error, assume supported
        or      eax,eax
        jnz     EscNotImplementedError
@@:
        mov     ebx,pcOutCount
        mov     eax,[ebx]            ;eax = received outcount
        cmp     eax,sizeof QUERYADAPTER ;If outcount < size needed, return error
        jl      EscLogError
        mov     edi,pOutData         ;edi -> out data
        call    pfnQueryApertureInfo ;Get info
        mov     eax,1                ;Success
        jmp     EscExit

ALIGN 4

;/*
;** SelectBank
;**
;**   Function: Set bank.
;**   Input:    ULONG bank number
;**   Output:   Return code in eax, 1 = success
;*/

EscSelectBank:
        cmp     pfnSetBankSelect,0   ;If pointer to set_bank_select is not
        jnz     @f                   ; initialized, initialize it
        QUERYSETBANKADDR             ;If no error, assume supported
        or      eax,eax
        jnz     EscNotImplementedError
@@:
        cmp     cInCount,sizeof DWORD ;If incount < size needed, return error
        jl      EscLogError
        mov     ebx,pInData
        mov     dl,byte ptr[ebx]
        call    pfnSetBankSelect
        mov     eax,1                ;Success
        jmp     EscExit

ALIGN 4

;/*
;** ReserveAdapter
;**
;**   Function: Enter driver semaphore and exclude pointer.
;**   Input: struct
;**          {
;**             ULONG fAFBFlags if bit AFB_SWITCH is set, switch bank
;**             ULONG ulBankNumber
;**             RECTL of exclude region
;**          }
;**   Output:   Return code in eax, 1 = success
;*/

EscReserveAdapter:
        cmp     pfnQueryApertureInfo,0 ;If pointer to QueryApertureInfo is not
        jnz     @f                     ; initialized, initialize it
        QUERYAPERTUREADDR              ;If no error, assume supported
        or      eax,eax
        jnz     EscNotImplementedError
@@:
        ASSUME  ebx:PTR RESERVEADAPTER
        mov     ebx,pInData
        test    dword ptr[ebx].fAFBFlags,AFB_SWITCH     ;fAFBFlags
        jz      @f
        cmp     pfnSetBankSelect,0   ;If pointer to set_bank_select is not
        jnz     @f                   ; initialized, initialize it
        QUERYSETBANKADDR             ;If no error, assume supported
        or      eax,eax
        jnz     EscNotImplementedError
@@:
        cmp     cInCount,sizeof RESERVEADAPTER ;If incount < size needed, return error
        jl      EscLogError
        mov     edx,pInstance
        INVOKE  enter_driver
        jc      EscLogError          ;eax = 0 on error

        test    dword ptr[ebx].fAFBFlags,AFB_SWITCH ;fAFBFlags
        jz      @f
        mov     dl,byte ptr[ebx].ulBankNumber       ;ulBankNumber
        call    pfnSetBankSelect
@@:
        mov     ecx,[ebx].Exclude_xLeft    ;X coordinate of left edge
        mov     edx,[ebx].Exclude_yTop     ;Y coordinate of top edge
        mov     esi,[ebx].Exclude_xRight   ;X coordinate of right edge (inclusive)
        mov     edi,[ebx].Exclude_yBottom  ;Y coordinate of bottom edge (inclusive)
        call    far_exclude
        mov     eax,1                ;Success
        jmp     EscExit

ALIGN 4

;/*
;** ReleaseAdapter
;**
;**   Function: Release driver semaphore and unexclude pointer.
;**   Input:    None
;**   Output:   Return code in eax, 1 = success
;*/

EscReleaseAdapter:
        cmp     pfnQueryApertureInfo,0 ;If pointer to QueryApertureInfo is not
        jnz     @f                     ; initialized, initialize it
        QUERYAPERTUREADDR              ;If no error, assume supported
        or      eax,eax
        jnz     EscNotImplementedError
@@:
        INVOKE  leave_driver
        call    far_unexclude
        mov     eax,1                ;Success
        jmp     EscExit

ALIGN 4

EscNotImplementedError:
        mov     eax,DEVESC_NOTIMPLEMENTED
        jmp     EscExit

;/*
;**            End
;*/

EscLogError:
        MOV     EAX,PMERR_INV_LENGTH_OR_COUNT
        save_error_code
        MOV     EAX,DEVESC_ERROR

EscExit:
        RET

Escape  ENDP

        END
