
#include "p16F54.inc"

 __CONFIG _OSC_HS & _WDT_OFF & _CP_OFF

#define _BZ	buf_A,2	;ﾌﾞｻﾞｰ
#define	SEN	PORTA,3	;電流検知
#define	dpf	flg,0	;小数点表示ﾌﾗｸﾞ
#define	DSP	flg,2	;7ｾｸﾞ表示ﾌﾗｸﾞ

;音程ﾃｰﾌﾞﾙ番号割付
#define	DO	0x10
#define	RE	0x20
#define	MI	0x30
#define	FA	0x40
#define	FAS	0x50
#define	SO	0x60
#define	RA	0x70
#define	SI	0x80
#define	DOH	0x90
;音の長さﾃｰﾌﾞﾙ番号割付
#define	L48	1
#define	L32	2
#define	L24	3
#define	L20	4
#define	L16	5
#define	L12	6
#define	L8	7
#define	L6	8
#define	L4	9
#define	L2	0xa
#define	L1	0xb

#define	LENGS_BGM   d'14'	;ｷｭｰﾃｰﾌﾞﾙ長さ

;***** 変数宣言
ck	equ	7
cp	equ	8
sec	equ	9
min	equ	0xa
k1	equ	0xb
k2	equ	0xc
buf_A	equ	0xd
buf_B	equ	0xe
buf_DATA equ	0xf
aregv1	equ	0x10
aregv2	equ	0x11
w_areg	equ	0x12
seq	equ	0x13
flg	equ	0x14
c0	equ	0x15
c1	equ	0x16
c2	equ	0x17
Qcnt	equ	0x18		;楽譜位置
Qdt	equ	0x19		;音符buf
TONE	equ	0x1a		;音程buf
tone_cnt equ	0x1b		;音程計数
TMR0_cnt equ	0x1c		;音の長さ計数

START	org    0x0000        ; processor reset vector

;***** 初期化
	clrf	PORTA
	movlw	b'1000'
	tris	PORTA
	clrf	PORTB
	clrw
	tris	PORTB	
	movlw	b'11010101'	;ﾌﾟﾘｽｹｰﾙ1/64
	option
	clrf	buf_A
	clrf	buf_B
	clrf	seq
	clrf	sec
	clrf	min
	clrf	cp
	clrf	ck
	clrf	flg
	goto	main
;ｻﾌﾞﾙｰﾁﾝ
distri
	call	dis_min
	movf	k2,W	;aregv1=(3-k2)+1
	movwf	aregv1
	comf	aregv1,F
	incf	aregv1,F
	movlw	4
	addwf	aregv1,F
dist1	decf	aregv1,F ;1桁8uSecｳｴｲﾄ
	btfsc	STATUS,Z
	retlw	0
	nop
	goto	$+1
	goto	dist1

dis_min			;分を桁分割
;	movf	sec,W
	movf	min,W
	movwf	k1
	clrf	k2
dis_m1	movlw	d'10'
	subwf	k1,W
	btfss	STATUS,C
	retlw	0
	movwf	k1
	incf	k2,F
	goto	dis_m1

cv7seg			;7ｾｸﾞDATA変換
	andlw	0xf
	addwf	PCL,F	;abcd efg(dp)
	retlw	0xfc	;1111 110 0
	retlw	0x60	;0110 000 0
	retlw	0xda	;1101 101 0
	retlw	0xf2	;1111 001 0
	retlw	0x66	;0110 011 0
	retlw	0xb6	;1011 011 0
	retlw	0xbe	;1011 111 0
	retlw	0xe4	;1110 010 0
	retlw	0xfe	;1111 111 0
	retlw	0xe6	;1110 011 0

tone_STA			;一音符演奏
	movf	TONE,W
	movwf	tone_cnt
	btfsc	STATUS,Z
	goto	tone_1
	movf	buf_A,W
	xorlw	b'100'		;ﾌﾞｻﾞｰﾋﾞｯﾄ反転
tone_1	movwf	buf_A
	movwf	PORTA
	goto	tone_2
tone_lp
	incfsz	TMR0,W
	goto	tone_3
	movlw	1
	movwf	TMR0
	decf	TMR0_cnt,F
	btfsc	STATUS,Z
	retlw	0
	goto	tone_4
tone_3	goto	$+1
	goto	$+1
	nop
tone_2	nop
tone_4	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	tone_cnt,F
	goto	tone_lp
	goto	tone_STA

TABLE_TIME
	addwf	PCL,F
	retlw	2		;L64
	retlw	3		;L48
	retlw	4		;L32
	retlw	6		;L24
	retlw	7		;L20
	retlw	8		;L16
	retlw	d'12'		;L12
	retlw	d'16'		;L8
	retlw	d'24'		;L6
	retlw	d'32'		;L4
	retlw	d'64'		;L2
	retlw	d'128'		;L1
	retlw	0
	retlw	0
	retlw	0
	retlw	0

TABLE_TONE
	addwf	PCL,F
	retlw	0		;休符(R)
	retlw	d'80'		;ﾄﾞ(C)
	retlw	d'71'		;ﾚ (D)
	retlw	d'63'		;ﾐ (E)
	retlw	d'60'		;ﾌｧ(F)
	retlw	d'56'		;ﾌｧ#(F#)
	retlw	d'53'		;ｿ (G)
	retlw	d'48'		;ﾗ (A)
	retlw	d'42'		;ｼ (B)
	retlw	d'40'		;ﾄﾞ(CH)
	retlw	0
	retlw	0
	retlw	0
	retlw	0
	retlw	0
	retlw	0

TABLE_BGM
	movf	Qcnt,W
	addwf	PCL,F
	retlw	RA+L4
	retlw	FA+L4
	retlw	DO+L4
	retlw	FA+L4
	retlw	SO+L4
	retlw	DOH+L2
	RETLW	L8
	retlw	SO+L4
	retlw	RA+L4
	retlw	SO+L4
	retlw	DO+L4
	retlw	FA+L2
	retlw	FA+L4
	retlw	L2
	retlw	0

;ﾒｲﾝﾙｰﾁﾝ
main	movf	seq,W
	andlw	3
	addwf	PCL,F
	goto	_s0	;IF SEN=0
	goto	_s1	;10m秒待ち
	goto	_s2	;IF SEN=1
	goto	_s3	;5秒待ち
_s0	clrf	sec
	clrf	min
	btfsc	SEN
	goto	_sw4	;IF SEN=0 10u
	movlw	8
	movwf	c0
	incf	seq,F
	goto	_send	;14u
_s1	btfsc	SEN
	goto	_s11
	decfsz	c0,F
	goto	_sw4	;10u
	clrf	sec
	bsf	DSP
	incf	seq,F
	goto	_send	;14u
_s11	clrf	seq
	goto	_sw3	;11u
_s2	btfss	SEN	;停止検知
	goto	_sw6	;8u
	movlw	4
	movwf	c1
	movlw	d'250'
	movwf	c2
	incf	seq,F
	goto	_send	;14u
_s3	btfss	SEN
	goto	_s31	;IF SEN=0
	decfsz	c2,F
	goto	_sw4	;IF c2>0 10u
	movlw	d'250'
	movwf	c2
	decfsz	c1,F
	goto	_send	;IF c1>0 14u
	goto	beep	;終了音
_s31	decf	seq,F
	goto	_sw3	;11u
_sw6	goto	$+1
_sw4	nop
_sw3	nop
	goto	$+1
_send	movf	ck,W
	andlw	7
	addwf	PCL,F
	goto	ck_0	;表示桁分解
	goto	ck_1	;1桁目7ｾｸﾞ変換
	goto	ck_2	;ULL出力
	goto	ck_3	;1桁目出力
	goto	ck_4	;2桁目7ｾｸﾞ変換
	goto	ck_2	;NULL出力
	goto	ck_6	;2桁目出力
	goto	ck_7	;計時処理

ck_0			;表示桁分解
	call	distri
	nop
	goto	wait
ck_1			;1桁目7ｾｸﾞ変換
	movf	k1,W
	call	cv7seg
	movwf	buf_DATA
	goto	w39
ck_2			;DATA NULL
	clrf	buf_B
	nop
	goto	w45
ck_3			;1桁目出力
	bcf	buf_A,1
	bsf	buf_A,0
	movf	buf_DATA,W
	movwf	buf_B
	btfsc	dpf
	goto	w42
	bsf	buf_B,0	;dp表示
	goto	w40
ck_4			;2桁目7ｾｸﾞ変換
	movf	k2,W
	call	cv7seg
	movwf	buf_DATA
	goto	w39

ck_6			;2桁目出力
	bcf	buf_A,0
	bsf	buf_A,1
	movf	buf_DATA,W
	movwf	buf_B
	goto	w43
ck_7			;計時処理
	incf	cp,F
	movlw	d'50'
	subwf	cp,W
	btfss	STATUS,C
	goto	w43
			;1秒ｶｳﾝﾄ
	clrf	cp
	incf	flg,F	;dpﾌﾘｯｶ
	bcf	flg,1
	incf	sec,F
	movlw	d'60'
	subwf	sec,W
	btfss	STATUS,C
	goto	ck_70
	clrf	sec
	incf	min,F
	goto	w37

ck_70	goto	$+1
	goto	$+1
	movlw	7
	goto	wai_0

w45	goto	$+1
w43	nop
w42	nop
w41	nop
w40	nop
w39	goto	$+1
w37	movlw	9	;15uSec wait
wai_0	movwf	w_areg
wai_t	nop
	decfsz	w_areg,F
	goto	wai_t
wait			;ｻｲｸﾙﾀｲﾑ2.5mS
	movlw	d'242'
	movwf	aregv2
wait1	goto	$+1
	goto	$+1
	goto	$+1
	nop
	decfsz	aregv2,F
	goto	wait1
	nop

	movf	buf_A,W	;出力処理
	movwf	PORTA
	movf	buf_B,W
	btfss	DSP	;表示ﾌﾗｸﾞ
	andlw	1
	movwf	PORTB
	incf	ck,F
	bcf	ck,4
	goto	main

beep				;音出し
	clrf	Qcnt
	clrf	buf_A
play_tone			;楽譜演奏
	movlw	1		;255-244
	movwf	TMR0
	call	TABLE_BGM	;音符取出
	movwf	Qdt		;音符保存
	andlw	0xf
	call	TABLE_TIME
	movwf	TMR0_cnt	;音符長さ
	swapf	Qdt,W
	andlw	0xf
	call	TABLE_TONE
	movwf	TONE		;音程保存
	call	tone_STA	;音符演奏
	incf	Qcnt,F
	movlw	LENGS_BGM
	subwf	Qcnt,W
	btfss	STATUS,Z
	goto	play_tone
	goto	START

    END