;*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 = THUNK.ASM
;*
;* DESCRIPTIVE NAME = Thunked Routines.
;*
;*
;* VERSION      V2.0
;*
;* DATE         10/22/91
;*
;* DESCRIPTION  Thunk routines
;*
;* FUNCTIONS    Vis32RegionCallBack 
;*              Get32PmddCodeSelector
;*              Get32ScreenSelector 
;*              Vio32GetPhysBuf
;*              Vio32SetState
;*              Vio32SetMode
;*              T_GetScreenSelector
;*              T_VIS16REGIONCALLBACK
;*              T_GetPmddCodeSelector
;*              T_VIO16GETPHYSBUF 
;*              T_VIO16SETSTATE
;*              T_VIO16SETMODE 
;*
;* 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/22/91                     File Compiled Tue Oct 22 14:36:43 1991 
;*                                Command Line: thunk -zy thunk.mif thunk.asm 
;*
;*****************************************************************************/

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

        TITLE   $thunk.asm

        .386
        .MODEL FLAT,SYSCALL

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
EXTERN   DOS32FLATTOSEL:NEAR


        EXTRN   VIS16REGIONCALLBACK:FAR16
        EXTRN   GetPmddCodeSelector:FAR16
        EXTRN   GetScreenSelector:FAR16
        EXTRN   VIO16GETPHYSBUF:FAR16
        EXTRN   VIO16SETSTATE:FAR16
        EXTRN   VIO16SETMODE:FAR16

        ASSUME DS:FLAT,ES:FLAT

.CODE

        PUBLIC  Get32PmddCodeSelector
        PUBLIC  Get32ScreenSelector
        PUBLIC  Vis32RegionCallBack
        PUBLIC  Vio32GetPhysBuf
        PUBLIC  Vio32SetState
        PUBLIC  Vio32SetMode

;/***************************************************************************
;*
;* FUNCTION NAME = Vis32RegionCallBack
;*
;* DESCRIPTION   = Call the 16 bit VisRegionCallback, and thunk the parameters
;*
;* INPUT         = myhdc          :DWORD 
;* OUTPUT        = same as from Thunked call
;*
;* RETURN-NORMAL = same as from Thunked call  
;* RETURN-ERROR  = same as from Thunked call  
;*
;**************************************************************************/

Vis32RegionCallBack PROC SYSCALL,
        myhdc          :DWORD

        push    ebp
        mov     ebp,esp

;/*
;** 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     short L1                          ; if not, skip bumping code

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

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

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

        push    eax
L1:

;/*
;** 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     edx,ss                            ; get cpl bits to use as dpl bits
        and     edx,3                             ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

;/*
;** From Name: hdc  Type: unsigned long
;*/

        push    DWORD PTR [ebp+8]                ; To: unsigned long

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

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

;/*
;** 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_VIS16REGIONCALLBACK
;**  but they trick masm into not generating nops.
;*/

        JMP     FAR ptr T_VIS16REGIONCALLBACK
ALIGN 4

R_VIS16REGIONCALLBACK::                            ; 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

;/*
;** Convert Return Code
;** USHORT --> ULONG
;*/

        movzx   eax,ax
L2:

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

        leave
        ret                                       ; Remove parameters

Vis32RegionCallBack endp

;/***************************************************************************
;*
;* FUNCTION NAME = Get32PmddCodeSelector 
;*
;* DESCRIPTION   = Call the 16 bit GetPmddCodeSelector, and thunk the parameters
;*
;* INPUT         = pselCompileData:PTR WORD 
;* OUTPUT        = same as from Thunked call
;*
;* RETURN-NORMAL = same as from Thunked call  
;* RETURN-ERROR  = same as from Thunked call  
;*
;**************************************************************************/

ALIGN 4
Get32PmddCodeSelector PROC SYSCALL,
        pselCompileData:PTR WORD

        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     short L4                          ; if not, skip bumping code

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

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

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

        push    eax
