
;/* Extended Joystick Reader
  * ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
  * The example provides you with a working test of the routine, this type of
  * routine is needed for games because they often need more information than
  * just Left/Right/Up/Down/Fire, they need up/left, down/left, etc.etc. and
  * if a fire button has been pressed ONCE, not the state of the fire button
  * i.e. trigger actions,etc. The provided routine works with both joysticks
  * and should need no changes for virtually any time of game.
  * 
  * 2-Cool/Ex-Scene ... Sort of :)
  *
  */

_ciaa		=	$bfe001
_custom		=	$dff000
vhposr		=	$0006
joy0dat		=	$000A
joy1dat		=	$000C
color00		=	$0180

testloop:	cmp.b	#255,_custom+vhposr	* wait vblank..
		bne.s	testloop

		lea	joy1(pc),a0		* joystick switch memory..
		moveq	#1,d1			* joystick port 1
		bsr	_LVOExtReadJoy

		tst.w	joy_oneshotfdn(a0)	* fire button triggered once?
		beq.w	no_hit

		move.w	#$f00,_custom+color00	* flash screen red
no_hit:

		btst	#6,_ciaa		* loop condition: Exit on LMB
		bne.s	testloop
		rts

*******************************************************************************
* _LVOExtReadJoy				All Trashed Registers Preserved
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Performs extensive state anaysis of the Amiga intenal joystick port hardware
* to determine 16 different state flags. Code is completely pc-relative and 
* fully relocatable.
*
* $Inputs:	a0.l = joystick switch buffer (buffer size is = joy_SIZEOF)
*		d1.l = 0 for reading of Joystick connected to Port [0] 
*		       1 for reading of Joystick connected to Port [1]
*
* $Outputs:	None. (simply test switch settings returned in switch buffer)
*******************************************************************************
		rsreset
joy_left1:	rs.b	1		* \  (used to test if already pressed)
joy_right1:	rs.b	1		*  \   tempory storage of joystick
joy_up1:	rs.b	1		*   \   switches for all L,R,U,D,F
joy_down1:	rs.b	1		*    \
joy_fire1:	rs.b	1		*     \

joy_left:	rs.b	1		* Joystick Left
joy_right:	rs.b	1		* Joystick Right
joy_up:		rs.b	1		* Joystick Up
joy_down:	rs.b	1		* Joystick Down
joy_fire:	rs.b	1		* Joystick Fire

joy_upright:	rs.b	1		* Joystick Up/Right
joy_upleft:	rs.b	1		* Joystick Up/Left
joy_downright:	rs.b	1		* Joystick Down/Right
joy_downleft:	rs.b	1		* Joystick Down/Left

joy_oneshotlft	rs.b	1		* Joystick Left  (Oneshot:Auto-Toggled)
joy_oneshotrht	rs.b	1		* Joystick Right (Oneshot:Auto-Toggled)
joy_oneshotup	rs.b	1		* Joystick Up    (Oneshot:Auto-Toggled)
joy_oneshotdwn	rs.b	1		* Joystick Down  (Oneshot:Auto-Toggled)

joy_oneshotfdn	rs.w	1		* Joystick Fire  (Oneshot:Set Pressed)
joy_oneshotfup	rs.w	1		* Joystick Fire  (Oneshot:After Toggle)
joy_direction:	rs.w	1		* Joystick Direction (values)

joy_SIZEOF	rs.b	0		* calculate buffer size requirements
		rsreset

_LVOExtReadJoy:	movem.l	d0-d2,-(sp)		* stack trashed registers

		move.w	_custom+joy0dat,d0	* joystick 0
		moveq	#6,d2			* joystick 0 fire button bit
		tst.b	d1			* read which joystick?
		beq.s	readjoy0
		move.w	_custom+joy1dat,d0	* joystick 1 switches
		moveq	#7,d2			* joystick 1 fire button bit

