[comp.unix.microport] A UNIX driver for the IBM-PC game port.

dave@viper.Lynx.MN.Org (David Messer) (07/10/88)

This is a driver for the IBM-PC game port.  It was written
for Microport UNIX and the IBM-AT or clones, but should be
easily adaptable to other systems.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  LICENSE MANIFEST Makefile README joy.7 joy.c joy.h
#   joyinp.s joytest.c
# Wrapped by dave@viper on Sun Jul 10 03:13:47 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'LICENSE' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'LICENSE'\"
else
echo shar: Extracting \"'LICENSE'\" \(6324 characters\)
sed "s/^X//" >'LICENSE' <<'END_OF_FILE'
X                           LICENSE AGREEMENT
X
X
X
X
X
X
X                                PURPOSE
X
The reasons that this product is distributed with a License rather than
given into the Public Domain are as follows:
X
We wish to make sure that each individuals freedom to use and
redistribute this product is maintained.  Restrictions may be placed on
Public Domain items by anybody, including charging for the product, not
allowing redistribution, or distributing only part of the original
product.
X
We want to retain ownership so that we are free to make other agreements
with companies or individuals wishing to make commercial use of the
product.
X
We wish to protect ourselves by making sure that everyone knows that
this product is distributed with NO WARRANTY and we want everyone to
know who wrote this product in case anyone is impressed by it.
X
X
X                                GENERAL
X
Lynx Data Systems and David Messer retain all rights not expressly
granted.  Nothing in this License Agreement constitutes a waiver of Lynx
Data Systems or David Messers rights under the U.S.  copyright laws or
any other Federal or State Law.
X
Lynx Data Systems and David Messer retain the ownership of the product.
This copy of the product is licensed to you for use under the terms set
forth below.
X
X
X                        PERMITTED USES/YOU MAY:
X
X  1.  You may copy and distribute verbatim copies of the product as you
X      receive it, in any medium, provided that you retain all copyright
X      notices, references to this License Agreement and the absence of
X      any warrenty; give each recipient a copy of this License Agreement
X      and warrenty notice; and conspicuously display on each copy the
X      following copyright notice,
X
X      Copyright 1988 Lynx Data Systems
X      Copyright 1988 David Messer
X      All Rights Reserved
X
X  2.  You may charge a reasonable fee for copying the product not to
X      exceed the actual cost of the medium, computer time, and operator
X      time envolved.
X
X
X
X
X
X
X
X
X
X
X
X  3.  You may modify your copy of the product for your own use.
X
X  4.  You may distribute copies of the product as modified by you
X      provided that you also do the following:
X
X        a.  Place a notice on all modified files stating that you have
X            changed the file with your name (or appropriate
X            organizational name) and the date of the change.
X
X        b.  Place a notice on the product as a whole stating that it is
X            a modified version of the original product.
X
X        c.  Retain all copyright notices, references to this License
X            Agreement and the absence of any warrenty, and include a
X            copy of this original License Agreement.
X
X        d.  Distribute the result under this License Agreement.
X
X  5.  You may distribute object code (binaries) of this product as long
X      as you make available, with no time limit, the original source
X      files you received at no cost other than as provided in this
X      License Agreement and tell the recipient in writing about their
X      availability.
X
X  6.  You may add additional warrenty protection to the distributed
X      product.  Lynx Data Systems, David Messer and any other
X      distributors are not responsible for any additional protection
X      added in this way.
X
X
X                      PROHIBITED USES/YOU MAY NOT:
X
X  1.  You may not place restrictions on the redistribution of this
X      product, or any derivitive works, other than as provided in this
X      License Agreement.
X
X  2.  You may not modify this License Agreement or distribute the
X      product, in whole or in part, without including this License
X      Agreement.
X
X  3.  You may not charge for this product, or any derivative work, in
X      excess of the actual cost of the medium, computer time, and
X      operator time envolved.
X
X
X                                  TERM
X
This License is effective until terminated.  You may terminate it at any
time by distroying all copies of the product files, including modified
copies.
X
Any violation of this License Agreement will terminate your rights to
use this product.
X
X
X
X
X
X
X
X
X
X
X
X
X
X                                WARRANTY
X
THE PRODUCT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
XEXPRESSED OR IMPLIED.  INCLUDING, BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
XENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PRODUCT IS WITH
YOU.  SHOULD THE PRODUCT PROVE DEFECTIVE, YOU (AND NOT LYNX DATA
SYSTEMS, DAVID MESSER OR ANY DISTRIBUTOR) ASSUME THE ENTIRE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
X
SOME STATES DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THE
ABOVE EXCLUSION MAY NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC
LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS WHICH VARY FROM STATE TO
STATE.
X
X
X                        LIMITATIONS OF REMEDIES
X
IN NO EVENT WILL LYNX DATA SYSTEMS, DAVID MESSER OR ANY DISTRIBUTOR BE
LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY LOST PROFITS, LOST SAVINGS
OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE THE PRODUCT EVEN IF LYNX DATA SYSTEMS, DAVID MESSER OR
A DISTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR
XFOR ANY CLAIM BY ANY OTHER PARTY.
X
SOME STATES DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY FOR
INCIDENTAL OR CONSEQUENTIAL DAMAGES SO THE ABOVE LIMITATION OR EXCLUSION
MAY NOT APPLY TO YOU.
X
REDISTRIBUTORS MAY OFFER ADDITIONAL WARRENTY PROTECTION.  SUCH
PROTECTION SHOULD BE OFFERED IN ANOTHER DOCUMENT.  LYNX DATA SYSTEMS AND
DAVID MESSER ARE NOT LIABLE FOR THE CONTENTS OF ANY ADDITIONAL DOCUMENT.
X
THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF
ALL OTHERS, ORAL OR WRITTEN, EXPRESSED OR IMPLIED.
X
This License Agreement will be governed by the laws of the State of
Minnesota.
X
X
X                               COPYRIGHT
X
Under the copyright laws, neither the documentation nor the software may
be copied, photocopied, reproduced, translated, or reduced to any
electronic medium or machine-readable form, in whole or in part, without
the prior written consent of Lynx Data Systems and David Messer, except
in the manner described in this License.
X
Copyright 1988 Lynx Data Systems
Copyright 1988 David Messer
All Rights Reserved
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
END_OF_FILE
if test 6324 -ne `wc -c <'LICENSE'`; then
    echo shar: \"'LICENSE'\" unpacked with wrong size!
