;MP3 Player kunio.h  Ver5.0(CPU:8MHz,VS1011:12.288MHz) H18.3.20
;**** includes **** 
.include "m8def.inc"

; Load immediate word into the resister pair.
;	ldiw	Z(X,Y),var
.macro	ldiw
	ldi	@0L,low(@1)
	ldi	@0H,high(@1)
.endm
; Output immediate   outi	port,var
.macro	outi
	ldi	r16,@1
	out	@0,r16
.endm
.MACRO cpi16	;cpi16	ra,rb,0xHHHH	;ra:rb-0xHHHH	set flags:N,C,Z
	push	@0
	push	@1
	subi	@1,low(@2)
	sbci	@0,high(@2)
	pop	@1
	pop	@0
.ENDMACRO
.MACRO addi16	;addi16	ra,rb,0xHHHH
        subi	@1,low(-@2)
        sbci	@0,high(-@2)
.ENDMACRO
;*****************************
;* レジスタ変数　設定 *
;*****************************
.def	temp1	= r16
.def	temp2	= r17
.def	temp3	= r18
.def	temp4	= r19

;*****************************
;*　 ビット　設定　　*

;**  PORTB  ***
.equ	mp3_dreq= 0
.equ	mp3_cs	= 1	
.equ	sd_cs	= 2	;SS
.equ	sd_in	= 3	;MOSI
.equ	sd_out	= 4	;MISO
.equ	sd_clk	= 5	;SCK
.equ	mp3_dcs	= 6 	;mp3_bsync
.equ	mp3_reset=7	;MP3~reset	
;**  PORTD  **
;.equ	= 0
;.equ	= 1 
;.equ	= 2
;.equ	= 3
;.equ   = 4	
;.equ	= 5
;.equ	= 6		
.equ	led	= 7
;**  PORTC  ***
;.epu	play	= 0
;.epu	ff	= 1
;.epu	rew	= 2
;.epu	vol+	= 3
;.epu	vol-	= 4
.equ	p_hold	= 5;power hold 
.equ	v_in	= 7;batt volt 
;key_in 	    76543210
.equ	key_stop= 0b00011110
.equ	key_ff	= 0b00011101
.equ	key_rew = 0b00011011
.equ	key_vp	= 0b00010111
.equ	key_vm	= 0b00001111
;（定数）
.equ	key_d_pl= 0b11110000 
.equ	key_d_mi= 0b11100000
.dseg
mode:		.BYTE	1	;0:1time,1:dir repeat,2:1file repeat
fattype:	.BYTE	1	;FAT16:1,FAT12:0
datastart:	.BYTE	4	;DATAstart[3:0]
dirstart:	.BYTE	2	;DIRstart[1:0]
secpcl:		.BYTE	1	;sectorspercluster
fatstart:	.BYTE	2	;FATstart[1:0]
rdirent:	.BYTE	2	;rootdirentriescount[1:0]
spi_arg:	.BYTE   5	;cmd,arg[3:0]
read32_arg:	.BYTE	4	;adr[3:0]
musiccount:	.BYTE	1	;MP3 file count
playmusic:	.BYTE	1	;play music count
musicsize:	.BYTE 	4	;play file size
cluster:	.BYTE	2	;play cluster
remainsec:	.BYTE   2	;play remain sector
buff:		.BYTE  32	;buff[31:0]
secdat:		.BYTE 512	;sectorDATA
volume:		.BYTE	1
key_in:		.BYTE	1
key_input:	.BYTE	1
key_c:		.BYTE	1
v_t:		.BYTE	2
led_time:	.byte	1
dir_count:	.byte	1	;play dir
dir_dat:	.byte  30	;root files H:L + cluster H:L x 14dir
play_dat:	.byte  20	;song entry_No x 20
dir_dat_w:	.byte  60	;dir_dat_work	

.eseg	;EEPROM add
rom_pm:	.BYTE	1	;play music
rom_cl:	.BYTE	2	;cluster
rom_re:	.BYTE	2	;remainsec
rom_mu:	.BYTE	3	;musicsize
rom_vo:	.BYTE	1	;volume
rom_mo:	.BYTE	1	;mode
rom_dc:	.BYTE	1	;dir_count
		
.cseg
;*********************
;* 割込みベクター *
;*********************
	rjmp start ;各種ﾘｾｯﾄ
	reti	;RJMP EXT_INT0 ;外部割り込み要求0
	reti	;EXT_INT1   ;外部割り込み要求1
	reti	;TIM2_COMP  ;ﾀｲﾏ/ｶｳﾝﾀ2 比較一致
	reti	;TIM2_OVF   ;ﾀｲﾏ/ｶｳﾝﾀ2 ｵｰﾊﾞｰﾌﾛｰ
	reti	;TIM1_CAPT   ;ﾀｲﾏ/ｶｳﾝﾀ1 ｷｬﾌﾟﾁｬ発生 mp3_dreq L→H sleep mood end
	reti	;TIM1_COMPA ;ﾀｲﾏ/ｶｳﾝﾀ1 比較A 一致
	reti	;TIM1_COMPB ;ﾀｲﾏ/ｶｳﾝﾀ1 比較B 一致
	rjmp	TIM1_OVF    ;ﾀｲﾏ/ｶｳﾝﾀ1 ｵｰﾊﾞｰﾌﾛｰ
	rjmp	TIM0_OVF    ;ﾀｲﾏ/ｶｳﾝﾀ0 ｵｰﾊﾞｰﾌﾛｰ
	reti	;SPI_STC    ;SPI 転送完了
	reti	;USART_RXC  ;USART 受信完了
	reti	;USART_DRE  ;USART 送信ﾊﾞｯﾌｧ空
	reti	;USART_TXC  ;USART 送信完了
	reti	;ADC_E      ;ADC 変換完了
	reti	;EE_RDY     ;EEPROM 操作可 
	reti	; ANA_COMP ;ｱﾅﾛｸﾞ ｺﾝﾊﾟﾚｰﾀ出力遷移
	reti	;TWSI ;2 線式ｼﾘｱﾙ ｲﾝﾀｰﾌｪｰｽ状態変化
	reti	;SPM_RDY ;SPM 命令操作可
;*********************
;* メイン プログラム *
;*********************
start:
	ldi	temp1,low(RAMEND)
	out	SPL,temp1
	ldi	temp1,high(RAMEND)
	out	SPH,temp1	;init Stack Pointer 

	ldi	temp1,0b00001111
	out	PORTB,temp1	
	ldi	temp1,0b11101110
	out	DDRB,temp1	
	ldi	temp1,0b00011111	
	out	PORTC,temp1
	ldi	temp1,0b00100000
	out	DDRC,temp1	 
	ldi	temp1,0b01111111	
	out	PORTD,temp1
	ldi	temp1,0b10000000
	out	DDRD,temp1	

	ldi	temp1,50
	rcall	wait_ms
	sbic	PINC,0
start1:
	rjmp	start1
	sbi	PORTC,p_hold	;power hold
	sbi	PORTD,led	;LED ON
ADC_int:
	outi	ADMUX,(1<<REFS0)|(1<<REFS1)|(1<<MUX2)|(1<< MUX1)|(1<<MUX0);基準電圧2.56V、結果右揃え、Ch7選択
	outi	ADCSR,(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);|(1<<ADEN);ADCck=8M/128=62.5k
sleep_mode:	;省電力設定、Analog Comparator
	outi	MCUCR,1<<SE	;Sleep許可、SM0-2=0　アイドル動作
	outi	ACSR,1<<ACD	;ｱﾅﾛｸﾞ比較器禁止
spi_mode_set:
	outi	SPCR,0x52	;SPI master,CPOL0,CPHA=0,CK=8M/64=125k
vs1011_start:
	rcall	mp3_hard_int	;HARD reset
	rcall	mp3_int		;soft reset
	rcall	v_read
	cpi16	zH,zL,310	;約3.1V以下の場合停止 
	brcc	v_ok
	outi	SPCR,0x50
	ldi	temp1,1
	mov	r0,temp1
	rjmp	loop
v_ok:
	clr	temp1
	sts	mode,temp1
	in	temp1,PINC
	andi	temp1,0b00011111
	cpi	temp1,0b00010110	; 'power on'+'vol+'
	brne	play_data_init
	ldi	temp1,5
	rcall	wait_ms	
	in	temp1,PINC
	andi	temp1,0b00011111
	cpi	temp1,0b00010110
	brne	play_data_init
