Newsgroups: comp.sys.apple2.programmer Path: news.uiowa.edu!uunet!usc!elroy.jpl.nasa.gov!decwrl!waikato!comp.vuw.ac.nz!actrix.gen.nz!dempson From: dempson@atlantis.actrix.gen.nz (David Empson) Subject: Re: Joystick and stuff Message-ID: Sender: news@actrix.gen.nz (News Administrator) Organization: Actrix Information Exchange Date: Thu, 16 Mar 1995 15:02:06 GMT References: X-Nntp-Posting-Host: atlantis.actrix.gen.nz Lines: 138 In article , Stephen Carpenter wrote: > I am on a GS and was wondering how I can read the Joystick > I am using Orca/c (if that helps any) It certainly affects how you will go about reading the joystick. There is no firmware or toolbox support provided for reading the joystick from GS/OS. Apart from writing your own assembly language code to read it, the easiest way is to use the FWEntry tool call in the Miscellaneous toolset to call the old PREAD routine in the monitor. This will allow one axis of the joystick to be read. You can then call it again with different parameters to read the other axis. Note: you have to ensure each axis has timed out before trying to read it. If you try to read the X and Y values immediately after each other, you will probably get a false reading on the second one. A delay of at least three milliseconds is recommended. One commonly used solution is to separate the reading of the X and Y values and do several other operations between them. Reading the buttons is easier: it is just a matter of reading the appropriate I/O locations directly. Now for the details: First, a very major warning: the FWEntry toolbox call has been implemented incorrectly in all versions of ORCA/C: its parameters are in a different order than they are listed in the toolbox reference. Even worse, the parameter order varies depending on which compiler version you have (all of them are wrong). The official definition of FWEntry is: regs = FWEntry(aReg, xReg, yReg, entryPt); With ORCA/C 1.0 to 2.0.0, you must reverse the parameters: regs = FWEntry(entryPt, yReg, xReg, aReg); With ORCA/C 2.0.1 to 2.0.3, you must swap the first and last parameters: regs = FWEntry(entryPt, xReg, yReg, aReg); This will probably be fixed in a future version of the compiler (it is actually a bug in the library code), so the correct parameter order will be used (a, x, y, entryPt). [Yes, Mike does know about this one.] If you change compiler versions, make sure you check your FWEntry calls are correct for the new version. Having got that out of the way, here is the code required to read either axis of the joystick from ORCA/C. I've used inline assembly language to read I/O ports directly, to avoid possible hickups with ORCA/C reading the following byte as well. #include /* Set the FWENTRY_BUG macro according to the compiler version you are using: 1 ORCA/C 1.x, or ORCA/C 2.0.0 2 ORCA/C 2.0.1 through 2.0.3, or future versions that still have the same bug. 0 Future versions of ORCA/C that have the bug fixed. */ #define FWENTRY_BUG 2 /* I'm assuming ORCA/C 2.0.1 to 2.0.3 */ #define PRead 0xFB1E /* Paddle read routine entry point */ Word read_paddle(Word n) { /* Get the current reading from a paddle. Paddle 0 is the joystick X axis, paddle 1 is the joystick Y axis. If a second joystick is connected, it corresponds to paddles 2 (X) and 3 (Y). */ FWRec regs; #if FWENTRY_BUG == 2 regs = FWEntry(PRead, n, 0, 0); #elif FWENTRY_BUG == 1 regs = FWEntry(PRead, 0, n, 0); #else regs = FWEntry(0, n, 0, PRead); #endif return regs.yRegExit & 0xFF; } Boolean test_paddle(Word n) { /* Test if a paddle has timed out since the last read. This routine can be used to check whether it is safe to call read_paddle again. The return value is TRUE if the specified paddle has timed out and can be read again, FALSE if it is still timing out (this may indicate that the paddle/joystick has not been connected if it continues long enough). */ Byte paddle_flag; asm { sep #0x30 lda n and #0x03 tax lda 0xE0C064,x and #0x80 sta paddle_flag rep #0x30 } return (paddle_flag != 0); } Boolean read_button(Word n) { /* Read the state of the specified paddle/joystick button. The return value will be TRUE if the button is on, FALSE if the button is off. This routine supports buttons 0, 1, 2, and 3. Button 3 is only available on the IIgs, and only on the internal 16-pin game port. Note: holding down the Apple key will make button 0 appear to be on; similarly, the Option key will make button 1 appear to be on. */ Byte button_state; asm { sep #0x30 lda n inc a and #0x03 tax lda 0xE0C060,x and #0x80 sta button_state rep #0x30 } return (button_state != 0); } -- David Empson dempson@actrix.gen.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand