From: [email-masked]
Date: Wed, 2 Sep 92 20:56:08 EDT

This is a preliminary specification and how-to guide for the
pointer/head-tracker drivers.  No other files available yet,
but comments are welcome.

--------------------------------------------------------------------------
| My life is Hardware,                    |         Dave Stampe          | 
| my destiny is Software,                 | [email-masked]    |
| my CPU is Wetware...                    | [email-masked]   | 
| Am I a techno-psychologist, or just an engineer dabbling in psychology?|
---------------------------------------------------------------------------

REND386 POINTER DEVICE DRIVERS

Poiner device drivers are compiled in pseudo-tiny mode (code, data in one
segment, stack not assumed in the same segment).  The interface is through
an assembly routine at the start of the driver.

When compiling the driver, set all assembly modules to use the memory model
.MODEL TINY FARSTACK and use a batch file based on mkmpd.bat to create
the driver.  Sounds simple, right?  I wish it was.  You'll probably have
to compile the C under compact model, and link in the compact mode libraries.
If this fails, comile under the tiny memory model and avoid the use of C
library calls in your code, as the C tiny mode libraries assume SS=DS=CS
(very nasty).  You can then link and use EXE2BIN to convert to a single
segment.

WARNING: IF YOU SEE "FIXUP REQUIRED" WHILE RUNNING EXE2BIN, YOUR DRIVER
WILL NOT WORK.

I'd appreciate it if someone more knowlwdgeable about DOS linking etc.
straightened out the link procedure, as it would be invaluable to be
able to use the COMPACT memory model in all cases.  Right now, it is
sort of iffy: the video driver needs TINY mode C compilation to work,
while the mouse pointer driver functions well with COMPACT model.
Any ideas?

-------------------------------

STRUCTURE OF THE POINTER DRIVER

The driver consists of an assembly interface module (linked in first),
a pconfig{} structure giving driver data, and an interperter module
which is called from REND386.

The interperter accepts these commands and arguments:

 /* driver call equates: call *driver_pointer with this code */
 /* all return *pconfig or integer */
 #define DRIVER_INIT  0   /* rtns *pconfig, args = type    */
 #define DRIVER_RESET 1   /* no rtn, no args               */
 #define DRIVER_READ  2   /* rtns NULL if no data ready, else *pconfig */
													/* args = *pointer, mode */
 #define DRIVER_CMD   3   /* args = mode, rtns *pconfig    */
 #define DRIVER_CHECK 4   /* no args, rtns *pconfig        */
 #define DRIVER_QUIT  5   /* no args, no rtn               */

Calls are usually made thru REND386's interface command, so
avoid returning anything unexpected.

INTERPERTER CALL DEFINITIONS (first argument)