erorr_rest_mode:	
	in	temp1,PINC
	andi	temp1,0b00011111
	cpi	temp1,0b00011111  ;no key_in
	brne	erorr_rest_mode
	ldi	temp1,1
	sts	playmusic,temp1
	clr	temp1
	sts	cluster,temp1
	sts	cluster+1,temp1
	sts	dir_count,temp1
	sts	remainsec,temp1
	sts	remainsec+1,temp1
	rjmp  	reset_start
play_data_init:
	ldiw	z,rom_pm
	rcall	EEPROM_RD
	sts	playmusic,temp2
	ldiw	z,rom_dc
	rcall	EEPROM_RD
	sts	dir_count,temp2
	ldiw	z,rom_cl
	rcall	EEPROM_RD
	sts	cluster,temp2
	ldiw	z,rom_cl+1
	rcall	EEPROM_RD
	sts	cluster+1,temp2
	ldiw	z,rom_re
	rcall	EEPROM_RD
	sts	remainsec,temp2
	ldiw	z,rom_re+1
	rcall	EEPROM_RD
	sts	remainsec+1,temp2
	ldiw	z,rom_mu
	rcall	EEPROM_RD
	sts	musicsize,temp2
	ldiw	z,rom_mu+1
	rcall	EEPROM_RD
	sts	musicsize+1,temp2
	ldiw	z,rom_mu+2
	rcall	EEPROM_RD
	sts	musicsize+2,temp2
	ldiw	z,rom_mo
	rcall	EEPROM_RD
	cpi	temp2,3
	brcs	mode_int
	clr	temp2
mode_int:
	sts	mode,temp2
reset_start:
	ldiw	z,rom_vo
	rcall	EEPROM_RD
	cpi	temp2,0x8A+1
	brcc	vol_init
	cpi	temp2,0x12
	brcs	vol_init
	rjmp	vol_set
vol_init:
	ldi	temp2,0x42	;init vol
vol_set:
	sts	volume,temp2
	ldi	temp1,10
	sts	v_t+1,temp1
	ldi	temp1,0
	sts	v_t,temp1
	sts	led_time,temp1
key_off_ck:	;power_SWを離したか
	in	temp1,PINC
	andi	temp1,0b00011111
	cpi	temp1,0b00011111  ;no key_in
	brne	key_off_ck
spi_0:	;SD(MMC)_int
	ldi	temp3,10	;SD SPI mode 80クロック送信
spi_1:	
	rcall	spi_in		;dumy clock
	dec	temp3
	brne	spi_1		;SD SPI mode 移行CMD
	cbi	PORTB,sd_cs	;CS=L
	ldi	temp1,0
	sts	spi_arg,temp1	;cmd
	ldi	temp1,BYTE4(0)	
	sts	spi_arg+1,temp1	;arg3
	ldi	temp1,BYTE3(0)	
	sts	spi_arg+2,temp1	;arg2
	ldi	temp1,BYTE2(0)	
	sts	spi_arg+3,temp1	;arg1
	ldi	temp1,low(0)	
	sts	spi_arg+4,temp1	;arg0
spi_11:
	rcall	spi_com	;(0,0)  temp2:spi_com_return
	cpi	temp2,0xff	;card  busy?  $FF  
	breq	spi_22   	;card error
	cpi	temp2,1	;card ok? until  return=1
	breq	spi_2
	ldi 	temp1,10
	rcall 	wait_us	;wait
	rjmp	spi_11
spi_2:
	ldi	temp1,1	
	sts	spi_arg,temp1
spi_21:
	rcall	spi_com;(1,0)
	cpi	temp2,1	;int OK? until	return!=1
	breq	spi_21
spi_22:
	sbi	PORTB,sd_cs	;CS=H

	outi	SPCR,0x50	;SPI master,CPOL0,CPHA=0,CK=8M/4=2M
;	sbi	SPSR,SPI2X	;ck x 2 -> 4M
	cpi	temp2,0xFF
	brne	main_1
	ldi	temp1,2
	mov	r0,temp1
	rjmp	loop
main_1:
	rcall	read_vfat
	tst	temp2
	breq	main_2
	ldi	temp1,3
	mov	r0,temp1
	rjmp	loop
main_2:
	ldi	temp1,0xFF
	rcall	search_mp3;temp2=MP3 count root_dir,r22 sub_dir count
	tst	r22
	breq	main_20 
	rcall	sort_dir
main_20:
	lds	temp2,dir_dat+1
	tst	temp2
	brne	main_3	;mp3 find
	lds	r22,dir_dat
	tst	r22	
	breq	main_29	;sub_dir=0
main_21:
	ldi	temp1,1
	mov	temp2,r22
	rcall	search_dir_mp3
	tst	temp2
	brne	main_3
	dec	r22
	brne	main_21
main_29:		;mp3 nothing
	ldi	temp1,4
	mov	r0,temp1
	rjmp	loop
main_3:
	lds	temp1,playmusic
	tst	temp1
	brne	main_32
	rjmp	main_5	;play_No=0 -> play top 
main_32:
	lds	temp2,dir_count
	tst	temp2
	breq	main_4		;root_dir
	lds	r22,dir_dat
	tst	r22
	breq	main_5
	ldi	temp1,0xFF
	rcall	search_dir_mp3	;n(temp2) dir
	rjmp	main_40	
main_4:
	ldi	temp1,20	;dumy
	rcall search_mp3	;sarch temp1 MP3
main_40:	
	tst	temp2
	breq	main_5		;this_dir no mp3 
	sts	musiccount,temp2 ;music count
	rcall	sort_song
	lds	temp1,playmusic
	lds	temp2,dir_count
	rcall	load_entry
	tst	temp2
	brmi	main_5
main_41:
	lds	temp1,buff+28
	lds	temp2,musicsize
	cp	temp1,temp2
	brne	main_5
	lds	temp1,buff+29
	lds	temp2,musicsize+1
	cp	temp1,temp2
	brne	main_5
	lds	temp1,buff+30
	lds	temp2,musicsize+2
	cp	temp1,temp2
	breq	play
main_5:	
	ldi	temp1,1		;play  top
	sts	playmusic,temp1
	clr	temp2		
	sts	cluster,temp2	;cluster int
	sts	cluster+1,temp2
	lds	temp3,dir_dat+1
	tst	temp3
	breq	main_52		;root mp3 nothing
	sts	dir_count,temp2	;root_dir -> 0
	rcall	search_mp3
	rjmp	main_59
main_52:			;sub No1_dir  
	ldi	r22,1
main_53:
	sts	dir_count,r22
	ldi	temp1,0xff
	mov	temp2,r22
	rcall	search_dir_mp3	;sub No1_dir  mp3 file count?
	tst	temp2
	brne	main_59
	inc	r22
	rjmp	main_53
main_59:
	sts	musiccount,temp2	;music count
	rcall	sort_song	
play:
	rcall	v_read
	cpi16	zH,zL,380	;about 3.8-
	brcs	play_b3
	ldi	temp1,3
	rjmp	play_b9
play_b3:
	cpi16	zH,zL,360	;about 3.6-
	brcs	play_b4
	ldi	temp1,2
	rjmp	play_b9
play_b4:	
	cpi16	zH,zL,340	;about 3.4-
	brcs	play0
	ldi	temp1,1
play_b9:
	mov	r0,temp1
play_ba:
	cbi	PORTD,led
	ldi	temp1,100
	rcall	wait_ms
	sbi	PORTD,led
	ldi	temp1,100
	rcall	wait_ms
	dec	r0
	brne	play_ba
timer1_int:
;	outi	TCCR1B,(1<<CS12)	
;	outi	TIMSK,1<<TOIE1		;time1 Overflow Interrupt
play0:
	lds	temp1,playmusic
	lds	temp2,musiccount
	cp	temp2,temp1	
	brcc	play_1		;files => play_No
	ldi	temp1,1		;	<
	sts	playmusic,temp1
	lds	temp4,mode
	tst	temp4
	breq	play_0
	lds	r20,key_input	
	cpi	r20,key_ff
	breq	play_0
	cpi	r20,key_d_pl
	breq	play_0
	rjmp	play_1		;mode 1 = dir repeet
play_0:				;mode 0	= no repeet
	lds	temp2,dir_count
	inc	temp2
	lds	temp1,dir_dat	;sub dir count
	cp	temp1,temp2	;
	brcc	play_01		;>= next dir 	
	rjmp	play_02		;<  dir end
play_01:
	sts	dir_count,temp2
	ldi	temp1,0xFF
	rcall	search_dir_mp3	;sub temp2_dir  mp3 file count?
	tst	temp2		;files?
	breq	play_0
	rjmp	play_04
