                .386

                EXTRN   DosFlatToSel:Proc
FLAT		GROUP	CODE32

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

; Performs Input/Output from/to hardware ports

; EXPECTS:      ecx     = 0,4,8,12,16,20 => Type of IO operation
;               eax     = Value (Output only)
;               dx      = Port number

System@__IOPort PROC    Near
                PUBLIC  System@__IOPort
                push    ebp ebx esi
                mov     ebp,esp
                cmp     sp,4*1024
                jae     @@1
                xor     sp,sp
              @@1:
                mov     ebx,eax
		mov	esi,ecx
                push    ss
                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:
                pop     ss
                mov     esp,ebp
                pop     esi ebx ebp
                ret
System@__IOPort ENDP

CODE32          ENDS

; Special IOPL segment. The following line should be included into
; module definition file:
; SEGMENTS IO16 IOPL

IO16            SEGMENT DWORD PUBLIC USE16 'CODE'
                ASSUME  CS:IO16
InputByte:      in      al,dx
                retf
ALIGN 4
InputWord:      in      ax,dx
                retf
ALIGN 4
InputDWord:     in      eax,dx
                retf
ALIGN 4
OutputByte:     mov     eax,ebx
                out     dx,al
                retf
ALIGN 4
OutputWord:     mov     eax,ebx
                out     dx,ax
                retf
ALIGN 4
OutputDWord:    mov     eax,ebx
                out     dx,eax
                retf

IO16            ENDS

; 16-bit segment containing thunk code

CODE16          SEGMENT DWORD PUBLIC USE16 'CODE'
                ASSUME  CS:CODE16
Thunk_16:
                Call    DWord Ptr @@CallTable[si]
                jmp     Far Ptr Back_To_32
ALIGN 4
@@CallTable     dd      InputByte
                dd      InputWord
                dd      InputDWord
                dd      OutputByte
                dd      OutputWord
                dd      OutputDWord

CODE16          ENDS

                END
