;**** includes **** 
.include "m8def.inc"

; Load immediate word into the resister pair.
;
;	ldiw	Z,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
.def	lcd_data	= r20

;*****************************
;*　 ビット　設定　　*
;*****************************

;**  PORTB  **
.equ	lcd_rs = 0
.equ	key    = 1
.equ	sd_cs  = 2	;SS
.equ	sd_in  = 3	;MOSI
.equ	sd_out= 4	;MISO
.equ	sd_clk = 5	;SCK

;**  PORTD  **
.equ	lcd_rw  = 2
.equ	lcd_enb = 3
.equ	lcd_db4 = 4
.equ	lcd_db5 = 5
.equ	lcd_db6 = 6
.equ	lcd_db7 = 7


.dseg
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]
fatbac:		.BYTE	2	;FATbac[1:0]
fat_sec:	.byte	1	;fat_sectors
dirsecnum:	.byte	1	;useing direntry sector num
rdirent:	.BYTE	2	;rootdirentriescount[1:0]
spi_arg:	.BYTE   5	;cmd,arg[3:0]
read32_arg:	.BYTE	4	;adr[3:0]
buff:		.BYTE  	32	;buff[31:0]
secdat:		.BYTE 	512	;sectorDATA & 受信データ
d_dat:		.byte	80	;表示用 20x4

.cseg
;*********************
;* 割込みベクター *
;*********************
	rjmp	start ;各種ﾘｾｯﾄ
	reti	;RJMP EXT_INT0 ;外部割り込み要求0
	reti	;EXT_INT1 ;外部割り込み要求1
	reti	;TIM2_COMP ;ﾀｲﾏ/ｶｳﾝﾀ2 比較一致
	reti	;TIM2_OVF ;ﾀｲﾏ/ｶｳﾝﾀ2 ｵｰﾊﾞｰﾌﾛｰ
	reti	;TIM1_CAPT ;ﾀｲﾏ/ｶｳﾝﾀ1 ｷｬﾌﾟﾁｬ発生
	reti	;TIM1_COMPA ;ﾀｲﾏ/ｶｳﾝﾀ1 比較A 一致
	reti	;TIM1_COMPB ;ﾀｲﾏ/ｶｳﾝﾀ1 比較B 一致
	reti	;TIM1_OVF ;ﾀｲﾏ/ｶｳﾝﾀ1 ｵｰﾊﾞｰﾌﾛｰ
	reti	;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,0xff
	out	DDRD,temp1	; pd0~7 out port
	ldi	temp1,0x00	; pd0~7 clear	
	out	PORTD,temp1	
	ldi	temp1,0b11101101	; pb765_32_0 out port
	out	DDRB,temp1	; pb765_32_0 clear
	ldi	temp1,0b00010010	; pb4 1 in port	
	out	PORTB,temp1	; pb4 1 pull up

USATR_int:
	outi	UBRRH,0			;4MHz/[(51+1)x16]-->4800Hz
	outi	UBRRL,51			
	outi	UCSRB,(1<<RXEN)|(1<<TXEN)	;RXEN：受信許可、TXEN：送信許可

; LCD - Initialize LCD controller
lcd_init:
	ldi	temp1,15	; wait for 15+ms
	rcall	wait_ms		; /
	rcall	lcd_int		; /
	ldi	temp1,5		; Wait for 4.1ms+
	rcall	wait_ms		; /
	rcall	lcd_int		; /
	ldi	temp1,100 	;wait for 100us+
	rcall	wait_us		; /
	rcall	lcd_int		; /

	ldi	lcd_data,0x20
	rcall	lcd_cmd
	ldi	temp1,100 	;wait for 100us+
	rcall	wait_us		; /
	ldi	lcd_data,0x28	; Data=4bit, Line=2, Font=5x7
	rcall	lcd_cmd		; /
	ldi	lcd_data,0x0c	; Display=ON, Cursor=OFF, Blink=OFF
	rcall	lcd_cmd		; /
	ldi	lcd_data,6		; Increment, No shift
	rcall	lcd_cmd		; /
	ldi	lcd_data,1		; clear ,homepos
	rcall	lcd_cmd

	ldi	lcd_data,0x84
 	rcall	lcd_cmd



spi_0:	;SPI/SD/MMC_int
	outi	SPCR,0x51	;SPI master,CPOL0,CPHA=0,CK=4M/16=250k
	cbi	SPSR,SPI2X
spi_01:
	ldi	temp3,10	;SD SPI mode 74クロック以上送信
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=4M/4=1M
	sbi	SPSR,SPI2X	;ck x 2 -> 2M

	cpi	temp2,0xFF
	brne	spi_30
	ldi	lcd_data,'S'
	rcall	lcd_dsp
	ldi	lcd_data,'D'
	rcall	lcd_dsp
	ldi	lcd_data,'N'
	rcall	lcd_dsp
	ldi	lcd_data,'G'
	rcall	lcd_dsp
spi_29:
	rjmp	spi_29

spi_30:
	ldi	lcd_data,'S'
	rcall	lcd_dsp
	ldi	lcd_data,'D'
	rcall	lcd_dsp
	ldi	lcd_data,'O'
	rcall	lcd_dsp
	ldi	lcd_data,'K'
	rcall	lcd_dsp

	rcall	read_vfat
	tst	temp2
	breq	spi_40
	ldi	lcd_data,'F'
	rcall	lcd_dsp
	ldi	lcd_data,'A'
	rcall	lcd_dsp
	ldi	lcd_data,'T'
	rcall	lcd_dsp
	ldi	lcd_data,'N'
	rcall	lcd_dsp
	ldi	lcd_data,'G'
	rcall	lcd_dsp
spi_39:
	rjmp	spi_39
spi_40:
	lds	temp1,d_dat	;FAT 2組？
	cpi	temp1,2
	breq	spi_99
	ldi	lcd_data,'F'
	rcall	lcd_dsp
	ldi	lcd_data,'A'
	rcall	lcd_dsp
	ldi	lcd_data,'T'
	rcall	lcd_dsp
	ldi	lcd_data,'<'
	rcall	lcd_dsp
	ldi	lcd_data,'>'
	rcall	lcd_dsp
	ldi	lcd_data,'2'
	rcall	lcd_dsp
spi_49:
	rjmp	spi_49	
spi_99:
	
	ldi	lcd_data,'F'
	rcall	lcd_dsp
	ldi	lcd_data,'A'
	rcall	lcd_dsp
	ldi	lcd_data,'T'
	rcall	lcd_dsp
	ldi	lcd_data,'O'
	rcall	lcd_dsp
	ldi	lcd_data,'K'
	rcall	lcd_dsp

	clr temp1
	sts	dirsecnum,temp1
	ldi	r24,2
	clr	r25

main:
	ldi	r22,178	;3min
main1:
	rcall	gps_main
	dec	r22
	brne	main1
	rcall	gps_log
	rjmp	main

gps_log:				
	rcall	fat_sear
	rcall	write_fat
	rcall	write_fat_bac
	rcall	entry_sear
	mov	r6,zl	;entry start addr
	mov	r7,zh
	rcall	entry_set
	
	rcall	gps_main
	rcall	sec_addr_set
	rcall	secdat_write
	
	rcall	entry_read
	mov	zl,r6
	mov	zh,r7
	rcall	entry_rewrite
	ret


	ldi	lcd_data,'O'
	rcall	lcd_dsp
	ldi	lcd_data,'k'
	rcall	lcd_dsp	
test_e:
	rjmp	test_e




gps_main:
	rcall	dat_clr
	ldiw	Z,secdat
	ldi	temp1,'$'
	st	z+,temp1
	ldi	temp1,'G'
	st	z+,temp1
	ldi	temp1,'P'
	st	z+,temp1
	ldi	temp1,'G'
	st	z+,temp1
	ldi	temp1,'G'
	st	z+,temp1
r_0:
	ldi	r17,2
