;
;SEGA SATURN PAD -> MSX converter  Ver 1.10
;1999/08/31 TOMO
;

;RA0	O	SS-SEL0
;RA1	O	SS-SEL1
;RA2	O	SPEAKER
;RA3	O	MSX-TRIGGER B
;RA4	O	MSX-TRIGGER A
;RB0~3	O	MSX-STICK
;RB4~7	I	SS-DATA0~3

;	SS KeyData (0:Push)
;	ofs	b4 b5 b6 b7
;---------------------------
;	+0	Z  Y  Z  RB
;	+1	B  C  A  ST
;	+2	U  D  L  R
;	+3	x  x  x  LB


	include	"P16F84.inc"

W_TEMP		equ	0ch		;W Register Temp
ST_TEMP		equ	0dh		;STATUS Register Temp

MSX_KEY		equ	0eh		;MSX-Pad Trigger+Stick data
SS_KEY		equ	0fh		;SS-Pad KeyData (4 bytes)

BUZZ_SW		equ	13h		;
BUZZ_FREQ	equ	14h		;
BUZZ_SPEED	equ	15h		;
BUZZ_CNT	equ	16h

EE_DATA_SIZE	equ	17h
LR_KEY_FLAG	equ	18h
SHOT_FLAG	equ	19h

KC_COUNT	equ	1ah		;Key config mode counter
TRG_SPD_FLAG	equ	1bh

TEMP0		equ	21h
TEMP1		equ	22h
TEMP2		equ	23h
TEMP3		equ	24h

COUNT0		equ	25h
COUNT1		equ	26h
COUNT2		equ	27h

CONF_DATA	equ	27h
CONF_SIZE	equ	8
KEY_TABLE	equ	27h		;Key config data (6 bytes)
TRG_SPEED	equ	2dh		;Shot speed (0~3)
BUZZ_ENABLE	equ	2eh		;0:stop
DUMMY		equ	2fh

TRG_TEMP	equ	TEMP0
EE_SRAM_ADR	equ	FSR
EE_EEPROM_ADR	equ	EEADR


EE_LOAD	macro	s_addr,d_addr,data_size
	movlw	s_addr
	movwf	EE_EEPROM_ADR
	movlw	d_addr
	movwf	EE_SRAM_ADR
	movlw	data_size
	call	ee_load
	endm

EE_SAVE	macro	s_addr,d_addr,data_size
	movlw	s_addr
	movwf	EE_SRAM_ADR
	movlw	d_addr
	movwf	EE_EEPROM_ADR
	movlw	data_size
	call	ee_save
	endm


;===============================================

start:
	org	000h
	goto	main

	org	004h
	movwf	W_TEMP
	movf	STATUS,W
	movwf	ST_TEMP
;---
intsub:
	bcf	STATUS,RP0

	btfss	INTCON,T0IF
	goto	intskp0
					;TMR0 Int
	movf	BUZZ_FREQ,W
	movwf	TMR0

	movf	BUZZ_SW,W
	btfsc	STATUS,Z
	goto	int_jp1

	decf	BUZZ_CNT,F
	btfss	STATUS,Z
	goto	int_jp2
	movf	BUZZ_SPEED,W		;BUZZ_CNT = 0
	movwf	BUZZ_CNT
	decf	BUZZ_SW,F
int_jp2:
	btfsc	BUZZ_SW,0		;b0=0 then stop
	goto	buzz_ring
buzz_stop:
	bsf	PORTA,2
	goto	int_jp1

buzz_ring:
	movf	PORTA,W
	xorlw	b'00000100'
	movwf	PORTA
int_jp1:
	bcf	INTCON,T0IF
intskp0:
;---
	movf	ST_TEMP,W
	movwf	STATUS
	swapf	W_TEMP,F
	swapf	W_TEMP,W
	retfie

;===============================================

main:
	movlw	2
	call	delay

	clrf	KC_COUNT
	clrf	SHOT_FLAG
	clrf	LR_KEY_FLAG
	clrf	BUZZ_SW

	movlw	150
	movwf	BUZZ_SPEED
	movlw	0
	movwf	BUZZ_FREQ

	EE_LOAD	ee_data-ee_data,CONF_DATA,CONF_SIZE	;Load config data
	movf	TRG_SPEED,W
	movwf	TRG_SPD_FLAG

	bsf	STATUS,RP0
	movlw	b'00000000'		;RA0~4 = Output
	movwf	TRISA
	movlw	b'11110000'		;RB0~3 = Output , RB4~7 = Input
	movwf	TRISB
	bcf	OPTION_REG,NOT_RBPU	;RBx Pull-Up
	movlw	b'00000000'
	movwf	OPTION_REG
	clrf	INTCON
	bsf	INTCON,T0IE		;TMR0 Int Enable
	bsf	INTCON,GIE
	bcf	STATUS,RP0

	call	get_ss_key
	movf	SS_KEY+0,W		;RB button
	andwf	SS_KEY+3,W		;LB button
	andwf	SS_KEY+1,W		;START button
	andlw	b'10000000'
	btfss	STATUS,Z
	goto	skip_reset
	call	reset_config_table
	movlw	255
	movwf	LR_KEY_FLAG
	goto	mainloop
skip_reset:
	btfsc	SS_KEY+1,7		;START button
	goto	start_main
	comf	BUZZ_ENABLE,F
	EE_SAVE	BUZZ_ENABLE,ee_buzz-ee_data,1
start_main:
	movlw	2
	call	beep2
mainloop:
	call	get_ss_key
	call	conv_key
	call	set_msx_key
	call	change_trigger_speed

	movf	SS_KEY+1,W		;START button
	iorwf	SS_KEY+0,W		;R button
	iorwf	SS_KEY+3,W		;L button
	andlw	b'10000000'
	btfss	STATUS,Z		;ckeck ST+R+L
	clrf	KC_COUNT

	incf	KC_COUNT,F
	btfsc	STATUS,Z
	call	key_config_mode

	movf	TRG_SPEED,W
	andlw	3
	addlw	1
	addwf	SHOT_FLAG,F

	movf	TRG_SPEED,W
	xorwf	TRG_SPD_FLAG,W
	btfss	STATUS,Z
	call	save_trg_speed

	movlw	52
	call	wait2			;wait 1/60 sec

	bsf	STATUS,RP0
	btfss	EECON1,EEIF
	goto	jmp1
	bcf	EECON1,EEIF
	bcf	EECON1,WREN
jmp1:
	bcf	STATUS,RP0
	goto	mainloop


;===============================================

reset_config_table:
	movlw	b'0100'
	movwf	KEY_TABLE+0
	movlw	b'1000'
	movwf	KEY_TABLE+1
	movlw	b'0100'
	movwf	KEY_TABLE+2
	movlw	b'0010'
	movwf	KEY_TABLE+3
	movlw	b'0001'
	movwf	KEY_TABLE+4
	movlw	b'0001'
	movwf	KEY_TABLE+5

	movlw	02h
	movwf	TRG_SPEED
	movlw	0ffh
	movlw	BUZZ_ENABLE
	EE_SAVE	KEY_TABLE,ee_key-ee_data,6
	movlw	8
	call	beep
	return


save_trg_speed:
	bsf	STATUS,RP0
	btfss	EECON1,WR
	goto	sts_jmp0
	bcf	STATUS,RP0
	return
sts_jmp0:
	bcf	STATUS,RP0
	movlw	ee_spd-ee_data
	movwf	EEADR
	movf	TRG_SPEED,W
	call	ee_save2
	movf	TRG_SPEED,W
	movwf	TRG_SPD_FLAG
	return


key_config_mode:
	movlw	2
	call	beep
	clrf	KEY_TABLE+0
	clrf	KEY_TABLE+1
	clrf	KEY_TABLE+2
	clrf	KEY_TABLE+3
	clrf	KEY_TABLE+4
	clrf	KEY_TABLE+5
kcm_loop0:
	call	get_ss_key
	movf	SS_KEY+1,W		;START button
	andwf	SS_KEY+0,W		;RB button
	andwf	SS_KEY+3,W		;LB button
	andlw	b'10000000'
	btfsc	STATUS,Z
	goto	kcm_loop0
kcm_loop1:
	call	get_ss_key

	call	kcm_set_sub
	iorlw	0			;W=0 then skip
	btfsc	STATUS,Z
	goto	kcm_jmp0

	addlw	KEY_TABLE-1
	movwf	FSR

	movf	SS_KEY+2,W
	movwf	TEMP0			;SS_KEY -> TEMP0(0~3)
	swapf	TEMP0,W
	andlw	b'00001111'
	xorlw	b'00001111'
	btfss	STATUS,Z
	iorwf	INDF,F
kcm_jmp0:
	btfsc	SS_KEY+1,7		;START button
	goto	kcm_loop1

	EE_SAVE	KEY_TABLE,ee_key-ee_data,6
	movlw	2
	call	beep
	return


kcm_set_sub:
	btfss	SS_KEY+0,4
	retlw	1
	btfss	SS_KEY+0,5
	retlw	2
	btfss	SS_KEY+0,6
	retlw	3
	btfss	SS_KEY+1,4
	retlw	4
	btfss	SS_KEY+1,5
	retlw	5
	btfss	SS_KEY+1,6
	retlw	6
	retlw	0


change_trigger_speed:
	btfss	SS_KEY+1,7		;Check START
	return

	btfsc	SS_KEY+3,7		;Check LB
	goto	cts_jmp0
	btfsc	LR_KEY_FLAG,0
	return

	incf	TRG_SPEED,F
	bsf	LR_KEY_FLAG,0
	goto	cts_change_speed
cts_jmp0:
	bcf	LR_KEY_FLAG,0
	btfsc	SS_KEY+0,7		;Check RB
	goto	cts_jmp1
	btfsc	LR_KEY_FLAG,1
	return

	decf	TRG_SPEED,F
	bsf	LR_KEY_FLAG,1
cts_change_speed:
	movf	TRG_SPEED,W
	andlw	3
	movwf	TRG_SPEED
	call	beep2
	return
cts_jmp1:
	bcf	LR_KEY_FLAG,1
	return



beep2:
	btfss	BUZZ_ENABLE,0
	return
beep:
	movwf	TEMP0
	addwf	TEMP0,W
	addlw	1
	movwf	BUZZ_SW
	movf	BUZZ_SPEED,W
	movwf	BUZZ_CNT
	return


conv_key:
	clrf	TRG_TEMP
	movlw	KEY_TABLE
	movwf	FSR

	movlw	b'00010000'		;tenuki...
	andwf	SS_KEY+0,W
	call	ck_set_sub
	movlw	b'00100000'
	andwf	SS_KEY+0,W
	call	ck_set_sub
	movlw	b'01000000'
	andwf	SS_KEY+0,W
	call	ck_set_sub

	movlw	b'00010000'
	andwf	SS_KEY+1,W
	call	ck_set_sub
	movlw	b'00100000'
	andwf	SS_KEY+1,W
	call	ck_set_sub
	movlw	b'01000000'
	andwf	SS_KEY+1,W
	call	ck_set_sub

	btfss	SHOT_FLAG,2
	goto	ck_jmp0

	btfsc	TRG_TEMP,2		;RA button -> A button
	bsf	TRG_TEMP,0
	btfsc	TRG_TEMP,3		;RB button -> B button
	bsf	TRG_TEMP,1
ck_jmp0:
	rlf	TRG_TEMP,F
	rlf	TRG_TEMP,F
	rlf	TRG_TEMP,F
	rlf	TRG_TEMP,W

	xorlw	b'00110000'
	andlw	b'00110000'
	movwf	MSX_KEY

	swapf	SS_KEY+2,W		;Stick data
	andlw	b'00001111'
	iorwf	MSX_KEY,F
	return

ck_set_sub:
	btfss	STATUS,Z
	goto	sk_exit
	movf	INDF,W
	iorwf	TRG_TEMP,F
sk_exit:
	incf	FSR,F
	return


set_msx_key:
	movwf	PORTB			;MSX_KEY -> MSX
	rrf	MSX_KEY,W
	andlw	b'00011000'
	movwf	TEMP0

	bcf	INTCON,T0IE
	movf	PORTA,W
	andlw	b'11100111'
	iorwf	TEMP0,W
	movwf	PORTA
	bsf	INTCON,T0IE
	return


get_ss_key:
	movlw	4
	movwf	TEMP0
	movlw	SS_KEY+3
	movwf	FSR
gsk_loop:
	bcf	INTCON,T0IE
	movf	PORTA,W
	andlw	b'11111100'
	addwf	TEMP0,W
	addlw	-1
	movwf	PORTA
	bsf	INTCON,T0IE

	movlw	1000/12			;wait 100uS
	call	wait1

	movf	PORTB,W
	movwf	INDF
	decf	FSR,F
	decfsz	TEMP0,F
	goto	gsk_loop

	return


;===============================================

ee_load:
	movwf	EE_DATA_SIZE
	bcf	STATUS,RP0
eel_loop:
	bsf	STATUS,RP0
	bsf	EECON1,RD
	bcf	STATUS,RP0
	movf	EEDATA,W
	movwf	INDF
	incf	EEADR,F
	incf	FSR,F
	decfsz	EE_DATA_SIZE,F
	goto	eel_loop
	return


ee_save:
	movwf	EE_DATA_SIZE		;data size -> TEMP3
	bsf	STATUS,RP0
	bsf	EECON1,WREN		;EEPROM write enable
	bcf	STATUS,RP0
ees_loop1:
	movf	INDF,W
	movwf	EEDATA

	bsf	STATUS,RP0
	movlw	55h
	movwf	EECON2
	movlw	0aah
	movwf	EECON2
	bsf	EECON1,WR		;Write start
ees_loop2:
	btfss	EECON1,EEIF
	goto	ees_loop2
	bcf	EECON1,EEIF

	bcf	STATUS,RP0
	incf	FSR,F
	incf	EEADR,F

	decfsz	EE_DATA_SIZE,F
        goto	ees_loop1

	bsf	STATUS,RP0
	bcf	EECON1,WREN		;EEPROM write disable
	bcf	STATUS,RP0
	return


ee_load2:
	bsf	STATUS,RP0
	bsf	EECON1,RD
	bcf	STATUS,RP0
	movf	EEDATA,W
	return

ee_save2:
	movwf	EEDATA
	bsf	STATUS,RP0
	bsf	EECON1,WREN		;EEPROM write enable
	movlw	55h
	movwf	EECON2
	movlw	0aah
	movwf	EECON2
	bsf	EECON1,WR		;Write start
	bcf	STATUS,RP0
	return


;===============================================

;	10MHz = 0.4uS/state
;	total W*3+4 state
;	1.2*W+1.6 [uS]
wait1:
	movwf	COUNT0		;1
w1_lop:	decfsz	COUNT0,F	;1
	goto	w1_lop		;2
	return			;2


;	wait 300*W [uS]
wait2:
	movwf	COUNT0
w2_lop0:clrf	COUNT1
w2_lop1:decfsz	COUNT1,F
	goto	w2_lop1
	decfsz	COUNT0,F
	goto	w2_lop0
	return


delay:
	movwf	COUNT0
d_lop0:	clrf	COUNT1
d_lop1:	clrf	COUNT2
d_lop2:	decfsz	COUNT2,F
	goto	d_lop2
	decfsz	COUNT1,F
	goto	d_lop1
	decfsz	COUNT0,F
	goto	d_lop0
	return



	org	2100h


;	EEPROM data (8 bytes)
ee_data:

; Key config data
;		RB,RA,B,A (R:Rapid)
ee_key:	de	b'0100'		;Z
	de	b'1000'		;Y
	de	b'0100'		;X
	de	b'0010'		;B
	de	b'0001'		;C
	de	b'0001'		;A

ee_spd:	de	02h		;SHOT_SPEED
ee_buzz:de	0ffh		;buzzer enable

	end