readjoy0:	btst	#1,d0			* joystick left pressed?
		sne	joy_right(a0)
		btst	#9,d0			* joystick right pressed?
		sne	joy_left(a0)

		move.w	d0,d1
		lsr.w	#1,d1
		eor.w	d1,d0
		btst	#0,d0			* joystick down pressed?
		sne	joy_down(a0)
		btst	#8,d0			* joystick up pressed?
		sne	joy_up(a0)

		btst	d2,_ciaa
		seq	joy_fire(a0)		* joystick fire button pressed?

		move.b	joy_up(a0),d0
		and.b	joy_right(a0),d0
		move.b	d0,joy_upright(a0)	* joystick up/right pressed?

		move.b	joy_down(a0),d0
		and.b	joy_right(a0),d0
		move.b	d0,joy_downright(a0)	* joystick down/right pressed?

		move.b	joy_down(a0),d0
		and.b	joy_left(a0),d0
		move.b	d0,joy_downleft(a0)	* joystick down/left pressed?

		move.b	joy_up(a0),d0
		and.b	joy_left(a0),d0
		move.b	d0,joy_upleft(a0)	* joystick up/left pressed?

		tst.b	joy_fire1(a0)		* tempfire clear?
		beq.b	joyset1_2

		clr.b	joy_oneshotfdn(a0)
		tst.b	joy_fire(a0)
		beq.b	joyset1_1

		tst.w	joy_oneshotfup(a0)
		beq.b	joyset1_3

		subq.w	#1,joy_oneshotfup(a0)
		bra.b	joyset1_3

joyset1_1:	clr.b	joy_fire1(a0)
		neg.w	joy_oneshotfup(a0)
		bra.b	joyset1_3

joyset1_2:	tst.b	joy_fire(a0)		* if fire clear
		sne	joy_oneshotfdn(a0)	* Do OneShot Fire down
		sne	joy_fire1(a0)		* if tempfire clear
		beq.b	joyset1_3		* skip oneshot set...

		move.w	#-1,joy_oneshotfup(a0)	* first time fire pressed

joyset1_3:	tst.b	joy_left1(a0)
		beq.b	joyset1_4

		clr.b	joy_oneshotlft(a0)
		tst.b	joy_left(a0)
		bne.b	joyset1_5

		clr.b	joy_left1(a0)

joyset1_4:	tst.b	joy_left(a0)
		sne	joy_oneshotlft(a0)
		sne	joy_left1(a0)

joyset1_5:	tst.b	joy_right1(a0)
		beq.b	joyset1_6

		clr.b	joy_oneshotrht(a0)
		tst.b	joy_right(a0)
		bne.b	joyset1_7

		clr.b	joy_right1(a0)

joyset1_6:	tst.b	joy_right(a0)
		sne	joy_oneshotrht(a0)
		sne	joy_right1(a0)

joyset1_7:	tst.b	joy_up1(a0)
		beq.b	joyset1_8

		clr.b	joy_oneshotup(a0)
		tst.b	joy_up(a0)
		bne.b	joyset1_9

		clr.b	joy_up1(a0)

joyset1_8:	tst.b	joy_up(a0)
		sne	joy_oneshotup(a0)
		sne	joy_up1(a0)

joyset1_9:	tst.b	joy_down1(a0)
		beq.b	joyset1_10

		clr.b	joy_oneshotdwn(a0)
		tst.b	joy_down(a0)
		bne.b	joyset1_11

		clr.b	joy_down1(a0)

joyset1_10:	tst.b	joy_down(a0)
		sne	joy_oneshotdwn(a0)
		sne	joy_down1(a0)

joyset1_11:	moveq	#1,d0
		tst.b	joy_upright(a0)
		bne.b	joy_done

		moveq	#3,d0
		tst.b	joy_downright(a0)
		bne.b	joy_done

		moveq	#5,d0
		tst.b	joy_downleft(a0)
		bne.b	joy_done

		moveq	#7,d0
		tst.b	joy_upleft(a0)
		bne.b	joy_done

		moveq	#0,d0
		tst.b	joy_up(a0)
		bne.b	joy_done

		moveq	#2,d0
		tst.b	joy_right(a0)
		bne.b	joy_done

		moveq	#4,d0
		tst.b	joy_down(a0)
		bne.b	joy_done

		moveq	#6,d0
		tst.b	joy_left(a0)
		bne.b	joy_done

		moveq	#-1,d0
joy_done:	move.w	d0,joy_direction(a0)

		movem.l	(sp)+,d0-d2		* restore stacked registers
		rts

*-------------- joystick buttons/flags..

joy1:		ds.b	joy_SIZEOF		* Buffer for joystick switches
joy2:		ds.b	joy_SIZEOF		*


		end