r_1:
	rcall	Rx
	cpi	r16,'G'
	brne	r_0
	dec	r17
	brne	r_1
r_2:
	rcall	Rx
	st	Z+,r16
	cpi	r16,'R'
	brne	r_3
	inc	r17
	rjmp	r_4
r_3:
	cpi	r16,13
	brne	r_4
	tst	r17
	brne	dsp_set
r_4:
	cpi	ZL,low(secdat+512)
	brne	r_2
	cpi	ZH,high(secdat+512)
	brne	r_2
dsp_set:
	sbiw	zl,1
	mov	r8,zl
	mov r9,zh
	ldiw	Z,secdat+7
	ldiw	Y,d_dat+10
time:
	ld	r16,Z+	;h
	ld	r17,Z+
	ldi	r18,' '
	ldi	r19,':'
	st	Y+,r18
	st	Y+,r16			
	st	Y+,r17
	st	Y+,r19
	ld	r16,Z+	;m
	ld	r17,Z+
	st	Y+,r16			
	st	Y+,r17
	st	Y+,r19	
	ld	r16,Z+	;s
	ld	r17,Z+
	st	Y+,r16			
	st	Y+,r17
	st	Y+,r18
north:
	ldiw	Y,d_dat+40
	st	Y+,r18
	ldi	r19,'N'
	st	Y+,r19	
	st	Y+,r18
	adiw	ZL,1
	ld	r16,Z+	
	ld	r17,Z+
	st	Y+,r16			
	st	Y+,r17
	ldi	r19,0xA1	
	st	Y+,r19
	ldi	r17,7
north1:
	ld	r16,Z+	
	st	Y+,r16			
	dec	r17
	brne	north1
	ldi	r17,7
north2:
	st	Y+,r18
	dec	r17
	brne	north2
east:
	ldiw	Y,d_dat+20
	st	Y+,r18
	ldi	r19,'E'
	st	Y+,r19	
	adiw	ZL,3
	ld	r16,Z+	
	ld	r17,Z+
	st	Y+,r16			
	st	Y+,r17
	ld	r16,Z+
	st	Y+,r16
	ldi	r19,0xA1	
	st	Y+,r19
	ldi	r17,7
east1:
	ld	r16,Z+	
	st	Y+,r16			
	dec	r17
	brne	east1
	st	Y+,r18
	st	Y+,r18
eisei:
	ldi	r19,'n'
	st	Y+,r19
	st	Y+,r18
	adiw	ZL,5
	ld	r16,Z+	
	ld	r17,Z+
	st	Y+,r16			
	st	Y+,r17
	st	Y+,r18
high0:
	ldiw	Y,d_dat+60
	st	Y+,r18	
	ldi	r19,'h'
	st	Y+,r19
	st	Y+,r18
	adiw	ZL,6
	ldi	r17,5
high1:
	ld	r16,Z+	
	st	Y+,r16			
	dec	r17
	brne	high1
	ldi	r19,'m'
	st	Y+,r19
	st	Y+,r18
d:
	st	Y+,r18
	ldi	r19,'d'
	st	Y+,r19
	st	Y+,r18
d1:
	ld	r16,Z+
	cpi	r16,'R'
	brne	d1
	ldi	r17,8	
d2:
	ld	r16,Z+
	cpi	r16,','
	brne	d2
	dec	r17
	brne	d2	
	ldi	r17,5
d3:
	ld	r16,Z+	
	st	Y+,r16			
	dec	r17
	brne	d3
	st	Y+,r18
	st	Y+,r18
date:
	ldiw	Y,d_dat
	st	Y+,r18
	adiw	ZL,7
	ldi	r19,'/'
	ld	r16,-Z
	ld	r17,-Z
	st	Y+,r17			
	st	Y+,r16
	st	Y+,r19
	ld	r16,-Z
	ld	r17,-Z
	st	Y+,r17			
	st	Y+,r16
	st	Y+,r19
	ld	r16,-Z
	ld	r17,-Z
	st	Y+,r17			
	st	Y+,r16
	st	Y+,r18
