[comp.sys.amiga] gameport.device

chiafari@umbc3.UUCP (02/18/87)

ARRRRRRRGGGGGGGGG!!!!!!!


Has anyone gotten the gameport.device to work?  I've gotten entirely too
frustrated with this.  My problem goes something like this:

I run a program using a joystick.  The program works fine.  If I run
it again, it STILL works fine.  If I run some OTHER program, then run
the joystick program, none of the system calls complain, but GetMsg()
always returns 0.  Occationally after this happens, the system crashes.
Typical crash:  mouse pointer becomes vertical column, power light starts
to blink.

Other interesting notes:  I first typed the joystick code in (doing a 
translation to my style) from the RKM joystick example under 
gameport.device.  When this ran fine, I incorperated it in another
program, calling the joystick init code at the beginning of main() in
the new code.  Consequently, CHIP memory is apparently being allocated
in exactly the same way by the two programs, and I can alternate running
them successfully, as long as I don't run anything else that uses CHIP ram.
When either of them doesn't work, the other one won't either.  I suspect
that there is something wrong with the way I'm cleaning up.

System configuration:
Amiga 1000 w/512K CHIP RAM.
ASDG MiniRack-C w/2M FAST RAM (using 2M rrd: programs usually load
1 External Drive.				into FAST RAM).
Mouse in left mouse port.
Joystick in right mouse port.
KickStart 1.2 V33.180
WorkBench 1.2 V33.47
Shell V2.05M
Lattice 3.03
Blink V6.5 (1986/09/29)

I think that's about all I can say...  Code follows...  Any suggestions
would be appreciated...  MAIL them (for GOD'S SAKE!) and if there's
interest, I'll post my eventual solution.

They nuked my account when I graduated, so send mail to:

	chiafari@umbc3.umd.edu

soon to be  !...!some!unknown!path!...!wedge!eric, but for right now
I'm NOT on USENET, so find an arpa gateway....

			-eric messick




-----------------------joy.c---begins---here-------------------------------
#include <exec/types.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <devices/gameport.h>
#include <devices/inputevent.h>
#include <stdio.h>

#define setmsg(msg, com, len, dat) {	\
(msg)->io_Command = (com) ;		\
(msg)->io_Length = (len) ;		\
(msg)->io_Data = (APTR)(dat) ; }

struct InputEvent *joyie;
struct IOStdReq *joyio;
struct MsgPort *joymp;

struct GamePortTrigger gpt;

int gamedevice = 0 ;

extern int joybutton, joyx, joyy, debug;

extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();

initjoy()
{
	printf("insert joystick in right mouse port.\n");

	joyie = (struct InputEvent *)AllocMem(sizeof(struct InputEvent),
						MEMF_PUBLIC);
	if (!joyie) cleanup ("no inputevent");

	joymp = CreatePort("gameport", 0);
	if (!joymp) cleanup ("no gameport");

	joyio = CreateStdIO(joymp);
	if (!joyio) cleanup ("no stdioreq");

	if (OpenDevice("gameport.device", 1, joyio, 0))
		cleanup ("no gameport device");
	gamedevice = 1 ;

	setmsg(joyio, GPD_SETCTYPE, 1, joyie);
	*(BYTE *)joyie = GPCT_ABSJOYSTICK ;
	SendIO(joyio);
	WaitPort(joymp);
	GetMsg(joymp);
	if (joyio->io_Error) cleanup ("can't GPD_SETCTYPE");

	setmsg(joyio, GPD_SETTRIGGER, sizeof(gpt), &gpt);
	gpt.gpt_Keys = GPTF_UPKEYS | GPTF_DOWNKEYS ;
	gpt.gpt_Timeout = 0 ;
	gpt.gpt_XDelta = 1 ;
	gpt.gpt_YDelta = 1 ;
	if (DoIO(joyio)) cleanup("can't GPD_SETTRIGGER");

	setmsg(joyio, GPD_READEVENT, sizeof(struct InputEvent), joyie);
	joyio->io_Flags = 0 ;
	SendIO(joyio);
}

checkjoy()
{
	if (GetMsg(joymp)) {
		joybutton = joyie->ie_Qualifier & IEQUALIFIER_MBUTTON ;
		joyx = joyie->ie_X ;
		joyy = joyie->ie_Y ;
		SendIO(joyio);
		return 1;
		}
	return 0;
}

cleanupjoy()
{
	if (joymp) {
		while (GetMsg(joymp))
			;
		setmsg(joyio, GPD_SETCTYPE, 1, joyie);
		*(BYTE *)joyie = GPCT_NOCONTROLLER ;
		SendIO(joyio);
		WaitPort(joymp);
		GetMsg(joymp);
		}

	if (gamedevice)	CloseDevice(joyio);
	if (joyio)	DeleteStdIO(joyio);
	if (joymp)	DeletePort(joymp);
	if (joyie)	FreeMem(joyie, sizeof(struct InputEvent));
}

/* notes on code:

cleanup() calls cleanupjoy()

main() calls initjoy() and checkjoy()

cleanup() is ALWAYS called before exiting.

joybutton, joyx, and joyy are defined elsewhere, and used to communicate
with the rest of the world

*/

cmcmanis@sun.UUCP (02/19/87)

In article <292@umbc3.UMD.EDU>, chiafari@umbc3.UMD.EDU (frank chiafari) writes:
[actually he is ghost writing for eric messick]
> ARRRRRRRGGGGGGGGG!!!!!!!
> Has anyone gotten the gameport.device to work?  I've gotten entirely too
> frustrated with this.  My problem goes something like this:
  ... He goes on to describe the problem ...
