;*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.;
;*****************************************************************************/
;Thunk Compiler Version 13.30  Sep 25 1991 13:13:22
; Altered to efficiently generate Mirrors Thunks
;File Compiled Tue Jan 14 16:42:41 1992

;Command Line: thunk -zy fsrsem.mif fsrthunk.asm

;       Static Name Aliases
;

        TITLE   $fsrthunk.asm

        .386

;Error codes taken out of error.h
ERROR_NOMEMORY EQU 8
ERROR_INVALIDPARAM EQU 87

DOS32FLATDS equ 53
extrn DOS32FLATTOSEL    :proc

        PUBLIC  _FSRSemEnter32
        PUBLIC  _FSRSemLeave32
        PUBLIC  _FSRSemExit32
        PUBLIC  _FSRSemCheck32

_CODE   SEGMENT DWORD USE32 PUBLIC 'CODE'
_CODE   ENDS

_CODE16 SEGMENT WORD USE16 PUBLIC 'CODE'
        EXTRN   DOS16ALLOCSEG:FAR
        EXTRN   DOS16FREESEG:FAR
_CODE16 ENDS

_DATA   SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA   ENDS
        EXTRN   FSRSEMENTER:FAR
        EXTRN   FSRSEMLEAVE:FAR
        EXTRN   FSRSEMEXIT:FAR
        EXTRN   FSRSEMCHECK:FAR

_CODE16 SEGMENT WORD USE16 PUBLIC 'CODE'
_CODE16 ENDS

;Create a dummy label to trick MASM into correct fixups

_CODE16 SEGMENT

T_FSRSEMENTER   LABEL FAR

_CODE16 ENDS


_CODE   SEGMENT
        ASSUME CS:FLAT,DS:FLAT,ES:FLAT
_FSRSemEnter32 PROC

        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 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]             ;pSem base address

;Pointer pSem --> pSem
        or      esi,esi
        jz      L2

        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,65516
        jbe     L2                      ;Enough room

; Allocate space on stack
        sub     esp,20                  ;Alloc Mem
        and     esp,0FFFFFFFCh          ;DWORD align
        mov     edi,esp                 ;Points to new data area
        mov     [ebp-36],edi

;Transfer 20 bytes

        mov     ecx,5
        rep     movsd

L2:

; ****> END Pointer/Structure Section

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

        push    es
        push    ds
        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: pSem  Type: struct FSRS
        mov     eax,DWORD PTR [ebp-36]
        or      eax,eax
        jz      short L5                ;NULL pointer

        call    DOS32FLATTOSEL          ;Convert in packed region

L5:     push    ax                      ;Push near pointer to FSR
        shr     eax, 16
        mov     ds, ax                  ;Change DS so near pointer is ok.


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

        db      66h,0eah
        dw      offset T_FSRSEMENTER, seg T_FSRSEMENTER


NOMEM_FSRSemEnter32:
        push    8
        pop     eax

ERR_FSRSemEnter32:
        mov     BYTE PTR [ebp-20],1             ;Set flag
        jmp     short L6

R_FSRSEMENTER:                          ; 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     ds
        pop     es


;Convert Return Code
;USHORT --> ULONG
        movzx   eax,ax
L6:
;Functions contain pointers, save return code
        mov     [ebp-4],eax             ;Save return code

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


;Undo Pointer pSem --> pSem


        mov     esi,[ebp-36]            ;pSem temp address
        or      esi,esi
        jz      L7



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

;Structures are Identical
;Structures don't have pointers
;Structure has 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      L7

;Item is fixed size

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

;Space was allocated on stack

;Transfer 20 bytes

        mov     ecx,5
        rep     movsd

L11:                    ;ErrorLabel C
;stack deallocated implicitly

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

_FSRSemEnter32 endp

_CODE   ENDS

;* 16-bit code to make API call.

_CODE16 SEGMENT

        ASSUME CS:_CODE16
        .errnz ($ - T_FSRSEMENTER)

        call    FAR PTR FSRSEMENTER             ; call 16-bit version
        jmp     FAR PTR FLAT:R_FSRSEMENTER              ; jump back

_CODE16 ENDS


;Create a dummy label to trick MASM into correct fixups

_CODE16 SEGMENT

T_FSRSEMLEAVE   LABEL FAR

_CODE16 ENDS


_CODE   SEGMENT
        ASSUME CS:FLAT,DS:FLAT,ES:FLAT
_FSRSemLeave32 PROC

        xor     eax,eax

C_FSRSemLeave32:

        push    ebp
        mov     ebp,esp

        push    eax             ;Save call number


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

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

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


;Insure that 1 DWORD exists on stack
        push    eax
L13:


; ****> BEGIN Pointer/Structure Section



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

;Pointer pSem --> pSem
        or      esi,esi
        jz      L14

        mov     [ebp-40],esi

;Structures are Identical
;Structures don't have pointers

;Treat structure same as buffer

;Check Boundary Crossing - fixed size item
        cmp     si,65516
        jbe     L14                     ;Enough room

; Allocate space on stack
        sub     esp,20                  ;Alloc Mem
        and     esp,0FFFFFFFCh          ;DWORD align
        mov     edi,esp                 ;Points to new data area
        mov     [ebp-40],edi

;Transfer 20 bytes

        mov     ecx,5
        rep     movsd

L14:

; ****> END Pointer/Structure Section

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

        push    es
        push    ds
        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: pSem  Type: struct FSRS
        mov     eax,DWORD PTR [ebp-40]
        or      eax,eax
        jz      short L17               ;NULL pointer

        call    DOS32FLATTOSEL          ;Convert in packed region

L17:    push    ax                      ;Push near pointer to FSR
        shr     eax, 16
        mov     ds, ax                  ;Change DS so near pointer is ok.


                        ;Generic Routine: get function number into ecx
        mov     ecx,[ebp-4]

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

        db      66h,0eah
        dw      offset T_FSRSEMLEAVE, seg T_FSRSEMLEAVE


;The following are entry points for routines that
;have the same semantics and parameters.

_FSRSemExit32:
        push    1
        pop     eax
        jmp     C_FSRSemLeave32


NOMEM_FSRSemLeave32:
        push    8
        pop     eax

ERR_FSRSemLeave32:
        mov     BYTE PTR [ebp-24],1             ;Set flag
        jmp     short L18

R_FSRSEMLEAVE:                          ; 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     ds
        pop     es


;Convert Return Code

;Return type maps directly.
L18:
;Functions contain pointers, save return code
        mov     [ebp-8],eax             ;Save return code

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


;Undo Pointer pSem --> pSem


        mov     esi,[ebp-40]            ;pSem temp address
        or      esi,esi
        jz      L19



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

;Structures are Identical
;Structures don't have pointers
;Structure has 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      L19

;Item is fixed size

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

;Space was allocated on stack

;Transfer 20 bytes

        mov     ecx,5
        rep     movsd

L23:                    ;ErrorLabel C
;stack deallocated implicitly

L19:            ;No action required

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

;* 32-bit return code.

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

_FSRSemLeave32 endp

_CODE   ENDS

;* 16-bit code to make API call.

_CODE16 SEGMENT

        ASSUME CS:_CODE16
        .errnz ($ - T_FSRSEMLEAVE)



;Target is at L24 + (cx * 8)

        mov     dx,offset L24
        movzx   edx,dx

        lea     edx,[edx+(ecx*4)]
        call    DWORD PTR CS:[EDX]
        jmp     FAR PTR FLAT:R_FSRSEMLEAVE              ; jump back


L24:


;Jump table for thunk routine
        dw      OFFSET FSRSEMLEAVE
        dw      SEG FSRSEMLEAVE
        dw      OFFSET FSRSEMEXIT
        dw      SEG FSRSEMEXIT
_CODE16 ENDS


;Create a dummy label to trick MASM into correct fixups

_CODE16 SEGMENT

T_FSRSEMCHECK   LABEL FAR

_CODE16 ENDS


_CODE   SEGMENT
        ASSUME CS:FLAT,DS:FLAT,ES:FLAT
_FSRSemCheck32 PROC

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

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

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


;Insure that 1 DWORD exists on stack
        push    eax
L26:


; ****> BEGIN Pointer/Structure Section



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

;Pointer pSem --> pSem
        or      esi,esi
        jz      L27

        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,65516
        jbe     L27                     ;Enough room

; Allocate space on stack
        sub     esp,20                  ;Alloc Mem
        and     esp,0FFFFFFFCh          ;DWORD align
        mov     edi,esp                 ;Points to new data area
        mov     [ebp-36],edi

;Transfer 20 bytes

        mov     ecx,5
        rep     movsd

L27:

; ****> END Pointer/Structure Section

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

        push    es
        push    ds
        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: pSem  Type: struct FSRS
        mov     eax,DWORD PTR [ebp-36]
        or      eax,eax
        jz      short L30               ;NULL pointer

        call    DOS32FLATTOSEL          ;Convert in packed region

L30:    push    ax                      ;Push near pointer to FSR
        shr     eax, 16
        mov     ds, ax                  ;Change DS so near pointer is ok.


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

        db      66h,0eah
        dw      offset T_FSRSEMCHECK, seg T_FSRSEMCHECK


NOMEM_FSRSemCheck32:
        push    8
        pop     eax

ERR_FSRSemCheck32:
        mov     BYTE PTR [ebp-20],1             ;Set flag
        jmp     short L31

R_FSRSEMCHECK:                          ; 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     ds
        pop     es


;Convert Return Code
;ULONG --> ULONG
        rol     eax,16
        mov     ax,dx
        rol     eax,16
L31:
;Functions contain pointers, save return code
        mov     [ebp-4],eax             ;Save return code

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


;Undo Pointer pSem --> pSem


        mov     esi,[ebp-36]            ;pSem temp address
        or      esi,esi
        jz      L32



        mov     edi,[ebp+8]             ;pSem 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      L32

;Item is fixed size
;stack deallocated implicitly

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

_FSRSemCheck32 endp

_CODE   ENDS

;* 16-bit code to make API call.

_CODE16 SEGMENT

        ASSUME CS:_CODE16
        .errnz ($ - T_FSRSEMCHECK)

        call    FAR PTR FSRSEMCHECK             ; call 16-bit version
        jmp     FAR PTR FLAT:R_FSRSEMCHECK              ; jump back

_CODE16 ENDS

        END