dsp:
	ldiw	Z,d_dat
dsp0:
	ldi	lcd_data,0x80
	rcall	lcd_cmd
	ldi	r19,40	
dsp1:
	ld	lcd_data,Z+
	rcall	lcd_dsp
	dec	r19
	brne	dsp1
	ldi	lcd_data,0xC0
	rcall	lcd_cmd
	ldi	r19,40
dsp2:
	ld	lcd_data,Z+
	rcall	lcd_dsp
	dec	r19
	brne	dsp2
	ret


dat_clr:
	ldiw	Z,secdat
	clr	r17
dat_clr1:
	st	Z+,r17
	cpi	Zl,low(secdat+512)
	brne	dat_clr1
	cpi	ZH,high(secdat+512)
	brne	dat_clr1
	ret

Tx:
	SBIS UCSRA,UDRE 	;送信ﾊﾞｯﾌｧ空きでｽｷｯﾌﾟ
	RJMP Tx 		;送信ﾊﾞｯﾌｧ空き待機
	OUT UDR,R16 	;ﾃﾞｰﾀ送信(送信開始)
	RET 		;呼び出し元へ復帰

Rx:
	SBIS UCSRA,RXC 	;受信完了でｽｷｯﾌﾟ
	RJMP Rx 		;受信完了待機
	IN R16,UDR 	;受信ﾃﾞｰﾀ取得
	RET		;呼び出し元へ復帰
;****************************

;-----------------------------------------------;
; LCD - Send a data/cmd into LCD
	;PORTD   7   6   5   4   3   2    1   0
	;write   <-data(H/L)->  enb r/w   -   -
	;read   BF / address   
 	;PORTB 0:R/S               -
lcd_int:	; Internal reset
	ldi	lcd_data,0x30	; data='0011',RW = "L",E = "L"
	out	PORTD,lcd_data	
	cbi	PORTB,lcd_rs	; RS = "L"
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTD,lcd_enb	; E = "L"
	ret

lcd_dsp:
	rcall	lcd_bfch
	sbi	PORTB,lcd_rs	; RS = "H"
	ldi	temp3,0		; RW = "L",E = "L",data='xxxx'
	rjmp	lcd_cmd1
lcd_cmd:
	rcall	lcd_bfch
	cbi	PORTB,lcd_rs	; RS = "L"
	ldi	temp3,0		; RW = "L",E = "L",data='xxxx'
lcd_cmd1:
	mov	temp2,lcd_data
	swap	temp2
	andi	temp2,0xf0	;data_L save

	andi	lcd_data,0xf0	 ;data_H set
	or	lcd_data,temp3
	out	PORTD,lcd_data	; PORTD = data_H,RW
	sbi	PORTD,lcd_enb	; E = "H"
	mov	lcd_data,temp2	; 
	or	lcd_data,temp3	;data_L set
	nop		
	cbi	PORTD,lcd_enb	; E = "L"
	nop			; I/O delay				
	out	PORTD,lcd_data	; PORTD = data_L,RW			
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTD,lcd_enb	; E = "L"
	ret

lcd_bfch:
	cbi	DDRD,lcd_db7	; lcd_db7 = INPUT
	sbi	PORTD,lcd_db7	; pullup
	sbi	PORTD,lcd_rw	; RW = "H"
	cbi	PORTB,lcd_rs	; RS = "L"
lcd_bfch1:
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp1,PIND
	cbi	PORTD,lcd_enb	; E = "L"
	nop
	nop
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp2,PIND
	cbi	PORTD,lcd_enb	; E = "L"

	andi	temp1,0x80	; Wait until busy flag becomes zero.
	brne	lcd_bfch1
	sbi	DDRD,lcd_db7	; lcd_db7 = OUTPUT
	cbi	PORTD,lcd_db7	; clear
	ret

;**********************************************
wait_us:	;base 4MHz  temp1　us (4clocks)
	nop			; 1clocks		
	dec	temp1		; 1clocks
	brne	wait_us		; 2clocks
	ret			; 