> 
> I think that's about all I can say...  Code follows...  Any suggestions
> would be appreciated...  MAIL them (for GOD'S SAKE!) and if there's
> interest, I'll post my eventual solution.
> 
> 			-eric messick
   ... and lots of code followed ...

Sorry for posting this to everyone unfortunately frank's address bounced
back faster than greased lightning. My advice to Eric and Frank and
anyone else doing exec level stuff on the Amiga :
	* Reply to your messages! *
When someone sends you a message, be it exec, intuition, or some user
task, you sould reply to it with ReplyMsg(), that way the person
calling you knows you got the message. If you don't then the sender
will get either very impatient or crash. Hope it solves your problems
with the gameport device.

-- 
--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

ee173way@sdcc3.UUCP (02/20/87)

  Don't even waste your time with the RKM version.  I have written a
video arcade-style game using *totally* my own routines.  I even
access port 0 with Intuition hooked up! What is the trick? It is so
simple, you probably won't believe it.
  Just READ THE HARDWARE! Get out your Hardware Manual and turn to
page Appendix_A Page 12. Bottom right of page lists:

   JOY0DAT 00A R
   JOY1DAT 00C R

   The 00A and the 00C are the offsets from $DFF000. So, the memory
locations to access are $DFF00A and $DFF00C. The R's mean read
locations. (I used absolute addressing BYTE vars).
  
   Now, look at page Appendix_A page 13, bottom left, above JOYTEST.
The bits you need to check are shown.  That's it! The necessary C
code takes only *a line or two, maybe three*, not *three* PAGES.
Plus, you can read port 0 with no problems (I haven't had any).  I
wrote my code in Modula-2 and it only took about half a page.

  This version is tons faster, much smaller, and less problematic.
If you wish to do the same for a mouse version, you'll have to write
the necessary code to support it (motion x,y,vel). Read Chapter 8 of
the hardware manual first to get an idea of what we are doing.
(You will also probably want to read the BUTTON addresses as well...
   

   Good Luck,
    
            John
            7OHN
 

michael@stb.UUCP (02/27/87)

There is a major problem with grabbing the joystick replies straight from
the hardware, and its a shame that EA does it this way. The reason?
 
How do you know what hardware I have?
 
The amiga supports mice and sticks. Trackballs that look like sticks are
available. Proportional sticks and real balls will be soon. Who know what
else will come later.
 
YOU CAN ALWAYS GRAB THE INTUITION INPUT STREAM.
 
The benefit of this method is:
 
A. The user can install filters and drivers for special hardware or
auto-fire mods, in software
B. Compatible with any hardware that will come out (it may be slower, but
it will work)

Remember, intuition grabs stuff at position 50 in the chain, so if you
plug in at 51, you get both joysticks (front and rear). The only thing
else you need is a short (5 line) program to set the front port to stick
and back to mouse. Then you write a 3 line script file that
set-stick
my_game
set-mouse
and the user modifies it if his hardware puts out proportional joystick
signals by putting in a peice of software that filters the proportional
into directional.

If I'm missing something here (some incorrect assumption or something),
let me know and I'll fix it. School prevents me from testing it (but
just wait() a month...)
-- 
: Michael Gersten		ihnp4!ucla-cs!cepu!ucla-an!remsit!stb!michael
: Remember, its not paranoia if the governemt really is out to get you.

ewhac@well.UUCP (03/01/87)

In article <13567@sun.uucp> cmcmanis@sun.uucp (Chuck McManis) writes:
>In article <292@umbc3.UMD.EDU>, chiafari@umbc3.UMD.EDU (frank chiafari) writes:
>[actually he is ghost writing for eric messick]
>> ARRRRRRRGGGGGGGGG!!!!!!!
>> Has anyone gotten the gameport.device to work?  I've gotten entirely too
>> frustrated with this.  My problem goes something like this:
>  ... He goes on to describe the problem ...
>> 
>> I think that's about all I can say...  Code follows...  Any suggestions
>> would be appreciated...  MAIL them (for GOD'S SAKE!) and if there's
>> interest, I'll post my eventual solution.
>> 
>> 			-eric messick
>   ... and lots of code followed ...
>
>Sorry for posting this to everyone unfortunately frank's address bounced
>back faster than greased lightning. My advice to Eric and Frank and
>anyone else doing exec level stuff on the Amiga :
>	* Reply to your messages! *
>When someone sends you a message, be it exec, intuition, or some user
>task, you sould reply to it with ReplyMsg() [.....]
>      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	NO NO NO NO NO!!!  You DON'T reply to everybody.  This is how it
works.

	All I/O on the Amiga is implemented as message passing.  When you
want the I/O system to do something, you create a message packet, open the
device, and send your requests to it.

	When the I/O driver has completed your request, it lets you know by
replying the message to a reply port which you've created.  Note that it is
the I/O DRIVER that is replying.  It is replying because you sent the
original message.

	DoIO() is a synchronous I/O call; it sends the I/O request to the
driver and waits for it to complete.  SendIO() is asynchronous; it passes
the request to the driver, and returns control to you.  WaitIO() waits for a
particular I/O request to complete.  If you wanted to do interleaved I/O
(for example, asking for a disk block that you know you're going to need
eventually, but you can do some computing in the meantime), then you'd send
the request using SendIO(), do some other stuff for a while, then wait for
the I/O to complete (if it hasn't already) with WaitIO().  BeginIO() is a
low-level version of SendIO().

	As always, never touch the message data while the I/O request is
still outstanding, since the I/O driver owns that data for as long as it has
it.

	The gameport is a device, so these rules apply.  I haven't stared at
the posted code, so I don't know what the problem is.

	For the sake of completeness, Intuition is a totally different
animal.  Intuition is not an I/O driver, it's a sort of application.
You don't send requests (messages) to Intuition, Intuition sends messages to
YOU.  That's why, when you get an IntuiMessage, you should reply it as soon
as you can (after you've copied all the relevant data into private
variables).

	Hope this helps.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 ________		 ___			Leo L. Schwab
	   \		/___--__		The Guy in The Cape
  ___  ___ /\		    ---##\		ihnp4!ptsfa!well!ewhac
      /   X  \_____    |  __ _---))			..or..
     /   /_\--    -----+==____\ // \  _		well ---\
___ (   o---+------------------O/   \/ \	dual ----> !unicom!ewhac
     \     /		    ___ \_  (`o )	hplabs -/       ("AE-wack")
 ____ \___/			     \_/
	      Recumbent Bikes:			"Work FOR?  I don't work FOR
	    The _O_n_l_y Way To Fly!		anybody!  I'm just having fun."

ewhac@well.UUCP (03/01/87)

In article <3757@sdcc3.ucsd.EDU> ee173way@sdcc3.ucsd.edu.UUCP (John Schultz) writes:
>
>  Don't even waste your time with the RKM version.  I have written a
>video arcade-style game using *totally* my own routines.  I even
>access port 0 with Intuition hooked up! What is the trick? It is so
>simple, you probably won't believe it.
>  Just READ THE HARDWARE!

(-:	You work for EA, don't you?  This must be why their stuff is so  :-)
(-:	flakey.								 :-)

	NO NO NO NO NO NO NO NO NO NO!!!!!!!!!!!!!!!!!!!!  DON'T READ THE
HARDWARE DIRECTLY!  USE THE I/O INTERFACE.  IT'S THERE FOR A REASON.

>I wrote my code in Modula-2 and it only took about half a page.
		    ^^^^^^^^
	Ah, that explains it. :-)
>
>  This version is tons faster, much smaller, and less problematic.
						  ^^^^^^^^^^^^^^^^
	Oh really?  What are you going to do when the new chips come out?
Recompile?  I hope this program isn't selling commercially, or you're going
to have a lot of irate users on your hands.

	The I/O interface is there for a reason.  It was designed openly so
that, when new hardware was inevitably developed, all the old stuff that
followed the rules would STILL WORK.

	Following the rules means using the I/O system.  It may be a little
slower, but it's infinitely more portable.  I haven't run tests, but I would
guess that using the IOF_QUICK flag and BeginIO() would probably afford
enough speed.

>If you wish to do the same for a mouse version, you'll have to write
>the necessary code to support it (motion x,y,vel).

	Or, better still, use the I/O system.  All the mouse translation
code has already been written.

	Does everyone see the point of this message?  Does anyone disagree?

>   Good Luck,
>    
>            John
>            7OHN

	This should not be taken as a slight upon you, John, but there are
expedient and correct ways of going about things.  On a C-64, your method
would be perfectly acceptable.  But not so on the Amiga.

	Hope I haven't made any enemies.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 ________		 ___			Leo L. Schwab
	   \		/___--__		The Guy in The Cape
  ___  ___ /\		    ---##\		ihnp4!ptsfa!well!ewhac
      /   X  \_____    |  __ _---))			..or..
     /   /_\--    -----+==____\ // \  _		well ---\
___ (   o---+------------------O/   \/ \	dual ----> !unicom!ewhac
     \     /		    ___ \_  (`o )	hplabs -/       ("AE-wack")
 ____ \___/			     \_/
	      Recumbent Bikes:			"Work FOR?  I don't work FOR
	    The _O_n_l_y Way To Fly!		anybody!  I'm just having fun."

ee173way@sdcc3.UUCP (03/03/87)

  Well, Leo, I understand your point, but do you really think that
they are going to change all of the addresses with the new machines?
I'll bet my *compiler* won't even generate code properly (judging
from how long it takes for them to deliver their upgrades (Modula-2)).
So how do you access port 0? If you do as shown in the RKM- Kaboom.
Of course one could always patch in ahead of input events (which I
may have to do to maintain machine compatibility).  I'll have to
experiment further...But for the average hack, what does it matter
to have fun reading the hardware?

  John
  7OHN

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (03/06/87)

In article <3771@sdcc3.ucsd.EDU> ee173way@sdcc3.ucsd.edu.UUCP (John Schultz) writes:
>
>  Well, Leo, I understand your point, but do you really think that
>they are going to change all of the addresses with the new machines?

	You don't know if they will or they won't.  But they will alter the
OS to make it invisible to programs that follow the rules.

>I'll bet my *compiler* won't even generate code properly (judging
>from how long it takes for them to deliver their upgrades (Modula-2)).
>So how do you access port 0? If you do as shown in the RKM- Kaboom.
>Of course one could always patch in ahead of input events (which I
>may have to do to maintain machine compatibility).

	This is one of the few fundamental design flaws of Intuition,
namely, that you can't make it go away and give back control of gameport 0
and sprite 0.  Yes, the official way is to patch in ahead of Intuition and
snarf all the InputEvents.  Personally, I just use gameport 1, which is tons
easier to attach to.

>I'll have to
>experiment further...But for the average hack, what does it matter
>				  ^^^^^^^^^^^^
>to have fun reading the hardware?
>
	Yes, personal private hacking is fine.  But if you're creating code
that is to be redistributed in any form, you really should follow the rules.
When I write a new display hack for public consumption, I try to follow all
the rules, and where things get iffy, I try to document what I'm up to so
that, if it breaks later on, you know where to look.  That's how I feel
about it.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 ________		 ___			Leo L. Schwab
	   \		/___--__		The Guy in The Cape
  ___  ___ /\		    ---##\		ihnp4!ptsfa!well!ewhac
      /   X  \_____    |  __ _---))			..or..
     /   /_\--    -----+==____\ // \  _		well ---\
___ (   o---+------------------O/   \/ \	dual ----> !unicom!ewhac
     \     /		    ___ \_  (`o )	hplabs -/       ("AE-wack")
 ____ \___/			     \_/
	      Recumbent Bikes:			"Work FOR?  I don't work FOR
	    The _O_n_l_y Way To Fly!		anybody!  I'm just having fun."

ee173way@sdcc3.ucsd.EDU (John Schultz) (03/09/87)

  While casually looking over the memory map diagram of the Amiga, I
realized that if they change the layout of the custom chips
(starting at $DFF000), *everything* is going to get changed
(obviously), hardware auto-config, 8520's, etc. Therefore, I am
going to leave my joystick routine as-is.  If new machines come out
that have new, incompatible hardware to the A1000, these machines
will most certainly have more goodies to take advantage of, so a new
version would be a must anyway. The A2000 is harware compatible
(custom chip adress-wise), and new machines are while away, so...

  By the way, the new TDI Modula-2 compiler finally arrived. Takes
full advantage of 1.2.  But it has one minor bug, it blows up after
a successful compile of my final Module, while writing out the .lnk
file.  See, my compiler won't even work on the current machines
hardware (8^& ...

  Worse comes to worse I'll finish it in their earlier compiler,
unless they get their latest bugs exterminated. What a bummer. All
that money, all that wait, for what...


  John
  7OHN

michael@stb.UUCP (03/28/87)

(I tried mailing this, but it bounced)
Please, do change that joystick routine. What do you mean, it would have to
be completely new hardware to change? Do you work with my proportional
joystick? How about the upside-down mouse (analog trackball?) And what if
I want to use my 5-line auto-fire program (to save thumb presses)?
 
(ok, its more than 5 lines. Includes, data structures, etc. But the meat
is only 5-10 lines or so).

Please, Please do it right. Set an example for EA to follow.

-- 
: Michael Gersten		ihnp4!hermix!ucla-an!remsit!stb!michael
:				sdcrdcf!trwrb!ucla-an!remsit!stb!michael
: Sealed with a curse \ As sharp as a knife
: Doomed is your sole \ And dammed is your wife.