fi
# end of 'LICENSE'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(393 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X LICENSE                    1	
X MANIFEST                   1	This shipping list
X Makefile                   1	
X README                     1	
X joy.7                      1	
X joy.c                      1	
X joy.h                      1	
X joyinp.s                   1	
X joytest.c                  1	
END_OF_FILE
if test 393 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2326 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#********************************************************************/
X#*                                                                  */
X#*  Copyright 1988 Lynx Data Systems                                */
X#*  Copyright 1988 David Messer                                     */
X#*  All Rights Reserved.                                            */
X#*                                                                  */
X#*  This file is part of a licensed software product.  Included     */
X#*  with this file should be the file "LICENSE" which is the        */
X#*  agreement under which this product is licensed.                 */
X#*                                                                  */
X#*  This file may be copied, or distributed, as long as all files   */
X#*  of the product are included along with the LICENSE file and     */
X#*  there is no charge.                                             */
X#*                                                                  */
X#*  If you wish to modify this product, read the license agreement. */
X#*                                                                  */
X#*  This product is distributed WITHOUT ANY WARRANTY.               */
X#*                                                                  */
X#********************************************************************/
X
LINKKIT =	/usr/linkkit
CFLAGS =	-Ml -O $(DEBUG) $(INCS)
INCS =		-I$(LINKKIT) -I$(LINKKIT)/sys -I$(ROOT)/usr/include 
X#
X# Use lib0 if lib2 results in an error.  Be sure to backup
X# whatever library you use.
X#
LIBNAME =	$(LINKKIT)/lib0
X#LIBNAME =	$(LINKKIT)/lib2
X
SRC =	joy.c joyinp.s
X
XFILES =	$(LIBNAME)(joy.o) $(LIBNAME)(joyinp.o)
X
X.PRECIOUS:	$(LIBNAME)
X
X.s~.s:
X	$(GET) $(GFLAGS) -p $< > $*.s
X
all:	$(FILES)
X
clean:
X	-rm -f *.[o]
X
kernel:	all
X	cd $(LINKKIT)/cf; $(MAKE)
X
install:	/usr/include/sys/joy.h
X# Use appropriate line below to install doco
X#	cp joy.7 $(MANFILE)/man7/joy.7
X#	nroff -man joy.7 >$(CATMAN)/man7/joy.7
X
X/usr/include/sys/joy.h:	joy.h
X	cp joy.h /usr/include/sys/joy.h
X
X$(LIBNAME)(joy.o): joy.c joy.h $(LINKKIT)/sys/types.h \
X		$(LINKKIT)/sys/param.h $(LINKKIT)/sys/systm.h \
X		$(LINKKIT)/sys/user.h $(LINKKIT)/sys/tss.h
X	$(CC) -c $(CFLAGS) joy.c
X	ar rv $(LIBNAME) joy.o
X
X$(LIBNAME)(joyinp.o): joyinp.s
X	$(CC) -c $(CFLAGS) joyinp.s
X	ar rv $(LIBNAME) joyinp.o
END_OF_FILE
if test 2326 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2386 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X/********************************************************************/
X/*                                                                  */
X/*  Copyright 1988 Lynx Data Systems                                */
X/*  Copyright 1988 David Messer                                     */
X/*  All Rights Reserved.                                            */
X/*                                                                  */
X/*  This file is part of a licensed software product.  Included     */
X/*  with this file should be the file "LICENSE" which is the        */
X/*  agreement under which this product is licensed.                 */
X/*                                                                  */
X/*  This file may be copied, or distributed, as long as all files   */
X/*  of the product are included along with the LICENSE file and     */
X/*  there is no charge.                                             */
X/*                                                                  */
X/*  If you wish to modify this product, read the license agreement. */
X/*                                                                  */
X/*  This product is distributed WITHOUT ANY WARRANTY.               */
X/*                                                                  */
X/********************************************************************/
X
This is a driver for the IBM-PC game port adaptor.  It was written
for Microport UNIX but should be adaptable for other UNIX flavors
which run on the IBM-AT.
X
Access to the adaptor is done by a simple UNIX read function.
The result is a ASCII text line containing switch positions
and a numeric representation of the position of the joystick.
X
Included in the package is a 'man' page describing the options
and results of the driver.
X
To install it on a Microport system:  (in the example, major
device number 13 is used, your system may vary from this.)
X
Add the following line to 'dfile.wini' in your linkkit cf
directory.  (Normally /usr/linkkit/cf/dfile.wini):
X
joy	0	1
X
And add this line to your 'master' file in the same directory.
X
joy	0	ocris	co	joy	0	13	2
X
X
XEdit the included Makefile to indicate where the linkkit is
in your system and type 'make kernel'.  If everything is
configured right, it should add the driver to the libraries
and build a kernel.  See the Microport documentation for
adding device drivers for details.
END_OF_FILE
if test 2386 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'joy.7' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'joy.7'\"
else
echo shar: Extracting \"'joy.7'\" \(5419 characters\)
sed "s/^X//" >'joy.7' <<'END_OF_FILE'
X''' *****************************************************************/
X'''                                                                 */
X''' Copyright 1988 Lynx Data Systems                                */
X''' Copyright 1988 David Messer                                     */
X''' All Rights Reserved.                                            */
X'''                                                                 */
X''' This file is part of a licensed software product.  Included     */
X''' with this file should be the file "LICENSE" which is the        */
X''' agreement under which this product is licensed.                 */
X'''                                                                 */
X''' This file may be copied, or distributed, as long as all files   */
X''' of the product are included along with the LICENSE file and     */
X''' there is no charge.                                             */
X'''                                                                 */
X''' If you wish to modify this product, read the license agreement. */
X'''                                                                 */
X''' This product is distributed WITHOUT ANY WARRANTY.               */
X'''                                                                 */
X''' *****************************************************************/
X'''
X''' SCCSID:	@(#)joy.7	1.1	7/10/88	03:03:05
X'''
X.TH JOY 7 "LYNX DATA SYSTEMS"
X.SH NAME
X\fBjoy\fR \- \fBIBM\-PC\fR and compatable joystick driver.
X.SH DESCRIPTION
X.I Joy
provides an interface to the standard IBM\-PC game adaptor (joystick)
port.
Minor devices are provided for raw data and several scaled types of
data derived from the joystick position.
Switch status is also provided.
X.P
This driver allows
X.I read(2)
access and
X.I ioctl(2)
access.
X.P
When read, it returns a three part ascii\-numeric data line, terminated
by an EOL (\\n):
X.P
X.RS
SSSS X Y\\n
X.RE
X.P
The
X.I X
and
X.I Y
fields represent the value of the two directions of the
joystick and are signed long integers.
X.P
They are an arbitrary number of characters long.
X.P
The
X.I SSSS
field represents four switches.
They are switch 1 and switch 2 of the selected joystick and
switch 1 and switch 2 of the other joystick.
X.P
XEach switch setting is represented by a digit from zero (0) to
three (3) which encode the following states:
X.RS
X.IP 0 3
The switch is
X.B OFF.
X.IP 1 3
The switch is
X.B ON.
X.IP 2 3
The switch was 
X.B ON
last read but is now
X.B OFF
X(falling edge).
X.IP 3 3
The switch was
X.B OFF
last read but now is
X.B ON
X(rising edge).
X.RE
X.P
Ten
X.I ioctl(2)
calls are available:
X.P
X.RS
X#include <sys/joy.h>
X.br
ioctl(fildes, command, arg)
X.br
int arg;
X.RE
X.P
The
X.I commands
are:
X.RS
X.ne 8
X.IP JOY_FLAG 15
X.I Arg
is a set of flag bits.
Currently only one bit is used:
X.IP "" 15
J_F_SYNC
X.IP "" 15
When set, this flag forces future reads to wait for the
next update rather than return immediatly.
X.IP JOY_RATE 15
X.I Arg
is the number of
X.I HZ
between reads of the game port.
If J_F_SYNC is set, this will be the minimum delay between reads.
If
X.I arg
is less than five (5) a value of one\-fifth of a second
will be used instead.
X.IP JOY_XZERO 15
X.IP JOY_YZERO 15
These set the zero point for scaled outputs.
If the
X.I raw
minor device is used (0), the zero point is set to
X.I arg
otherwise the zero point is set by reverse\-scaling
X.I arg
using the current scaling values.
X.IP JOY_XMAX 15
X.IP JOY_YMAX 15
These set the maximum value for scaled outputs.
X.I Arg
is handled as in JOY_XZERO and JOY_YZERO.
X.IP "" 15
It is recommended that the
X.I raw
minor device (0) be used for setting the
X.I zero
and
X.I maximum
points as reverse\-scaling may have unpredictable results.
X.IP JOY_XSCALE 15
X.IP JOY_YSCALE 15
These set the scaling factor for the scaled minor devices.
X.I Arg
is the value used when the joystick is positioned at the
maximum point as set with JOY_XMAX and JOY_YMAX.
X.IP JOY_XDEADBAND 15
X.IP JOY_YDEADBAND 15
When the value of the joystick is within
X.I arg
of the zero point, zero is used instead.
X.I Arg
is a scaled value.
X.SH "MAJOR, MINOR DEVICE NUMBERS"
The major device number is system dependent.
My system is configured to use major device number 13.
X.P
The minor device number is encoded as two, four\-bit fields.
X.P
Bits 0 - 3 (least significant bits) contain the joystick number.
On an IBM\-PC, only 0 and 1 are used as there are only two
joysticks allowed.
X.P
Bits 4 - 7 (most significant bits) contain a code for the type
of scaling to use:
X.RS
X.IP 0 3
Raw data.
This minor device uses the raw count data from the game port.
The values used are (usually) small positive integers.
X.IP 1 3
Double-integral of the scaled value.
This is the integral with respect to time of the next
parameter.
X.IP 2 3
Integral of the scaled value.
This is the integral with respect to time of the next
parameter.
This allows the joystick to simulate a mouse or a trackball
by remembering a position.
In this mode, the joystick would be used to input a velocity
of movement.
X.IP 3 3
Scaled value.
This value is taken from the raw input value using the
following formula:
X.IP "" 3
X.RS
value = scale * (raw - zero) / range
X.RE
X.IP "" 3
Where scale, zero, and range are set with the
X.I ioctl(2)
mechanism.
X.IP 4 3
Derivative of the scaled value.
This gives the rate\-of\-change of the scaled value with
respect to time.
X.RE
X.SH "SEE ALSO"
ioctl(2),
read(2)
X.SH AUTHOR
David Messer, Lynx Data Systems
END_OF_FILE
if test 5419 -ne `wc -c <'joy.7'`; then
    echo shar: \"'joy.7'\" unpacked with wrong size!