wait_ms:
				;temp1　ms
	ldi	temp2,50		;80*50=4000clocks
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
;*********************************************
entry_set:
	ldi	temp1,'T'
	st	z+,temp1	;0 name 8+3 [0-10]
	ldi	temp1,'E'
	st	z+,temp1	;1
	ldi	temp1,'S'
	st	z+,temp1	;2
	ldi	temp1,'T'
	st	z+,temp1	;3
	ldi	temp1,'0'
	st	z+,temp1	;4
	ldi	temp1,'0'
	st	z+,temp1	;5
	ldi	temp1,'0'
	st	z+,temp1	;6
	mov	temp1,r21
	st	z+,temp1	;7
	ldi	temp1,'L'
	st	z+,temp1	;8
	ldi	temp1,'O'
	st	z+,temp1	;9
	ldi	temp1,'G'
	st	z+,temp1	;10

	ldi	temp1,0x20
	st	z+,temp1	;11	attr
	ldi	temp1,0
	st	z+,temp1	;12 reserved	
	st	z+,temp1	;13 1/10sec
	ldi	temp1,20
	mov	temp2,temp1
	andi	temp2,0x07
	lsl	temp2
	swap	temp2
	andi	temp1,0x38
	lsl	temp1
	swap	temp1
	ldi	temp3,15
	lsl	temp3
	lsl	temp3
	lsl	temp3
	or	temp1,temp3
	st	z+,temp2	;[14-15]time
	st	z+,temp1	;hhhhh:mmm mmm:sssss
	ldi	temp3,107-80	;2007-1980
	lsl	temp3
	ldi	temp4,6
	swap	temp4
	clr	r20
	lsl	temp4
	adc	temp3,r20
	ldi	r20,10
	or	temp4,r20
	st	z+,temp4	;[16-17]date
	st	z+,temp3	;yyyyyyy:m mmm:ddddd
	st	z+,temp4	;[18-19]date
	st	z+,temp3	;yyyyyyy:m mmm:ddddd
	clr	r20
	st	z+,r20	;[20-21] fat_num h3:h2  fat16=0
	st	z+,r20
	st	z+,temp2	;[22-23]time
	st	z+,temp1	;hhhhh:mmm mmm:sssss
	st	z+,temp4	;[24-25]date
	st	z+,temp3	;yyyyyyy:m mmm:ddddd
	st	z+,r24		;fat num [26-27]
	st	z+,r25					
	clr	temp1
	st	z+,temp1	;[28-31]file size
	st	z+,temp1
	st	z+,temp1
	st	z+,temp1
	rcall	entry_write				 
	ret

;*********************************************
entry_rewrite:
	ldiw	Y,d_dat
	ldd	temp1,Y+11
	st	z,temp1		;0 name 8+3 [0-10]
	ldd	temp1,Y+12
	std	z+1,temp1	;1
	ldd	temp1,Y+14
	std	z+2,temp1	;2
	ldd	temp1,Y+15
	std	z+3,temp1	;3
	ldd	temp1,Y+17
	std	z+4,temp1	;4
	ldd	temp1,Y+18
	std	z+5,temp1	;5
	ldi	temp1,' '
	std	z+6,temp1	;6
	ldi	temp1,' '
	std	z+7,temp1	;7

	ldd	temp2,Y+14
	subi	temp2,0x30
	ldd	temp1,Y+15
	subi	temp1,0x30
	lsl	temp2
	add	temp1,temp2
	lsl	temp2
	lsl	temp2
	add	temp1,temp2
	mov	temp2,temp1
	andi	temp2,0x07
	lsl	temp2
	swap	temp2
	andi	temp1,0x38
	lsl	temp1
	swap	temp1
	ldd	temp4,Y+11
	subi	temp4,0x30
	ldd	temp3,Y+12
	subi	temp3,0x30
	lsl	temp4
	add	temp3,temp4
	lsl	temp4
	lsl	temp4
	add	temp3,temp4
	lsl	temp3
	lsl	temp3
	lsl	temp3
	or	temp1,temp3
	std	z+14,temp2	;[14-15]time
	std	z+15,temp1	;hhhhh:mmm mmm:sssss
	std	z+22,temp2	;[22-23]time
	std	z+23,temp1	;hhhhh:mmm mmm:sssss

	ldd	temp4,Y+1
	subi	temp4,0x30
	ldd	temp3,Y+2
	subi	temp3,0x30
	lsl	temp4
	add	temp3,temp4
	lsl	temp4
	lsl	temp4
	add	temp3,temp4
	subi	temp3,-20	;base 1980
	lsl	temp3

	ldd	temp2,Y+4
	subi	temp2,0x30
	ldd	temp4,Y+5
	subi	temp4,0x30
	lsl	temp2
	add	temp4,temp2
	lsl	temp2
	lsl	temp2
	add	temp4,temp2
	swap	temp4
	clr	temp1
	lsl	temp4
	adc	temp3,temp1

	ldd	temp2,Y+7
	subi	temp2,0x30
	ldd	temp1,Y+8
	subi	temp1,0x30
	lsl	temp2
	add	temp1,temp2
	lsl	temp2
	lsl	temp2
	add	temp1,temp2
	or	temp4,temp1
	std	z+16,temp4	;[16-17]date
	std	z+17,temp3	;yyyyyyy:m mmm:ddddd
	std	z+18,temp4	;[18-19]date
	std	z+19,temp3	;yyyyyyy:m mmm:ddddd
	std	z+24,temp4	;[24-25]date
	std	z+25,temp3	;yyyyyyy:m mmm:ddddd

	mov	temp1,r8	;file size zl
	mov temp2,r9	;zh
	subi	temp1,low(secdat)
	sbci	temp2,high(secdat)
	std	z+28,temp1	;[28-29]file size byte4:3
	std	z+29,temp2
	rcall	entry_write	
	ret
;*********************************************
entry_sear:
	rcall	entry_read
	ldiw	z,secdat
e_s_1:
	ld	temp1,z
	cpi	temp1,0xe5
	breq	e_s_e
	cpi	temp1,0
	breq	e_s_e
	adiw	zl,32
	cpi	zl,low(secdat+512)
	brne	e_s_1
	cpi	zh,high(secdat+512)
	brne	e_s_1
	lds	temp1,dirsecnum
	inc	temp1
	cpi	temp1,32
	brne	e_s_2
	rjmp	err_dir_full
e_s_2:
	sts	dirsecnum,temp1
	rjmp	entry_sear
e_s_e:
	ret
;*********************************************
entry_read:
	rcall	dir_add_set
	rcall	secdat_read	;addr=spi_arg[4:1]
	ret
;*********************************************
entry_write:	; FAT16  
	rcall	dir_add_set
	rcall	secdat_write ;addr=spi_arg[4:1]
	ret
;*********************************************
dir_add_set:
	clr	temp1			
	lds	temp2,dirstart		;(dirstart+dirsecnum)*512  ->
	lds	temp3,dirstart+1	;temp4:3:2:1
	clr	temp4
	lds	r13,dirsecnum
	clr	r12
	add	temp1,r12
	adc	temp2,r13
	adc	temp3,r12
	adc	temp4,r12
	lsl	temp1
	rol	temp2
	rol	temp3
	rol	temp4			;addr=temp4:3:2:1
	sts	spi_arg+1,temp4
	sts	spi_arg+2,temp3
	sts	spi_arg+3,temp2
	sts	spi_arg+4,temp1
	ret
;*********************************************
fat_sear:
	rcall	read_fat
	ldiw	Z,secdat
	mov	temp2,r24
	clr temp1
	lsl	temp2
	rol	temp1
	add	zl,temp2	;
	adc	zh,temp1	;
