;*======================================================================*
;*                TITLE:                  JOYSTICK.S                    *
;*                Function:               68000 joystick input routines *
;*                                                                      *
;*                Project #:              JAGUAR                        *
;*                Programmer:             Jerome Strach                 *
;*                                        Andrew J Burgess              *
;*                                                                      *
;*                Created:                12/14/92                      *
;*                                                                      *
;*              COPYRIGHT 1992 Atari Computer Corporation               *
;*          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
;*          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
;*        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
;*                            ALL RIGHTS RESERVED.                      *
;*                                                                      *
;*======================================================================*
;*
;* This file contains functions which setup the 'controller' input variables:
;*
;*       joy_old    - (necessary for creating joy_edge)
;*       joy_level  - reflects currently held down (level) joypad direction
;*       joy_edge   - reflects an 'edge' of a joypad direction (trigger)
;*
;*       fire_old   - (necessary for creating fire_edge)
;*       fire_level - reflects currently held down (level) fire buttons
;*       fire_edge  - reflects an 'edge' of a fire button (trigger)
;*
;*       key_old    - (necessary for creating key_edge)
;*       key_level  - reflects currently held down (level) keypad buttons
;*       key_edge   - reflects an 'edge' of a keypad button (trigger)
;*
;*======================================================================*

BASE	EQU	$00D00000		;* 68000 register base address
BAR_ON	EQU	0

	.include "jaguar.inc"
	.include "joydefs.inc"
	.include "defs.inc"

;*======================================================================*

	.globl	GetInput
	.globl	read_joypad
	.globl	read_firebuts
	.globl	read_keypad

	.globl	joy_level
	.globl	joy_edge
	.globl	fire_level
	.globl	fire_edge
	.globl	key_level
	.globl	key_edge

;*======================================================================*
;*	PROGRAM SEGMENT
;*======================================================================*

	.text

;*======================================================================*
;* GetInput() - read in the joystick inputs
;*======================================================================*

GetInput:

	;* read in the inputs
	TIMEBAR	RGB_WHITE
	jsr	read_joypad
	TIMEBAR	RGB_DKGREY
	jsr	read_firebuts
	TIMEBAR	RGB_LTGREY
	jsr	read_keypad
	TIMEBAR	RGB_VIOLET

	rts

;*======================================================================*
;* read_joypad() - read in the joypad portion of the input controller.
;*		   the variables joy_old, joy_level, and joy_edge are
;*		   set within this routine.
;*
;*	preserved:
;*		d0-d1
;*======================================================================*

read_joypad:

	movem.l	d0-d1,-(sp)		; save registers

	;* Player #1
	move.b	joy_level, joy_old	;* current now becomes old
	move.w	#$7ffe, JOYOUT		;* we want joypad input
	move.b	JOYIN, d0		;*	can result
	eor.b	#$FF, d0		;*	toggle all of the bits
	move.b	d0, joy_level		;* reflects current directions held
					;*	down by user - joy_level set
	move.b	joy_old, d1
	eor.b	d1, d0
	and.b	joy_level, d0
	move.b	d0, joy_edge		;* the 'edge' is now reflected in
					;*	joy_edge

	;*==============================================================*
.if	TWO_PLAYERS = YES
	; Player #2

	move.b	joy_level+1,joy_old+1	;* current now becomes old
	move.w	#$7f7f, JOYOUT		;* we want joypad input
	move.b	JOYIN, d0		;*	can result
	eor.b	#$FF, d0		;*	toggle all of the bits
	lsr.b	#4, d0			;* bring high nybble to low nybble
	move.b	d0, joy_level+1		;* reflects current directions held
					;*	down by user - joy_level set
	move.b	joy_old+1, d1
	eor.b	d1, d0
	and.b	joy_level+1, d0
	move.b	d0, joy_edge+1		;* the 'edge' is now reflected in
					;*	joy_edge
.endif	;* TWO_PLAYERS
	;*==============================================================*

	movem.l	(sp)+,d0-d1		; restore resgisters

	rts

;*======================================================================*
;* read_firebuts() - read in the fire button portion of the controller.
;*		   the variables fire_old, fire_level, and fire_edge are
;*		   set within this routine.
;*
;*	preserved:
;*		d0-d1
;*======================================================================*

read_firebuts:

	movem.l	d0-d1,-(sp)		; save registers

	move.l	#0,d0
	move.b	fire_level, fire_old	;* current now becomes old


	move.w	#$7ff7,JOYOUT		;* scan for Option
	move.b	JOYIN+3,d1
	and.w	#$2,d1
	bne		.10
	ori.w	#OPTION_BIT,d0		;* set Option bit if Option pressed

.10:
	move.w	#$7ffb,JOYOUT		;* scan for Fire C
	move.b	JOYIN+3,d1
	and.w	#$2,d1
	bne		.20
	ori.w	#FIRE_C_BIT,d0		;* set Fire C bit if Fire C pressed

.20:
	move.w	#$7ffd,JOYOUT		;* scan for Fire B
	move.b	JOYIN+3,d1
	and.w	#$2,d1
	bne		.30
	ori.w	#FIRE_B_BIT,d0		;* set Fire B bit if Fire B pressed

.30:
	move.w	#$7ffe,JOYOUT		;* scan for Fire A
	move.b	JOYIN+3,d1
	and.w	#$2,d1
	bne		.40
	ori.w	#FIRE_A_BIT,d0		;* set Fire A bit if Fire A pressed

.40:
	move.b	JOYIN+3,d1		;* scan for Pause
	and.w	#$1,d1
	bne		.50
	ori.w	#PAUSE_BIT,d0		;* set Pause bit if Pause pressed

.50:
	move.b	d0, fire_level		;* fire_level set - reflects current
					;*	fire buttons held down by user
	move.b	fire_old, d1
	eor.b	d1, d0
	and.b	fire_level, d0
	move.b	d0, fire_edge		;* the 'edge' is now reflected in fire_edge

	;*==============================================================*
.if	TWO_PLAYERS = YES

	move.l	#0,d0
	move.b	fire_level+1,fire_old+1	;* current now becomes old


	move.w	#$7fef,JOYOUT		;* scan for Option
	move.b	JOYIN+3,d1
	and.w	#$8,d1
	bne		.60
	ori.w	#OPTION_BIT,d0		;* set Option bit if Option pressed

.60:
	move.w	#$7fdf,JOYOUT		;* scan for Fire C
	move.b	JOYIN+3,d1
	and.w	#$8,d1
	bne		.70
	ori.w	#FIRE_C_BIT,d0		;* set Fire C bit if Fire C pressed

.70:
	move.w	#$7fbf,JOYOUT		;* scan for Fire B
	move.b	JOYIN+3,d1
	and.w	#$8,d1
	bne		.80
	ori.w	#FIRE_B_BIT,d0		;* set Fire B bit if Fire B pressed

.80:
	move.w	#$7f7f,JOYOUT		;* scan for Fire A
	move.b	JOYIN+3,d1
	and.w	#$8,d1
	bne		.90
	ori.w	#FIRE_A_BIT,d0		;* set Fire A bit if Fire A pressed

.90:
	move.b	JOYIN+3,d1		;* scan for Pause
	and.w	#$4,d1
	bne		.99
	ori.w	#PAUSE_BIT,d0		;* set Pause bit if Pause pressed

.99:
	move.b	d0, fire_level+1	;* fire_level set - reflects current
					;*	fire buttons held down by user
	move.b	fire_old+1, d1
	eor.b	d1, d0
	and.b	fire_level+1, d0
	move.b	d0, fire_edge+1		;* the 'edge' is now reflected in fire_edge

.endif	;* TWO_PLAYERS
	;*==============================================================*

	movem.l	(sp)+,d0-d1		; restore resgisters

	rts


;*======================================================================*
;* read_keypad() - read in the keypad button portion of the controller.
;*		   the variables key_old, key_level, and key_edge are
;*		   set within this routine.
;*
;*	preserved:
;*		d0-d3
;*======================================================================*

read_keypad:

	movem.l	d0-d3,-(sp)		; save registers

	move.w	key_level, key_old	;* current now becomes old
	move.l	#0, d0			;* initialize registers
	move.l	d0, d3

	;*==============================================================*
	;* This is the shifting algorithm for setting up d0 below.
	;*
	;* NOTE:	bits 0-3 => 0-3   (no shift)
	;*		bits 0-3 => 4-7   lsl.w   #4,d0
	;*		bits 0-3 => 8-11  lsl.w   #8,d0
	;*==============================================================*
;s741
	move.w	#$7ffd, JOYOUT		;* we want 1st column of keypad input
	move.b	JOYIN, d0		;*	matrix result
	eor.b	#$FF, d0		;*	toggle all of the bits - bit set means ON
	or.b	d0, d3			;*	set bits 0-3
;0852
	move.w	#$7ffb, JOYOUT		;* we want 1st column of keypad input
	move.b	JOYIN, d0		;*	matrix result
	eor.b	#$FF, d0		;*	toggle all of the bits - bit set means ON
	lsl.w	#4, d0
	or.b	d0, d3			;*	set bits 4-7
;h963
	move.w	#$7ff7, JOYOUT		;* we want 1st column of keypad input
	move.b	JOYIN, d0		;*	matrix result
	eor.b	#$FF, d0		;*	toggle all of the bits - bit set means ON
	lsl.w	#8, d0
	or.w	d0, d3			;*	set bits 8-11

	move.w	d3, key_level		;* reflects current directions held
					;*	down by user - key_level set
	move.w	key_old, d1
	eor.w	d1, d3
	and.w	key_level, d3
	move.w	d3, key_edge		;* the 'edge' is now reflected in key_edge

	;*==============================================================*
.if	TWO_PLAYERS = YES
	move.w	key_level+2, key_old+2	;* current now becomes old
	move.l	#0, d0			;*	initialize registers
	move.l	d0, d3

	;*==============================================================*
	;* This shifting algorithm for setting up d0 is different from above
	;* because we need to manipulate the upper nybble since JOYIN returns
	;* our result in the upper nybble.
	;*
	;* NOTE:	bits 4-7 => 0-3   lsr.b   #4,d0
	;*		bits 4-7 => 4-7   (no shift)
	;*		bits 4-7 => 8-11  lsl.w   #4,d0
	;*==============================================================*
;s741
	move.w	#$7fbf, JOYOUT		;* we want 1st column of keypad input
	move.b	JOYIN, d0		;*	matrix result
	eor.b	#$FF, d0		;*	toggle all of the bits - bit set means ON
	lsr.b	#4, d0			;* NOTE: dealing with high nybble
	or.b	d0, d3			;*	set bits 0-3
;0852
	move.w	#$7fdf, JOYOUT		;* we want 1st column of keypad input
	move.b	JOYIN, d0		;*	matrix result
	eor.b	#$FF, d0		;*	toggle all of the bits - bit set means ON
;	lsl.w	#4, d0			;* NOTE: dealing with high nybble
	or.b	d0, d3			;*	set bits 4-7
;h963
	move.w	#$7fef, JOYOUT		;we want 1st column of keypad input
	move.b	JOYIN, d0		;*	matrix result
	eor.b	#$FF, d0		;*	toggle all of the bits - bit set means ON
	lsl.w	#4, d0			;* NOTE: dealing with high nybble
	or.w	d0, d3			;*	set bits 8-11

	move.w	d3, key_level+2		;* reflects current directions held
					;*	down by user - key_level set
	move.w	key_old+2, d1
	eor.w	d1, d3
	and.w	key_level+2, d3
	move.w	d3, key_edge+2		;* the 'edge' is now reflected in key_edge

.endif	;* TWO_PLAYERS
	;*==============================================================*

	movem.l	(sp)+,d0-d3		; restore resgisters

	rts

;*======================================================================*
;*	CONTROLLER VARIABLES
;*======================================================================*

	.data

	.even

.if	TWO_PLAYERS = YES

joy_old:	dc.b	0,0
joy_level:	dc.b	0,0
joy_edge:	dc.b	0,0

fire_old:	dc.b	0,0
fire_level:	dc.b	0,0
fire_edge:	dc.b	0,0

key_old:	dc.w	0,0
key_level:	dc.w	0,0
key_edge:	dc.w	0,0

.else ; TWO_PLAYERS

joy_old:	dc.b	0
joy_level:	dc.b	0
joy_edge:	dc.b	0

fire_old:	dc.b 	0
fire_level:	dc.b 	0
fire_edge:	dc.b 	0

key_old:	dc.w 	0
key_level:	dc.w	0
key_edge:	dc.w 	0

.endif	; TWO_PLAYERS

;*======================================================================*
;*                      EOF
;*======================================================================*

