1995-01-25 20:11:51 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 1995 Jean-Marc Zucconi
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer
|
|
|
|
* in this position and unchanged.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software withough specific prior written permission
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include "joy.h"
|
|
|
|
|
|
|
|
#if NJOY > 0
|
|
|
|
|
|
|
|
#include <errno.h>
|
1995-02-26 05:14:53 +00:00
|
|
|
|
1995-03-28 07:58:53 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
1995-02-26 05:14:53 +00:00
|
|
|
|
|
|
|
#include <machine/joystick.h>
|
1995-01-25 20:11:51 +00:00
|
|
|
|
1995-02-26 05:14:53 +00:00
|
|
|
#include <i386/isa/isa.h>
|
|
|
|
#include <i386/isa/isa_device.h>
|
|
|
|
#include <i386/isa/timerreg.h>
|
1995-01-25 20:11:51 +00:00
|
|
|
|
the second set of changes in a move towards getting devices to be
totally dynamic.
this is only the devices in i386/isa
I'll do more tomorrow.
they're completely masked by #ifdef JREMOD at this stage...
the eventual aim is that every driver will do a SYSINIT
at startup BEFORE the probes, which will effectively
link it into the devsw tables etc.
If I'd thought about it more I'd have put that in in this set (damn)
The ioconf lines generated by config will also end up in the
device's own scope as well, so ioconf.c will eventually be gutted
the SYSINIT call to the driver will include a phase where the
driver links it's ioconf line into a chain of such. when this phase is done
then the user can modify them with the boot: -c
config menu if he wants, just like now..
config will put the config lines out in the .h file
(e.g. in aha.h will be the addresses for the aha driver to look.)
as I said this is a very small first step..
the aim of THIS set of edits is to not have to edit conf.c at all when
adding a new device.. the tabe will be a simple skeleton..
when this is done, it will allow other changes to be made,
all teh time still having a fully working kernel tree,
but the logical outcome is the complete REMOVAL of the devsw tables.
By the end of this, linked in drivers will be exactly the same as
run-time loaded drivers, except they JUST HAPPEN to already be linked
and present at startup..
the SYSINIT calls will be the equivalent of the "init" call
made to a newly loaded driver in every respect.
For this edit,
each of the files has the following code inserted into it:
obviously, tailored to suit..
----------------------somewhere at the top:
#ifdef JREMOD
#include <sys/conf.h>
#define CDEV_MAJOR 13
#define BDEV_MAJOR 4
static void sd_devsw_install();
#endif /*JREMOD */
---------------------somewhere that's run during bootup: EVENTUALLY a SYSINIT
#ifdef JREMOD
sd_devsw_install();
#endif /*JREMOD*/
-----------------------at the bottom:
#ifdef JREMOD
struct bdevsw sd_bdevsw =
{ sdopen, sdclose, sdstrategy, sdioctl, /*4*/
sddump, sdsize, 0 };
struct cdevsw sd_cdevsw =
{ sdopen, sdclose, rawread, rawwrite, /*13*/
sdioctl, nostop, nullreset, nodevtotty,/* sd */
seltrue, nommap, sdstrategy };
static sd_devsw_installed = 0;
static void sd_devsw_install()
{
dev_t descript;
if( ! sd_devsw_installed ) {
descript = makedev(CDEV_MAJOR,0);
cdevsw_add(&descript,&sd_cdevsw,NULL);
#if defined(BDEV_MAJOR)
descript = makedev(BDEV_MAJOR,0);
bdevsw_add(&descript,&sd_bdevsw,NULL);
#endif /*BDEV_MAJOR*/
sd_devsw_installed = 1;
}
}
#endif /* JREMOD */
1995-11-28 09:42:06 +00:00
|
|
|
#ifdef JREMOD
|
|
|
|
#include <sys/conf.h>
|
|
|
|
#define CDEV_MAJOR 51
|
|
|
|
static void joy_devsw_install();
|
|
|
|
#endif /*JREMOD*/
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
/* The game port can manage 4 buttons and 4 variable resistors (usually 2
|
1995-01-25 20:11:51 +00:00
|
|
|
* joysticks, each with 2 buttons and 2 pots.) via the port at address 0x201.
|
|
|
|
* Getting the state of the buttons is done by reading the game port:
|
|
|
|
* buttons 1-4 correspond to bits 4-7 and resistors 1-4 (X1, Y1, X2, Y2)
|
|
|
|
* to bits 0-3.
|
|
|
|
* if button 1 (resp 2, 3, 4) is pressed, the bit 4 (resp 5, 6, 7) is set to 0
|
|
|
|
* to get the value of a resistor, write the value 0xff at port and
|
|
|
|
* wait until the corresponding bit returns to 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
/* the formulae below only work if u is ``not too large''. See also
|
1995-01-28 21:54:37 +00:00
|
|
|
* the discussion in microtime.s */
|
1995-01-29 01:00:14 +00:00
|
|
|
#define usec2ticks(u) (((u) * 19549)>>14)
|
|
|
|
#define ticks2usec(u) (((u) * 3433)>>12)
|
1995-01-25 20:11:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
#define joypart(d) minor(d)&1
|
|
|
|
#define UNIT(d) minor(d)>>1&3
|
|
|
|
#ifndef JOY_TIMEOUT
|
|
|
|
#define JOY_TIMEOUT 2000 /* 2 milliseconds */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
int port;
|
|
|
|
int x_off[2], y_off[2];
|
|
|
|
int timeout[2];
|
|
|
|
} joy[NJOY];
|
|
|
|
|
|
|
|
|
1995-01-28 21:54:37 +00:00
|
|
|
extern int timer0_max_count;
|
1995-01-25 20:11:51 +00:00
|
|
|
|
|
|
|
int joyprobe (struct isa_device *), joyattach (struct isa_device *);
|
|
|
|
|
|
|
|
struct isa_driver joydriver = {joyprobe, joyattach, "joy"};
|
|
|
|
|
|
|
|
static int get_tick ();
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
joyprobe (struct isa_device *dev)
|
|
|
|
{
|
|
|
|
#ifdef WANT_JOYSTICK_CONNECTED
|
|
|
|
outb (dev->id_iobase, 0xff);
|
|
|
|
DELAY (10000); /* 10 ms delay */
|
|
|
|
return (inb (dev->id_iobase) & 0x0f) != 0x0f;
|
|
|
|
#else
|
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
joyattach (struct isa_device *dev)
|
|
|
|
{
|
|
|
|
joy[dev->id_unit].port = dev->id_iobase;
|
|
|
|
joy[dev->id_unit].timeout[0] = joy[dev->id_unit].timeout[1] = 0;
|
|
|
|
printf("joy%d: joystick\n", dev->id_unit);
|
|
|
|
|
the second set of changes in a move towards getting devices to be
totally dynamic.
this is only the devices in i386/isa
I'll do more tomorrow.
they're completely masked by #ifdef JREMOD at this stage...
the eventual aim is that every driver will do a SYSINIT
at startup BEFORE the probes, which will effectively
link it into the devsw tables etc.
If I'd thought about it more I'd have put that in in this set (damn)
The ioconf lines generated by config will also end up in the
device's own scope as well, so ioconf.c will eventually be gutted
the SYSINIT call to the driver will include a phase where the
driver links it's ioconf line into a chain of such. when this phase is done
then the user can modify them with the boot: -c
config menu if he wants, just like now..
config will put the config lines out in the .h file
(e.g. in aha.h will be the addresses for the aha driver to look.)
as I said this is a very small first step..
the aim of THIS set of edits is to not have to edit conf.c at all when
adding a new device.. the tabe will be a simple skeleton..
when this is done, it will allow other changes to be made,
all teh time still having a fully working kernel tree,
but the logical outcome is the complete REMOVAL of the devsw tables.
By the end of this, linked in drivers will be exactly the same as
run-time loaded drivers, except they JUST HAPPEN to already be linked
and present at startup..
the SYSINIT calls will be the equivalent of the "init" call
made to a newly loaded driver in every respect.
For this edit,
each of the files has the following code inserted into it:
obviously, tailored to suit..
----------------------somewhere at the top:
#ifdef JREMOD
#include <sys/conf.h>
#define CDEV_MAJOR 13
#define BDEV_MAJOR 4
static void sd_devsw_install();
#endif /*JREMOD */
---------------------somewhere that's run during bootup: EVENTUALLY a SYSINIT
#ifdef JREMOD
sd_devsw_install();
#endif /*JREMOD*/
-----------------------at the bottom:
#ifdef JREMOD
struct bdevsw sd_bdevsw =
{ sdopen, sdclose, sdstrategy, sdioctl, /*4*/
sddump, sdsize, 0 };
struct cdevsw sd_cdevsw =
{ sdopen, sdclose, rawread, rawwrite, /*13*/
sdioctl, nostop, nullreset, nodevtotty,/* sd */
seltrue, nommap, sdstrategy };
static sd_devsw_installed = 0;
static void sd_devsw_install()
{
dev_t descript;
if( ! sd_devsw_installed ) {
descript = makedev(CDEV_MAJOR,0);
cdevsw_add(&descript,&sd_cdevsw,NULL);
#if defined(BDEV_MAJOR)
descript = makedev(BDEV_MAJOR,0);
bdevsw_add(&descript,&sd_bdevsw,NULL);
#endif /*BDEV_MAJOR*/
sd_devsw_installed = 1;
}
}
#endif /* JREMOD */
1995-11-28 09:42:06 +00:00
|
|
|
#ifdef JREMOD
|
|
|
|
joy_devsw_install();
|
|
|
|
#endif /*JREMOD*/
|
|
|
|
|
1995-01-25 20:11:51 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1995-09-08 19:57:13 +00:00
|
|
|
joyopen (dev_t dev, int flags, int fmt, struct proc *p)
|
1995-01-25 20:11:51 +00:00
|
|
|
{
|
|
|
|
int unit = UNIT (dev);
|
|
|
|
int i = joypart (dev);
|
|
|
|
|
|
|
|
if (joy[unit].timeout[i])
|
|
|
|
return EBUSY;
|
|
|
|
joy[unit].x_off[i] = joy[unit].y_off[i] = 0;
|
|
|
|
joy[unit].timeout[i] = JOY_TIMEOUT;
|
|
|
|
return 0;
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
int
|
1995-09-08 19:57:13 +00:00
|
|
|
joyclose (dev_t dev, int flags, int fmt, struct proc *p)
|
1995-01-25 20:11:51 +00:00
|
|
|
{
|
|
|
|
int unit = UNIT (dev);
|
|
|
|
int i = joypart (dev);
|
|
|
|
|
|
|
|
joy[unit].timeout[i] = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
joyread (dev_t dev, struct uio *uio, int flag)
|
|
|
|
{
|
|
|
|
int unit = UNIT(dev);
|
|
|
|
int port = joy[unit].port;
|
|
|
|
int i, t0, t1;
|
|
|
|
int state = 0, x = 0, y = 0;
|
1995-02-22 23:34:58 +00:00
|
|
|
struct joystick c;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
1995-01-25 20:11:51 +00:00
|
|
|
disable_intr ();
|
|
|
|
outb (port, 0xff);
|
|
|
|
t0 = get_tick ();
|
|
|
|
t1 = t0;
|
|
|
|
i = usec2ticks(joy[unit].timeout[joypart(dev)]);
|
|
|
|
while (t0-t1 < i) {
|
|
|
|
state = inb (port);
|
1995-05-30 08:16:23 +00:00
|
|
|
if (joypart(dev) == 1)
|
1995-01-25 20:11:51 +00:00
|
|
|
state >>= 2;
|
|
|
|
t1 = get_tick ();
|
|
|
|
if (t1 > t0)
|
1995-01-28 21:54:37 +00:00
|
|
|
t1 -= timer0_max_count;
|
1995-01-25 20:11:51 +00:00
|
|
|
if (!x && !(state & 0x01))
|
|
|
|
x = t1;
|
|
|
|
if (!y && !(state & 0x02))
|
|
|
|
y = t1;
|
1995-05-30 08:16:23 +00:00
|
|
|
if (x && y)
|
1995-01-25 20:11:51 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
enable_intr ();
|
1995-02-22 23:34:58 +00:00
|
|
|
c.x = x ? joy[unit].x_off[joypart(dev)] + ticks2usec(t0-x) : 0x80000000;
|
|
|
|
c.y = y ? joy[unit].y_off[joypart(dev)] + ticks2usec(t0-y) : 0x80000000;
|
1995-01-25 20:11:51 +00:00
|
|
|
state >>= 4;
|
1995-02-22 23:34:58 +00:00
|
|
|
c.b1 = ~state & 1;
|
|
|
|
c.b2 = ~(state >> 1) & 1;
|
1995-03-28 07:58:53 +00:00
|
|
|
return uiomove ((caddr_t)&c, sizeof(struct joystick), uio);
|
1995-01-25 20:11:51 +00:00
|
|
|
}
|
|
|
|
int joyioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
|
|
|
{
|
|
|
|
int unit = UNIT (dev);
|
|
|
|
int i = joypart (dev);
|
|
|
|
int x;
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case JOY_SETTIMEOUT:
|
|
|
|
x = *(int *) data;
|
|
|
|
if (x < 1 || x > 10000) /* 10ms maximum! */
|
|
|
|
return EINVAL;
|
|
|
|
joy[unit].timeout[i] = x;
|
|
|
|
break;
|
|
|
|
case JOY_GETTIMEOUT:
|
|
|
|
*(int *) data = joy[unit].timeout[i];
|
|
|
|
break;
|
|
|
|
case JOY_SET_X_OFFSET:
|
|
|
|
joy[unit].x_off[i] = *(int *) data;
|
|
|
|
break;
|
|
|
|
case JOY_SET_Y_OFFSET:
|
|
|
|
joy[unit].y_off[i] = *(int *) data;
|
|
|
|
break;
|
|
|
|
case JOY_GET_X_OFFSET:
|
|
|
|
*(int *) data = joy[unit].x_off[i];
|
|
|
|
break;
|
|
|
|
case JOY_GET_Y_OFFSET:
|
|
|
|
*(int *) data = joy[unit].y_off[i];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static int
|
|
|
|
get_tick ()
|
|
|
|
{
|
|
|
|
int low, high;
|
|
|
|
|
|
|
|
outb (TIMER_MODE, TIMER_SEL0);
|
|
|
|
low = inb (TIMER_CNTR0);
|
|
|
|
high = inb (TIMER_CNTR0);
|
|
|
|
|
|
|
|
return (high << 8) | low;
|
|
|
|
}
|
|
|
|
|
the second set of changes in a move towards getting devices to be
totally dynamic.
this is only the devices in i386/isa
I'll do more tomorrow.
they're completely masked by #ifdef JREMOD at this stage...
the eventual aim is that every driver will do a SYSINIT
at startup BEFORE the probes, which will effectively
link it into the devsw tables etc.
If I'd thought about it more I'd have put that in in this set (damn)
The ioconf lines generated by config will also end up in the
device's own scope as well, so ioconf.c will eventually be gutted
the SYSINIT call to the driver will include a phase where the
driver links it's ioconf line into a chain of such. when this phase is done
then the user can modify them with the boot: -c
config menu if he wants, just like now..
config will put the config lines out in the .h file
(e.g. in aha.h will be the addresses for the aha driver to look.)
as I said this is a very small first step..
the aim of THIS set of edits is to not have to edit conf.c at all when
adding a new device.. the tabe will be a simple skeleton..
when this is done, it will allow other changes to be made,
all teh time still having a fully working kernel tree,
but the logical outcome is the complete REMOVAL of the devsw tables.
By the end of this, linked in drivers will be exactly the same as
run-time loaded drivers, except they JUST HAPPEN to already be linked
and present at startup..
the SYSINIT calls will be the equivalent of the "init" call
made to a newly loaded driver in every respect.
For this edit,
each of the files has the following code inserted into it:
obviously, tailored to suit..
----------------------somewhere at the top:
#ifdef JREMOD
#include <sys/conf.h>
#define CDEV_MAJOR 13
#define BDEV_MAJOR 4
static void sd_devsw_install();
#endif /*JREMOD */
---------------------somewhere that's run during bootup: EVENTUALLY a SYSINIT
#ifdef JREMOD
sd_devsw_install();
#endif /*JREMOD*/
-----------------------at the bottom:
#ifdef JREMOD
struct bdevsw sd_bdevsw =
{ sdopen, sdclose, sdstrategy, sdioctl, /*4*/
sddump, sdsize, 0 };
struct cdevsw sd_cdevsw =
{ sdopen, sdclose, rawread, rawwrite, /*13*/
sdioctl, nostop, nullreset, nodevtotty,/* sd */
seltrue, nommap, sdstrategy };
static sd_devsw_installed = 0;
static void sd_devsw_install()
{
dev_t descript;
if( ! sd_devsw_installed ) {
descript = makedev(CDEV_MAJOR,0);
cdevsw_add(&descript,&sd_cdevsw,NULL);
#if defined(BDEV_MAJOR)
descript = makedev(BDEV_MAJOR,0);
bdevsw_add(&descript,&sd_bdevsw,NULL);
#endif /*BDEV_MAJOR*/
sd_devsw_installed = 1;
}
}
#endif /* JREMOD */
1995-11-28 09:42:06 +00:00
|
|
|
|
|
|
|
#ifdef JREMOD
|
|
|
|
struct cdevsw joy_cdevsw =
|
|
|
|
{ joyopen, joyclose, joyread, nowrite, /*51*/
|
|
|
|
joyioctl, nostop, nullreset, nodevtotty,/*joystick */
|
|
|
|
seltrue, nommap, NULL};
|
|
|
|
|
|
|
|
static joy_devsw_installed = 0;
|
|
|
|
|
|
|
|
static void joy_devsw_install()
|
|
|
|
{
|
|
|
|
dev_t descript;
|
|
|
|
if( ! joy_devsw_installed ) {
|
|
|
|
descript = makedev(CDEV_MAJOR,0);
|
|
|
|
cdevsw_add(&descript,&joy_cdevsw,NULL);
|
|
|
|
#if defined(BDEV_MAJOR)
|
|
|
|
descript = makedev(BDEV_MAJOR,0);
|
|
|
|
bdevsw_add(&descript,&joy_bdevsw,NULL);
|
|
|
|
#endif /*BDEV_MAJOR*/
|
|
|
|
joy_devsw_installed = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* JREMOD */
|
1995-01-25 20:11:51 +00:00
|
|
|
#endif /* NJOY > 0 */
|