fat_2:
	ld	temp1,Z+
	ld	temp2,Z+
	or	temp1,temp2
	breq	fat_3	;find 0x0000
	adiw	r24,1
	cpi	zl,low(secdat+512)
	brne	fat_2
	cpi	zh,high(secdat+512)
	brne	fat_2

	lds	temp2,fat_sec
	cp	temp2,r25
	brcc	fat_sear
	rjmp	err_fat_full
fat_3:
	ldi	temp1,0xff
	st	-Z,temp1
	st	-Z,temp1
	ret
;*********************************************
read_fat:	; FAT16  
	rcall	fat_add_set
	rcall	secdat_read	;addr=spi_arg[4:1]
	ret
;*********************************************
write_fat:	; FAT16  r25=fatsecnum
	rcall	fat_add_set
	rcall	secdat_write	;addr=spi_arg[4:1]
	ret
;*********************************************
write_fat_bac:	; FAT16  
	lds	temp2,fatbac	
	lds	temp3,fatbac+1	
	rcall	fat_add_set1
	rcall	secdat_write	;addr=spi_arg[4:1]
	ret
;*********************************************
fat_add_set:	;r25=fatsecnum
	lds	temp2,fatstart	
	lds	temp3,fatstart+1
fat_add_set1:
	clr	temp1			;(fatstart+fatsecnum)*512  ->
	clr	temp4			;temp4:3:2:1
	clr	r12
	mov	r13,r25
	add	temp1,r12
	adc	temp2,r13
	adc	temp3,r12
	adc	temp4,r12
	lsl	temp1
	rol	temp2
	rol	temp3
	rol	temp4			;addr=temp4:3:2:1
	sts	spi_arg+1,temp4
	sts	spi_arg+2,temp3
	sts	spi_arg+3,temp2
	sts	spi_arg+4,temp1
	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	r11
	brne	read_vfat20  ;not fat16? 
	tst	r10
	brne	read_vfat2
read_vfat20:
	ldi	temp2,1		;not FAT16/12(FAT32?)
	ret	
read_vfat2:
	sts	fat_sec,r10
	lds	temp3,buff+16	;buff[16]
	sts	d_dat,temp3	;fat class save  2?
	lds	temp1,fatstart	;temp2:temp1 <- fatstart[1:0]	
	lds	temp2,fatstart+1
	add	temp1,r10
	adc	temp2,r11
	sts	fatbac,temp1	;fat_back sector addr 
	sts	fatbac+1,temp2	;fatbac[1:0]
	add	temp1,r10
	adc	temp2,r11
	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
	rjmp	err1
s_r_c2:
	sbi	PORTB,sd_cs	;CS=H
	ret	
;**********************************************
;spi_write_open spi_arg[4:1]
spi_w_open:
	ldi	temp4,100
s_w_o1:
	cbi	PORTB,sd_cs	;CS=L
	ldi	temp1,24
	sts	spi_arg,temp1
	rcall	spi_com
	cpi	temp2,1
	breq	s_w_o4
	ldiw	x,4096
s_w_o2:	
	rcall	spi_in
	cpi	temp2,0
	brne	s_w_o3
	rcall	spi_in
	cpi	temp2,0xff	;wait 1byte 
	brne	s_w_o3
	ldi	temp1,0xFE	;data talkn send
	rcall	spi_out
	clr	temp2
	ret
s_w_o3:
	sbiw	xL,1
	brne	s_w_o2
	rjmp	s_w_o4
s_w_o4:
	sbi	PORTB,sd_cs	;CS=H
	ldi	temp1,20
	rcall	wait_us
	dec	temp4
	breq	s_w_o5
	rjmp	s_w_o1
s_w_o5:
	ldi	temp2,1
	ret	
;**********************************************
;spi_write_close
spi_w_close:
	rcall	spi_out	;CRC
	rcall	spi_out	;CRC
	rcall	spi_in	;data Resp 
	mov	temp3,temp2
	ldiw	y,2048
s_w_c1:
	rcall	spi_in
	cpi	temp2,0xFF
	breq	s_w_c2
	sbiw	yL,1
	brne	s_w_c1