L4:

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


        mov     esi,[ebp+8]                       ;pselData base address

;/*
;** Pointer pselData --> pselData
;*/

        or      esi,esi
        jz      L5

        mov     [ebp-36],esi

;/*
;** Check Boundary Crossing - fixed size item
;*/

        cmp     si,65534
        jbe     L5                                ;Enough room
;/*
;** Allocate space on stack
;*/

        sub     esp,2                             ;Alloc Mem
        and     esp,0FFFFFFFCh                    ;DWORD align
        mov     edi,esp                           ;Points to new data area
        mov     [ebp-36],edi

;/*
;** Transfer 2 bytes
;*/

        movsw

L5:

;/*
;** ****> 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     edx,ss                            ; get cpl bits to use as dpl bits
        and     edx,3                             ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

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

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

        call    DOS32FLATTOSEL                    ;Convert in packed region

L8:     push    eax

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

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

;/*
;** Jump to 16-bit segment to issue call (so that 16-bit API can RETF).
;*/

        JMP     FAR ptr T_GetPmddCodeSelector
ALIGN 4


NOMEM_Get32PmddCodeSelector:
        push    8
        pop     eax

ERR_Get32PmddCodeSelector:
        mov     BYTE PTR [ebp-20],1               ;Set flag
        jmp     short L9
ALIGN 4

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

L9:

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

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

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

;/*
;** Undo Pointer pselData --> pselData
;*/


        mov     esi,[ebp-36]                      ;pselData temp address
        or      esi,esi
        jz      L10



        mov     edi,[ebp+8]                       ;pselData original address

;/*
;** Types are identical and no imbedded pointers exist
;** This means that we treated the pointer as a buffer
;** If temp address == original address then no work required
;*/
        cmp     esi,edi
        je      L10

;/*
;**Item is fixed size
;**stack deallocated implicitly
;*/

L10:            ;No action required

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

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

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

Get32PmddCodeSelector endp


;/***************************************************************************
;*
;* FUNCTION NAME = Get32ScreenSelector
;*
;* DESCRIPTION   = Call the 16 bit GetScreenSelector and thunk the parameters
;*                                                                               
;* INPUT         = gssspScreen    :PGSSP                                         
;* OUTPUT        = same as from Thunked call                                     
;*                                                                               
;* RETURN-NORMAL = same as from Thunked call                                     
;* RETURN-ERROR  = same as from Thunked call                                     
;*
;**************************************************************************/
ALIGN 4
Get32ScreenSelector PROC SYSCALL,
        gssspScreen    :PGSSP

        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     short L15                         ; if not, skip bumping code

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

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

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

        push    eax
L15:

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


        mov     esi,[ebp+8]                       ;pss base address
;/*
;** Pointer pss --> pss
;*/

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

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

;/*
;**  Allocate space on stack
;*/

        sub     esp,10                            ;Alloc Mem
        and     esp,0FFFFFFFCh                    ;DWORD align
        mov     edi,esp                           ;Points to new data area
        mov     [ebp-36],edi
;/*
;** Copy structure to new area
;*/


;/*
;** Element ulSize --> ulSize, Add 2 bytes of unsigned short to transfer 
;*/

;/*
;** Element cSel --> cSel. Add 2 bytes of unsigned short to transfer 
;*/

;/*
;** Element cb --> cb. Add 2 bytes of unsigned short to transfer 
;*/

;/*
;** Element pPhysMem --> pPhysMem. Alignment Change 
;*/

;/*
;** Transfer 6 bytes
;*/

        movsd
        movsw
;/*
;** ReAlignment
;*/

        add     esi,2
;/*
;** Add 4 bytes of unsigned long to transfer
;*/

        movsd

L16:

