From: jpenne@ee.ualberta.ca (Jerry Penner)
Subject: Re: Port I/O for 32 Bit Apps
Organization: University Of Alberta, Edmonton Canada
Date: Sat, 21 Nov 1992 10:14:09 GMT

feustel@netcom.com (David Feustel) writes:

>Bertram.Moshier@f115.n282.z1.tdkt.kksys.com (Bertram Moshier) writes:

>>Actually, this question is best put on comp.os.os2.programmer.  To
>>answer your question, though, what you say is true.  A 32 bit OS/2
>>application can get to I/O devices.  You should look at IOPL.  This
>>interface allows a ring three application to perform selected ring two
>>operations (namely I/O).

>Could you give a simple example? My impression is that IBM doesn't
>currently use this hardware feature to permit ring 3 i/o for os2
>applications.

All port I/O must be done at ring 2 or less and from 16-bit code.

The rules to follow when doing this are:

- Declare IOPL 16-bit routines as _pascal (I'm assuming you are
  writing 16-bit code with Microsoft C v6) to the 16-bit compiler.
- Declare IOPL 16-bit routines as _Far16 _Pascal to the 32-bit
  compiler.  (These first two points can be taken care of easily with
  an include file that #defines _Far16 and _Pascal to different things
  depending on which compiler you are using.  See the \ibmc\samples\
  sample04 directory for examples on this or look at your C Set/2
  User's guide around page 270 (I think, my book is at work).
- Ensure that your parameter declarations and return values are the
  same size.  Ie.  Microsoft C 'int' is 16-bits, C Set/2 'int' is
  32-bits.  Use 'short' for 16-bits and 'long' for 32-bits.
- In your .DEF file (for creating the 16-bit DLL) do NOT prefix IOPL
  routines in your EXPORTS section with '_'.  And make sure you add a
  number after the function name to inform the system how many WORDS
  (not bytes) of parameters are defined.
- Make sure each function name that runs under IOPL is in all
  CAPITALS.  Other non-IOPL functions should have their case settings
  the same as in the source code.
- Also in the DEF file, the SEGMENTS line should read:
	SEGMENTS your_seg_name CLASS 'CODE' IOPL
  'your_seg_name' is usually the filename of your 16-bit code minus
  the extension.

Here's a little example which I'm making up from memory since I am not
at work.  If you can't get this to work with Microsoft C v6 and IBM C
Set/2 email me and I will check this over.

-------------------------------
test16.c
-------------------------------

#include "common.h"

short _Far16 _Pascal InPort( short ioport )
{
	short rc;

	_asm	MOV	DX,ioport
	_asm	IN	AX,DX
	_asm	SUB	AH,AH
	_asm	MOV	rc,AX

	return rc;	/* you probably don't need the MOV rc,AX */
			/* or the return rc since AX is the return */
			/* value but I did it this way and it works */
			/* but I didn't try it with it removed.  :)
			*/
} /* end InPort() */



-------------------------------
common.h
-------------------------------

#ifndef __32BIT__
	#define	_Far16
	#define _Pascal _pascal
	#define _Seg16 /* something may go here, I can't remember */

	#define extern
#endif

extern _Far16 _Pascal InPort( short ioaddr );

-------------------------------
test16.def
-------------------------------

LIBRARY
DESCRIPTION '16-bit IOPL code DLL'
PROTMODE
EXPORTS
	INPORT	1
SEGMENTS
	'TEST16' CLASS 'CODE' IOPL


-------------------------------
test32.c
-------------------------------

#include <stdio.h>
#include "common.h"

main()
{
	int  in;


	in = InPort( 0x300 );
	printf( "port value = %d\n", in );
}


-------------------------------
test32.def
-------------------------------

NAME
DESCRIPTION '32-bit part of 32/16 bit example w/ IOPL code'
PROTMODE


-------------------------------
compiling commands (normally in a makefile)
-------------------------------

test16.obj: test16.c common.h
	cl -c -Alfu -G2s test16.c

test16.dll: test16.obj test16.def
	link /NOL /NOI /MAP /NOD test16,test16.dll,test16,os2286,test16.def

test16.lib: test16.def
	implib test16.lib test16.def

test32.obj: test32.c common.h
	icc -c -Gd- test32.c

test32.exe: test32.obj test16.dll
	link386 /NOL test32,test32.exe,test32,test16.lib,test32.def


I think that should do it.  I spent a lot of time figuring most of
this out so hopefully you won't have to do the same.  Some of this
info is in the manuals (C Set/2 User's and Migration Guides) but some
of it isn't but is the result of trial and error testing...

Good luck.
-- 
Jerry Penner   jpenne@ee.ualberta.ca   Try a 1-line .sig today.
Newsgroups: comp.os.os2.misc