Thread View: comp.sources.atari.st
1 messages
1 total messages
Started by Steven Grimm
Tue, 29 Mar 1988 17:58
v01i003: Joystick-reading routines
Author: 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]));
}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads