;----------------  RC用コンバットサウンド　Ver.1 --------------------
;受信機の信号で、コンバットサウンドと、それに合わせて、
;LEDを点灯させるプログラムです。
;
;-------　ジャンパ　スイッチ-------
;１．ショートの状態(2chプロポモード)
;　　1chと2chと両方入力して、2chがセンターの時だけ
;    1chのスティックを倒して音を出します。
;２．外した状態(4ch以上のプロポモード)
;　　1chのみ入力して、1chのスティックを倒して音を出します。
;
;----------設定モードについて------------------
;１．プロポのトリム・スティックをセンターに合わせて置いて設定ボタンを押します。
;２．基板の電源LEDが点滅します。
;３．基板の1chに繋いだスティックを左右どちらかに倒して、ボタンを押します。
;４．設定が記憶され、基板の電源LEDが点灯します。
;----------------------------------------------

;Ver1.0.0	2003.06.30	By T.HINOKI

		LIST		P=16C84,R=DEC
	PC	EQU	2
	STATUS	EQU	3
	PG	EQU	5
	PORTA	EQU	5
	PORTB	EQU	6
	EEDATA	EQU	8
	EEADR	EQU	9
	OPTION_REG	EQU	H'81'
	TRISA	EQU	H'85'
	TRISB	EQU	H'86'
	EECON1	EQU	H'88'
	EECON2	EQU	H'89'
	RD	EQU	0
	WR	EQU	1
	WREN	EQU	2
	COUNT1	EQU	H'10'
	COUNT2	EQU	H'11'
	PIN1	EQU	H'12'	;1ｃｈ入力パルス幅（左・右）
	PIN2	EQU	H'13'	;２ｃｈ入力パルス幅（前進・後進）
	CENTER1	EQU	H'14'	;1chセンター位置
	CENTER2	EQU	H'15'	;2chセンター位置
	CENTER3	EQU	H'16'	;1chスイッチONの位置
	SW1	EQU	H'17'	;大砲スイッチ位置
	SW2	EQU	H'18'	;機関銃スイッチ位置
	CENTER2A	EQU	H'19'	;2chセンター位置A
	CENTER2B	EQU	H'1A'	;2chセンター位置B

	KEISAN1	EQU	H'1B'	;計算用変数
	KEISAN2	EQU	H'1C'	;計算用変数
	KEISAN3	EQU	H'1D'	;計算用変数
	COUNT10	EQU	H'1E'	;長時間のウエイト用
	COUNT8	EQU	H'1F'	;機銃発光のタイミング
	COUNT4	EQU	H'20'	;大砲のタイミング
	COUNT9	EQU	H'21'	;
	PIN1B	EQU	H'22'	;1ｃｈ入力パルス幅チェック用
	PIN2B	EQU	H'23'	;２ｃｈ入力パルス幅チェック用
	COUNT3	EQU	H'24'	;設定用

	ORG	0
	GOTO	START
;=================================================================
START
	CLRF	PORTB		;クリア PORTB
	BSF	STATUS,PG	;Change Page1
	MOVLW	B'00001100'	;RB2とRB3のみ入力
	MOVWF	TRISB		;
	MOVLW	B'01110'	;RA0とRA4のみ出力
	MOVWF	TRISA		;RA2-3は入力
	BCF	STATUS,PG	;Change Page0

;--------------音・発光の初期値 ----------------
	BSF	PORTB,7		;音のスイッチ off
        MOVLW	B'10000'	;RA4のLEDをOFF・RA0のLEDをON
	MOVWF	PORTA		;
	BSF	PORTB,0		;RB0 LED off

	MOVLW	1		;発光のタイミング設定クリア
	MOVWF	COUNT8

	MOVLW	255		;大砲のタイミングをクリア
	MOVWF	COUNT4

;------------------ ＥＥＰＲＯＭ読込
        MOVLW	B'10001'	;RA4のLEDをOFF・RA0のLEDをOff
	MOVWF	PORTA		;

	MOVLW	0		;EPPROMの0番地（先頭）のＤＡＴＡを読む
	MOVWF	EEADR		;
	BSF	STATUS,PG	;Change Page1
	BSF	EECON1,RD	;読出し開始
	BCF	STATUS,PG	;Change Page0
	MOVF	EEDATA,0
	MOVWF	CENTER1		;CENTER1=W　1chサーボセンターの位置を取出し

	MOVLW	1		;EPPROMの1番地のＤＡＴＡを読む
	MOVWF	EEADR		;
	BSF	STATUS,PG	;Change Page1
	BSF	EECON1,RD	;読出し開始
	BCF	STATUS,PG	;Change Page0
	MOVF	EEDATA,0
	MOVWF	CENTER2		;CENTER2=W 2chサーボセンターの位置を取出し

	MOVLW	2		;EPPROMの2番地のＤＡＴＡを読む
	MOVWF	EEADR		;
	BSF	STATUS,PG	;Change Page1
	BSF	EECON1,RD	;読出し開始
	BCF	STATUS,PG	;Change Page0
	MOVF	EEDATA,0
	MOVWF	CENTER3		;CENTER3=W　スイッチONのスティック量

;-------ＲＯＭ値のチェック(CENTER1)
	MOVLW	170		;
	SUBWF	CENTER1,0	;
	BTFSC	STATUS,0	;(CY=1) CENTER1>=170はDATCHK01へ
	GOTO	DATCHK01	;
	MOVLW	130		;
	SUBWF	CENTER1,0	;
	BTFSS	STATUS,0	;(CY=0) CENTER1<130はDATCHK01へ
	GOTO	DATCHK01	;
	GOTO	DATCHK02
DATCHK01
	MOVLW	150		;センターを１５０に設定
	MOVWF	CENTER1
DATCHK02
;-------ＲＯＭ値のチェック(CENTER2)
	MOVLW	170		;
	SUBWF	CENTER2,0	;
	BTFSC	STATUS,0	;(CY=1) CENTER2>=170はDATCHK03へ
	GOTO	DATCHK03	;
	MOVLW	130		;
	SUBWF	CENTER2,0	;
	BTFSS	STATUS,0	;(CY=0) CENTER2<130はDATCHK03へ
	GOTO	DATCHK03	;
	GOTO	DATCHK04
DATCHK03
	MOVLW	150		;センターを１５０に設定
	MOVWF	CENTER2
DATCHK04

;-------ＲＯＭ値のチェック(CENTER3)
	MOVLW	80		;
	SUBWF	CENTER3,0	;
	BTFSC	STATUS,0	;(CY=1) CENTER3>=80はDATCHK05へ
	GOTO	DATCHK05	;
	MOVLW	10		;
	SUBWF	CENTER3,0	;
	BTFSS	STATUS,0	;(CY=0) CENTER3<10はDATCHK05へ
	GOTO	DATCHK05	;
	GOTO	DATCHK06
DATCHK05
	MOVLW	30		;３０に設定
	MOVWF	CENTER3
DATCHK06
        MOVLW	B'10000'	;RA4のLEDをOFF・RA0のLEDをON
	MOVWF	PORTA		;

;-------音のスイッチ位置の設定

	MOVF	CENTER3,0	;W=CENTER3
	ADDWF	CENTER1,0	;W=CENTER1+CENTER3
	MOVWF	SW1		;SW1=W

	MOVF	CENTER3,0	;W=CENTER3
	SUBWF	CENTER1,0	;W=CENTER1-CENTER3
	MOVWF	SW2		;SW2=W

;-------センター幅の設定
	MOVLW	2		;
	ADDWF	CENTER2,0	;W=CENTER2+2
	MOVWF	CENTER2A	;CENTER2A=W

	MOVLW	1		;
	SUBWF	CENTER2,0	;W=CENTER2-2
	MOVWF	CENTER2B	;CENTER2B=W

;-------------------メインルーチン -------------
LOOP1

	CALL	PULSIN1		;1chパルス幅取得
	BTFSS	PORTB,3		;OFF の時
	CALL	PULSIN2		;2chパルス幅取得

	BTFSS	PORTB,2		;設定スイッチ　OFF の時
	CALL	SETEI		;スティック設定モード



	BTFSC	PORTB,3		;ＯＮの時は、
	GOTO	LOOP10
;--------停止中のチェック
	MOVF	CENTER2A,0		;2chがCENTER2A以上は
	SUBWF	PIN2,0		;
	BTFSC	STATUS,0	;(CY=1) PIN2>=CENTER2AはLOOP100へ
	GOTO	LOOP100
	MOVF	CENTER2B,0		;2chがCENTER2B以下は
	SUBWF	PIN2,0		;
	BTFSS	STATUS,0	;(CY=0) PIN2<CENTER2BはLOOP100へ
	GOTO	LOOP100

LOOP10
;-----------------　音　---------------

	MOVF	SW1,0		;
	SUBWF	PIN1,0		;
	BTFSC	STATUS,0	;(CY=1) PIN1>=SW1はOTO10へ
	GOTO	OTO10		;

	MOVF	SW2,0		;
	SUBWF	PIN1,0		;
	BTFSS	STATUS,0	;(CY=0) PIN1<SW1はOTO20へ
	GOTO	OTO20		;

	BSF	PORTB,7		;音のＳＷ off
        MOVLW	B'10000'	;RA4のLEDをOFF
	MOVWF	PORTA		;制御実行
	BSF	PORTB,0		;LED OFF


	GOTO	LOOP100

;---------------- 機関銃音 ---------------
OTO10
        MOVLW	B'10000'	;RA4のLEDをOFF
	MOVWF	PORTA		;大砲 LED OFF

	BSF	STATUS,PG	;Change Page1
	BSF	TRISB,6		;RB6を入力に切替
	BCF	STATUS,PG	;Change Page0

	BCF	PORTB,7		;音のＳＷ on(機関銃音)

	DECFSZ	COUNT8,1	;COUNT8が0の時だけＬＥＤ点ける
	GOTO	OTO11
	BCF	PORTB,0		;LED on
	MOVLW	7		;発光のタイミング設定 1-10
	MOVWF	COUNT8

	CALL	PULSOFF		;発光の間隔の時間稼ぎ
	CALL	PULSOFF		;発光の間隔の時間稼ぎ
	CALL	PULSOFF		;発光の間隔の時間稼ぎ
	CALL	PULSOFF		;発光の間隔の時間稼ぎ

	GOTO	LOOP100		;

OTO11
	BSF	PORTB,0		;機関銃　LED OFF
	GOTO	LOOP100		;


;---------------- 大砲音 ---------------
OTO20

	BSF	PORTB,0		;機関銃　LED OFF

	MOVLW	255		;COUNT4<>255だったら
	SUBWF	COUNT4,0	;
	BTFSS	STATUS,2	;(Z=0) COUNT4<>255
	GOTO	LOOP100

        MOVLW	B'00000'	;RA4のLEDをON
	MOVWF	PORTA		;

	BSF	STATUS,PG	;Change Page1
	BCF	TRISB,6		;RB6を出力に切替
	BCF	STATUS,PG	;Change Page0

	BSF	PORTB,6		;PULS6 on（音切り換え）
	CALL	TIM20		;ちょっと待つ
	BCF	PORTB,7		;音のＳＷ on（大砲音）
	MOVLW	0		;
	MOVWF	COUNT4		;COUNT4=0


LOOP100

	CALL	PULSOFF

;------------　　砲身を戻す処理(大砲音の間隔)
	MOVLW	250		;250以上だったら
	SUBWF	COUNT4,0	;
	BTFSS	STATUS,0	;(CY=0) COUNT4<250は
	GOTO	LOOP102
	MOVLW	255		;
	MOVWF	COUNT4		;COUNT4=255
	GOTO	LOOP104
LOOP102
	MOVLW	4		;砲身を戻す時のスピード(1-5)
	ADDWF	COUNT4,1	;COUNT4=COUNT4+4
LOOP104

	GOTO	LOOP1

;-------------------センター設定ルーチン
SETEI
	CALL	PULSOFF
	BTFSC	PORTB,2		;設定スイッチ　OFF のチェック
	RETUEN			;ONの時は戻る
;-----------------センターチェック1
	CALL	PULSIN1A		;1chパルス幅取得
	MOVF	PIN1,0
	MOVWF	PIN1B
	MOVWF	PIN2
	BTFSS	PORTB,3		;OFF の時
	CALL	PULSIN2A		;2chパルス幅取得
	MOVF	PIN2,0
	MOVWF	PIN2B
	CALL	PULSOFF
