_WRITING OS/2 APPLICATIONS WITH I/O PRIVILEGES_
by Ray Duncan

[EXAMPLE 1]

        title   PORTIO.ASM  read/write I/O ports
        page    55,132
        .286

; PORTIO.ASM -- general purpose port read/write
;               routines for C or MASM programs
;
; Copyright (C) 1988 Ray Duncan
;
; When this module is linked into a program, the
; following lines must be present in the program's
; module definition (.DEF) file:
;
; SEGMENTS
;    IO_TEXT IOPL
;
; EXPORTS
;    rport 1
;    wport 2
;
; The SEGMENT and EXPORT directives are recognized by 
; the Linker and cause information to be built into
; the .EXE file header for the OS/2 program loader.
; The loader is signalled to give I/O privilege to 
; code executing in the segment IO_TEXT, and to build
; call gates for the routines 'rport' and 'wport'.

IO_TEXT segment word public 'CODE'
        
        assume  cs:IO_TEXT


; RPORT: read 8-bit data from I/O port.  Port address 
; is passed on stack, data is returned in register AX
; with AH zeroed.  Other registers are unchanged.
; 
; C syntax:     unsigned port, data;
;               data = rport(port);

        public  rport
rport   proc    far

        push    bp              ; save registers and
        mov     bp,sp           ; set up stack frame
        push    dx

        mov     dx,[bp+6]       ; get port number 
        in      al,dx           ; read the port
        xor     ah,ah           ; clear upper 8 bits
                
        pop     dx              ; restore registers
        pop     bp

        ret     2               ; discard parameters,
                                ; return port data in AX
rport   endp


; WPORT: write 8-bit data to I/O port.  Port address and 
; data are passed on stack.  All registers are unchanged.
; 
; C syntax:     unsigned port, data;
;               wport(port, data);

        public  wport
wport   proc    far

        push    bp              ; save registers and
        mov     bp,sp           ; set up stack frame
        push    ax
        push    dx

        mov     ax,[bp+6]       ; get data to write
        mov     dx,[bp+8]       ; get port number
        out     dx,al           ; write the port

        pop     dx              ; restore registers
        pop     ax
        pop     bp

        ret     4               ; discard parameters,
                                ; return nothing
wport   endp

IO_TEXT ends

        end


[EXAMPLE 2]


/*
    PORTS.C:    Demonstration program with IOPL.  
                Reads and displays the first 256 I/O ports.
                Requires separate module PORTIO.ASM.

    (C) 1988 Ray Duncan

    To build:   MASM /Mx PORTIO;
                CL /c PORTS.C
                LINK PORTS+PORTIO,PORTS,,,PORTS.DEF

    Usage:      PORTS
*/

#include <stdio.h>

#define API extern far pascal

unsigned API rport(unsigned);           /* function prototypes */
void     API wport(unsigned, unsigned);
void     API DosSleep(unsigned long);
unsigned API DosPortAccess(unsigned, unsigned, unsigned, unsigned);

                                /* parameters for DosPortAccess */
#define REQUEST 0                       /* request port */
#define RELEASE 1                       /* release port */
#define BPORT   0                       /* beginning port */
#define EPORT   255                     /* ending port */

main(int argc, char *argv[])
{
    int i;                              /* scratch variable */

                                        /* request port access */
    if(DosPortAccess(0, REQUEST, BPORT, EPORT))
    {   
        printf("\nDosPortAccess failed.\n");
        exit(1);
    }

    printf("\n      ");                 /* print title line */
    for(i=0; i<16; i++) printf(" %2X", i);

    for(i=BPORT; i<=EPORT; i++)         /* loop through all ports */
    {
        if((i & 0x0f)==0)
        {
            printf("\n%04X  ", i);      /* new line needed */
        }

        printf(" %02X", rport(i));      /* read & display port */
    }
                                        /* release port access */
    DosPortAccess(0, RELEASE, BPORT, EPORT);
}



[EXAMPLE 3]

NAME PORTS WINDOWCOMPAT

PROTMODE

SEGMENTS
  IO_TEXT IOPL

EXPORTS
  rport 1
  wport 2



[EXAMPLE 4]

ports.obj : ports.c
  cl /c ports.c

portio.obj : portio.asm
  masm /Mx portio;

ports.exe : ports.obj portio.obj ports.def
  link ports+portio,ports,,,ports.def



