Article View: comp.sources.atari.st
Article #348v01i003: Joystick-reading routines
From: Steven Grimm
Date: Tue, 29 Mar 1988 17:58
Date: Tue, 29 Mar 1988 17:58
198 lines
7568 bytes
7568 bytes
Submitted-by: sirkm@ucscb.ucsc.edu (Greg Anderson)
Posting-number: Volume 1, Issue
Archive-name: joyread
[Lots of STers seem to have trouble reading the joystick ports, which is much
more painful on the ST than on the 8-bit. These routines should help make
it easier. Note that these are just some routines, and not a complete
program. -sg]
/*-------------------------------------------------------------------------
| Stick.c: Joystick interupt service routine
|
| Placed in the public domain March 1988 by Greg Anderson.
|
| The joystick demo by Steve Jankowski was instrumental to
| the creation of these routines.
|
| Many thanks to Steven Grimm for providing essential information
| and the aforementioned joystick demo.
|
|##########################################################################
| THESE ROUTINES ONLY WORK UNDER LASER C! THEY MUST BE MODIFIED FOR
| OTHER C COMPILERS, _INCLUDING_ MEGAMAX C VERSION 1.xx!
|
| MegaMax instructions: A4 must be saved somewhere so that it is
| available durring the isr. Then, the isr can access joyinf
| with "lea joyinf(A4),A1" instead of "lea joyinf,A1".
|##########################################################################
|
| This package sets up an interupt to read the joystick on the
| ST. The joystick is read via the ikbd--the intelligent keyboard
| interface chip. The ikbd can be placed into "joystick-reading
| mode" by sending an appropriate command with Ikbdws(). This has
| two effects: first, the mouse is disabled. Second, the ikbd will
| be prompted to send a three-byte packet every time one of the
| joysticks changes states. The packet is as follows:
|
| [Stick #] [State of Stick 0] [State of Stick 1]
|
| The first byte is $FE if stick 0 changed, or $FF if stick 1
| changed. These routines ignore the first byte.
| The next two bytes contain the states of sticks 0 and 1.
| There values will be the sum of:
|
| +1 (+128)
| |
| +4 ---< >--- +8
| |
| +2
|
| Add the apropriate value if the contact is down. For example,
| if stick 0 is NW and the trigger has not been pressed, its
| current state will be 1 + 4 = 5.
|
| These packets are sent to a routine pointed to by "joyvec".
| Joyvec is part of the structure returned by Kbdvbase(). Joyvec
| can be changed to point to an interupt service routine (isr) of
| our devising. If this is done, the isr will find that A0 points
| to the first byte of the the packet sent by the ikbd. The isr
| must be very short (less than 1ms exicution time). Atari's docs
| of Kbdvbase indicate that a copy of the pointer to the packet is
| also deposited on the stack; however, this does not appear to be
| the case.
|
| Using these routines:
|
| Call stick_init() to set up the joystick isr and place the ikbd
| into joystick send mode. This will also disable the mouse.
|
| stick_exit() will return the ikbd to mouse send mode. Your
| program should do this before exiting.
|
| Once the initialize routine has been called, the following
| commands are available:
|
| _stick(n): Return the state of stick N. (See above chart)
| stick(n) : Return the direction of stick N. (Minus the trigger)
| trig(n) : Return the state of the trigger on stick N.
| hstick(n): Return the horizontal position of stick N. (-1 to +1)
| vstick(n): Return the vertical position of stick N.
|
-------------------------------------------------------------------------*/
#include <osbind.h>
char ikbdcmd[10]; /* Storage space for ikbd commands */
#define SENDJOY 0x14 /* Send joystick packets */
#define SENDMOUSE 0x08 /* Send mouse packets */
extern joyisr(); /* Interupt service routine follows */
int (*oldjoyvec)(); /* Save old isr vector here */
int initialized = 0; /* Initialized flag */
unsigned char joyinf[2]; /* Holds data for joystick states */
int joytab[4] = { 0, -1, 1, 0 };
#define xstick(v) joytab[ v & 0x03 ]
/*-------------------------------------------------------------------
| Initialize joystick isr
-------------------------------------------------------------------*/
void stick_init()
{
kbdvecs *KB;
/* Do nothing if joystick isr has been initialized */
if (initialized)
return;
/* Put our isr into the joystick interupt vector slot */
KB = Kbdvbase();
oldjoyvec = KB->joyvec;
KB->joyvec = joyisr;
/* Tell ikbd to send joystick packets. */
ikbdcmd[0] = SENDJOY;
Ikbdws(0, ikbdcmd);
initialized = 1;
}
/*-------------------------------------------------------------------
| End joystick mode--go back to sending mouse packets.
-------------------------------------------------------------------*/
void stick_exit()
{
kbdvecs *KB;
/* Do nothing if joystick isr not initialized */
if (! initialized)
return;
/* Tell ikbd to go back to sending mouse packets */
ikbdcmd[0] = SENDMOUSE;
Ikbdws(0, ikbdcmd);
/* Restore the old joystick interupt vector */
KB = Kbdvbase();
KB->joyvec = oldjoyvec;
initialized = 0;
}
/*-------------------------------------------------------------------
| Here is the actual joystick interupt service routine.
| Both stick 0 and stick 1 are placed into the variable
| "joyinf".
-------------------------------------------------------------------*/
asm
{
joyisr:
lea joyinf,A1 /* "joyinf" holds data */
addq.l #1,A0 /* We don't want first byte */
move.b (A0)+,(A1)+ /* Joystick 0 state */
move.b (A0)+,(A1)+ /* Joystick 1 state */
rts
}
/*-------------------------------------------------------------------
| Return the state of stick 0 or stick 1.
| Bits 0-3 = stick direction, bit 7 = trigger.
-------------------------------------------------------------------*/
int _stick(n)
int n;
{
return(joyinf[n]);
}
/*-------------------------------------------------------------------
| Return the direction bits of stick 0 or stick 1.
-------------------------------------------------------------------*/
int stick(n)
int n;
{
return( joyinf[n] & 0x0F );
}
/*-------------------------------------------------------------------
| Return the state of the trigger of stick n:
-------------------------------------------------------------------*/
int trig(n)
int n;
{
return( (joyinf[n] & 0x80) != 0 );
}
/*-------------------------------------------------------------------
| Return the horizontal state of stick n:
| +1 = right, 0 = centered, & -1 = left
-------------------------------------------------------------------*/
int hstick(n)
int n;
{
return(xstick(joyinf[n] / 4));
}
/*-------------------------------------------------------------------
| Return the vertical state of stick n:
| +1 = down, 0 = centered, -1 = up.
-------------------------------------------------------------------*/
int vstick(n)
int n;
{
return(xstick(joyinf[n]));
}
Technical Details
Message-ID:
<2544@saturn.ucsc.edu>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!think!ames!pasteur!ucbvax!agate!saturn!ssyx!korethShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!think!ames!pasteur!ucbvax!agate!saturn!ssyx!koreth From: koreth@ssyx.ucsc.edu (Steven Grimm) Newsgroups: comp.sources.atari.st Subject: v01i003: Joystick-reading routines Message-ID: <2544@saturn.ucsc.edu> Date: 29 Mar 88 17:58:37 GMT Sender: usenet@saturn.ucsc.edu Lines: 198 Keywords: Laser Approved: koreth@ssyx.ucsc.edu