;-----------------センターチェック2
	CALL	PULSIN1A		;1chパルス幅取得
	MOVF	PIN1,0
	MOVWF	PIN2
	BTFSS	PORTB,3		;OFF の時
	CALL	PULSIN2A		;2chパルス幅取得

;-----------------センターチェック1と2の比較
	MOVF	PIN1,0
	SUBWF	PIN1B,0
	BTFSS	STATUS,2		;(Z<>1)
	GOTO	SETEI

	MOVF	PIN2,0
	SUBWF	PIN2B,0
	BTFSS	STATUS,2		;(Z<>1)
	GOTO	SETEI

SETEI02
	CALL	PULSOFF
	BTFSS	PORTB,2		;設定スイッチ　OFF のチェック
	GOTO	SETEI02		;OFFの時はループ
	CALL	PULSOFF

;--------------------設定開始----------------
SETEI10
	MOVLW	B'10001'	;RA4のLEDをOFF
	MOVWF	PORTA		;
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF

	BTFSS	PORTB,2		;設定スイッチ　OFF のチェック
	GOTO	SETEI20		;OFFで設定終了
	CALL	PULSOFF

	MOVLW	B'10000'	;RA4のLEDをON
	MOVWF	PORTA		;
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF
	CALL	PULSOFF

	GOTO	SETEI10
SETEI20
	MOVLW	B'10000'	;RA4のLEDをOFF
	MOVWF	PORTA		;

	CALL	PULSIN1A	;1chパルス幅取得
;-----------スティックのチェック
	MOVF	PIN1,0
	SUBWF	PIN1B,0
	BTFSC	STATUS,2		;(Z=1)
	GOTO	SETEI90

	BTFSC	STATUS,0		;(CY=1) PIN1B=<PIN1
	GOTO	SETEI40

;---------センターより小さい時
SETEI30

	MOVF	PIN1B,0		;W=PIN1B
	SUBWF	PIN1,0		;W=PIN1-PIN1B
	MOVWF	CENTER3		;CENTER3=W
	MOVLW	1		;
	SUBWF	CENTER3,1		;CENTER3=CENTER3-W

	GOTO	SETEI50

;---------センターより大きい時
SETEI40

	MOVF	PIN1,0		;W=PIN1
	SUBWF	PIN1B,0		;W=PIN1B-W(PIN1)
	MOVWF	CENTER3		;CENTER3=W
	MOVLW	1		;
	SUBWF	CENTER3,1		;CENTER3=CENTER3-W

;--------センター設定値の更新
SETEI50
	MOVF	PIN1B,0		;W=PIN1B
	MOVWF	CENTER1		;CENTER1=W
	MOVF	PIN2B,0		;W=PIN2B
	MOVWF	CENTER2		;CENTER2=W

	MOVF	CENTER3,0	;W=CENTER3
	ADDWF	CENTER1,0	;W=CENTER1+CENTER3
	MOVWF	SW1		;SW1=W

	MOVF	CENTER3,0	;W=CENTER3
	SUBWF	CENTER1,0	;W=CENTER1-CENTER3
	MOVWF	SW2		;SW2=W

	MOVLW	2		;
	ADDWF	CENTER2,0	;W=CENTER2+2
	MOVWF	CENTER2A	;CENTER2A=W

	MOVLW	1		;
	SUBWF	CENTER2,0	;W=CENTER2-2
	MOVWF	CENTER2B	;CENTER2B=W

;-------- ＥＥＰＲＯＭ書き込み
	MOVF	CENTER1,0	;W=CENTER1
	MOVWF	EEDATA		;EEDATA=W
	MOVLW	0		;
	CALL	EEPW

	MOVF	CENTER2,0	;W=CENTER2
	MOVWF	EEDATA		;EEDATA=W
	MOVLW	1		;
	CALL	EEPW

	MOVF	CENTER3,0	;W=CENTER3
	MOVWF	EEDATA		;EEDATA=W
	MOVLW	2		;
	CALL	EEPW

SETEI90
	CALL	PULSOFF
	BTFSS	PORTB,2		;設定スイッチ　OFF のチェック
	GOTO	SETEI90		;OFFの時はループ
	RETURN


;-------------  20サイクルタイマー（実際は19サイクル）
TIM20
	GOTO	$+1	;2
	GOTO	$+1	;+2=4
	GOTO	$+1	;+2=6
	GOTO	$+1	;+2=8
	GOTO	$+1	;+2=10
	GOTO	$+1	;+2=12
	GOTO	$+1	;+2=14
	GOTO	$+1	;+2=16
	NOP		;+1=17
	RETURN		;+2=19

;-------------  Ｗレジスタ分のカウントタイマー(1カウント=25サイクル)×Ｗ
TIM25
	MOVWF	COUNT1		;1+1=2
TIM26
	CALL	TIM20		;19+2=21
	NOP			;+1=22
	DECFSZ	COUNT1,1	;+1=23
	GOTO	TIM26		;+2=25
	RETURN			;+1+(W*25)+2-1

;-----------パルスとパルスの間の空き時間-----------------
PULSOFF
	MOVLW	150
	CALL	TIM25		;
	MOVLW	255
	CALL	TIM25		;
	RETURN

;-------------  時間稼ぎ(1/4秒×Ｗ)
TIM90
	MOVWF	COUNT10		;
TIM91
	MOVLW	50
	MOVWF	COUNT9		;
TIM92
	MOVLW	255
	CALL	TIM25		;
	DECFSZ	COUNT9,1	;
	GOTO	TIM92		;
	DECFSZ	COUNT10,1	;
	GOTO	TIM91		;
	RETURN			;


;-------- ＥＥＰＲＯＭ書き込み
EEPW
	MOVWF	EEADR		;
	BSF	STATUS,PG	;Change Page1
	BSF	EECON1,WREN	;EECON1のWREN=1(書込許可)
	MOVLW	H'55'
	MOVWF	EECON2		;書込開始
	MOVLW	H'AA'
	MOVWF	EECON2
	BSF	EECON1,WR	;
WR_LP
	BTFSC	EECON1,WR	;書込終了チェック
	GOTO	WR_LP
	BCF	STATUS,PG	;Change Page0
	RETURN
;-----------1CHパルス幅測定（PIN1）-------
PULSIN1A
	BTFSS	PORTA,2		;OFF の時
	GOTO	PULSIN1		;入力開始
	CALL	TIM20
	GOTO	PULSIN1A	;次の信号まで待つ
;-----------1CHパルス幅測定（PIN1）左右のステック-----------
PULSIN1
	BTFSS	PORTA,2		;OFF の時
	GOTO	PULSIN1		;入力待ちループ
	MOVLW	0		;
	MOVWF	PIN1		;カウンター初期化
PULSIN11
	CALL	TIM20		;20サイクル待ち	(19+2)
	INCF	PIN1,1		;PIN1=PIN1+1	(22)
	BTFSC	PORTA,2		;ＯＮの時は	(23)
	GOTO	PULSIN11	;カウント継続	(25)

	MOVLW	90		;カウントが90以下だったら
	SUBWF	PIN1,0		;カウントしなおし！
	BTFSS	STATUS,0	;(CY=0) PIN1<90
	GOTO	PULSIN1		;
	RETURN
;-----------2CHパルス幅測定（PIN2）前進・後進のスティックの信号チェック-------
PULSIN2A
	BTFSS	PORTA,3		;OFF の時
	GOTO	PULSIN2		;入力開始
	CALL	TIM20
	GOTO	PULSIN2A	;次の信号まで待つ

;-----------2CHパルス幅測定（PIN2）前進・後進のスティック-----------
PULSIN2
	BTFSS	PORTA,3		;OFF の時
	GOTO	PULSIN2		;入力待ちループ
	MOVLW	0		;
	MOVWF	PIN2		;カウンター初期化
PULSIN21
	CALL	TIM20		;20サイクル待ち
	INCF	PIN2,1		;PIN1=PIN1+1
	BTFSC	PORTA,3		;ＯＮの時は、
	GOTO	PULSIN21	;カウント継続

	MOVLW	90		;カウントが90以下だったら
	SUBWF	PIN2,0		;カウントしなおし！
	BTFSS	STATUS,0	;(CY=0) PIN2<90
	GOTO	PULSIN2		;
	RETURN


	END

