***************************
* JAGUAR POWERPAD HANDLER *
** FOR ATARI STE/FALCON ***
**** CODED BY MR. PINK ****
* (C) 1995 RESERVOIR GODS *
***************************

; The routines to read powerpads A and B are separate.
; Each updates two variables, a directional byte and a key word.
; The directional byte contains information about the directions being
; pressed and the state of the fire buttons.
; The key word contains info about all the numeric keypad buttons
; and Pause and Option buttons.

; NOTE: You must be in supervisor mode to call these routines!
; You must either call them every vertical blank or put them on the vbl.

; DIRECTIONAL BYTE FORMAT
; -------------------
; Bit | Powerpad key
; ------------------
;  0  | Up
;  1  | Down
;  2  | Left
;  3  | Right
;  4  | (not used)
;  5  | Fire C
;  6  | Fire B
;  7  | Fire A

; KEY WORD FORMAT
; --------------
; Bit | Powerpad Key
; --------------
;  0  | *
;  1  | 7
;  2  | 4
;  3  | 1
;  4  | 0
;  5  | 8
;  6  | 5
;  7  | 2
;  8  | #
;  9  | 9
; 10  | 6
; 11  | 3
; 12  | Option
; 13  | Pause

read_powerpad_a:
	lea	$ffff9200.w,a0	;extended port address (read only)
	lea	2(a0),a1	;extended port address (read/write)
	moveq	#0,d2		;clear d2 - it will contain key information
	move.w	#$fffe,(a1)	;write mask
	move.w	(a1),d0		;read directional data
	move.w	(a0),d3		;read fire_a/pause data
	not.w	d0		;invert bits (0->1)
	move.w	d0,d1		;save directional data
	lsr.w	#8,d1		;shift into low bits (0-3)
	and.w	#%1111,d1	;mask off unwanted data
	lsr.w	d3		;check bit 0 (pause data)
	bcs.s	no_pause_a	;if set, pause is not pressed
	bset	#13,d2		;pause is pressed so set pause bit
no_pause_a:
	lsr.w	d3		;check bit 1 (fire a data)
	bcs.s	no_firea_a	;if set, fire is not pressed
	bset	#7,d1		;fire_a is pressed, so set fire_a bit
no_firea_a:
	move.w	#$fffd,(a1)	;write mask
	move.w	(a1),d0		;read key data
	move.w	(a0),d3		;read fire data
	not.w	d0		;invert bits (0->1)
	btst	#1,d3		;check fire_b
	bne.s	no_fireb_a	;if set, fire_b is not pressed
	bset	#6,d1		;fire_b is pressed, set relevant bit
no_fireb_a:
	lsr.w	#8,d0		;shift key data into bits 0-3
	and.w	#%1111,d0	;mask off unwanted data
	or.w	d0,d2		;store in key word

	move.w	#$fffb,(a1)	;write mask
	move.w	(a1),d0		;read key data
	move.w	(a0),d3		;read fire data
	not.w	d0		;invert bits (0->1)
	btst	#1,d3		;check for fire_c
	bne.s	no_firec_a	;if set, fire_c is not pressed
	bset	#5,d1		;fire_c is pressed, set relevant bit
no_firec_a:
	lsr.w	#4,d0		;shift key data into bits 4-7
	and.w	#%11110000,d0	;mask off unwanted data
	or.w	d0,d2		;store in key word

	move.w	#$fff7,(a1)	;write mask
	move.w	(a1),d0		;read key data
	move.w	(a0),d3		;read fire data
	not.w	d0		;invert bits (0->1)
	btst	#1,d3		;check for option
	bne.s	no_option_a	;if set, option is not pressed
	bset	#12,d2		;set option bit
no_option_a:
	and.w	#%111100000000,d0	;mask off unwanted bits
	or.w	d0,d2		;store key data
	move.b	d1,jp1_dir	;save directional+fire data in variable
	move.w	d2,jp1_key	;save key data in variable
	rts

read_powerpad_b:
	lea	$ffff9200.w,a0	;extended port address (read only)
	lea	2(a0),a1	;extended port address (read/write)
	moveq	#0,d2		;clear d2 - it will contain key information
	move.w	#$ffef,(a1)	;write mask
	move.w	(a1),d0		;read directional data
	move.w	(a0),d3		;read fire_a/pause data
	not.w	d0		;invert bits (0->1)
	move.w	d0,d1		;save directional data
	lsr.w	#8,d1		;shift directional data down
	lsr.w	#4,d1		;shift into low bits (0-3)
	and.w	#%1111,d1	;mask off unwanted data
	btst	#2,d3		;check bit 2 (pause data)
	bne.s	no_pause_b	;if set, pause is not pressed
	bset	#13,d2		;pause is pressed so set pause bit
no_pause_b:
	btst	#3,d3		;check bit 3 (fire a data)
	bne.s	no_firea_b	;if set, fire is not pressed
	bset	#7,d1		;fire_a is pressed, so set fire_a bit
no_firea_b:
	move.w	#$ffdf,(a1)	;write mask
	move.w	(a1),d0		;read key data
	move.w	(a0),d3		;read fire data
	not.w	d0		;invert bits (0->1)
	btst	#3,d3		;check fire_b
	bne.s	no_fireb_b	;if set, fire_b is not pressed
	bset	#6,d1		;fire_b is pressed, set relevant bit
no_fireb_b:	
	lsr.w	#8,d0
	lsr.w	#4,d0		;shift key data into bits 0-3
	and.w	#%1111,d0	;mask off unwanted data
	or.w	d0,d2		;store in key word

	move.w	#$ffbf,(a1)	;write mask
	move.w	(a1),d0		;read key data
	move.w	(a0),d3		;read fire data
	not.w	d0		;invert bits (0->1)
	btst	#3,d3		;check for fire_c
	bne.s	no_firec_b	;if set, fire_c is not pressed
	bset	#5,d1		;fire_c is pressed, set relevant bit
no_firec_b:		
	lsr.w	#8,d0		;shift key data into bits 4-7
	and.w	#%11110000,d0	;mask off unwanted data
	or.w	d0,d2		;store in key word

	move.w	#$ff7f,(a1)	;write mask
	move.w	(a1),d0		;read key data
	move.w	(a0),d3		;read fire data
	not.w	d0		;invert bits (0->1)
	btst	#3,d3		;check for option
	bne.s	no_option_b	;if set, option is not pressed
	bset	#12,d2		;set option bit
no_option_b:
	lsr.w	#4,d0		;shift key data into bits 8-11
	and.w	#%111100000000,d0	;mask off unwanted bits
	or.w	d0,d2		;store key data
	move.b	d1,jp2_dir	;save directional+fire data in variable
	move.w	d2,jp2_key	;save key data in variable
	rts

jp1_dir:	ds.b	1
jp2_dir:	ds.b	1
jp1_key:	ds.w	1
jp2_key:	ds.w	1


