;*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.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = VIO.ASM
;*
;* DESCRIPTIVE NAME = Thunked Routines.
;*
;*
;* VERSION      V2.0
;*
;* DATE         10/22/91
;*
;* DESCRIPTION  Thunked Vio routines
;*
;* FUNCTIONS    Vio32GetConfig
;*              GETCONFIG_CALL_16_R3
;*
;* 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/15/91                     File Compiled Tue Oct 15 14:18:09 1991  
;*                                Command Line: \mirrors\thunks\thunk -zy vio.mif vio.asm
;*
;*****************************************************************************/

;/*
;**        Static Name Aliases
;*/

        TITLE   $vio.asm

        .386
OPTION PROLOGUE:None    
OPTION EPILOGUE:None

OS2_NOBASEAPI EQU 1
        INCLUDE PMGRE.INC

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

EXTERNDEF DOS32FLATDS                  :ABS

        PUBLIC  Vio32GetConfig

_CODE16 SEGMENT PARA USE16 PUBLIC 'CODE'
        extrn   DOS16CALLBACK:FAR
        EXTRN   DOS16ALLOCSEG:FAR
        EXTRN   DOS16FREESEG:FAR
_CODE16 ENDS

        EXTRN   VIO16GETCONFIG:FAR

;/*
;** Create a dummy label to trick MASM into correct fixups
;*/


_CODE   SEGMENT PARA FLAT PUBLIC 'CODE'
        ASSUME DS:FLAT,ES:FLAT

EXTERN   DOS32FLATTOSEL:NEAR

;/***************************************************************************
;*
;* FUNCTION NAME = Vio32GetConfig
;*
;* DESCRIPTION   = Call the 16 bit VioGetConfig, and thunk the parameters
;*
;* INPUT         = usReserved:DWORD,                 
;*                 pvioin:DWORD,                     
;*                 hvio:DWORD                        
;* OUTPUT        = same as from Thunked call
;*
;* RETURN-NORMAL = same as from Thunked call  
;* RETURN-ERROR  = same as from Thunked call  
;*
;**************************************************************************/

ALIGN 4
Vio32GetConfig PROC SYSCALL,
        usReserved:DWORD,
        pvioin:DWORD, 
        hvio:DWORD

        push    ebp
        mov     ebp,esp


        cld                                      ;Assume direction flag clear
        xor     eax,eax
        push    eax                              ; temp storage for return value
        push    esi
        push    edi
        push    eax                              ; temp storage 
        push    eax                              ;Error flag for cleanup
        push    eax                              ; temp storage for Stack Allocation Flags
        push    eax                              ; temp storage for BMP Flags
        push    eax                              ; temp storage for Alias Flags
        push    eax                              ; temp storage for ptr param #1

;/*
;** Compare stack selector against FLAT:R3DSB
;** If the selector is not equal, then don't bump stack.
;*/

        mov     eax,ss
        cmp     ax,DOS32FLATDS                    ;32 bit stack?
        jne     L1                               ; if not, skip bumping code

;/*
;** * Bump the stack down if too near 64K boundary.
;*/

        mov     eax,esp
        cmp     ax,1024
        jae     L1
        xor     ax,ax
        mov     esp,eax                          ; bump the stack down

;/*
;** Insure that 1 DWORD exists on stack
;*/

        push    eax
L1:

;/*
;**  ****> BEGIN Pointer/Structure Section
;*/

        mov     esi,[ebp+12]                      ;pvioin base address

;/*
;** Pointer pvioin --> pvioin
;*/

        mov     [ebp-36],esi
        or      esi,esi
        jz      L2

;/*
;** Structures are not Identical
;** Structures don't have pointers
;*/

L2:

;/*
;**  ****> END Pointer/Structure Section
;*/

;/*
;** * Create new call frame, using 16-bit semantics.
;*/

        push    es
        push    ebx
        push    ebp                               ; save ebp
        mov     eax,esp                           ; save current esp
        push    ss
        push    eax


        mov     dx,ds                             ; get cpl bits to use as dpl bits
        and     dx,3                              ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

;/*
;** From Name: usReserved  Type: unsigned short
;*/

        push    WORD PTR [ebp+8]                 ; To: unsigned short

;/*
;** From Name: pvioin  Type: struct VIOCONFIGINFO
;*/

        mov     eax,DWORD PTR [ebp-36]
        or      eax,eax
        jz      L3                               ;NULL pointer

        ror     eax,16                            ;CRMA on structure pointer
        shl     ax,3
        or      al,dl
        rol     eax,16

L3:     push    eax


;/*
;** From Name: hvio  Type: unsigned short
;*/

        push    WORD PTR [ebp+16]                ; To: unsigned short

;/*
;** * Convert SS:ESP to 16-bit SS:SP.
;*/


        mov     dx,ss                             ; get cpl bits to use as dpl bits
        and     dx,3                              ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

        mov     eax,esp                           ; use CRMA on ESP to get SS
        ror     eax,16
        shl     eax,3
        or      al,dl
        mov     ss,ax

;/*
;** Jump to 16-bit segment to issue call (so that 16-bit API can RETF).
;** The following two lines are the same as:
;*/

        jmp     FAR PTR T_VIO16GETCONFIG
ALIGN 4


NOMEM_Vio32GetConfig:
        push    8
        pop     eax

ERR_Vio32GetConfig:
        mov     BYTE PTR [ebp-20],1               ;Set flag
        jmp     L4
ALIGN 4

R_VIO16GETCONFIG::                                 ; label defining return jmp location

;/*
;** * Restore 32-bit SS:ESP - it is on top of stack.
;*/

        movzx   esp,sp                            ; make sure that esp is correct
        lss     esp,[esp]
        pop     ebp
        pop     ebx
        pop     es


;/*
;** Return type maps directly.
;*/

L4:

;/*
;** Functions contain pointers, save return code
;*/

        mov     [ebp-4],eax                       ;Save return code

;/*
;** * 32-bit return code.
;*/

        lea     esp,[ebp-12]
        pop     edi
        pop     esi
        pop     eax                              ;Pop saved return code
        leave
        ret                                       ; Remove parameters

Vio32GetConfig endp

_CODE   ENDS

_Text16 SEGMENT PARA USE16 PUBLIC 'CODE'

        PUBLIC  T_VIO16GETCONFIG
T_VIO16GETCONFIG LABEL    FAR

        mov     bp,sp                           ; load base register
        mov     ax,cs
        and     al, 3
        cmp     al, 3                           ; at ring 3?
        je      @F                              ;yes jump
                                                ;NO we're at ring2
                mov     ax,[bp]
                mov     ebx,[bp+2]
                mov     cx,[bp+6]

                push    SEG GETCONFIG_CALL_16_R3
                push    OFFSET GETCONFIG_CALL_16_R3
                call    DOS16CALLBACK
                add     sp,8    ; pop the VioGetConfig parameters
                                ; NOT!!! the DosCallback parameters
                                ; this is because VioGetConfig was
                                ; called from another stack, so we
                                ; must clean up our own stack
                jmp     FAR PTR FLAT:R_VIO16GETCONFIG  ; jump back
        ALIGN 4

@@:
                call    FAR PTR VIO16GETCONFIG    ; call 16-bit version
                jmp     FAR PTR FLAT:R_VIO16GETCONFIG  ; jump back
        ALIGN 4


;/***************************************************************************
;*
;* FUNCTION NAME = GETCONFIG_CALL_16_R3 
;*
;* DESCRIPTION   = Calls the 16 bit function of the same name and then jumps
;*                 back to 32 bit land.
;*
;* INPUT         = Same as for 16 bit call
;* OUTPUT        = Same as for 16 bit call
;*
;* RETURN-NORMAL = Same as for 16 bit call
;* RETURN-ERROR  = Same as for 16 bit call
;*
;**************************************************************************/
        public  GETCONFIG_CALL_16_R3
ALIGN 4
GETCONFIG_CALL_16_R3      proc    far

        push    bp
        mov     bp,sp

        push    cx
        push    ebx
        push    ax
        call    FAR PTR VIO16GETCONFIG            ; call 16-bit version

        mov     sp,bp                           ; skip stack readjust, just reset frame.        
        pop     bp
        ret
GETCONFIG_CALL_16_R3      endp

_Text16 ENDS

        END