fi
# end of 'joy.7'
fi
if test -f 'joy.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'joy.c'\"
else
echo shar: Extracting \"'joy.c'\" \(7433 characters\)
sed "s/^X//" >'joy.c' <<'END_OF_FILE'
X/***
X *	joy.c 1.1 [7/10/88] - game adapter (joystick) driver for IBM-AT
X */
X
X/********************************************************************
X *                                                                  *
X *  Copyright 1988 Lynx Data Systems                                *
X *  Copyright 1988 David Messer                                     *
X *  All Rights Reserved.                                            *
X *                                                                  *
X *  This file is part of a licensed software product.  Included     *
X *  with this file should be the file "LICENSE" which is the        *
X *  agreement under which this product is licensed.                 *
X *                                                                  *
X *  This file may be copied, or distributed, as long as all files   *
X *  of the product are included along with the LICENSE file and     *
X *  there is no charge.                                             *
X *                                                                  *
X *  If you wish to modify this product, read the license agreement. *
X *                                                                  *
X *  This product is distributed WITHOUT ANY WARRANTY.               *
X *                                                                  *
X ********************************************************************/
X
X#include <types.h>
X#include <sys/errno.h>
X#include <sys/dir.h>
X#include <sys/signal.h>
X#include <param.h>
X#include <systm.h>
X#include <user.h>
X#include <sys/ioctl.h>
X#include "joy.h"
X
X#ifndef lint
static char sccsid[] = "@(#)joy.c	1.1	7/10/88 02:29:38" ;
X#endif
X
X#define	public
X#define	private	static
X
X
X#define	UNIT(x)		((x)&0x0F)
X#define	DATATYPE(x)	(((x)>>4)&0x0F)
X
extern joyinp() ;			/* Input routine */
X
extern int joy_val ;		/* Analog value, set by joyinp() */
extern char joy_switches ;	/* Switch values, set by joyinp() */
X
X
private int joy_flag = J_F_SYNC ;
private int open_flag = 0 ;
private int joy_sync = 0 ;
X
private int inpindex = 0 ;	/* Next input channel */
private int cntzero[4] ;	/* Raw input count zero point */
private int cntmax[4] ;		/* Raw input count maximum point */
private long range[4] =		/* cntmax[] - cntzero[] */
X	{ -1L, 1L, -1L, 1L } ;
private long scale[4] =		/* Output value at cntmax */
X	{ 1L, 1L, 1L, 1L } ;
private long deadband[4] =	/* Band around zero to force to zero */
X	{ 0L, 0L, 0L, 0L } ;
X
private time_t lastlbolt ;	/* lbolt at last conversion */
private long val[5][4] ;	/* Analog values for read */
private int sw[2] ;			/* Switch values for read */
private int lastsw[2] =		/* Switch values at last read */
X	{ 0, 0 } ;
X
X
private int cycletime ;		/* Rate of reading inputs in HZ */
X
X
X
X
X
X/**
X *	joyinit - initialize the game device.
X */
X
public void
joyinit()
X{
X	register i ;
X
X	printf( "JOY v1.1 - Copyright 1988 Lynx Data Systems\n" ) ;
X
X	for( i = 0; i < 4; i++ ) {	/* Get a zero point at power up */
X		joyinp( (char)(1 << i) ) ;
X		cntzero[i] = joy_val ;
X		cntmax[i] = cntzero[i] + ((i&1) == 0? -1 : 1) ;
X		}
X
X	cycletime = HZ / 5 ;
X
X	} /* joyinit */
X
X
X
X
X
X/**
X * joyopen - open a game device.
X */
X
public void
joyopen( dev, flag )
int dev ;
int flag ;
X{
X	register i, j ;
X
X	if( UNIT( dev ) > 1 || DATATYPE( dev ) > 4 ) {
X		u.u_error = ENXIO ;
X		return ;
X		} 
X
X	open_flag++ ;
X	if( open_flag <= 1 ) {
X		open_flag = 1 ;
X		lastlbolt = lbolt ;
X		for( i = 0; i < 4; i++ ) {
X			for( j = 0; j < 5; j++ ) {
X				val[j][i] = 0L ;
X				}
X			}
X		sw[0] =
X			sw[1] =
X			lastsw[0] =
X			lastsw[1] = 0 ;
X		inpindex = 0 ;
X		joytimer() ;
X		}
X
X	} /* joyopen */
X
X
X
X
X
X/**
X * joyclose - close a game device
X */
X
public void
joyclose( dev )
int dev;
X{
X	open_flag-- ;
X
X	} /* joyclose */
X
X
X
X
X
X/**
X * joyread - read the game port
X */
X
public void
joyread( dev )
int dev;
X{
X	int unit, type, i ;
X	char s, schg ;
X
X	if( (joy_flag&J_F_SYNC) != 0 && joy_sync == 0 ) {
X		sleep( &joy_sync, PZERO ) ;
X		}
X
X	unit = UNIT( dev ) ;
X	type = DATATYPE( dev ) ;
X
X	s = sw[unit] ;
X	schg = lastsw[unit] ^ s ;
X	lastsw[unit] = s ;
X
X	schg <<= 1 ;
X	for( i = 0; i < 4; i++ ) {
X		passc( '0' + (schg & 0x02) + (s & 0x01) ) ;
X		s >>= 1 ;
X		schg >>= 1 ;
X		}
X	passc( ' ' ) ;
X	unit <<= 1 ;
X	passlong( val[ type ][ unit ] ) ;
X	passc( ' ' ) ;
X	passlong( val[ type ][ unit+1 ] ) ;
X	passc( '\n' ) ;
X	joy_sync = 0 ;
X
X	} /* joyread */
X
X
X
X
X
X/**
X *	passlong - send a long integer to the user program.
X */
X
private int
passlong( l )
long l ;
X{
X	register char *cp ;
X	char buf[11] ;
X
X	if( l < 0 ) {
X		if( passc( '-' ) < 0 ) return( -1 ) ;
X		l = -l ;
X		}
X
X	cp = buf ;
X	do {
X		*cp++ = '0' + (int)(l % 10L) ;
X		l /= 10L ;
X		} while( l > 0 ) ;
X
X	while( cp != buf ) {
X		cp-- ;
X		if( passc( *cp ) < 0 ) return( -1 ) ;
X		}
X
X	} /* passlong */
X
X
X
X
X
X/**
X * joyioctl - set parameters for the game device.
X */
X
public void
joyioctl( dev, cmd, arg, mode )
unsigned int dev ;
unsigned int cmd ;
union ioctl_arg arg;
unsigned int mode ;
X{
X	register i, j ;
X	register type ;
X	register long v ;
X
X	type = DATATYPE( dev ) ;
X	i = UNIT( dev ) << 1 ;
X
X	switch( cmd ) {
X		case JOY_FLAG:
X			joy_flag = arg.iarg ;
X			break ;
X
X		case JOY_RATE:
X			cycletime = arg.iarg ;
X			if( cycletime <= 4 ) cycletime = HZ / 5 ;
X			break ;
X
X		case JOY_YZERO:
X			i++ ;
X			/*** FALL THROUGH ***/
X
X		case JOY_XZERO:
X			if( type == 0 ) cntzero[i] = arg.iarg ;
X			else {
X				v = (long)(arg.iarg) * range[i] ;
X				if( scale[i] != 0 ) v /= scale[i] ;
X				cntzero[i] += v ;
X				}
X			goto calcrange ;
X
X		case JOY_YMAX:
X			i++ ;
X			/*** FALL THROUGH ***/
X
X		case JOY_XMAX:
X			if( type == 0 ) cntmax[i] = arg.iarg ;
X			else {
X				v = (long)(arg.iarg) * range[i] ;
X				if( scale[i] != 0 ) v /= scale[i] ;
X				cntmax[i] = cntzero[i] + v ;
X				}
X
X			calcrange:
X				range[i] = (cntmax[i] - cntzero[i]) ;
X				if( range[i] == 0 ) range[i] = 1L ;
X				for( j = 0; j < 5; j++ ) {
X					val[j][i] = 0L ;
X					}
X			break ;
X
X		case JOY_YSCALE:
X			i++ ;
X			/*** FALL THROUGH ***/
X
X		case JOY_XSCALE:
X			scale[i] = (arg.iarg != 0? arg.iarg : 1) ;
X			break ;
X		
X		case JOY_YDEADBAND:
X			i++ ;
X			/*** FALL THROUGH ***/
X
X		case JOY_XDEADBAND:
X			deadband[i] = arg.iarg ;
X			break ;
X
X		}
X
X	} /* joyioctl */
X
X
X
X
X
X/**
X *	joytimer - timer to read the game port in the background.
X */
X
joytimer() 
X{
X	register long v, x, y ;
X	register time_t t, dt ;
X
X	if( open_flag > 0 ) {
X		t = lbolt ;
X		dt = t - lastlbolt ;
X		if( dt > 0 ) {
X			lastlbolt = t ;
X
X			joyinp( (char)(1 << inpindex) ) ;	/* Get analog value */
X
X			/* Scaled value */
X			v = (long)(joy_val - cntzero[inpindex]) * scale[inpindex] ;
X			if( range[inpindex] != 0 ) v /= range[inpindex] ;
X			if( v >= 0 && v <= deadband[inpindex] ||
X				v < 0 && v >= -deadband[inpindex] ) v = 0L ;
X
X			/* dv */
X			x = (v - val[3][inpindex]) * HZ ;
X			val[4][inpindex] = x / dt;
X
X			/* int( v ) */
X			x = val[2][inpindex] ;
X			y = ((v + val[3][inpindex]) / 2L) * dt ;
X			val[2][inpindex] += y / HZ ;
X
X			/* int( int( v ) ) */
X			y = ((x + val[2][inpindex]) / 2L) * dt ;
X			val[1][inpindex] += y / HZ ;
X
X			/* v */
X			val[3][inpindex] = v ;
X
X			/* raw input */
X			val[0][inpindex] = joy_val ;
X
X			/* Save Switches */
X			sw[0] = (~joy_switches >> 4) & 0x0F ;
X			sw[1] = ((sw[0] >> 2) & 0x03) | ((sw[0] << 2) & 0x0C) ;
X
X			inpindex++ ;
X			}
X
X		/* Set for new cycle */
X		if( inpindex < 4 ) {
X			timeout( joytimer, (caddr_t)0, 1 ) ;
X			}
X		else {
X			inpindex = 0 ;
X			joy_sync = 1 ;
X			wakeup( &joy_sync ) ;
X			timeout( joytimer, (caddr_t)0, cycletime-3 ) ;
X			}
X		}
X
X	} /* joytimer */
END_OF_FILE
if test 7433 -ne `wc -c <'joy.c'`; then
    echo shar: \"'joy.c'\" unpacked with wrong size!