;/*
;**  ****> 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     edx,ss                            ; get cpl bits to use as dpl bits
        and     edx,3                             ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

;/*
;** From Name: pss  Type: struct GSSP
;*/


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

        call    DOS32FLATTOSEL                    ;Convert in packed region

L17:    push    eax

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


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

;/*
;** * Jump to 16-bit segment to issue call (so that 16-bit API can RETF).
;*/


        JMP     FAR ptr T_GetScreenSelector
ALIGN 4


NOMEM_Get32ScreenSelector:
        push    8
        pop     eax

ERR_Get32ScreenSelector:
        mov     BYTE PTR [ebp-20],1               ;Set flag
        jmp     short L18
ALIGN 4

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

L18:

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

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

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

;/*
;** Undo Pointer pss --> pss
;*/

        mov     esi,[ebp-36]                      ;pss temp address
        or      esi,esi
        jz      L19



        mov     edi,[ebp+8]                       ;pss original address

;/*
;** Structures are not Identical
;** Structures don't have pointers
;** Structure doesn't have output semantics
;** Return structure to original area
;** Deallocate Temporary Structure
;*/

;/*
;** Stack allocated memory deallocated implicitly
;*/

L19:            ;No action required

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

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

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

;/***************************************************************************
;*
;* FUNCTION NAME = Vio32GetPhysBuf
;*
;* DESCRIPTION   = Call the 16 bit VioGetPhysBuf and thunk the parameters
;*                                                                           
;* INPUT         = same as from Thunked call                                 
;* OUTPUT        = same as from Thunked call                                 
;*                                                                           
;* RETURN-NORMAL = same as from Thunked call                                 
;* RETURN-ERROR  = same as from Thunked call                                 
;*
;**************************************************************************/

ALIGN 4
Vio32GetPhysBuf PROC SYSCALL

        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
        push    eax                              ; temp storage for ptr param #2

;/*
;** 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     short L1                          ; if not, skip bumping code

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

        mov     eax,esp
        cmp     ax,1024
        jae     short 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+8]                       ;pviopb base address

;/*
;** Pointer pviopb --> pviopb
;*/

        or      esi,esi
        jz      L2

        mov     [ebp-36],esi

;/*
;** Structures are Identical
;** Structures have pointers
;** Allocate space on stack
;*/

        sub     esp,10                            ;Alloc Mem
        and     esp,0FFFFFFFCh                    ;DWORD align
        mov     edi,esp                           ;Points to new data area
        mov     [ebp-36],edi

;/*
;** Copy structure to new area
;*/

;/*
;** Element pBuf --> pBuf. Pointer converted later 
;*/

;/*
;** Element cb --> cb - Add 4 bytes of unsigned long to transfer  
;*/

;/*
;** Element asel --> asel - Add 2 bytes of unsigned short to transfer 
;*/

;/*
;** Transfer 10 bytes
;*/


        mov     ecx,2
        rep     movsd
        movsw

;/*
;** Fixup imbedded pointer pBuf
;*/

        mov     esi,[ebp-36]                      ;Get parents pointer
        mov     esi,[esi+0]                       ;Get Fixups pointer

;/*
;** Pointer pBuf --> pBuf
;*/

        or      esi,esi
        jz      L3

        mov     [ebp-40],esi

;/*
;** Check Boundary Crossing - fixed size item
;*/

        cmp     si,65535
        jbe     L3                                ;Enough room

;/*
;**  Allocate space on stack
;*/

        sub     esp,1                             ;Alloc Mem
        and     esp,0FFFFFFFCh                    ;DWORD align
        mov     edi,esp                           ;Points to new data area
        mov     [ebp-40],edi

;/*
;** Transfer 1 bytes
;*/

        movsb

L3:

;/*
;** Patch in new pointer value
;*/

        mov     edi,[ebp-36]                      ;Get parents pointer
        mov     esi,[ebp-40]                      ;Get Fixups new pointer

