 REM >"AcornTest"

 REM This program displays the state of a specified joystick using
 REM the 'Joystick_Read' SWI conforming to an Acorn standard.

 ON ERROR REPORT : PRINT " at line ";ERL : END

 REM Set up the screen
 MODE 13
 @% = &50A : REM was 506  2 (fixed decimals) 04 (places) 08 (field width)

 PRINT "Joystick status read using standard Acorn SWI 'Joystick_Read'..."

 REM Test the first stick only
 stick%=0

 PRINT "Please enter the stick number (0 is the first)"
 REPEAT
   stick% = GET
 UNTIL stick%>=48 AND stick%<=57

 stick% = stick% - 48
 PRINT "Using stick ";stick%

 code16% = 1
 stickandcode16% = (stick% AND &FF) OR ((code16% AND &FF) << 8)
 stickandcode8% = (stick% AND &FF)

 VDU 28,0,31,79,4

 REM Read the initial state of the joystick
 SYS &43F40,stickandcode8% TO prev_status8%
 SYS &43F40,stickandcode16% TO prev_status16%,prev_b16%

 loops%=0
 REPEAT
   IF loops%=0 OR loops%>20 THEN
     loops%=0
     PRINT
     PRINT ',"     ", "8-bit"," "," "," "," "," "," ","16-bit"
     PRINT "Stick", "X-axis","Y-axis","Btns","Left","Right","Down","Up","X-axis","Y-axis","Btns","Left","Right","Down","Up"
     PRINT "     ", "-l +r ","-d +u "," "," "," "," "," ","0l +r","0d +u"
   ENDIF

   REM Read the current state of the joystick
   SYS &43F40,stickandcode8% TO status8%
   SYS &43F40,stickandcode16% TO status16%,b16%

   WAIT

   IF loops% = 0 OR prev_status8% <> status8% OR prev_status16% <> status16% OR prev_b16% <> b16% THEN

     REM Extract each field from the status word. ( The x,y values may
     REM range from +127 to -128 because the joystick may be analogue
     REM or digital. The rest position is defined as the range from
     REM +32 to -32, digital joystick interfaces will generate values
     REM of +64, 0 and -64. There may be up to 8 fire buttons ! )

     x8% = ((status8% AND &FF00) << 16) >> 24
     y8% = ((status8% AND &FF) << 24) >> 24
     b8% = ((status8% AND &FF0000) >> 16)

     l8% = (x8% <= -64)
     r8% = (x8% >= +64)
     d8% = (y8% <= -64)
     u8% = (y8% >= +64)

     x16% = ((status16% AND &FFFF0000) >>> 16)
     y16% = (status16% AND &FFFF)
     b16% = (b16% AND &FF)

     l16% = (x16% <= 24576)
     r16% = (x16% >= 40960)
     d16% = (y16% <= 24576)
     u16% = (y16% >= 40960)

     REM Print everything out
     PRINT ;stick%,;x8%,;y8%,;FNbin(b8%),;l8%,;r8%,;d8%,;u8%,;x16%,;y16%,;FNbin(b16%),;l16%,;r16%,;d16%,;u16%
     loops% = loops% + 1

   ENDIF

   prev_status8% = status8%
   prev_status16% = status16%
   prev_b16% = b16%

 UNTIL FALSE

 END

 DEF FNbin(b%)
   LOCAL b$
   b$=""
   FOR i%=7 TO 0 STEP -1
     IF ((b%>>i%) AND 1) THEN
       b$ = b$ + "1"
     ELSE
       b$ = b$ + "-"
     ENDIF
     REM b$ = b$ + STR$((b%>>i%) AND 1)
   NEXT i%
 =b$

