                .386

                EXTRN   DosFlatToSel:Proc

FLAT		GROUP	CODE32

CODE32          SEGMENT DWORD PUBLIC USE32 'CODE'
                ASSUME  CS:FLAT,DS:FLAT

@Uses           equ     6*4                     ; ds,es,ebp,ebx,esi,edi

System@__Far16Pas PROC  Near
                PUBLIC  System@__Far16Pas
                push    ds es ebp ebx esi edi
                mov     ebp,esp
                mov     edx,[esp+@Uses+4]       ; Parameter Data
                mov     eax,[esp+@Uses+8]       ; Far16Proc @
                lea     esi,[esp+@Uses+12]      ; Last parameter offset
                mov     ebx,edx
                test    edx,edx
                jz      @@NoParms
              @@1:
                add     esi,4
                shr     edx,2
                jnz     @@1
; esi = First parameter offset
; Setup thunk stack
              @@NoParms:
                cmp     sp,4*1024       ; 4K = Thunk minimum stack
                jae     @@2
                xor     sp,sp
              @@2:
                Call    DosFlatToSel    ; eax = Far16Proc@
                push    eax             ; Save Far16Proc@
                mov     edi,esp         ; edi = @ Far16Proc@
                push    ebp             ; Code to save EBP, ESP, and SS
                push    esi             ; Stack position after call(with removed parameters)
                mov     eax,esp
                push    ss              ; Save FLATSS:ESP
                push    eax
              @@3:
                mov     ecx,ebx
                and     ecx,11b
                jz      @@ParmDone
                shr     ebx,2
                sub     esi,4
                mov     eax,[esi]
                jmp     DWord Ptr @@JmpTable[ecx*4-4]
ALIGN 4
@@JmpTable      dd      OFFSET FLAT:@@Word
                dd      OFFSET FLAT:@@DWord
                dd      OFFSET FLAT:@@Addr
              @@Word:
                push    ax
                jmp     @@3
ALIGN 4
              @@Addr:
                Call    DosFlatToSel
              @@DWord:
                push    eax
                jmp     @@3
ALIGN 4
              @@ParmDone:
                mov     eax,esp                 ; Convert SS:ESP to
                Call    DosFlatToSel            ; SS:SP for a 0:32->16:16 thunk.
                push    eax
                lss     sp,[esp]                ; Here is the far (16:16) jump
                jmp     Far Ptr Thunk_16        ; to the function's 16 bit thunk.
ALIGN 4
Back_To_32:
                and     esp,0FFFFh
                lss     esp,[esp]
                shl     eax,16                  ; Convert return value:
                shrd    eax,edx,16              ; DX:AX -> EAX
                pop     ecx                     ; ESP after call
                pop     esp                     ; ESP after pushing used registers
                pop     edi esi ebx ebp es ds   ; Restore used registers
                pop     edx                     ; Return@
                mov     esp,ecx                 ; Restore ESP
                jmp     edx                     ; Return to caller
System@__Far16Pas ENDP

CODE32          ENDS


CODE16          SEGMENT WORD PUBLIC USE16 'CODE'
                ASSUME  CS:CODE16
Thunk_16:
                mov     ax,ss
                mov     ds,ax
                mov     es,ax
                Call    DWord Ptr [di]
                jmp     Far Ptr Back_To_32

CODE16          ENDS

                END
