home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!pipex!warwick!uknet!pyrltd!mwuk!tony
- From: tony@microware.co.uk (Tony Mountifield)
- Newsgroups: comp.sys.atari.st
- Subject: Re: Accessing joystick from 'C'
- Message-ID: <1292@mwuk.UUCP>
- Date: 19 Nov 92 13:10:23 GMT
- References: <1992Nov18.093245.8277@ccsun.strath.ac.uk>
- Organization: Microware Systems (UK) Ltd., Winchester, UK.
- Lines: 207
-
- In article <1992Nov18.093245.8277@ccsun.strath.ac.uk> cabp09@ccsun.strath.ac.uk ("David McNicol") writes:
- >
- > Hi there,
- > Does ANYONE out there know how to read the joystick ports
- > of an atari ST in C/Assembly ?? I presume there must be tonnes of
- > people out there.
-
- I never saw it properly documented, so about 4 years ago, using
- information from the old Abacus/DataBecker internals book, I set about
- investigating the Keyboard vector routines, using a packet handler which
- I could patch into the vectors I wanted to investigate. The C program I
- used is given below. As written, it hooks into the status and joystick
- vectors. For just the joystick information, it is not necessary to use
- the status vector. Obviously, the program could be cut dow to just bare
- bones for joystick handling, but I thought the complete thing might be
- of interest.
-
- It was compiled using Lattice C 3.0.4. UBYTE is just a typedef of
- unsigned char. You won't need <portab.h> if you define this by hand.
- cprintf() is just printf() directly to the console. The include file
- <fctype.h> is just a variant of <ctype.h>, which itself would do fine.
-
- It should be compiled to a .TOS executable.
-
- ------------------------------------------------------------------------
- #include <portab.h>
- #include <osbind.h>
- #include <fctype.h>
-
- typedef struct {
- void (*midivec)();
- void (*vkbderr)();
- void (*vmiderr)();
- void (*statvec)();
- void (*mousevec)();
- void (*clockvec)();
- void (*joyvec)();
- void (*midisys)();
- void (*ikbdsys)();
- } KBVEC;
-
- UBYTE joy0,joy1;
- UBYTE list[10];
- int got=FALSE;
-
- void dopkt(packet)
- UBYTE packet[];
- {
- register int i;
-
- for(i=0;i<10;i++)
- list[i]=packet[i];
- got=TRUE;
-
- if (packet[0]>=0xFE) {
- joy0=packet[1];
- joy1=packet[2];
- }
- }
-
- void main()
- {
- KBVEC *p,save;
- UBYTE old0,old1;
- char buf[128];
- int cmd;
- char c;
-
- p = (KBVEC *)Kbdvbase();
- save.joyvec = p->joyvec;
- p->joyvec = dopkt;
- save.statvec = p->statvec;
- p->statvec = dopkt;
-
- Ikbdws(0,"\x12"); /* Turn mouse off */
-
- old0=old1=0xFF;
- cmd = 0;
-
- for(;;) {
-
- if (Cconis()) {
- c=toupper((short)Crawcin());
- if (c=='\x03') {
- Ikbdws(0,"\x08"); /* Restore mouse operation */
- p->joyvec = save.joyvec;
- p->statvec = save.statvec;
- Pterm0();
- }
- else if (c=='\r') {
- buf[0]=cmd;
- Ikbdws(0,buf);
- cmd = 0;
- }
- else if (c>='0' && c<='9') {
- cmd = ((cmd & 0xF) << 4) | (c-'0');
- cprintf("cmd = %X\r\n",cmd);
- }
- else if (c>='A' && c<='F') {
- cmd = ((cmd & 0xF) << 4) | (c-'A'+10);
- cprintf("cmd = %X\r\n",cmd);
- }
- }
-
- if (got) {
- cprintf("Packet = %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
- list[0],list[1],list[2],list[3],list[4],
- list[5],list[6],list[7],list[8],list[9]);
- got=FALSE;
- }
-
- if (old0 != joy0) {
- old0 = joy0;
- cprintf("Joy0 = %02X\r\n",old0);
- }
-
- if (old1 != joy1) {
- old1 = joy1;
- cprintf("Joy1 = %02X\r\n",old1);
- }
- }
- }
- ------------------------------------------------------------------------
-
- Armed with the information gleaned by this program, it was possible to
- write assembler routines to setup, use and unsetup the joystick. JOYINI
- and JOYEND should be callable from ASM or C, and the global variables
- JOY0 and JOY1 will be updated automatically whenever a joystick state
- changes.
-
- I can't remember what bit means what, but that is easily determined by
- trial and error.
-
- ------------------------------------------------------------------------
- ;
- JOYINI MOVEM.L A0-A1/D0,-(SP) ; Save registers
- MOVE.W #34,-(SP) ; Kbdvbase()
- TRAP #14 ; Xbios
- LEA 2(SP),SP ; Better than ADDQ, as it
- ; doesn't set any flags.
- ; Now D0 points to the table of longword vectors. The
- ; joystick vector is at offset 24 from this.
- ;
- MOVEA.L D0,A0 ; Must be in an addr reg
- MOVE.L A0,ADRSAV ; Save table address
- MOVE.L 24(A0),JOYSAV ; Save current joy value
- LEA OURJOY(PC),A1 ; Position independent
- MOVE.L A1,24(A0) ; Point vector to our code
- PEA MOUSOF(PC) ; Command to turn off mouse
- MOVE.W #MOUSOFL-1,-(SP) ; Length-1
- MOVE.W #25,-(SP) ; Ikbdws()
- TRAP #14 ; Xbios
- LEA 8(SP),SP ; Tidy stack
- MOVEM.L (SP)+,A0-A1/D0 ; Restore registers
- RTS
- ;
- JOYEND MOVEM.L A0,-(SP) ; Save registers
- MOVEA.L ADRSAV,A0 ; Point to table
- MOVE.L JOYSAV,24(A0) ; Restore old value
- PEA MOUSON(PC) ; Command to restore mouse
- MOVE.W #MOUSONL-1,-(SP) ; Length-1
- MOVE.W #25,-(SP) ; Ikbdws()
- TRAP #14 ; Xbios
- LEA 8(SP),SP ; Tidy stack
- MOVEM.L (SP)+,A0 ; Restore registers
- RTS
- ;
- MOUSOF DC.B $12
- MOUSOFL EQU *-MOUSOF
- MOUSON DC.B $08
- MOUSONL EQU *-MOUSON
- ;
- ; This next is our joystick interrupt routine. We may use
- ; registers A0-A2 and D0-D2 without having to save them.
- ;
- OURJOY MOVEA.L 4(SP),A0 ; Pointer to packet
- CMPI.B #$FE,(A0) ; Joystick packet?
- BLO.S NOJOY ; Ignore if not
- YESJOY MOVE.B 1(A0),JOY0 ; Copy joystick 0.
- MOVE.B 2(A0),JOY1 ; Copy joystick 1.
- NOJOY RTS
- ;
- DATA
- ;
- BSS
- ;
- ADRSAV DS.L 1 ; 4 bytes for table addr
- JOYSAV DS.L 1 ; 4 bytes for old vector
- JOY0 DS.B 1 ; Joystick 0 state.
- JOY1 DS.B 1 ; Joystick 1 state.
- ;
- END
- ------------------------------------------------------------------------
-
- Hope this is of help to people. Please feel free to add the contents of
- this article to any FAQs, etc.
-
- Tony
-
- --
- Tony Mountifield (G4CJO) | Microware Systems (UK) Ltd.
- -----------------------------------| Leylands Farm, Nobs Crook,
- Email: tony@microware.co.uk | Colden Common, WINCHESTER, SO21 1TH.
- (or: ...!uknet!mwuk!tony) | Tel: 0703 601990 Fax: 0703 601991
- ------------------------------------------------------------------------
- ** Any opinions are mine, not Microware's - but you knew that anyway. **
- ------------------------------------------------------------------------
-