;/*
;** Convert 0:32 --> 16:16
;*/

        or      esi,esi
        jz      short L6
        xchg    eax,esi                          ;Packed Region
        call    DOS32FLATTOSEL                    ;Convert in packed region
        xchg    esi,eax

L6:
        mov     [edi+0],esi                       ;Put Fixups pointer

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     edx,ss                            ; get cpl bits to use as dpl bits
        and     edx,3                             ; mask off rest of register

        or      dl,4                              ;Force LDT bit on


        ;From Name: pviopb  Type: struct VIOPHYSBUF
        mov     eax,DWORD PTR [ebp-36]
        or      eax,eax
        jz      short L7                          ;NULL pointer

        call    DOS32FLATTOSEL                    ;Convert in packed region

L7:     push    eax

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

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

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

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

;/*
;** 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_VIO16GETPHYSBUF
ALIGN 4


NOMEM_Vio32GetPhysBuf:
        push    8
        pop     eax

ERR_Vio32GetPhysBuf:
        mov     BYTE PTR [ebp-20],1               ;Set flag
        jmp     short L8
ALIGN 4

R_VIO16GETPHYSBUF::                                ; 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

;/*
;** Convert Return Code - USHORT --> ULONG 
;*/

        movzx   eax,ax
L8:

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

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

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

;/*
;** Undo Pointer pviopb --> pviopb
;*/

        mov     esi,[ebp-36]                      ;pviopb temp address
        or      esi,esi
        jz      L9



        mov     edi,[ebp+8]                       ;pviopb original address

;/*
;** Structures are Identical
;** Structures have pointers
;** Structure has output semantics
;** Return structure to original area
;*/

        test    BYTE PTR[ebp-20],1                ;Check for errors D
        jnz     L10                               ;No copy if error

;/*
;** Element pBuf --> pBuf - Pointer elements not copied out 
;*/

        add     esi,4
        add     edi,4

;/*
;** Element cb --> cb - Add 4 bytes of unsigned long to transfer 
;*/

;/*
;** Element asel --> asel - Add 2 bytes of unsigned short to transfer 
;*/

;/*
;** Transfer 6 bytes
;*/

        movsd
        movsw

L10:                    ;ErrorLabel D

;/*
;** Unpack imbedded pointer pBuf
;*/

        mov     esi,[ebp-40]                      ;Get pointer to temporary
        or      esi,esi                          ;Ignore if NULL
        jz      L11

        mov     edi,[ebp+8]                       ;Get parents original pointer
        mov     edi,[edi+0]                       ;Get Fixups original address

;/*
;** Types are identical and no imbedded pointers exist
;** This means that we treated the pointer as a buffer
;** If temp address == original address then no work required
;*/

        cmp     esi,edi
        je      L11

;/*
;** Item is fixed size
;*/


        test    BYTE PTR[ebp-20],1                ;Check for errors C
        jnz     L15                               ;No copy if error

;/*
;** Space was allocated on stack
;*/

;/*
;** Transfer 1 bytes
;*/

        movsb

L15:                    ;ErrorLabel C
;/*
;** stack deallocated implicitly
;*/

L11:

;/*
;** Stack allocated memory deallocated implicitly
;*/


L9:             ;No action required

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

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


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

Vio32GetPhysBuf endp

;/***************************************************************************
;*
;* FUNCTION NAME = Vio32SetState
;*
;* DESCRIPTION   = Call the 16 bit VioSetState and thunk the parameters
;*                                                                           
;* INPUT         = same as from Thunked call                                 
;* OUTPUT        = same as from Thunked call                                 
;*                                                                           
;* RETURN-NORMAL = same as from Thunked call                                 
;* RETURN-ERROR  = same as from Thunked call                                 
;*
;**************************************************************************/
ALIGN 4
Vio32SetState PROC SYSCALL

        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     short L17                         ; if not, skip bumping code

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

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

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

        push    eax
L17:

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

        mov     esi,[ebp+8]                       ;pviops base address

