home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / sys / atari / st / 16852 < prev    next >
Encoding:
Text File  |  1992-11-19  |  7.0 KB  |  218 lines

  1. Path: sparky!uunet!pipex!warwick!uknet!pyrltd!mwuk!tony
  2. From: tony@microware.co.uk (Tony Mountifield)
  3. Newsgroups: comp.sys.atari.st
  4. Subject: Re: Accessing joystick from 'C'
  5. Message-ID: <1292@mwuk.UUCP>
  6. Date: 19 Nov 92 13:10:23 GMT
  7. References: <1992Nov18.093245.8277@ccsun.strath.ac.uk>
  8. Organization: Microware Systems (UK) Ltd., Winchester, UK.
  9. Lines: 207
  10.  
  11. In article <1992Nov18.093245.8277@ccsun.strath.ac.uk> cabp09@ccsun.strath.ac.uk ("David McNicol") writes:
  12. > Hi there,
  13. >      Does ANYONE out there know how to read the joystick ports
  14. > of an atari ST in C/Assembly ?? I presume there must be tonnes of
  15. > people out there.
  16.  
  17. I never saw it properly documented, so about 4 years ago, using
  18. information from the old Abacus/DataBecker internals book, I set about
  19. investigating the Keyboard vector routines, using a packet handler which
  20. I could patch into the vectors I wanted to investigate. The C program I
  21. used is given below. As written, it hooks into the status and joystick
  22. vectors. For just the joystick information, it is not necessary to use
  23. the status vector. Obviously, the program could be cut dow to just bare
  24. bones for joystick handling, but I thought the complete thing might be
  25. of interest.
  26.  
  27. It was compiled using Lattice C 3.0.4.  UBYTE is just a typedef of
  28. unsigned char.  You won't need <portab.h> if you define this by hand. 
  29. cprintf() is just printf() directly to the console. The include file
  30. <fctype.h> is just a variant of <ctype.h>, which itself would do fine.
  31.  
  32. It should be compiled to a .TOS executable.
  33.  
  34. ------------------------------------------------------------------------
  35. #include <portab.h>
  36. #include <osbind.h>
  37. #include <fctype.h>
  38.  
  39. typedef struct {
  40.    void (*midivec)();
  41.    void (*vkbderr)();
  42.    void (*vmiderr)();
  43.    void (*statvec)();
  44.    void (*mousevec)();
  45.    void (*clockvec)();
  46.    void (*joyvec)();
  47.    void (*midisys)();
  48.    void (*ikbdsys)();
  49. }  KBVEC;
  50.  
  51. UBYTE joy0,joy1;
  52. UBYTE list[10];
  53. int got=FALSE;
  54.  
  55. void dopkt(packet)
  56. UBYTE packet[];
  57. {
  58.    register int i;
  59.  
  60.    for(i=0;i<10;i++)
  61.       list[i]=packet[i];
  62.    got=TRUE;
  63.  
  64.    if (packet[0]>=0xFE) {
  65.       joy0=packet[1];
  66.       joy1=packet[2];
  67.    }
  68. }
  69.  
  70. void main()
  71. {
  72.    KBVEC *p,save;
  73.    UBYTE old0,old1;
  74.    char buf[128];
  75.    int cmd;
  76.    char c;
  77.  
  78.    p = (KBVEC *)Kbdvbase();
  79.    save.joyvec = p->joyvec;
  80.    p->joyvec = dopkt;
  81.    save.statvec = p->statvec;
  82.    p->statvec = dopkt;
  83.  
  84.    Ikbdws(0,"\x12");                   /* Turn mouse off */
  85.  
  86.    old0=old1=0xFF;
  87.    cmd = 0;
  88.  
  89.    for(;;) {
  90.  
  91.       if (Cconis()) {
  92.          c=toupper((short)Crawcin());
  93.          if (c=='\x03') {
  94.             Ikbdws(0,"\x08");          /* Restore mouse operation */
  95.             p->joyvec = save.joyvec;
  96.             p->statvec = save.statvec;
  97.             Pterm0();
  98.          }
  99.          else if (c=='\r') {
  100.             buf[0]=cmd;
  101.             Ikbdws(0,buf);
  102.             cmd = 0;
  103.          }
  104.          else if (c>='0' && c<='9') {
  105.             cmd = ((cmd & 0xF) << 4) | (c-'0');
  106.             cprintf("cmd = %X\r\n",cmd);
  107.          }
  108.          else if (c>='A' && c<='F') {
  109.             cmd = ((cmd & 0xF) << 4) | (c-'A'+10);
  110.             cprintf("cmd = %X\r\n",cmd);
  111.          }
  112.       }
  113.  
  114.       if (got) {
  115.          cprintf("Packet = %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
  116.                   list[0],list[1],list[2],list[3],list[4],
  117.                   list[5],list[6],list[7],list[8],list[9]);
  118.          got=FALSE;
  119.       }
  120.  
  121.       if (old0 != joy0) {
  122.          old0 = joy0;
  123.          cprintf("Joy0 = %02X\r\n",old0);
  124.       }
  125.  
  126.       if (old1 != joy1) {
  127.          old1 = joy1;
  128.          cprintf("Joy1 = %02X\r\n",old1);
  129.       }
  130.    }
  131. }
  132. ------------------------------------------------------------------------
  133.  
  134. Armed with the information gleaned by this program, it was possible to
  135. write assembler routines to setup, use and unsetup the joystick. JOYINI
  136. and JOYEND should be callable from ASM or C, and the global variables
  137. JOY0 and JOY1 will be updated automatically whenever a joystick state
  138. changes.
  139.  
  140. I can't remember what bit means what, but that is easily determined by
  141. trial and error.
  142.  
  143. ------------------------------------------------------------------------
  144. ;
  145. JOYINI  MOVEM.L A0-A1/D0,-(SP)          ; Save registers
  146.         MOVE.W  #34,-(SP)               ; Kbdvbase()
  147.         TRAP    #14                     ; Xbios
  148.         LEA     2(SP),SP                ; Better than ADDQ, as it
  149.                                         ; doesn't set any flags.
  150. ;       Now D0 points to the table of longword vectors. The
  151. ;       joystick vector is at offset 24 from this.
  152. ;
  153.         MOVEA.L D0,A0                   ; Must be in an addr reg
  154.         MOVE.L  A0,ADRSAV               ; Save table address
  155.         MOVE.L  24(A0),JOYSAV           ; Save current joy value
  156.         LEA     OURJOY(PC),A1           ; Position independent
  157.         MOVE.L  A1,24(A0)               ; Point vector to our code
  158.         PEA     MOUSOF(PC)              ; Command to turn off mouse
  159.         MOVE.W  #MOUSOFL-1,-(SP)        ; Length-1
  160.         MOVE.W  #25,-(SP)               ; Ikbdws()
  161.         TRAP    #14                     ; Xbios
  162.         LEA     8(SP),SP                ; Tidy stack
  163.         MOVEM.L (SP)+,A0-A1/D0          ; Restore registers
  164.         RTS
  165. ;
  166. JOYEND  MOVEM.L A0,-(SP)                ; Save registers
  167.         MOVEA.L ADRSAV,A0               ; Point to table
  168.         MOVE.L  JOYSAV,24(A0)           ; Restore old value
  169.         PEA     MOUSON(PC)              ; Command to restore mouse
  170.         MOVE.W  #MOUSONL-1,-(SP)        ; Length-1
  171.         MOVE.W  #25,-(SP)               ; Ikbdws()
  172.         TRAP    #14                     ; Xbios
  173.         LEA     8(SP),SP                ; Tidy stack
  174.         MOVEM.L (SP)+,A0                ; Restore registers
  175.         RTS
  176. ;
  177. MOUSOF  DC.B    $12
  178. MOUSOFL EQU     *-MOUSOF
  179. MOUSON  DC.B    $08
  180. MOUSONL EQU     *-MOUSON
  181. ;
  182. ;       This next is our joystick interrupt routine. We may use
  183. ;       registers A0-A2 and D0-D2 without having to save them.
  184. ;
  185. OURJOY  MOVEA.L 4(SP),A0                ; Pointer to packet
  186.         CMPI.B  #$FE,(A0)               ; Joystick packet?
  187.         BLO.S   NOJOY                   ; Ignore if not
  188. YESJOY  MOVE.B  1(A0),JOY0              ; Copy joystick 0.
  189.         MOVE.B  2(A0),JOY1              ; Copy joystick 1.
  190. NOJOY   RTS
  191. ;
  192.         DATA
  193. ;
  194.         BSS
  195. ;
  196. ADRSAV  DS.L    1                       ; 4 bytes for table addr
  197. JOYSAV  DS.L    1                       ; 4 bytes for old vector
  198. JOY0    DS.B    1                       ; Joystick 0 state.
  199. JOY1    DS.B    1                       ; Joystick 1 state.
  200. ;
  201.         END
  202. ------------------------------------------------------------------------
  203.  
  204. Hope this is of help to people. Please feel free to add the contents of
  205. this article to any FAQs, etc.
  206.  
  207. Tony
  208.  
  209. -- 
  210. Tony Mountifield     (G4CJO)       | Microware Systems (UK) Ltd.
  211. -----------------------------------| Leylands Farm, Nobs Crook,
  212. Email:  tony@microware.co.uk       | Colden Common, WINCHESTER, SO21 1TH.
  213. (or:  ...!uknet!mwuk!tony)         | Tel: 0703 601990   Fax: 0703 601991
  214. ------------------------------------------------------------------------
  215. ** Any opinions are mine, not Microware's - but you knew that anyway. **
  216. ------------------------------------------------------------------------
  217.