play_02:
	clr	temp2
	sts	dir_count,temp2
	lds	r20,key_input
	cpi	r20,key_ff
	breq	play_03
	cpi	r20,key_d_pl
	breq	play_03
	rjmp	play_stop
play_03:
	clr	r20	;ky_in clr
	sts	key_input,r20
	lds	temp2,dir_dat+1
	tst	temp2
	breq	play_0
	ldi	temp1,20	;dumy
	rcall	search_mp3
play_04:
	sts	musiccount,temp2
	rcall	sort_song
play_1:
	clr	r20	;ky_in clr
	sts	key_input,r20
;	outi	TCNT1H,0x80	;0x8000/(8M/256)=1.05s
;	outi	TCNT1L,0
;	outi	TCCR1B,(1<<CS12)
;	sei
	rcall	play_mp3	;arg=playmusic(temp1),dir_count,cluster,remainsec
	cli
	outi	TCCR1B,0
	tst	temp2
	breq	play_3
	brpl	play_2
play_err:
	ldi	temp1,5
	mov	r0,temp1
	rjmp	loop
play_2:
	clr	r1
	inc	r1
	mov	r0,r1	
	rcall	beep	;high 1time
	lds	r20,key_input
	cpi	r20,key_ff
	breq	play_ff
	cpi	r20,key_rew
	breq	play_rew
	cpi	r20,key_d_pl
	breq	play_d_pl
	cpi	r20,key_d_mi
	breq	play_d_mi
	cpi	r20,key_stop
	breq	play_stop_1
	lds	temp1,playmusic ;key_input=error?
	rjmp	play_1
play_stop_1:
	rjmp	play_stop
play_3:
	lds	temp1,mode
	cpi	temp1,2
	breq	play_ff1
play_ff:
	lds	temp1,playmusic
	inc	temp1
	sts	playmusic,temp1
play_ff1:
	clr	temp2
	sts	cluster,temp2
	sts	cluster+1,temp2
	rjmp	play
play_d_pl:
	lds	temp1,musiccount
	inc	temp1
	sts	playmusic,temp1
	rjmp	play_ff1
play_rew:
	lds	temp2,playmusic
	dec	temp2
	brne	play_rew1
play_d_mi:
	lds	temp2,dir_count
	tst	temp2
	breq	play_rew00
play_d_mi0:
	dec	temp2
	brne	play_rew05
play_rew0:
	lds	temp2,dir_dat+1	
	tst	temp2
	breq	play_rew00
	clr	temp2
	sts	dir_count,temp2
	rcall	search_mp3
	rjmp	play_rew06
play_rew00:
	lds	temp2,dir_dat
	tst	temp2
	breq	play_rew0
play_rew05:
	sts	dir_count,temp2
	ldi	temp1,0xff
	rcall	search_dir_mp3
	tst	temp2
	brne	play_rew06
	rjmp	play_d_mi0
play_rew06:
	sts	musiccount,temp2
	rcall	sort_song
play_rew07:
	lds	temp2,musiccount
	lds	temp1,key_input
	cpi	temp1,key_d_mi
	brne	play_rew1
	ldi	temp2,1
play_rew1:
	sts	playmusic,temp2
	clr	temp2
	sts	cluster,temp2
	sts	cluster+1,temp2
	rjmp	play
play_stop:
	cli
	lds	temp1,playmusic
	ldiw	z,rom_pm
	rcall	EEPROM_WR
	lds	temp1,dir_count
	ldiw	z,rom_dc
	rcall	EEPROM_WR
	mov	temp1,r10
	ldiw	z,rom_cl
	rcall	EEPROM_WR
	mov	temp1,r11
	ldiw	z,rom_cl+1
	rcall	EEPROM_WR
	lds	temp1,secpcl
	inc	temp1
	sub	temp1,r3
	clr	temp2
	add	temp1,r8
	adc	r9,temp2
	ldiw	z,rom_re
	rcall	EEPROM_WR
	mov	temp1,r9
	ldiw	z,rom_re+1
	rcall	EEPROM_WR
	lds	temp1,musicsize
	ldiw	z,rom_mu
	rcall	EEPROM_WR
	lds	temp1,musicsize+1
	ldiw	z,rom_mu+1
	rcall	EEPROM_WR
	lds	temp1,musicsize+2
	ldiw	z,rom_mu+2
	rcall	EEPROM_WR
	lds	temp1,volume
	ldiw	z,rom_vo
	rcall	EEPROM_WR
	lds	temp1,mode
	ldiw	z,rom_mo
	rcall	EEPROM_WR
play_stop0:
	ldi	temp2,0
	ldi	temp3,0
	ldi	temp4,0x10
	rcall	mp3_cmd	;0,0x0010 power down
	ldi	temp1,200
	rcall	wait_ms
	cbi	PORTD,led
key_off_ck1:	;power_SWを離したか
	in	temp1,PINC
	andi	temp1,0b00011111
	cpi	temp1,0b00011111  ;no key_in
	brne	key_off_ck1
	ldi	temp1,250
	rcall	wait_ms
	ldi	temp2,1
	rcall	mp3_read	;SCI_STATUS read
	ldi	temp2,1
;	ori	temp3,0
	ori	temp4,0x08	;SCI_STATUS|SS_APDOWN2(3bit)
	rcall	mp3_cmd		;SCI_STATUS write
	cbi	PORTB,mp3_reset
	cbi	PORTC,p_hold	;power down
	sleep
play_stop1:
	rjmp	play_stop1
;**********************************************
loop:
	cli
	clr	r1
	inc	r1
	rcall	beep
loop1:
	rjmp	play_stop0	
;**********************************************
;play_MP3 ;arg=playmusic,cluster,remainsec
play_mp3:
	lds	temp1,playmusic
	lds	temp2,dir_count
	rcall	load_entry
	tst	temp2
	brmi	play_mp3_3
play_mp3_2:
	lds	temp1,buff+11
	cpi	temp1,0x20
	breq	p_mp3_1
play_mp3_3:
	clr	temp2	;no file entry 
	ret
p_mp3_1:
	lds	r12,buff+28
	lds	r13,buff+29
	lds	r14,buff+30
	lds	r15,buff+31	;musicsize=r15:14:13:12
	tst	r15
	breq	p_mp3_2	;filesize < $FFFFFF(16MB)
	ldi	temp2,0	;         >=
	ret
p_mp3_2:
	sts	musicsize,r12
	sts	musicsize+1,r13
	sts	musicsize+2,r14
	lds	r10,buff+26	;play start top	
	lds	r11,buff+27	;cluster=r11:10
	clr	temp3		;r14:13:12/512=r9:8 (remainsec)	
	mov	temp2,r14	;r14:13:12 mod 512=r7:6(remain　byte)
	mov	temp1,r13
	lsr	temp2
	ror	temp1
	brcc	p_mp3_21	;carry_flag =0
	ldi	temp3,1		;           =1
p_mp3_21:
	mov	r8,temp1
	mov	r9,temp2
	mov	r6,r12
	mov	r7,temp3
	lds	r3,secpcl
;p_mp3_8:
	lds	r10,buff+26	
	lds	r11,buff+27	
	lds	temp1,cluster
	lds	temp2,cluster+1
	clr	temp3
	or	temp3,temp1
	or	temp3,temp2	
	brne	p_mp3_29
	sts	cluster,r10
	sts	cluster+1,r11
	sts	remainsec,r8
	sts	remainsec+1,r9
	rjmp	p_mp3_3
p_mp3_29:
	mov	r10,temp1	;play cont
	mov	r11,temp2	;
	lds	r8,remainsec
	lds	r9,remainsec+1
p_mp3_3:
	mov	temp1,r10
	and	temp1,r11	;r11:10=0xFFFF?
	cpi	temp1,0xFF
	breq	p_mp3_4
	tst	r11
	brne	p_mp3_5
	ldi	temp1,2
	cp	r10,temp1
	brcc	p_mp3_5
p_mp3_4:
	ldi	temp2,-2
	ret
p_mp3_5:
	rcall	sec_addr_set
	rcall	mp3_int
	clr	temp1
	sts	key_c,temp1
	sts	key_in,temp1
p_mp3_9:
	ldi	temp1,1
	clr	temp2
	sub	r8,temp1
	sbc	r9,temp2
	brcc	p_mp3_91
	rjmp	p_mp3_30
p_mp3_91:
	sts	spi_arg+1,r15
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13	
	sts	spi_arg+4,r12
	rcall	secdat_read
	ldiw	y,secdat
p_mp3_09:
	sbic	PINB,mp3_dreq
	rjmp	p_mp3_09n
	rcall	Interrupt
	tst	r20
	brmi	p_mp3_09
p_mp3_092:
	mov	temp2,r20
	ret
p_mp3_09n:
	ld	temp1,y+
	cbi	PORTB,mp3_dcs
	rcall	spi_out
	sbi	PORTB,mp3_dcs
	cpi	yL,low(secdat+512)	;+512
	brne	p_mp3_09
	cpi	yH,high(secdat+512)	
	brne	p_mp3_09
	dec	r3
	breq	p_mp3_20
	ldi	temp1,0x02
	clr	temp2
	add	r13,temp1
	adc	r14,temp2
	adc	r15,temp2
	rjmp	p_mp3_9
p_mp3_20:
	rcall	next_cluster	;cluster=r11:10,return=r5:4
	mov	r10,r4
	mov	r11,r5
	mov	temp1,r10
	and	temp1,r11	;r11:10=0xFFFF?
	cpi	temp1,0xFF
	breq	p_mp3_201
	tst	r11
	brne	p_mp3_22
	ldi	temp1,2
	cp	r10,temp1
	brcc	p_mp3_22
p_mp3_201:
	ldi	temp2,-2
	ret
p_mp3_22:
	lds	r3,secpcl
	rcall	sec_addr_set
	rjmp	p_mp3_9
p_mp3_30:
	mov	temp1,r6
	or	temp1,r7
	brne	p_mp3_31
	clr	temp2
	ret	;remain btye=0
p_mp3_31:
	sts	spi_arg+1,r15
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13	
	sts	spi_arg+4,r12
	rcall	secdat_read
	ldiw	y,secdat
	add	r6,yL
	adc	r7,yH	;r7:r6 end byte set
p_mp3_40:
	sbic	PINB,mp3_dreq
	rjmp	p_mp3_40n
	rcall	Interrupt
	tst	r20
	brmi	p_mp3_40
p_mp3_401:
	mov	temp2,r20
	ret
p_mp3_40n:
	ld	temp1,y+
	cbi	PORTB,mp3_dcs
	rcall	spi_out
	sbi	PORTB,mp3_dcs
	cp	yL,r6
	cpc	yH,r7
	brcs	p_mp3_40
p_mp3_50:
	clr	temp2
	ret		
;**********************************************
Interrupt:	;割り込み処理　
	cli
	outi	TCCR1B,0
	lds	zL,v_t
	lds	zH,v_t+1
	sbiw	zL,1
	breq	inter95
inter94:
	sts	v_t,zL
	sts	v_t+1,zH
	rjmp	inter96
inter95:
	ldi	temp1,0
	sts	v_t,temp1
	ldi	temp1,10
	sts	v_t+1,temp1
	rcall	v_read
	cpi16	zH,zL,305
	brcc	inter96
	ldi	temp1,1
	rcall	wait_ms
	rcall	v_read
	cpi16	zH,zL,305
	brcc	inter96
	ldi	temp1,10
	mov	r0,temp1
	clr	r1	
	rcall	beep	;low 10times
	ldi	temp1,key_stop
	sts	key_input,temp1
	rjmp	inter_stop	;shut down mode
inter96:
	in	temp4,PINC
	andi	temp4,0b00011111
	cpi	temp4,0b00011111  ;key_CK
	breq	inter98
	lds	temp1,key_in
	cp	temp1,temp4
	breq	inter0
inter98:
	sts	key_in,temp4
	clr	temp1
	sts	key_c,temp1
	rjmp	inter99
inter0:
	lds	temp4,key_c
	inc	temp4
	cpi	temp4,7
	breq	inter01
	sts	key_c,temp4
	rjmp	inter99
inter01:
	sts key_input,temp1
	clr	temp4
	sts	key_in,temp4
	sts	key_c,temp4
	cpi	temp1,key_vp
	brne	inter1
	lds	temp3,volume
	subi	temp3,4
	cpi	temp3,0x12
	brcc	inter_vol
	ldi	temp3,0x12
	rjmp	inter_vol
inter1:
	cpi	temp1,key_vm
	brne	inter2
	lds	temp3,volume
	subi	temp3,-4
	cpi	temp3,0x8A
	brcs	inter_vol
	ldi	temp3,0x8A
	rjmp	inter_vol
inter2:
	cpi	temp1,key_ff
	brne	inter3
	ldi	temp1,250
	rcall	wait_ms
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_ff
	brne	inter21
	ldi	temp1,key_d_pl
	sts	key_input,temp1
inter21:
	ldi	r20,1
	rjmp	inter_end
inter3:
	cpi	temp1,key_rew
	brne	inter4
	ldi	temp1,250
	rcall	wait_ms
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_rew
	brne	inter31
	ldi	temp1,key_d_mi
	sts	key_input,temp1
inter31:
	ldi	r20,2	
	rjmp	inter_end
inter_vol:
	sts	volume,temp3
	ldi	temp2,11
	mov	temp4,temp3
	rcall	mp3_cmd
inter99:
	outi	TIMSK,1<<TICIE1
	outi	TCCR1B,1<<ICES1	;捕獲(ｷｬﾌﾟﾁｬ)起動入力ｴｯｼﾞ選択 Ｌ→Ｈ
	sbic	PINB,mp3_dreq
	rjmp	inter991
	sei
	sleep
inter991:
	ldi	r20,-1
	rjmp	inter_end
inter_stop:	;key in 		
	ldi	r20,3
	ret
inter_end:
	outi	TCNT1H,0x80
	outi	TCNT1L,0	;0x8000/8M*256=1s
	outi	TIMSK,1<<TOIE1
	outi	TCCR1B,1<<CS12	
	sei
	ret
inter4:
	cpi	temp1,key_stop
	brne	inter99
	ldi	temp1,200
	rcall	wait_ms
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_stop
	breq	inter_stop
	ldi	temp1,70
	rcall	wait_ms
inter_wait0:	;timer0_int
	outi	TCNT0,0
	outi	TIMSK,1<<TOIE0	;Overflow int
	outi	TCCR0,5		;Tck=CK/1024  256/8M/1024---33ms
	sei
inter_wait:
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_vp
	brne	inter_mode1
	ldi	temp1,100
	rcall	wait_ms
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_vp
	brne	inter_mode1
	lds	temp1,mode
	dec	temp1
	brpl	inter_mode2
	ldi	temp1,2
inter_mode2:
	sts	mode,temp1
	clr	r20
	sts	led_time,r20
inter_mode1:
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_stop
	brne	inter_wait
	ldi	temp1,50
	rcall	wait_ms
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,key_stop
	brne	inter_wait
inter_mode3:
	in	temp4,PINC
	andi	temp4,0b00011111;key_CK
	cpi	temp4,0b00011111;key_no
	brne inter_mode3
	sbi	PORTD,led
	cli
	outi	TCCR0,0
	rjmp	inter991
;**********************************************
v_read:
	sbi     ADCSR,ADEN	;adc on
	sbi     ADCSR,ADIF	;Reset interrupt flag
 	sbi	ADCSR,ADSC	;Start A/D conversion
v_read1:	
 	sbis	ADCSR,ADIF
 	rjmp	v_read1
	in	zL,ADCL	;
	in	zH,ADCH	;
	cbi	ADCSR,ADEN	;adc off  
	lsr	zH	;V/2:256=X:1024
	ror	zL	;V=X/2 (uint0.01V)
	ret
;**********************************************
mp3_hard_int:
	sbi	PORTB,mp3_reset	;set H		
mp3_hard_int0:
	ldi	temp1,15
	rcall	wait_ms
	sbi	PORTB,mp3_dcs	;mp3_bsync daly 10ms+ from XRESET
mp3_hard_int1:
	sbis	PINB,mp3_dreq
	rjmp	mp3_hard_int1
	ret
;**********************************************
mp3_int:		;soft reset
	clr	temp4	;'0' 2048byte(8x256) send to SDI 
mp3_int0:	
	ldiw	z,mp3_0*2
	rcall	mp3_sin
	inc	temp4
	brne	mp3_int0	
	ldi	temp2,0
	ldi	temp3,0x08	;SM_SDINEW bit set VS1002 native SPI modes
	ldi	temp4,0x04	;reset bit set
	rcall	mp3_cmd	;0,0x0804 ;cmd=temp2,arg[H:L]=temp3:temp4
mp3_int1:
	sbis	PINB,mp3_dreq
	rjmp	mp3_int1
	ldi	temp2,3
	ldi	temp3,0x98
	ldi	temp4,0x00	;0x8000+12288000/2000
	rcall	mp3_cmd	;3,0x9800		
	ldi	temp2,11
	lds	temp3,volume
	mov	temp4,temp3
	rcall	mp3_cmd	;11,left/right
	ret	
;**********************************************
mp3_cmd:	;com=temp2,arg=temp3:4
	cbi	PORTB,mp3_cs
	ldi	temp1,2
	rcall	spi_out
	mov	temp1,temp2
	rcall	spi_out
	mov	temp1,temp3
	rcall	spi_out
	mov	temp1,temp4
	rcall	spi_out
	sbi	PORTB,mp3_cs
	ldi	temp1,10
	rcall	wait_us
	ret
;**********************************************
mp3_read:	;com=temp2,data=temp3:4
	cbi	PORTB,mp3_cs
	ldi	temp1,3
	rcall	spi_out
	mov	temp1,temp2
	rcall	spi_out
	rcall	spi_in
	mov	temp3,temp2
	rcall	spi_in
	mov	temp4,temp2
	sbi	PORTB,mp3_cs
	ldi	temp1,10
	rcall	wait_us
	ret
;**********************************************
mp3_sin:	;data_addr Z
	ldi	r21,8
mp3_sin_0:
	sbis	PINB,mp3_dreq
	rjmp	mp3_sin_0
	cbi	PORTB,mp3_dcs
	lpm	temp1,z+
	rcall	spi_out
	sbi	PORTB,mp3_dcs
	dec	r21
	brne	mp3_sin_0
	ret
;**********************************************
beep:	;times:r0,High/Low:r1(=1/0) 
	rcall	mp3_int
	ldi	temp2,0
	ldi	temp3,0x08	;SM_SDINEW bit set 
	ldi	temp4,0x20	;SDI test set
	rcall	mp3_cmd	
	ldi	temp1,100	;wait
	rcall	wait_ms
beep_0:
	tst	r1
	breq	beep_1
	ldiw	z,beep_H*2
	rjmp	beep_2
beep_1:
	ldiw	z,beep_L*2
beep_2:
	rcall	mp3_sin
	ldi	temp1,100	;音の長さ
	rcall	wait_ms
	ldiw	z,beep_s*2
	rcall	mp3_sin
	ldi	temp1,30	;無音の長さ
	rcall	wait_ms
	dec	r0
	brne	beep_0
	rcall	mp3_int
	ret		
;**********************************************
sec_addr_set:
	clr	r12
	lds	r13,datastart
	lds	r14,datastart+1
	lds	r15,datastart+2
	mov	temp1,r10
	mov	temp2,r11
	subi	temp1,2
	sbci	temp2,0
	clr	temp3
	mul	temp1,r3
	add	r13,r0
	adc	r14,r1
	adc	r15,temp3
	mul	temp2,r3
	add	r14,r0
	adc	r15,r1
	lsl	r13
	rol	r14
	rol	r15
	ret
;**********************************************
next_cluster:	;cluster=r11:10  FAT16 
	clr	temp1		;fatstart*512  ->
	lds	temp2,fatstart	;temp4:3:2:1
	lds	temp3,fatstart+1
	clr	temp4
	lsl	temp2
	rol	temp3
	rol	temp4
	mov	r12,r10
	mov	r13,r11
	clr	r14		;cluster*2
	lsl	r12
	rol	r13
	rol	r14
	clr	r15
	add	temp1,r12
	adc	temp2,r13
	adc	temp3,r14
	adc	temp4,r15	;addr=temp4:3:2:1
	ldiw	z,0x01FF	
	and	zL,temp1
	and	zH,temp2	;addr&511 -> Z
	clr	temp1
	andi	temp2,0xFE
	sts	spi_arg+1,temp4
	sts	spi_arg+2,temp3
	sts	spi_arg+3,temp2
	sts	spi_arg+4,temp1
	rcall	spi_read_open	;addr=spi_arg[4:1]
	tst	temp2
	breq	n_c_1
	rcall	spi_read_close
	clr	r4
	clr	r5
	ret	
n_c_1:
	ldiw	x,0
n_c_2:
	rcall	spi_in
	cp	xL,zL
	cpc	xH,zH
	breq	n_c_3
	rcall	spi_in
	adiw	xL,2
	rjmp	n_c_2
n_c_3:
	mov	temp3,temp2
	rcall	spi_in
	mov	temp4,temp2
	cpi	temp4,0xff
	brne	n_c_4
	cpi	temp3,0xf7
	brcs	n_c_4
	ldi	temp4,0xff
	ldi	temp3,0xff
n_c_4:
	mov	r4,temp3
	mov	r5,temp4
n_c_5:
	adiw	xL,2
	cpi	xH,0x02
	breq	n_c_6
	rcall	spi_in
	rcall	spi_in
	rjmp	n_c_5
n_c_6:
	rcall	spi_read_close
	ret
;**********************************************
secdat_read:	;512byte read -> secdat[511:0]
	rcall	spi_read_open	
	tst	temp2
	breq	s_d_r0
	ret
s_d_r0:
	ldiw	y,secdat
s_d_r1:
	rcall	spi_in
	st	y+,temp2
	cpi	yL,low(secdat+512)	;512?
	brne	s_d_r1
	cpi	yH,high(secdat+512)	
	brne	s_d_r1
	rcall	spi_read_close
	ret
;**********************************************
sort_dir:
	ldiw	x,dir_dat+2	;dir_dat[2:29]=0
	clr	temp1	
sort_dir_0:
	st	x+,temp1
	cpi	xL,low(dir_dat+30)
	brne	sort_dir_0
	cpi	xH,high(dir_dat+30)
	brne	sort_dir_0
	ldiw	z,dir_dat_w
	lds	r20,dir_dat
sort_dir_1:
	lds	r22,dir_dat
	clr	r21
	ldd	temp1,z+2
	ldd	temp2,z+3
	ldiw	y,dir_dat_w
sort_dir_2:
	ldd	temp3,y+2
	ldd	temp4,y+3
	cp	temp4,temp2
	cpc	temp3,temp1
	brcc	sort_dir_3	;fname(n) >= fname(x) 
	inc	r21		;         <
sort_dir_3:
	dec	r22
	breq	sort_dir_4
	adiw	yL,4
	rjmp	sort_dir_2
sort_dir_4:
	ldiw	x,dir_dat+2
	lsl	r21
	clr	temp1
	add	xL,r21
	adc	xH,temp1
sort_dir_5:
	ld	temp1,x+
	ld	temp2,x+
	or	temp1,temp2	;temp1:2=0  ?
	brne	sort_dir_5
	sbiw	xL,2		
	ld	temp1,z
	ldd	temp2,z+1
	st	x+,temp1
	st	x,temp2
	dec	r20
	breq	sort_dir_e
	adiw	zL,4
	rjmp	sort_dir_1
sort_dir_e:
	ret
;**********************************************
sort_song:	;r21 song count
	ldiw	x,play_dat	;play_dat[0:19]=0
	ldi	temp1,0xFF		
sort_song_0:
	st	x+,temp1
	cpi	xL,low(play_dat+20)
	brne	sort_song_0
	cpi	xH,high(play_dat+20)
	brne	sort_song_0
	ldiw	z,dir_dat_w
	mov	r20,r21
sort_song_1:
	mov	r22,r21
	clr	r23
	ldd	temp1,z+1
	ldd	temp2,z+2
	ldiw	y,dir_dat_w
sort_song_2:
	ldd	temp3,y+1
	ldd	temp4,y+2
	cp	temp4,temp2
	cpc	temp3,temp1
	brcc	sort_song_3	;fname(n) >= fname(x) 
	inc	r23		;         <
sort_song_3:
	dec	r22
	breq	sort_song_4
	adiw	yL,3
	rjmp	sort_song_2
sort_song_4:
	ldiw	x,play_dat
	clr	temp1
	add	xL,r23
	adc	xH,temp1
sort_song_5:
	ld	temp1,x+
	cpi	temp1,0xFF
	brne	sort_song_5		
	ld	temp1,z
	st	-x,temp1
	dec	r20
	breq	sort_song_e
	adiw	zL,3
	rjmp	sort_song_1
sort_song_e:
	ret
;**********************************************
load_entry:	;temp1:playmusic,temp2:dir_count
	cpi	temp1,21
	brcc	load_entry3
	tst	temp1
	breq	load_entry3
	lds	temp3,dir_dat
	cp	temp3,temp2
	brcc	load_entry5
load_entry3:	
	ldi	temp2,-1
	ret