;/*
;** Pointer pviops --> pviops
;*/

        or      esi,esi
        jz      L18

        mov     [ebp-36],esi

;/*
;** Structures are Identical
;** Structures don't have pointers
;** Treat structure same as buffer
;*/

;/*
;** Check Boundary Crossing - fixed size item
;*/

        cmp     si,65498
        jbe     L18                               ;Enough room

;/*
;**  Allocate space on stack
;*/

        sub     esp,38                            ;Alloc Mem
        and     esp,0FFFFFFFCh                    ;DWORD align
        mov     edi,esp                           ;Points to new data area
        mov     [ebp-36],edi

;/*
;** Transfer 38 bytes
;*/

        mov     ecx,9
        rep     movsd
        movsw

L18:

;/*
;**  ****> 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     edx,ss                            ; get cpl bits to use as dpl bits
        and     edx,3                             ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

;/*
;** From Name: pviops  Type: struct VIOPALSTATE
;*/

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

        call    DOS32FLATTOSEL                    ;Convert in packed region

L21:    push    eax


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

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

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

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

;/*
;** 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_VIO16SETSTATE
ALIGN 4


NOMEM_Vio32SetState:
        push    8
        pop     eax

ERR_Vio32SetState:
        mov     BYTE PTR [ebp-20],1               ;Set flag
        jmp     short L22
ALIGN 4

R_VIO16SETSTATE::                                  ; 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

;/*
;** Convert Return Code - USHORT --> ULONG 
;*/

        movzx   eax,ax

L22:

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

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

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

;/*
;** Undo Pointer pviops --> pviops
;*/

        mov     esi,[ebp-36]                      ;pviops temp address
        or      esi,esi
        jz      L23

        mov     edi,[ebp+8]                       ;pviops original address

;/*
;** Structures are Identical
;** Structures don't have pointers
;** Structure doesn't have output semantics
;** Treat structure same as buffer
;** Types are identical and no imbedded pointers exist
;** This means that we treated the pointer as a buffer
;** If temp address == original address then no work required
;*/

        cmp     esi,edi
        je      L23

;/*
;** Item is fixed size
;** stack deallocated implicitly
;*/

L23:            ;No action required

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

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

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

Vio32SetState endp

;/***************************************************************************
;*
;* FUNCTION NAME = Vio32SetMode
;*
;* DESCRIPTION   = Call the 16 bit VioSetState and thunk the parameters
;*                                                                           
;* INPUT         = same as from Thunked call                                 
;* OUTPUT        = same as from Thunked call                                 
;*                                                                           
;* RETURN-NORMAL = same as from Thunked call                                 
;* RETURN-ERROR  = same as from Thunked call                                 
;*
;**************************************************************************/
ALIGN 4
Vio32SetMode PROC SYSCALL

        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     short L28                         ; if not, skip bumping code

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

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

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

        push    eax
L28:

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

        mov     esi,[ebp+8]                       ;pviomi base address

;/*
;** Pointer pviomi --> pviomi
;*/

        or      esi,esi
        jz      L29

        mov     [ebp-36],esi

;/*
;** Structures are Identical
;** Structures don't have pointers
;** Treat structure same as buffer
;** Check Boundary Crossing - fixed size item
;*/

        cmp     si,65524
        jbe     L29                               ;Enough room

;/*
;**  Allocate space on stack
;*/

        sub     esp,12                            ;Alloc Mem
        and     esp,0FFFFFFFCh                    ;DWORD align
        mov     edi,esp                           ;Points to new data area
        mov     [ebp-36],edi

;/*
;** Transfer 12 bytes
;*/

        mov     ecx,3
        rep     movsd

L29:

;/*
;**  ****> 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     edx,ss                            ; get cpl bits to use as dpl bits
        and     edx,3                             ; mask off rest of register

        or      dl,4                              ;Force LDT bit on

;/*
;** From Name: pviomi  Type: struct VIOMODEINFO
;*/

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

        call    DOS32FLATTOSEL                    ;Convert in packed region

L32:    push    eax


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

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

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

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

;/*
;** 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_VIO16SETMODE
ALIGN 4


NOMEM_Vio32SetMode:
        push    8
        pop     eax

ERR_Vio32SetMode:
        mov     BYTE PTR [ebp-20],1               ;Set flag
        jmp     short L33
ALIGN 4

R_VIO16SETMODE::                                   ; 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

;/*
;** Convert Return Code - USHORT --> ULONG 
;*/

        movzx   eax,ax
L33:

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

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

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

;/*
;** Undo Pointer pviomi --> pviomi
;*/

        mov     esi,[ebp-36]                      ;pviomi temp address
        or      esi,esi
        jz      L34



        mov     edi,[ebp+8]                       ;pviomi original address

;/*
;** Structures are Identical
;** Structures don't have pointers
;** Structure doesn't have output semantics
;** Treat structure same as buffer
;** Types are identical and no imbedded pointers exist
;** This means that we treated the pointer as a buffer
;** If temp address == original address then no work required
;*/

        cmp     esi,edi
        je      L34

;/*
;** Item is fixed size
;** stack deallocated implicitly
;*/

L34:            ;No action required

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

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

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

Vio32SetMode endp


;/***************************************************************************
;*
;* FUNCTION NAME = T_GetScreenSelector
;*
;* 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
;*
;**************************************************************************/

_CODE16 SEGMENT PARA USE16 PUBLIC 'CODE'

ALIGN 4
T_GetScreenSelector PROC FAR

        call    FAR PTR GetScreenSelector         ; call 16-bit version
        jmp     FAR PTR FLAT:R_GetScreenSelector  ; jump back
ALIGN 4
T_GetScreenSelector ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = T_VIS16REGIONCALLBACK 
;*
;* 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
;*
;**************************************************************************/

ALIGN 4
T_VIS16REGIONCALLBACK PROC FAR
        call    FAR PTR VIS16REGIONCALLBACK       ; call 16-bit version
        jmp     FAR PTR FLAT:R_VIS16REGIONCALLBACK  ; jump back
ALIGN 4
T_VIS16REGIONCALLBACK ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = T_GetPmddCodeSelector 
;*
;* 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
;*
;**************************************************************************/

ALIGN 4
T_GetPmddCodeSelector PROC FAR

        call    FAR PTR GetPmddCodeSelector       ; call 16-bit version
        jmp     FAR PTR FLAT:R_GetPmddCodeSelector  ; jump back
ALIGN 4
T_GetPmddCodeSelector ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = T_VIO16GETPHYSBUF 
;*
;* 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
;*
;**************************************************************************/
ALIGN 4
T_VIO16GETPHYSBUF PROC FAR
        call    FAR PTR VIO16GETPHYSBUF           ; call 16-bit version
        jmp     FAR PTR FLAT:R_VIO16GETPHYSBUF    ; jump back
ALIGN 4
T_VIO16GETPHYSBUF ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = T_VIO16SETSTATE 
;*
;* 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
;*
;**************************************************************************/
ALIGN 4
T_VIO16SETSTATE PROC FAR
        call    FAR PTR VIO16SETSTATE             ; call 16-bit version
        jmp     FAR PTR FLAT:R_VIO16SETSTATE      ; jump back
ALIGN 4
T_VIO16SETSTATE  ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = T_VIO16SETMODE  
;*
;* 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
;*
;**************************************************************************/
ALIGN 4
T_VIO16SETMODE  PROC FAR
        call    FAR PTR VIO16SETMODE              ; call 16-bit version
        jmp     FAR PTR FLAT:R_VIO16SETMODE       ; jump back
ALIGN 4

T_VIO16SETMODE  ENDP


_CODE16 ENDS
        END