DRIVER_INIT:
First call after loading driver.  You may hook all interrupts, but
be sure you know what you're doing!  And do not modify the timer interrupt
rate, which will usually be between 140 and 200 ticks per second. Try
to do your interrupt processing AFTER the original call.
ARGS: type (may be used to set driver type, if marked as available
in the pconfig.type field.
RETURNS: Address of pconfig structure of driver.

DRIVER_RESET:
Used to reset the driver, recenter it, etc.  No args or return, currently
unused.

DRIVER_READ:
Called to read driver position.  The read gives raw device coords if
called in pointer mode, and the "mouse" screen location (scaled to match
the .maxsx and .maxsy parameters in pconfig, which can be changed by
the external software!).  The read data is recorded into the *pointer
structure given as an argument.
Note that all scaling, motion detection, etc. is performed by code
in the REND386 pointer interface library.  You driver need not handle
this, but it must handle gesture recognition or coding to buttons.
ARGS: mode is P_POINTER or P_SCREEN, which may be or'd with P_CENTER to
request recentering of the device as well.
RETURNS: NULL if no new data, else address of pconfig.

DRIVER_CMD:
Sends a direct command to driver.  No commands yet defined.
ARGS: Command word

DRIVER_CHECK:
RETURNS: address of pconfig if everything's OK, else NULL.

DRIVER_QUIT:
Called on exit from the program, in reverse order that drivers were loaded.
Should unhook all interrupts, etc.

THE PCONFIG{} STRUCTURE:

 /* configuration structure: part of driver */
 /* MUST corresp. to lefthand coord sys or negate scale! */
 /* for non- ht devices, the scaling may be adjusted as desired */

 typedef struct _pconfig {
			 long xres, yres, zres;     /* position res: mm/tick in <16.16>  */
			 long maxx, maxy, maxz;     /* numeric range             */
			 long minx, miny, minz;

			 long xrres, yrres, zrres;  /* rotation res: deg/tick in <16.16  */
			 long maxxr, maxyr, maxzr;  /* numeric range                */
			 long minxr, minyr, minzr;  /* min, max: left-hand dir.     */

			 int maxsx, maxsy;    /* limits on mouse-mode motion (writable) */

			 int databits;     /* what data is available from device */
			 int commands;     /* what sort of control is available  */
			 int nullkey;			 /* button code for null keypress      */
			 int flexnum;      /* number of flex parameters          */
			 int delay;        /* millisec. read delay               */
			 int idelay;       /* internal delay in ms               */
			 int rrate;        /* max. reads per second possible     */
			 int type;         /* suggested useage                   */
			 char id[80];      /* id or more data                    */
		} pconfig;

The resolution entries give the true space measurements of each "tick"
(or unit) of the pointer devices's raw resolution.  These make it possible
to use a device for head tracking directly.  If you wish, you may "fudge"
this factor to expand the spatial range of a device.
Rotational resolution is 1/65536 of the actual <16.16> format of the
rotation resolution.  So, for example, the PowerGlove has 12 ticks for its
entire rotation range.  The tick must be multiplied by 65536 in the
driver, so that it will scale correctly.  These are used by the absscale()
routine.

The max and min are used with the tscale() and rscale() functions to center
and set the range of the pointer device.

The maxsx and maxsy values are used inside the driver to set mouse-emulation
(screen coordinate) range, which goes from 0 to the maximum.  The x axis is
positive rigt, the y axis is positive up.

Databits flags what response data is available:

For most mice, you may use button3->button1 | button2
or pass it seperately.

 #define P_HASB1    0x0001   /* what buttons we can have  */
 #define P_HASB2    0x0002   /* also mask for button bits */
 #define P_HASB3    0x0004   /* should really return 0x07 for compatibility */
 #define P_HASX     0x0008   /* which axes we can read */
 #define P_HASY     0x0010
 #define P_HASZ     0x0020
 #define P_HASRX    0x0040   /* what rotations are available */
 #define P_HASRY    0x0080
 #define P_HASRZ    0x0100
 #define P_HASGEST  0x0200   /* gestural interface   */
 #define P_HASFLEX  0x0400   /* fingers?             */
 #define P_HASKEYS  0x0800   /* do we have a keypad? */
 #define P_HASSCR   0x1000   /* capable of emulating XY mouse */

The modes word contains bits to represent available modes for reading:

 #define P_CENTER    1   /* recenter without reinitializing */
 #define P_SCREEN    2   /* screen mouse mode read     */
 #define P_POINTER   4   /* any extended pointing mode */

The type word has bits to flag what type of uses the device driver may be
useful for:

 #define P_NOPOS 0   /* just a keypad or something */
 #define P_IS2D  1   /* 2D mouse, for example      */
 #define P_IS2DP 2   /* 2D, but Z mapped by button */
 #define P_IS3D  4   /* 3D mouse, for example      */
 #define P_IS6D  8   /* 6D mouse, for example      */
 #define P_IS3DG 16  /* 3D glove-- don't use rot   */
 #define P_IS6DG 32  /* 6D glove-- use rotation    */
 #define P_IS3RH 64  /* 3D (rotation) head tracker */
 #define P_IS3TH 128 /* 3D (position) head tracker */
 #define P_IS6H  256 /* full 6D head tracker       */

All other functions are carried out by code in REND386 itself.
If you need more data, look at the files mouseptr.c, drheader.asm,
mkmpd.bat in the driver kit, and mouseptr.c, gloveptr.c, cursors.c, and
pointer.c in the REND386 source.