	GBLA	P_opt
P_opt	SETA	{OPT}		; Preserve Entry Listing Status
	OPT	2		; Force Listing Off
;
r0	RN	0		; RN directive: defines ARM register names
R0	RN	r0		; Note: register names can be defined from each other
r1	RN	1
R1	RN	r1
r2	RN	2
R2	RN	r2
r3	RN	3
R3	RN	r3
r4	RN	4
R4	RN	r4
r5	RN	5
R5	RN	r5
r6	RN	6
R6	RN	r6
r7	RN	7
R7	RN	r7
r8	RN	8
R8	RN	r8
r9	RN	9
R9	RN	r9
sl	RN	10
r10	RN	10
R10	RN	r10
fp	RN	11
r11	RN	11
R11	RN	r11
ip	RN	12
r12	RN	12
R12	RN	r12
sp	RN	13
r13	RN	13
R13	RN	r13
lr	RN	14
r14	RN	14
R14	RN	r14
pc	RN	15
PC	RN	15
r15	RN	15
R15	RN	r15
;
f0	FN	0		; FN directive: defines Floating Point register names
f1	FN	1
f2	FN	2
f3	FN	3
f4	FN	4
f5	FN	5
f6	FN	6
f7	FN	7
;
N_flag	EQU	1 << 31		; Processor Status_flag definitions
Z_flag	EQU	1 << 30
C_flag	EQU	1 << 29
V_flag	EQU	1 << 28
I_flag	EQU	1 << 27
F_flag	EQU	1 << 26
;
User_Mode	EQU	0	; Processor Mode definitions
FastIRQ_Mode	EQU	1
NormalIRQ_Mode	EQU	2
Supervisor_Mode	EQU	3
;
	GET	A_Headers:SWI_Names
	OPT	P_opt

Module_Start
	DCD	&00000000
	DCD	Init             - Module_Start
	DCD	Final            - Module_Start
	DCD	&00000000
	DCD	Title            - Module_Start
	DCD	Help             - Module_Start
	DCD	&00000000
	DCD	&00043F40		; Official Acorn Joystick SWI
	DCD	SwiCode          - Module_Start
	DCD	SwiDecodingTable - Module_Start
	DCD	&00000000
	DCD	&00000000
	DCD	&00000000


Title	=	"JoyA3010",0
Help	=	"JoyA3010",9,"3.10 (13 Apr 1993)  Mel Sutton",0
	ALIGN


	ROUT
SwiDecodingTable
	=	"Joystick",0
	=	"Read",0
	ALIGN


Hardware
	DCD	&33A0000


	ROUT
Init	STMFD	R13!,{R14}
	LDR	R0,[R12],#0
	CMP	R0,#0
	MOVNE	R12,R0
	BNE	%00
	MOV	R0,#6
	MOV	R3,#&14
	SWI	XOS_Module
	LDMVSFD	R13!,{PC}		; Exit, if workspace claim failed

	STR	R2,[R12],#0
	MOV	R12,R2