s_w_c2:
	sbi	PORTB,sd_cs	;CS=H
	cpi	temp3,0x05	;data Resp OK?
	brne	s_w_c3
	clr	temp2	;yes 0,no -1
s_w_c3:
	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,2048
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
	cpi	temp2,24	;block write
	brne	spi_com41
	ret
spi_com41:
	ldiw	Y,2048
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
;**********************************************
sec_addr_set:	;cluster_num > sec_addr
	clr	r12
	lds	r13,datastart
	lds	r14,datastart+1
	lds	r15,datastart+2
	mov	temp1,r24
	mov	temp2,r25
	subi	temp1,2
	sbci	temp2,0
	clr	temp3
	lds	r3,secpcl
	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
	sts	spi_arg+1,r15	;addr=r15-r12
	sts	spi_arg+2,r14
	sts	spi_arg+3,r13
	sts	spi_arg+4,r12
	ret
;**********************************************
secdat_read:	;512byte read -> secdat[511:0]
	rcall	spi_read_open	
	tst	temp2
	breq	s_d_r0
	rjmp	err
	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
;**********************************************
secdat_write:	;secdat[511:0] > sd
	rcall	spi_w_open	
	tst	temp2
	breq	s_d_w0
	ret
s_d_w0:
	ldiw	y,secdat
s_d_w1:
	ld	temp1,y+
	rcall	spi_out
	cpi	yL,low(secdat+512)	;512?
	brne	s_d_w1
	cpi	yH,high(secdat+512)	
	brne	s_d_w1
	rcall	spi_w_close
	ret
;**********************************************
sec_dsp:
 	rcall	lcd_cmd
;	ldiw	y,secdat
	mov	yl,zl
	mov	yh,zh
	ldi	r21,40
sec_dsp1:
	ld	lcd_data,y+
;	subi	lcd_data,-0x30
	rcall	lcd_dsp
	dec	r21
	brne	sec_dsp1
	ret

err:
	ldi	lcd_data,0x94
	rcall	lcd_cmd
	ldi	lcd_data,'c'
	rcall	lcd_dsp
	ldi	lcd_data,'a'
	rcall	lcd_dsp
	ldi	lcd_data,'n'
	rcall	lcd_dsp
	ldi	lcd_data,'t'
	rcall	lcd_dsp
	ldi	lcd_data,'o'
	rcall	lcd_dsp
	ldi	lcd_data,'p'
	rcall	lcd_dsp
	rjmp err_e
err1:
	ldi	lcd_data,0x94
	rcall	lcd_cmd
	ldi	lcd_data,'c'
	rcall	lcd_dsp
	ldi	lcd_data,'a'
	rcall	lcd_dsp
	ldi	lcd_data,'n'
	rcall	lcd_dsp
	ldi	lcd_data,'t'
	rcall	lcd_dsp
	ldi	lcd_data,'c'
	rcall	lcd_dsp
	ldi	lcd_data,'L'
	rcall	lcd_dsp

err_e:
	rjmp err_e

err_fat_full:
	ldi	lcd_data,0x94
	rcall	lcd_cmd
	ldi	lcd_data,'f'
	rcall	lcd_dsp
	ldi	lcd_data,'a'
	rcall	lcd_dsp
	ldi	lcd_data,'t'
	rcall	lcd_dsp
	ldi	lcd_data,'f'
	rcall	lcd_dsp
	ldi	lcd_data,'u'
	rcall	lcd_dsp
	ldi	lcd_data,'l'
	rcall	lcd_dsp
	rjmp err_e

err_dir_full:
	ldi	lcd_data,0x94
	rcall	lcd_cmd
	ldi	lcd_data,'d'
	rcall	lcd_dsp
	ldi	lcd_data,'i'
	rcall	lcd_dsp
	ldi	lcd_data,'r'
	rcall	lcd_dsp
	ldi	lcd_data,'f'
	rcall	lcd_dsp
	ldi	lcd_data,'u'
	rcall	lcd_dsp
	ldi	lcd_data,'l'
	rcall	lcd_dsp
	rjmp err_e