fi
# end of 'joy.c'
fi
if test -f 'joy.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'joy.h'\"
else
echo shar: Extracting \"'joy.h'\" \(1804 characters\)
sed "s/^X//" >'joy.h' <<'END_OF_FILE'
X/***
X *	joy.h 1.1 [7/9/88] - header file for game port driver.
X */
X
X/********************************************************************
X *                                                                  *
X *  Copyright 1988 Lynx Data Systems                                *
X *  Copyright 1988 David Messer                                     *
X *  All Rights Reserved.                                            *
X *                                                                  *
X *  This file is part of a licensed software product.  Included     *
X *  with this file should be the file "LICENSE" which is the        *
X *  agreement under which this product is licensed.                 *
X *                                                                  *
X *  This file may be copied, or distributed, as long as all files   *
X *  of the product are included along with the LICENSE file and     *
X *  there is no charge.                                             *
X *                                                                  *
X *  If you wish to modify this product, read the license agreement. *
X *                                                                  *
X *  This product is distributed WITHOUT ANY WARRANTY.               *
X *                                                                  *
X ********************************************************************/
X
X/*
X *	Mnemonics for ioctl() calls
X */
X
X#define	JOY_FLAG		0
X#define	JOY_RATE		1
X#define	JOY_XZERO		2
X#define	JOY_YZERO		3
X#define	JOY_XMAX		4
X#define	JOY_YMAX		5
X#define	JOY_XSCALE		6
X#define	JOY_YSCALE		7
X#define	JOY_XDEADBAND	8
X#define	JOY_YDEADBAND	9
X
X
X/*
X * Flags set with JOY_FLAG ioctl()
X */
X
X#define	J_F_SYNC	0x01	/* Reads are synchronize with reading
X							   the game adaptor  (normally set) */
END_OF_FILE
if test 1804 -ne `wc -c <'joy.h'`; then
    echo shar: \"'joy.h'\" unpacked with wrong size!
