;*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
INCL_FONTFILEFORMAT EQU 1                                               ;IBMJ
        OPTION  OLDSTRUCTS                                              ;IBMJ
        INCLUDE PMGRE.INC

DINCL_VIO          EQU 1                                                ;IBMJ
DINCL_BITMAP       EQU 1
DINCL_ENABLE       EQU 1
        INCLUDE DRIVER.INC
        INCLUDE EXTERN.INC
        INCLUDE PROTOS.INC

IFDEF DBCS  ; DBCS codepage / DBCS device font support                   ;IBMJ
 INCLUDE FONTDRVR.INC
; INCLUDE OS2NLSFD.INC

EXTERN DOS32SELTOFLAT:NEAR
ENDIF;DBCS                                                               ;IBMJ
;/*
;** 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
IFNDEF DBCS                                                             ;IBMJ
        JNE     EscExit
ELSE ;DBCS  ; DBCS device font support
 JE EscEscsupport
 TEST swFlags,SW_DISPLAY_DBCS  ; font manager installed ?
 JZ EscExit    ; no...
 CMP DX,DEVESC_DBE_FONTMANAGEMENT
 JE EscFontmanagement
 JMP EscExit
EscEscsupport:
ENDIF;DBCS                                                              ;IBMJ

;/*
;** 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
IFDEF DBCS  ; DBCS device font support     ;IBMJ
 JE EscSupportedExit
 TEST swFlags,SW_DISPLAY_DBCS ; font manager installed ?
 JZ EscSupportExit  ; no...
 CMP DX,DEVESC_DBE_FONTMANAGEMENT
ENDIF;DBCS        ;IBMJ
        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
IFNDEF DBCS        ;IBMJ
        MOV     eax,cDevVioCells
        MOV     DWORD ptr [EDI],eax
ELSE ;DBCS  ; DBCS device font support     ;IBMJ
 MOVZX EAX,WORD PTR cDevVioCells
 MOV [EDI],EAX
ENDIF;DBCS        ;IBMJ
        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
IFNDEF DBCS        ;IBMJ
        MOV     ECX,cDevVioCells     ; ECX is maximum cell structures
ELSE ;DBCS  ; DBCS device font support     ;IBMJ
 MOVZX ECX,WORD PTR cDevVioCells ; ECX is maximum cell structures
ENDIF;DBCS        ;IBMJ
        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
IFNDEF DBCS        ;IBMJ
        MOV     EAX,cDevVioCells     ; Store count of sizes available
ELSE ;DBCS  ; DBCS device font support     ;IBMJ
 MOVZX EAX,WORD PTR cDevVioCells  ; store count of sizes available
ENDIF;DBCS        ;IBMJ
        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

IFDEF DBCS  ; DBCS device font support     ;IBMJ

;-----------------------------------------------------------------------;
; Load/Unload specified font driver to add/remove optional device fonts.
;
;   This sub-escape function works only with font manager enabled
;   environment (font manager loads the font driver).
;   The swFlags should be checked before whether the font manager is
;   installed or not.
;
; History:
;   08-Aug-1991  -by-  Soh Ohta [jl09057 @ ymtvm3]
; Add Vio font attribute query function (DCR 189 @ JP20).
;-----------------------------------------------------------------------;

 .errnz (size DBE_FDI_PARAMETERS - size VIOFONTATTRIBUTE)
 .errnz (fdi_lFunctionID - vioa_lFunctionID)

 public EscFontmanagement
EscFontmanagement::

 mov eax,CE_INVALID_PRESENTATION_SPACE
 mov edx,pInstance
 invoke enter_driver
 jc esc_fm_error

 mov eax,PMERR_INV_LENGTH_OR_COUNT
 cmp cInCount,size DBE_FDI_PARAMETERS
 jne esc_fm_error

 mov eax,PMERR_INV_ESCAPE_DATA
 mov edi,pInData
 cmp [edi].fdi_lFunctionID.hi,0
 jne esc_fm_error


; Check sub function id and dispatch to functions according to
; the function request.

 mov ecx,[edi].fdi_lFunctionID ; ECX = request id
 cmp ecx,LOAD_FD_PRIVATE
 je esc_fm_fd_management
 cmp ecx,LOAD_FD_PUBLIC
 je esc_fm_fd_management
 cmp ecx,UNLOAD_FD_PRIVATE
 je esc_fm_fd_management
 cmp ecx,UNLOAD_FD_PUBLIC
 je esc_fm_fd_management
 cmp ecx,QUERY_VIO_FONTATTRIBUTE
 je esc_fm_query_vio
 jmp esc_fm_error


;-----------------------------------------------------------------------;
; The request is to load/unload the specified font driver.
; Try to load/unload with specified font driver name.
;-----------------------------------------------------------------------;

esc_fm_fd_management:
 mov eax,[edi].fdi_pFontInfo  ; EAX = font driver name
 call DOS32SELTOFLAT ;get flat pointer to the selector
 invoke DbcsLoadFontDriver
 and eax,PMERR_INV_ESCAPE_DATA ; AX=ffffh on error
 jnz esc_fm_error
 jmp esc_fm_ok


;-----------------------------------------------------------------------;
; The request is to return the Vio font attribute corresponding to
; the specified cellsize. Search the list of cells (DCR 189 @ JP20).
;-----------------------------------------------------------------------;

esc_fm_query_vio:
 mov ebx,[edi].vioa_cx ; cell width
 mov edx,[edi].vioa_cy ; cell height
 lea esi,adDevVioCells ; list of CellFont structure
 movzx ecx,word ptr cDevVioCells ; number of cellsizes available
 jcxz esc_fm_error2  ; no vio cells available. why?

esc_fm_check_loop:
 cmp [esi].CellFont.cf_width,ebx
 jne esc_fm_check_next
 cmp [esi].CellFont.cf_height,edx
 je esc_fm_font_found ; specified cellsize is found
esc_fm_check_next:
 add esi,size CellFont
 loop esc_fm_check_loop
esc_fm_error2:
 jmp esc_fm_error  ; specified cellsize not found

esc_fm_font_found:

IFDEF IBMJ  ; IBMJ application compatibility    ;IBMJ

 cmp swDrvAdjustCellSize,1
 jne esc_fm_save_fattr ; compatibility is not requested

; Some applications assume that the yInternalLeading of Vio compatible
; fonts are set to zero (e.g. 13x18 font --> 12x24 font).
; Searching criteria: usNominalPointSize is equal
;   xAveCharWidth    is equal or smaller
;   yInternalLeading   is zero
; We assume that the resource table is sorted by height within width.

 mov edi,[esi].CellFont.cf_ptr ; EDI --> FOCAFONT structure
 cmp [edi].FOCAFONT.ff_fmMetrics.foca_yInternalLeading,0
 je esc_fm_save_fattr ; criteria exactly match

 mov ax,[edi].FOCAFONT.ff_fmMetrics.foca_usNominalPointSize
 mov ebx,esi   ; EBX --> current  CellFont struct
 lea ecx,adDevVioCells ; ECX --> smallest CellFont struct

esc_fm_look_prev:
 sub ebx,size CellFont ; EBX --> previous CellFont struct
 cmp ebx,ecx
 jb esc_fm_save_fattr ; eventually not found
 mov edi,[ebx].CellFont.cf_ptr ; EDI --> FOCAFONT structure
 cmp [edi].FOCAFONT.ff_fmMetrics.foca_yInternalLeading,0
 jne esc_fm_look_prev
 cmp [edi].FOCAFONT.ff_fmMetrics.foca_usNominalPointSize,ax
 jne esc_fm_look_prev

; The font of old metrics is found.

 mov esi,ebx   ; ESI --> old font's CellFont

ENDIF;IBMJ        ;IBMJ

; Fill font attrinbute structure with selected Vio font metrics.
; Be sure all sizes are in device coordinate.

esc_fm_save_fattr:
 mov eax,[esi].CellFont.cf_ptr ; EAX --> FOCAFONT structure
 invoke DbcsQueryMatchNum  ; EAX = match number

 mov esi,[esi].CellFont.cf_ptr ; ESI --> FOCAFONT structure
 mov edi,pOutData   ; EDI --> FATTRS structure

 mov [edi].FATTRS.fat_lMatch,eax
 mov [edi].FATTRS.fat_usRecordLength,(size FATTRS)
 mov [edi].FATTRS.fat_fsFontUse,0

 mov ax,[esi].FOCAFONT.ff_fmMetrics.foca_fsSelectionFlags
 mov [edi].FATTRS.fat_fsSelection,ax
 mov ax,[esi].FOCAFONT.ff_fmMetrics.foca_usRegistryId
 mov [edi].FATTRS.fat_idRegistry,ax
 movzx eax,[esi].FOCAFONT.ff_fmMetrics.foca_yMaxBaselineExt
 mov [edi].FATTRS.fat_lMaxBaselineExt,eax
 movzx eax,[esi].FOCAFONT.ff_fmMetrics.foca_xAveCharWidth
 mov [edi].FATTRS.fat_lAveCharWidth,eax

 xor cx,cx
 mov ax,[esi].FOCAFONT.ff_fmMetrics.foca_fsTypeFlags
 test ax,FM_TYPE_KERNING
 jz @f
 or cx,FATTR_TYPE_KERNING
    @@: and ax,(FM_TYPE_MBCS or FM_TYPE_DBCS)
 cmp ax,FM_TYPE_MBCS
 jne @f
 or cx,FATTR_TYPE_MBCS
    @@: cmp ax,FM_TYPE_DBCS
 jne @f
 or cx,FATTR_TYPE_DBCS
    @@: mov [edi].FATTRS.fat_fsType,cx

 mov ax,[esi].FOCAFONT.ff_fmMetrics.foca_usCodePage
 cmp ax,DEFAULTVIOCODEPAGE ; SBCS universal codepage?
 jne @f   ; no...
 xor ax,ax   ; be sure DBCS universal codepage
@@: mov [edi].FATTRS.fat_usCodePage,ax

 lea esi,[esi].FOCAFONT.ff_fmMetrics.foca_szFacename
 lea edi,[edi].FATTRS.fat_szFacename
 mov ecx,FACESIZE
 cld
 rep movsb   ; copy facename
 jmp esc_fm_ok


;-----------------------------------------------------------------------;
; Complete our job.
;-----------------------------------------------------------------------;

esc_fm_ok:
 mov eax,DEV_OK
 jmp esc_fm_done
esc_fm_error:
 save_error_code
 mov eax,DEV_ERROR
esc_fm_done:
 invoke leave_driver
 jmp EscExit

ENDIF;DBCS        ;IBMJ

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