load_entry5:	
	dec	temp1
	clr	temp3
	ldiw	x,play_dat
	add	xL,temp1
	adc	xH,temp3
	ld	temp3,x		;entry_No
	clr	r22		;  x 32 ->
	lsl	temp3		;    r22:temp3
	rol	r22
	swap	temp3
	mov	temp1,temp3
	andi	temp1,0x0F
	swap	r22
	or	r22,temp1
	andi	temp3,0xF0
	mov	r20,temp3
	ldi	r21,0x01
	and	r21,r22		;addr(0-511) -> r21:r20
	andi	r22,0xFE
	tst	temp2
	breq	load_entry_20	;root_dir
load_entry_10:
	lsl	temp2
	clr	temp1
	ldiw	z,dir_dat
	add	zl,temp2
	adc	zH,temp1
	ld	r10,z+  	;cluster_No L
	ld	r11,z		;cluster_No H
	mov	temp1,r10
	and	temp1,r11
	cpi	temp1,0xFF
	breq	load_entry_1a
	mov	temp1,r10
	or	temp1,r11
	brne	load_entry_11
load_entry_1a:
	ldi	temp2,-1
	ret	
load_entry_11:	
	lds	r3,secpcl
	lsl	r3		;high(secpcl*512) -> 2 x secpcl
	mov	r23,r22
load_entry_12:
	sub	r23,r3
	brcs	load_entry_18
	rcall	next_cluster
	mov	r10,r4
	mov	r11,r5
	rjmp	load_entry_12
load_entry_18:
	lds	r3,secpcl
	rcall	sec_addr_set
	rjmp	load_entry_21
load_entry_20:	
	clr	r12
	lds	r13,dirstart	;dirstart[1:0]*512 
	lds	r14,dirstart+1	;   ->  r15:14:13:12
	clr	r15
	lsl	r13
	rol	r14
	rol	r15
load_entry_21:
	add	r13,r22		;+sector addr 
	adc	r14,r12
	adc	r15,r12
	sts	spi_arg+1,r15		
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13
	sts	spi_arg+4,r12
	rcall	secdat_read
	ldiw	y,secdat
	add	yL,r20
	adc	yH,r21
	ldiw	x,buff			
load_entry_e:			;entry dat -> buff[0:31]
	ld	temp1,y+
	st	x+,temp1
	cpi	xL,low(buff+32)
	brne	load_entry_e	
	cpi	xH,high(buff+32)
	brne	load_entry_e
	clr	temp2	
	ret
;**********************************************
;root MP3&sub_dir search  temp1 file number  
;temp2 found MP3 files		
;max entry:256,sub_dir:14,mp3_file:20
search_mp3:
	mov	r20,temp1
	clr	r21		;return	MP3_count
	clr	r22		;dir count
	clr	r12		;dirstart[1:0]*512 
	lds	r13,dirstart	;   ->  r15:14:13:12
	lds	r14,dirstart+1	
	clr	r15
	lsl	r13
	rol	r14
	rol	r15
	sts	spi_arg+1,r15		
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13
	sts	spi_arg+4,r12	
	clr	r23
search_mp3_1:
	rcall	secdat_read
	ldiw	y,secdat
search_mp3_3:
	ld	temp1,y	
	tst	temp1		;entry[0]=0?
	brne	search_mp3_30	;no
	rjmp	search_mp3_e	;yes entry end  
search_mp3_30:
	cpi	temp1,0xE5	;deleted file?
	breq	search_mp3_4	;yes next entry
	ldd	temp1,y+26
	ldd	temp2,y+27
	or	temp1,temp2	;entry[26]=0 & entry[27]=0
	breq	search_mp3_4	;yes next entry
	ldd	temp1,y+11
	ldi	temp2,0x10
	and	temp2,temp1	;entry[11]  4bit=1
	breq	search_mp3_31	;dir entry? no
	cpi	r20,0xFF	;
	brne	search_mp3_4	;dir dat no set
	inc	r22		;
	ldiw	x,dir_dat_w
	clr	temp1
	mov	temp2,r22
	dec	temp2
	lsl	temp2
	lsl	temp2		;4(n-1)
	add	xL,temp2
	adc	xH,temp1	;X=dir_dat_w[4(n-1)]
	ldd	temp1,y+26	;cluster_No L  ->
	st	x+,temp1	;dir_dat_w[4(n-1)]
	ldd	temp1,y+27	;cluster_No H  ->
	st	x+,temp1	;dir_dat_w[4(n-1)+1]
	ld	temp1,y		;file name[0] ->
	st	x+,temp1	;dir_dat_w[4(n-1)+2]
	ldd	temp1,y+1	;file name[1] ->
	st	x,temp1		;dir_dat_w[4(n-1)+3]
	cpi	r22,14		;max 14dirs
	brne	search_mp3_4	
	rjmp	search_mp3_e
search_mp3_31:
	andi	temp1,0x20	;entry[11] 5bit=1
	breq	search_mp3_4	;Volume or LFN_extension..etc yes next entry
	ldd	temp1,y+8	;file entry
	cpi	temp1,'M'
	brne	search_mp3_4	;entry[8]="M" not  next entry
	ldd	temp1,y+9
	cpi	temp1,'P'
	brne	search_mp3_4	;entry[9]="P" not  next entry
	ldd	temp1,y+10
	cpi	temp1,'3'
	brne	search_mp3_4	;entry[10]="3" not  next entry
	inc	r21		;MP3_file found,MP3_count++
	cpi	r20,0xFF
	breq	search_mp3_39
	ldiw	x,dir_dat_w
	ldi	temp1,3
	mov	temp2,r21
	dec	temp2
	mul	temp1,temp2	;3(n-1)
	add	xL,r0
	adc	xH,r1		;X=dir_dat_w[3(n-1)]
	st	x+,r23		;entry_No
	ld	temp1,y	
	st	x+,temp1	;name[0]
	ldd	temp1,y+1
	st	x,temp1		;name[1]
search_mp3_39:
	cpi	r21,20		;max 20files
	breq	search_mp3_e
search_mp3_4:
	inc	r23
	breq	search_mp3_e	;entry =256
	adiw	yL,32		;entry addr+32
	cpi	yL,low(secdat+512)	;512?	
	breq	search_mp3_5
	rjmp	search_mp3_3
search_mp3_5:	
	cpi	yH,high(secdat+512)	
	breq	search_mp3_6
	rjmp	search_mp3_3	;sector end? not next entry 
search_mp3_6:
	ldi	temp1,0x02	;r15:14:13:12+=512
	clr	temp2		;next sector addr set
	add	r13,temp1	
	adc	r14,temp2
	adc	r15,temp2
	sts	spi_arg+1,r15
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13
	rjmp	search_mp3_1
search_mp3_e:
	cpi	r20,0xFF	
	brne	search_mp3_e0
	ldiw	x,dir_dat	
	st	x+,r22		;dir_dat[0]=sub dir count
	st	x,r21		;dir_dat[1]=root dir files
search_mp3_e0:
	mov	temp1,r20
	mov	temp2,r21
	ret
;**********************************************
;MP3 dir search   temp1 file num,temp2 dir number 
;temp2 found MP3 files
search_dir_mp3:
	mov	r20,temp1
	clr	r23
	clr	r21		;return	MP3_count
	lsl	temp2
	ldiw	z,dir_dat
	add	zl,temp2
	adc	zH,r21
	ld	r10,z+  	;cluster_No L
	ld	r11,z		;cluster_No H
	ldi	temp1,0xFF
	and	temp1,r11
	and	temp1,r10
	cpi	temp1,0xFF
	brne	search_dir_mp3_1
	ret
search_dir_mp3_1:
	lds	r3,secpcl
	rcall	sec_addr_set
search_dir_mp3_11:
	sts	spi_arg+1,r15		
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13
	sts	spi_arg+4,r12	
	rcall	secdat_read
	ldiw	y,secdat
search_dir_mp3_3:
	ld	temp1,y	
	tst	temp1			;entry[0]=0?
	breq	search_dir_mp3_e	;yes entry end  
	cpi	temp1,0xE5		;deleted file?
	breq	search_dir_mp3_4	;yes next entry
	ldd	temp1,y+26
	ldd	temp2,y+27
	or	temp1,temp2		;entry[26]=0 & entry[27]=0
	breq	search_dir_mp3_4	;yes next entry
	ldd	temp1,y+11
;	cpi	temp1,0x10		;entry[11]=0x10 
;	breq	search_dir_mp3_4	;dir entry
	andi	temp1,0x20		;entry[11] 5bit=1
	breq	search_dir_mp3_4	;LFN_extension..etc yes next entry
	ldd	temp1,y+8		;file entry
	cpi	temp1,'M'
	brne	search_dir_mp3_4	;entry[8]="M" not  next entry
	ldd	temp1,y+9
	cpi	temp1,'P'
	brne	search_dir_mp3_4	;entry[9]="P" not  next entry
	ldd	temp1,y+10
	cpi	temp1,'3'
	brne	search_dir_mp3_4	;entry[10]="3" not  next entry
	inc	r21			;MP3_file found MP3_count++
	cp	r20,r21
	breq	search_dir_mp3_e
	ldiw	x,dir_dat_w
	ldi	temp1,3
	mov	temp2,r21
	dec	temp2
	mul	temp1,temp2	;3(n-1)
	add	xL,r0
	adc	xH,r1		;X=dir_dat_w[3(n-1)]
	st	x+,r23		;entry_No
	ld	temp1,y	
	st	x+,temp1	;name[0]
	ldd	temp1,y+1
	st	x,temp1		;name[1]
	cpi	r21,20
	breq	search_dir_mp3_e
search_dir_mp3_4:
	inc	r23
	breq	search_dir_mp3_e	;entry_No =256
	adiw	yL,32			;entry addr+32
	cpi	yL,low(secdat+512)	;512?	
	brne	search_dir_mp3_3	
	cpi	yH,high(secdat+512)	
	brne	search_dir_mp3_3	;sector end? not next entry 
	dec	r3
	breq	search_dir_mp3_5	;cluster end
	ldi	temp1,0x02		;r15:14:13:12+=512
	clr	temp2			;next sector addr set
	add	r13,temp1	
	adc	r14,temp2
	adc	r15,temp2
	rjmp	search_dir_mp3_11
search_dir_mp3_5:
	rcall	next_cluster
	and	temp3,temp4	;=r4&r5
	cpi	temp3,0xFF	;next_cluster nothing
	breq	search_dir_mp3_e
	mov	r10,r4
	mov	r11,r5
	rjmp	search_dir_mp3_1
search_dir_mp3_e:
	mov	temp1,r20
	mov	temp2,r21
	ret
;**********************************************
;Vfat read  sector=512
read_vfat:
	ldi	temp1,BYTE4(446)	
	sts	read32_arg,temp1
	ldi	temp1,BYTE3(446)	
	sts	read32_arg+1,temp1
	ldi	temp1,BYTE2(446)	
	sts	read32_arg+2,temp1
	ldi	temp1,low(446)	
	sts	read32_arg+3,temp1
	rcall	read_32	;(446)
	lds	r2,buff+8	;buff[9:8]-->r3:r2=bpb 
	lds	r3,buff+9	;bpb top sec read 
	clr	temp1	
	mov	temp2,r2
	mov	temp3,r3
	clr	temp4
	lsl	temp2
	rol	temp3
	rol	temp4	;temp4:3:2:1 <= x 512(9bit left_shift)
	sts	read32_arg,temp4
	sts	read32_arg+1,temp3
	sts	read32_arg+2,temp2
	sts	read32_arg+3,temp1
	rcall	read_32	;(temp4:3:2:1)
	lds	temp1,buff+11	;buff[12:11]-->r11:10=sec_log
	lds	temp2,buff+12		
	cpi16	temp2,temp1,0x0200
	breq	read_vfat1
	ldi	temp2,2	;1sec not 512bytes
	ret
read_vfat1:
	lds	temp1,buff+13
	sts	secpcl,temp1	;buff[13]->secpcl
	lds	temp1,buff+14
	lds	temp2,buff+15
	add	temp1,r2
	adc	temp2,r3
	sts	fatstart,temp1
	sts	fatstart+1,temp2 ;buff[15:14]+bpb -> fatstart[1:0]
	lds	temp1,buff+17
	lds	temp2,buff+18
	sts	rdirent,temp1
	sts	rdirent+1,temp2	;buff[18:17] -> rdirent[1:0]
	lds	r10,buff+22
	lds	r11,buff+23	;buff[23:22] -> r11:10=fat_sectors 
	tst	r10
	brne	read_vfat2
	tst	r11
	brne	read_vfat2
	ldi	temp2,1		;not FAT16/12(FAT32?)
	ret	
read_vfat2:
	lds	temp3,buff+16	;buff[16]
	mul	r10,temp3	;buff[16]*fat_sectors_L -> r1:r0
	mov	temp2,r1	;
	mov	temp1,r0	;r1:r0 -> temp2:temp1
	mul	r11,temp3	;buff[16]*fat_sectors_H	 -> r1:r0 (r1=0)
	add	temp2,r0	;temp2:temp1 +=r0:0x00 (fat_sectors*buff[16])
	lds	temp3,fatstart
	lds	temp4,fatstart+1 ;temp4:temp3 <- fatstart[1:0]
	add	temp1,temp3
	adc	temp2,temp4	;temp2:temp1= fat_sectors*buff[16]+ fatstart[1:0]
	sts	dirstart,temp1
	sts	dirstart+1,temp2 ;temp2:temp1 -> dirstart[1:0]
	lds	temp1,rdirent
	lds	temp2,rdirent+1
				;temp2:temp1/16 -> temp2:temp1...temp4
	swap	temp2		;H2:H1 -> H1:H2
 	mov	temp3,temp2
	andi	temp3,0xF0	;H1:0  H1 save
	andi	temp2,0x0F	;0:H2
	ldi	temp4,0x0F
	and	temp4,temp1	;L1 save (temp2:temp1 MOD 16)
	swap	temp1		;L2:L1 -> L1:L2
	andi	temp1,0x0F	;0:L2
	or	temp1,temp3	;H1:L2   (n=temp2:temp1=0:H2:H1:L2)
	tst	temp4
	breq	read_vfat3
	addi16	temp2,temp1,1
read_vfat3:
	lds	temp3,dirstart
	lds	temp4,dirstart+1
	clr	r0
	clr	r1
	add	temp3,temp1
	adc	temp4,temp2
	adc	r0,r1		;n+dirstart[1:0] -> r1:r0:temp4:temp3
	sts	datastart,temp3	;datastart[3:0] <- r1:r0:temp4:temp3
	sts	datastart+1,temp4
	sts	datastart+2,r0
	sts	datastart+3,r1	
	lds	temp1,buff+19
	lds	temp2,buff+20	;all_sectors= buff[20:19]
	clr	temp3		;all_sectors=temp4:3:2:1 =0:0:XX:XX 
	clr	temp4		;                      (16bytes long)
	clr	r15
	or	r15,temp2
	or	r15,temp1	;r15 <- r15|temp2|temp1
	brne	read_vfat4	;(temp2:temp1=0)? not next
	ldi	temp1,32	;yes  bpb=r3:r2	
	clr	r15		;arg <- 32+bpb*512 (9bit left_shift)
	lsl	r2
	rol	r3
	rol	r15	
	sts	read32_arg,r15
	sts	read32_arg+1,r3
	sts	read32_arg+2,r2
	sts	read32_arg+3,temp1
	rcall	read_32	;(32+bpb*512)
	lds	temp1,buff
	lds	temp2,buff+1
	lds	temp3,buff+2
	lds	temp4,buff+3	;all_sectors=temp4:3:2:1
read_vfat4:
	lds	r13,fatstart
	lds	r14,fatstart+1
	clr	r15
	sub	temp1,r13
	sbc	temp2,r14
	sbc	temp3,r15
	sbc	temp4,r15	;all_sectors -= fatstart
	clr	r20		;spcpcl -> r23:22:21:20 (base r20)
	lds	r21,secpcl	;***spcpcl*4096(12bit L_shift)***
	mov	r22,r21		;r20->r21 8bit,r21=r22(H:L) copy
	swap	r21		;r21 H<->L
	andi	r21,0xF0	;r21 L0 (+4bit->12bit)
	swap	r22		;r22 H<->L
	andi	r22,0x0F	;r22 0H  
	clr	r23		;spcpcl*4096 -> r23:22:21:20 
	cp	temp1,r20
	cpc	temp2,r21
	cpc	temp3,r22
	cpc	temp4,r23	;sec:spcpcl*4096
	brmi	read_vfat5
	ldi	temp1,1		;FAT16
	rjmp	read_vfat6
read_vfat5:
	clr	temp1		;FAT12
	ldi	temp2,3		;
	ret			;
read_vfat6:
	sts	fattype,temp1
	clr	temp2
	ret
;**********************************************
;read_32 read32_arg[3:0]
read_32:
	lds	r15,read32_arg	
	lds	r14,read32_arg+1
	lds	r13,read32_arg+2
	lds	r12,read32_arg+3
	mov	temp4,r15
	mov	temp3,r14
	ldi	temp2,0xFE
	and	temp2,r13
	clr	temp1
	sts	spi_arg+1,temp4
	sts	spi_arg+2,temp3
	sts	spi_arg+3,temp2
	sts	spi_arg+4,temp1
	rcall	spi_read_open
	tst	temp2
	breq	read_32_1
	ret	;temp2=1 erro
read_32_1:
	mov	temp3,r12
	ldi	temp4,1
	and	temp4,r13	;low_addr=temp4:3 <- addr&0x1FF
	clr	yL
	clr	yH		;Y:counter 0 to 511
	ldiw	x,buff
	ldiw	z,buff+32
read_32_2:
	rcall	spi_in
	cp	yL,temp3
	cpc	yH,temp4	;Y:low_addr	
	brmi	read_32_3	;Y<low_addr
	cp	xL,zL		;Y>=low_addr
	cpc	xH,zH		;x:buff+32
	brpl	read_32_3	;x>=buff+32
	st	x+,temp2	;Y>=low_addr & x<buff+32
read_32_3:
	adiw	yL,1
	cpi	yH,0x02	;Y=512?
	brne	read_32_2 ;no
read_32_e:
	rcall	spi_read_close
	ret
;**********************************************
;spi_read_open spi_arg[4:1]
spi_read_open:
	ldi	temp4,100
s_r_o1:
	cbi	PORTB,sd_cs	;CS=L
	ldi	temp1,17
	sts	spi_arg,temp1
	rcall	spi_com
	tst	temp2
	brne	s_r_o3
	ldiw	x,4096
s_r_o2:	
	rcall	spi_in
	cpi	temp2,0xFE
	brne	s_r_o21
	clr	temp2
	ret
s_r_o21:
	sbiw	xL,1
	brne	s_r_o2
	rjmp	s_r_o4
s_r_o3:
	cpi	temp2,0xFE
	brne	s_r_o4
	clr	temp2
	ret
s_r_o4:
	sbi	PORTB,sd_cs	;CS=H
	ldi	temp1,20
	rcall	wait_us
	dec	temp4
	breq	s_r_o5
	rjmp	s_r_o1
s_r_o5:
	ldi	temp2,1
	ret	
;**********************************************
;spi_read_close
spi_read_close:
	rcall	spi_in	;CRC
	rcall	spi_in	;CRC
	ldiw	y,2024
s_r_c1:
	rcall	spi_in
	cpi	temp2,0xFF
	breq	s_r_c2
	sbiw	yL,1
	brne	s_r_c1
s_r_c2:
	sbi	PORTB,sd_cs	;CS=H
	ret	
;**********************************************
;SPI DATA input 
spi_in:
	outi	SPDR,0xff
spi_in1:
	sbis	SPSR,SPIF
	rjmp	spi_in1
	in	temp2,SPDR
	ret
;**********************************************
;SPI DATA output   data=temp1
spi_out:
	out	SPDR,temp1
spi_out1:
	sbis	SPSR,SPIF
	rjmp	spi_out1
	ret
;**********************************************
;spi command
spi_com:	;cmd,arg[3:0],ret-->temp2

	ldiw	Y,2024
spi_com1:
	rcall	spi_in
	cpi	temp2,0xff
	breq	spi_com2
	sbiw	YL,1
	brne	spi_com1
	ldi	temp2,1
	ret	;busy error return=1
spi_com2:
	lds	temp1,spi_arg
	mov	temp2,temp1
	ori	temp1,0x40	
	rcall	spi_out		;cmd
	lds	temp1,spi_arg+1
	rcall	spi_out		;arg3
	lds	temp1,spi_arg+2
	rcall	spi_out		;arg2
	lds	temp1,spi_arg+3
	rcall	spi_out		;arg1
	lds	temp1,spi_arg+4
	rcall	spi_out		;arg0
	tst	temp2
	brne	spi_com3
	ldi	temp1,0x95	;int CRC
	rjmp	spi_com4
spi_com3:
	ldi	temp1,1
spi_com4:
	rcall	spi_out		;CRC
	ldiw	Y,2024
spi_com5:
	rcall	spi_in	
	cpi	temp2,0xFE
	breq	spi_com6	;data talken start
	ldi	temp3,0x80
	and	temp3,temp2
	breq	spi_com6	;cmd response (MSB=0)
	sbiw	YL,1
	brne	spi_com5
spi_com6:       ;return=temp2
	ret
;**********************************************
wait_us:	;base 8MHz  temp1　us (8clocks)
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks			
	dec	temp1		; 1clocks
	brne	wait_us		; 2clocks
	ret			; 
wait_ms:	;temp1　ms
	ldi	temp2,100	;80*100=8000clocks
wait_ms_01:
	ldi	temp3,19    	;1clocks  4*(19+1)=80
wait_ms_02:
	nop			; 1clocks
	dec	temp3		; 1clocks
	brne	wait_ms_02	; 2clocks
	dec	temp2		; 1clocks
	brne	wait_ms_01	; 2clocks
	dec	temp1		; 1clocks	
	brne	wait_ms		; 2clocks
	ret
;*********************************************
EEPROM_WR:
	rcall	EEPROM_RD
	cp	temp1,temp2	;同じ値ならスキップ
	brne	EEPROM_WR1
	ret	
EEPROM_WR1:	
	 SBIC	 EECR,EEWE	 ;EEPROM書き込み完了ならばｽｷｯﾌﾟ
	 RJMP	 EEPROM_WR1	 ;以前のEEPROM書き込み完了まで待機
	 OUT	 EEARH,ZH	 ;EEPROMｱﾄﾞﾚｽ上位ﾊﾞｲﾄ設定
	 OUT	 EEARL,ZL	 ;EEPROMｱﾄﾞﾚｽ下位ﾊﾞｲﾄ設定
	 OUT	 EEDR,temp1	 ;EEPROM書き込み値を設定
	 SBI	 EECR,EEMWE	 ;EEPROMﾏｽﾀ書き込み許可ﾋﾞｯﾄ設定
	 SBI	 EECR,EEWE	 ;EEPROM書き込み開始(書き込み許可ﾋﾞｯﾄ設定)
	 RET	 	 	 ;呼び出し元へ復帰
;*********************************************
EEPROM_RD: 
	 SBIC	 EECR,EEWE	 ;EEPROM書き込み完了ならばｽｷｯﾌﾟ
	 RJMP	 EEPROM_RD	 ;以前のEEPROM書き込み完了まで待機
	 OUT	 EEARH,ZH	 ;EEPROMｱﾄﾞﾚｽ上位ﾊﾞｲﾄ設定
	 OUT	 EEARL,ZL	 ;EEPROMｱﾄﾞﾚｽ下位ﾊﾞｲﾄ設定
	 SBI	 EECR,EERE	 ;EEPROM読み出し開始(読み込み許可ﾋﾞｯﾄ設定)
	 IN	 temp2,EEDR	 ;EEPROM読み出し値を取得
	 RET	 	 	 ;呼び出し元へ復帰
;*********************************************
;BEEP data  
beep_H:	.db 0x53,0xEF,0x6E,0xF0,0,0,0,0	;1500Hz
beep_L:	.db 0x53,0xEF,0x6E,0xE8,0,0,0,0	; 750Hz
beep_s:	.db 0x45,0x78,0x69,0x74,0,0,0,0	; stop
mp3_0:	.db 0,0,0,0,0,0,0,0
;*********************************************
TIM1_OVF:
	ldi	temp1,low(RAMEND)
	out	SPL,temp1
	ldi	temp1,high(RAMEND)
	out	SPH,temp1	;init Stack Pointer 
	outi	TCCR1B,0
	rjmp	main_5
;*********************************************
;LED_flush	mode  0:33*5=170,1:33*10=330,2:33*20=660ms
TIM0_OVF:
	in	r0,SREG
	lds	r30,mode
	ldi	r31,5
TIM0_OVF1:
	dec	r30
	brmi	TIM0_OVF2
	lsl	r31
	rjmp	TIM0_OVF1
TIM0_OVF2:
	lds	r20,led_time
	inc	r20
	cp	r20,r31
	brne	TIM0_OVF9
	clr	r20
	sbic	PORTD,led
	rjmp	TIM0_OVF3
	sbi	PORTD,led
	rjmp	TIM0_OVF9
TIM0_OVF3:
	cbi	PORTD,led
TIM0_OVF9:
	sts	led_time,r20
	out	SREG,r0
	reti 