fi
# end of 'joy.h'
fi
if test -f 'joyinp.s' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'joyinp.s'\"
else
echo shar: Extracting \"'joyinp.s'\" \(3403 characters\)
sed "s/^X//" >'joyinp.s' <<'END_OF_FILE'
X	.file	"joyinp.s"
X
X/SCCSID:	@(#)joyinp.s	1.1 7/9/88 21:54:46
X
X/ NAME
X/ 	joyinp.s 1.1 [7/9/88] -- do actual inputs from game adaptor.
X/
X/ SYNOPSIS
X/	void joyinp( char input_mask )
X/
X/ DESCRIPTION
X/	This routine reads an analog (resistance) value from
X/	the IBM GAME ADAPTOR.  The method is to trigger the
X/	GAME ADAPTOR one-shot and loop until it times-out.
X/	The number of loops is proportional to the analog
X/	value.
X/
X/ RETURNS
X/	The following external values are returned:
X/	extern int joy_val - proportional to analog value
X/	extern char joy_switches - last input port value read
X/
X/ CAVEATS
X/	Some game adaptors fail if the one-shot is triggered
X/	too soon after the previous reading.  This routine
X/	should have a certain delay between calls.
X/
X/	Interrupts are disabled during the loop in order
X/	to make sure the count is accurate.  It is possible
X/	that interrupts are disabled too long for some high-
X/	speed interrupt processors to work.
X/
X/ NOTES
X/	The structure of this assembly language file was
X/	blindly adapted from compiler output for a similer
X/	function.  If it could have been better written,
X/	so be it.
X/	This subroutine is for use with the LARGE model.
X/
X/ HISTORY
X/	02/07/88 David Messer, Lynx Data Systems
X/	         Original coding
X/
X/********************************************************************/
X/*                                                                  */
X/*  Copyright 1988 Lynx Data Systems                                */
X/*  Copyright 1988 David Messer                                     */
X/*  All Rights Reserved.                                            */
X/*                                                                  */
X/*  This file is part of a licensed software product.  Included     */
X/*  with this file should be the file "LICENSE" which is the        */
X/*  agreement under which this product is licensed.                 */
X/*                                                                  */
X/*  This file may be copied, or distributed, as long as all files   */
X/*  of the product are included along with the LICENSE file and     */
X/*  there is no charge.                                             */
X/*                                                                  */
X/*  If you wish to modify this product, read the license agreement. */
X/*                                                                  */
X/*  This product is distributed WITHOUT ANY WARRANTY.               */
X/*                                                                  */
X/********************************************************************/
X
X	.set	MAX_CNT,1000
X	.data
X	.comm	joy_val,2
X	.comm	joy_switches,1
X	.text
X	.def	joyinp; .val joyinp; .scl 2; .type 044; .endef
X	.globl	joyinp
X
joyinp:
X	enter	$.F1,$0
X
X	mov	$0x201,%dx		/ Game adaptor I/O port address
X
X	movb	6(%bp),%bl		/ Get analog input bit
X	mov	$MAX_CNT,%cx		/ Max count
X	cli				/ No interrupts during loop
X	outb	(%dx)			/ Trigger one-shot
joy0:
X	inb	(%dx)			/ Read game port
X	testb	%bl,%al			/ See if one-shot is done
X	loopnz	joy0			/ Loop if not
X	sti				/ Allow interrupts again
X
X	mov	$<s>joy_val,%dx	/ Get segment for return value
X	mov	%dx,%ds
X	mov	%cx,%ds:joy_val	/ Save first analog value
X
X	mov	$<s>joy_switches,%dx
X	mov	%dx,%ds
X	movb %al,%ds:joy_switches	/ Save switch values
X
X	leave
X	ret
X	.def	joyinp; .val .; .scl -1; .endef
X	.set	.T1,1
X	.set	.S1,0
X	.set	.F1,0
X	.data
END_OF_FILE
if test 3403 -ne `wc -c <'joyinp.s'`; then
    echo shar: \"'joyinp.s'\" unpacked with wrong size!
fi
# end of 'joyinp.s'
fi
if test -f 'joytest.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'joytest.c'\"
else
echo shar: Extracting \"'joytest.c'\" \(3887 characters\)
sed "s/^X//" >'joytest.c' <<'END_OF_FILE'
X/***
X *	joytest.c 1.1 [7/9/88] - test routine for game port driver.
X */
X
X/********************************************************************/
X/*                                                                  */
X/*  Copyright 1988 Lynx Data Systems                                */
X/*  Copyright 1988 David Messer                                     */
X/*  All Rights Reserved.                                            */
X/*                                                                  */
X/*  This file is part of a licensed software product.  Included     */
X/*  with this file should be the file "LICENSE" which is the        */
X/*  agreement under which this product is licensed.                 */
X/*                                                                  */
X/*  This file may be copied, or distributed, as long as all files   */
X/*  of the product are included along with the LICENSE file and     */
X/*  there is no charge.                                             */
X/*                                                                  */
X/*  If you wish to modify this product, read the license agreement. */
X/*                                                                  */
X/*  This product is distributed WITHOUT ANY WARRANTY.               */
X/*                                                                  */
X/********************************************************************/
X
X#include <fcntl.h>
X#include <stdio.h>
X#include "joy.h"
X
X#ifndef lint
static char sccsid[] = "@(#)joytest.c	1.1	7/9/88 22:03:46" ;
X#endif
X
char *joy_file[] =
X	{ "/dev/joy00", "/dev/joy10",
X	  "/dev/joy03", "/dev/joy13",
X	  "/dev/joy02", "/dev/joy12",
X	  "/dev/joy03", "/dev/joy13",
X	  "/dev/joy01", "/dev/joy11",
X	  "/dev/joy03", "/dev/joy13",
X	  "/dev/joy04", "/dev/joy14",
X	  "/dev/joy03", "/dev/joy13",
X	  NULL } ;
X
main()
X{
X	register i, j, fd1, fd2 ;
X	FILE *st1, *st2 ;
X	char sw1[20] ;
X	char sw2[20] ;
X	long x1, y1 ;
X	long x2, y2 ;
X
X	for( j = 0; joy_file[j] != NULL; j += 2 ) {
X		if( (fd1 = open( joy_file[j], O_RDONLY ) ) < 0 ) {
X			fprintf( stderr, "Can't open: %s\n", joy_file[j] ) ;
X			exit( 1 ) ;
X			}
X		st1 = fdopen( fd1, "r" ) ;
X
X		if( (fd2 = open( joy_file[j+1], O_RDONLY ) ) < 0 ) {
X			fprintf( stderr, "Can't open: %s\n", joy_file[j+1] ) ;
X			exit( 1 ) ;
X			}
X		st2 = fdopen( fd2, "r" ) ;
X
X		printf( "%s, %s\n", joy_file[j], joy_file[j+1] ) ;
X
X		printf( "Center Joystick and press first button.\n" ) ;
X		
X		for(;;) {
X			fscanf( st1, "%s %ld %ld\n", sw1, &x1, &y1 ) ;
X			fscanf( st2, "%s %ld %ld\n", sw2, &x2, &y2 ) ;
X			printf( "%4s %12ld %12ld     %4s %12ld %12ld\r",
X						sw1, x1, y1, sw2, x2, y2 ) ;
X			if( sw1[0] == '3' ) break ;
X			}
X
X		ioctl( fd1, JOY_XZERO, (int)x1 ) ;
X		ioctl( fd1, JOY_YZERO, (int)y1 ) ;
X		ioctl( fd2, JOY_XZERO, (int)x2 ) ;
X		ioctl( fd2, JOY_YZERO, (int)y2 ) ;
X
X		printf( "\nMove Joystick to Upper Right and press second button.\n" ) ;
X		
X		for(;;) {
X			fscanf( st1, "%s %ld %ld\n", sw1, &x1, &y1 ) ;
X			fscanf( st2, "%s %ld %ld\n", sw2, &x2, &y2 ) ;
X			printf( "%4s %12ld %12ld     %4s %12ld %12ld\r",
X						sw1, x1, y1, sw2, x2, y2 ) ;
X			if( sw1[0] == '3' ) break ;
X			}
X
X		ioctl( fd1, JOY_XMAX, (int)x1 ) ;
X		ioctl( fd1, JOY_YMAX, (int)y1 ) ;
X		ioctl( fd1, JOY_XSCALE, 10000 ) ;
X		ioctl( fd1, JOY_YSCALE, 10000 ) ;
X		ioctl( fd1, JOY_XDEADBAND, 200 ) ;
X		ioctl( fd1, JOY_YDEADBAND, 200 ) ;
X
X		ioctl( fd2, JOY_XMAX, (int)x2 ) ;
X		ioctl( fd2, JOY_YMAX, (int)y2 ) ;
X		ioctl( fd2, JOY_XSCALE, 10000 ) ;
X		ioctl( fd2, JOY_YSCALE, 10000 ) ;
X		ioctl( fd2, JOY_XDEADBAND, 200 ) ;
X		ioctl( fd2, JOY_YDEADBAND, 200 ) ;
X
X		printf( "\nPress Both Buttons to End.\n" ) ;
X		
X		for(;;) {
X			fscanf( st1, "%s %ld %ld\n", sw1, &x1, &y1 ) ;
X			fscanf( st2, "%s %ld %ld\n", sw2, &x2, &y2 ) ;
X			printf( "%4s %12ld %12ld     %4s %12ld %12ld\r",
X						sw1, x1, y1, sw2, x2, y2 ) ;
X			if( sw1[0] == '3' && sw1[0] == '3' ) break ;
X			}
X		}
X
X	}
END_OF_FILE
if test 3887 -ne `wc -c <'joytest.c'`; then
    echo shar: \"'joytest.c'\" unpacked with wrong size!
fi
# end of 'joytest.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
If you can't convince |   David Messer - (dave@Lynx.MN.Org)
them, confuse them.   |   Lynx Data Systems
   -- Harry S Truman  | 
                      |   amdahl   --!bungia!viper!dave
                      |   hpda    /

Copyright 1988 David Messer -- All Rights Reserved
This work may be freely copied.  Any restrictions on
redistribution of this work are prohibited.