REM >ReadJoy
DIM Code 2048
FOR pass=0 TO 2 STEP2
P%=Code:[OPT pass

;*** THIS JOYSTICK  CODE DOES  REQUIRE THE JOYSTICK    ***
;*** ULE  BE ǔED IN DER  IT  WORK.             ***

;*** THIS  SECTION  CODE IS  CHECKING THAT THE       ***
;*** JOYSTICK BOARD IS PRESENT - NO LANATION  THE CODE   ***
;*** IS GIVEN AS IT WOULD REQUIRE AN UNDERSTANDING  THE     ***
;*** MC6854 (ECONET CONTROLLER CHIP). THIS ROUTINE LEAVES A   ***
;*** BYTE UE IN 'RESULT' THAT HAS 3 POSSIBLE SETTINGS-     ***
;***     0 = RTFM JOYSTICK ERFACE                          ***
;***   128 = ACORN ECONET BOARD                               ***
;***   255 = HING                                          ***
;*** THE JOYSTICK DO  HAVE  BE CENTERD ETC..  FIND OUT ***
;***  THE BOARD IS FITTED, THE CODE ALLOWS  JOYSTICK     ***
;*** MENT DURING BOARD CHECKING.                          ***
;***                                                          ***
;*** THIS ROUTINE MUST BE ED (LY CE) BEFORE YOU TRY   ***
;***  USE THE  JOYSTICK ֈ                          ***

.BoardAddr EQUD &33A0000:.CheckPort
SWI "OS_EnterOS":LDR R10,BoardAddr:MOV R0,#&F8:STRB R0,[R10,#0]
MOV R0,#&7F:STRB R0,[R10,#4]:LDRB R1,[R10,#0]:TST R1,#&ED:BNE NoEconet
MOV R0,#&7F:STRB R0,[R10,#4]:LDRB R2,[R10,#4]:TST R2,#&DB:BNE NoEconet
MOV R0,#0:STR R0,[R10,#12]:LDRB R0,[R10,#0]:LDRB R1,[R10,#4]
TEQ R0,R1:BNE Econet:LDRB R1,[R10,#8]:TEQ R0,R1:BNE Econet
LDRB R1,[R10,#12]:TEQ R0,R1:BNE Econet:TEQ R0,#0:BNE NoEconet
MOV R0,#&82:STRB R0,[R10,#0]:MOV R0,#&E5:STRB R0,[R10,#4]:MOV R0,#&1000
.loop SUBS R0,R0,#1:BNE loop:LDRB R1,[R10,#0]:TST R1,#&ED:BNE Econet
LDRB R2,[R10,#4]:TST R0,#&DB:BEQ NoEconet
.Econet MOV R0,#128:B finished:.NoEconet
LDR R0,[R10,#4]:AND R0,R0,#&0C:CMP R0,#&C:MOVEQ R0,#255:BEQ finished
LDR R0,[R10,#4]:AND R0,R0,#&03:CMP R0,#&3:MOVEQ R0,#255:BEQ finished
LDR R0,[R10,#8]:AND R0,R0,#&C0:CMP R0,#&C0:MOVEQ R0,#255:BEQ finished
LDR R0,[R10,#8]:AND R0,R0,#&28:CMP R0,#&28:MOVEQ R0,#255:BEQ finished
MOV R8,#10:MOV R9,#255
.mainloop MOV R0,#30:.loop1 MOV R1,#&1000
LDRB R2,[R10,#4]:AND R2,R2,#&0F:LDRB R5,[R10,#8]:AND R5,R5,#&E8
.loop2 LDRB R3,[R10,#4]:AND R3,R3,#&0F:LDRB R6,[R10,#8]:AND R6,R6,#&E8
CMP R3,R2:BNE fail:CMP R5,R6:BNE fail:SUBS R1,R1,#1:BNE loop2
MOV R0,#0:B next:.fail SUBS R0,R0,#1:BNE loop1:MOV R0,#255
.next CMP R0,#0:MOVEQ R9,#0:MOVEQ R8,#1:SUBS R8,R8,#1:BNE mainloop
MOV R0,R9:.finished STRB R0,result:TEQP PC,#0:MOVNV R0,R0:MOV PC,R14
.result EQUB 255:ALIGN

;*** CODE   UES FROM THE JOYTSICK BOARD ( FITTED)  ***


.ReadPorts LDRB R0,result     ; Check result of test routine
           CMP  R0,#0
           MOVNE R0,#0        ; If board not present then return
           STRNEB R0,port1    ; from routine, setting directions
           STRNEB R0,port2    ; etc. to zero.
           MOVNE PC,R14
           SWI "OS_EnterOS"   ; Enter supervisor mode
           LDR R0,BoardAddr   ; Get the address of the joystick board
           LDRB R1,[R0,#4]    ; Read from port 1
           AND R1,R1,#&1F     ; Mask out redundant bits
           STRB R1,port1      ; Store the result
           LDRB R0,[R0,#8]    ; Read from port 2
           MOV R1,R0,LSR#4    ; }
           BIC R1,R1,#1       ; } Shuffle the bits so as they are
           TST R0,#&10        ; } in the same order as for port 1
           ORRNE R1,R1,#&10   ; }
           TST R0,#&08        ; }   (%FUDLR)
           ORRNE R1,R1,#&01   ; }
           STRB R1,port2      ; Store the result
           TEQP PC,#0         ; Return to user mode
           MOVNV R0,R0        ; Delay to allow ARM to change modes
           MOV PC,R14         ; Exit routine

.port1     EQUB 0
.port2     EQUB 0:ALIGN
]:NEXT
CALL CheckPort
PRINT"Contents of Econet port : ";
IF ?result=255 THEN PRINT"Empty":END
IF ?result=128 THEN PRINT"Acorn Econet Board":END
IF ?result=0   THEN PRINT"RTFM Joystick Interface"

fire=16:up=8:down=4:left=2:right=1
REM Values are returned as %xxxFUDLR
REM AND the contents of ?Port1 etc.. with the above 5 variables
REM to find out if that action is requested
REM E.g. IF (?Port1 AND fire)>0 THEN The fire button is pressed
REM      on joystick 1.

PRINT TAB(0,3);"Joystick 1 : FUDLR"
PRINT TAB(0,6);"Joystick 2 : FUDLR"
REPEAT:CALL ReadPorts
PRINT TAB(13,4);FNbin(?port1)
PRINT TAB(13,7);FNbin(?port2)
UNTIL0

DEF FNbin(a%)
a$=""
IF (a% AND &10)>0 THEN a$=a$+"*" ELSE a$=a$+" "
IF (a% AND &08)>0 THEN a$=a$+"*" ELSE a$=a$+" "
IF (a% AND &04)>0 THEN a$=a$+"*" ELSE a$=a$+" "
IF (a% AND &02)>0 THEN a$=a$+"*" ELSE a$=a$+" "
IF (a% AND &01)>0 THEN a$=a$+"*" ELSE a$=a$+" "
=a$