00	MOV	R0,#0
	STR	R0,[R12,#0]
	BL	I_rtfm			; Initialise RTFM interface
	CMP	R0,#0
	LDMEQFD	R13!,{PC}		; Exit, if initialised successfully

	ADR	R0,%01			; Err: Joystick hardware not present
	BL	Message
	BL	Final2
	CMP	PC,#&80000000
	LDMFD	R13!,{PC}
01
	DCD	&00043F40
	=	"NoHWare",0

	ROUT
Final	STMFD	R13!,{R14}
	LDR	R12,[R12],#0
	CMP	R12,#0
	LDMEQFD	R13!,{PC}^
	BL	Final2
	LDMFD	R13!,{PC}^

Final2	STMFD	R13!,{R0,R2,R14}
	LDR	R0,[R12,#0]
	TEQ	R0,#0
	ADDNE	R0,R12,#4
	SWINE	XMessageTrans_CloseFile
	MOV	R2,R12
	MOV	R0,#7
	SWI	XOS_Module
	LDMFD	R13!,{R0,R2,PC}


	ROUT
Message	STMFD	R13!,{R14}
	CMP	PC,#0
	LDR	R1,[R12,#0]
	TEQ	R1,#0
	BLEQ	%00
	LDMVSFD	R13!,{PC}
	ADD	R1,R12,#4
	MOV	R2,#0
	SWI	XMessageTrans_ErrorLookup
	LDMFD	R13!,{PC}

00	STMFD	R13!,{R0-R2,R14}
	ADD	R0,R12,#4
	ADR	R1,%01
	MOV	R2,#0
	SWI	XMessageTrans_OpenFile
	MVNVC	R0,#0
	STRVC	R0,[R12,#0]
	STRVS	R0,[R13],#0
	LDMFD	R13!,{R0-R2,PC}
01
	=	"Resources:$.Resources.Joystick.Messages",0
	DCD	&00006490


	ROUT
SwiCode	STMFD	R13!,{R1-R4,R14}
	LDR	R12,[R12],#0
	CMP	R11,#0
	ADRNE	R0,%02			; Err: Bad SWI
	ADRNE	R4,Title
	BLNE	Message
	LDMVSFD	R13!,{R1-R4,PC}

	LDR	R1,Hardware		; get Hardware address: {RTFM device}
	CMP	R0,#0			; read Joystick 0 request?
	BEQ	%00
	CMP	R0,#1			; read Joystick 1 request?
	MOVEQ	R0,#0
	BEQ	%01
	
	ADR	R0,%03			; Err: Joystick number out of range
	BL	Message
	LDMFD	R13!,{R1-R4,PC}

00	LDRB	R1,[R1,#4]		; Read RTFM port 0 status
	TST	R1,#2_00001000		; Up
	ORRNE	R0,R0,#&40
	TST	R1,#2_00000100		; Down
	ORRNE	R0,R0,#&C0
	TST	R1,#2_00000001		; Right
	ORRNE	R0,R0,#&4000
	TST	R1,#2_00000010		; Left
	ORRNE	R0,R0,#&C000
	TST	R1,#2_00010000
	ORRNE	R0,R0,#&10000		; fire
	LDMFD	R13!,{R1-R4,PC}

01	LDRB	R1,[R1,#8]		; Read RTFM port 1 status
	TST	R1,#2_10000000		; Up
	ORRNE	R0,R0,#&40
	TST	R1,#2_01000000		; Down
	ORRNE	R0,R0,#&C0
	TST	R1,#2_00001000		; Right
	ORRNE	R0,R0,#&4000
	TST	R1,#2_00100000		; Left
	ORRNE	R0,R0,#&C000
	TST	R1,#2_00010000
	ORRNE	R0,R0,#&10000		; fire
	LDMFD	R13!,{R1-R4,PC}
02
	DCD	&00000112
	=	"BadSWI",0
	ALIGN
03
	DCD	&00043F41
	=	"BadJoy",0
	ALIGN


	ROUT
I_rtfm	STMFD	R13!,{R1-R10,R14}	; Initialise RTFM interface..
	LDR	R10,Hardware		; Hardware address {of RTFM device}
	MOV	R0,#&F8
	STRB	R0,[R10,#0]
	MOV	R0,#&7F
	STRB	R0,[R10,#4]
	LDRB	R1,[R10,#0]
	TST	R1,#&ED
	BNE	%02

	MOV	R0,#&7F
	STRB	R0,[R10,#4]
	LDRB	R2,[R10,#4]
	TST	R2,#&DB
	BNE	%02

	MOV	R0,#0
	STR	R0,[R10,#12]
	LDRB	R0,[R10,#0]
	LDRB	R1,[R10,#4]
	TEQ	R0,R1
	BNE	%01

	LDRB	R1,[R10,#8]
	TEQ	R0,R1
	BNE	%01

	LDRB	R1,[R10,#12]
	TEQ	R0,R1
	BNE	%01
	TEQ	R0,#0
	BNE	%02

	MOV	R0,#&82
	STRB	R0,[R10,#0]
	MOV	R0,#&E5
	STRB	R0,[R10,#4]
	MOV	R0,#&1000
00	SUBS	R0,R0,#1
	BNE	%00
	LDRB	R1,[R10,#0]
	TST	R1,#&ED
	BNE	%01

	LDRB	R2,[R10,#4]
	TST	R0,#&DB
	BEQ	%02

01	MOV	R0,#128			; Econet is present
	B	%08

02	LDR	R0,[R10,#4]		; no Econet present
	AND	R0,R0,#&0C
	CMP	R0,#&C
	MOVEQ	R0,#255
	BEQ	%08

	LDR	R0,[R10,#4]
	AND	R0,R0,#&03
	CMP	R0,#&3
	MOVEQ	R0,#255
	BEQ	%08

	LDR	R0,[R10,#8]
	AND	R0,R0,#&C0
	CMP	R0,#&C0
	MOVEQ	R0,#255
	BEQ	%08

	LDR	R0,[R10,#8]
	AND	R0,R0,#&28
	CMP	R0,#&28
	MOVEQ	R0,#255
	BEQ	%08

	MOV	R8,#10
	MOV	R9,#255
03	MOV	R0,#30
04	MOV	R1,#&1000
	LDRB	R2,[R10,#4]
	AND	R2,R2,#&0F
	LDRB	R5,[R10,#8]
	AND	R5,R5,#&E8
05	LDRB	R3,[R10,#4]
	AND	R3,R3,#&0F
	LDRB	R6,[R10,#8]
	AND	R6,R6,#&E8
	CMP	R3,R2
	BNE	%06
	CMP	R5,R6
	BNE	%06
	SUBS	R1,R1,#1
	BNE	%05
	MOV	R0,#0
	B	%07

06	SUBS	R0,R0,#1
	BNE	%04
	MOV	R0,#255			; No RTFM hardware present

07	CMP	R0,#0
	MOVEQ	R9,#0
	MOVEQ	R8,#1
	SUBS	R8,R8,#1
	BNE	%03

	MOV	R0,R9
08	LDMFD	R13!,{R1-R10,PC}


	END
