⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.s

📁 采用Mega16+VS1011B+SD卡制作的Mp3
💻 S
📖 第 1 页 / 共 3 页
字号:
	.module fat.c
	.area text(rom, con, rel)
	.dbfile D:\学习\AVRpro\Mega16程序\TestLCD\fat.c
	.area data(ram, con, rel)
	.dbfile D:\学习\AVRpro\Mega16程序\TestLCD\fat.c
_old_pos_a::
	.blkb 2
	.area idata
	.word 0
	.area data(ram, con, rel)
	.dbfile D:\学习\AVRpro\Mega16程序\TestLCD\fat.c
	.dbsym e old_pos_a _old_pos_a i
	.area lit(rom, con, rel)
_Search_FileExName1::
	.byte 'M,'P
	.byte 51
	.dbsym e Search_FileExName1 _Search_FileExName1 A[3:3]kc
	.area text(rom, con, rel)
	.dbfile D:\学习\AVRpro\Mega16程序\TestLCD\fat.c
	.dbfunc e fat_root_dir_addr _fat_root_dir_addr fl
	.dbstruct 0 62 BootSec
	.dbfield 0 BS_jmpBoot A[3:3]c
	.dbfield 3 BS_OEMName A[8:8]c
	.dbfield 11 BPB_BytesPerSec i
	.dbfield 13 BPB_SecPerClus c
	.dbfield 14 BPB_RsvdSecCnt i
	.dbfield 16 BPB_NumFATs c
	.dbfield 17 BPB_RootEntCnt i
	.dbfield 19 BPB_TotSec16 i
	.dbfield 21 BPB_Media c
	.dbfield 22 BPB_FATSz16 i
	.dbfield 24 BPB_SecPerTrk i
	.dbfield 26 BPB_NumHeads i
	.dbfield 28 BPB_HiddSec l
	.dbfield 32 BPB_TotSec32 l
	.dbfield 36 BPB_PhyDriNum c
	.dbfield 37 BPB_Rsvd1 c
	.dbfield 38 BPB_ExtBootSig c
	.dbfield 39 BPB_VolumeSer l
	.dbfield 43 BPB_VolumeLab A[11:11]c
	.dbfield 54 BPB_SysID A[8:8]c
	.dbend
	.dbstruct 0 90 BootSec32
	.dbfield 0 BS_jmpBoot A[3:3]c
	.dbfield 3 BS_OEMName A[8:8]c
	.dbfield 11 BPB_BytesPerSec i
	.dbfield 13 BPB_SecPerClus c
	.dbfield 14 BPB_RsvdSecCnt i
	.dbfield 16 BPB_NumFATs c
	.dbfield 17 BPB_RootEntCnt i
	.dbfield 19 BPB_TotSec16 i
	.dbfield 21 BPB_Media c
	.dbfield 22 BPB_FATSz16 i
	.dbfield 24 BPB_SecPerTrk i
	.dbfield 26 BPB_NumHeads i
	.dbfield 28 BPB_HiddSec l
	.dbfield 32 BPB_TotSec32 l
	.dbfield 36 BPB_FATSz32 l
	.dbfield 40 BPB_ExtFlag i
	.dbfield 42 BPB_FileSysVer i
	.dbfield 44 BPB_RootCluNum l
	.dbfield 48 BPB_FileSysInf i
	.dbfield 50 BPB_BootBack i
	.dbfield 52 BPB_Rsvd A[12:12]c
	.dbfield 64 BPB_PhyDriNum c
	.dbfield 65 BPB_Rsvd1 c
	.dbfield 66 BPB_ExtBootSig c
	.dbfield 67 BPB_VolumeSer l
	.dbfield 71 BPB_VolumeLab A[11:11]c
	.dbfield 82 BPB_SysID A[8:8]c
	.dbend
;         VBRadd -> R12,R13
;        bootp32 -> R14,R15
;          bootp -> R10,R11
;           buff -> R14,R15
	.even
_fat_root_dir_addr::
	xcall push_xgsetF0FC
	movw R14,R16
	sbiw R28,2
	.dbline -1
	.dbline 22
; #include "fat.h"
; #include "mmc.h"
; 
; //每扇区的字节数目
; unsigned int    BlockSize;		//每扇区的字节数,一般为512
; unsigned long	fat_offset;		////FAT1的起始扇区号
; unsigned long	data_offset;	//数据区的起始扇区数,FAT32的根目录区和数据区重合:
; unsigned char	FatFlags;		//FAT类型:FAT32,FAT16,FAT12
; unsigned long	blocknow;
; unsigned char	SecPerClus;		//每个簇占用的扇区数目,1GB的SD卡应为8
; unsigned char   *pointer_FDT;
; unsigned long   FirstRootDirSecNum;  //根目录区(FDT)的起始扇区号
; unsigned int    old_pos_a=0;
; unsigned long   old_pos_blk;
; 
; const unsigned char Search_FileExName1[3]={'M','P','3'};	//要查找的是TXT文件,可以改成其它的
; 
; //############################################################################
; //从BPB中获取根目录区的起始地址,同时判断FAT制式(判定方法不可靠,不是微软推荐的)
; unsigned long fat_root_dir_addr(unsigned char *buff) 
; //############################################################################
; {
	.dbline 27
; 	struct BootSec *bootp; 			//FAT16 BPB
; 	struct BootSec32 *bootp32;		//FAT32 BPB
; 	unsigned int	VBRadd;	   		//DBR起始扇区号,在它之前都是磁盘分区信息占用的扇区数目
; 
; 	MMC_SD_ReadSingleBlock(BIOS_PARAMETER_BLOCK,buff);   //读取BPB/MBR
	std y+1,R15
	std y+0,R14
	ldi R16,0
	ldi R17,0
	ldi R18,0
	ldi R19,0
	xcall _MMC_SD_ReadSingleBlock
	.dbline 28
; 	if(buff[0] != 0xEB || buff[0] != 0xE9)	  //buff[0]!=0xEB,0xE9,this is mbr //我们的SD卡应该是这一种
	movw R30,R14
	ldd R2,z+0
	clr R3
	mov R24,R2
	cpi R24,235
	brne L4
X0:
	cpi R24,233
	breq L2
X1:
L4:
	.dbline 29
; 	{
	.dbline 30
; 		VBRadd = buff[VBR_ADDR] + (buff[VBR_ADDR + 1])*256;	//real BPB address
	movw R30,R14
	subi R30,57  ; addi 455
	sbci R31,254
	ldd R18,z+0
	clr R19
	ldi R16,256
	ldi R17,1
	xcall empy16s
	movw R30,R14
	subi R30,58  ; addi 454
	sbci R31,254
	ldd R12,z+0
	clr R13
	add R12,R16
	adc R13,R17
	.dbline 31
; 	}
	xjmp L3
L2:
	.dbline 33
; 	else	 //  buff[0]==0xEB,mbr和DBR相同,都是从0扇区开始
; 	{
	.dbline 34
; 		VBRadd = 0;
	clr R12
	clr R13
	.dbline 35
; 	}
L3:
	.dbline 36
; 	MMC_SD_ReadSingleBlock(VBRadd,buff);		//重新再读取DBR
	std y+1,R15
	std y+0,R14
	movw R16,R12
	movw R18,R14
	clr R18
	clr R19
	xcall _MMC_SD_ReadSingleBlock
	.dbline 38
; 
; 	bootp=(struct BootSec *)buff;		//Fat16 的BPB 
	movw R10,R14
	.dbline 39
; 	bootp32=(struct BootSec32 *)buff;	  //Fat32 的BPB
	.dbline 41
; 
; 	if(bootp->BPB_RootEntCnt == 0)		 //根据根目录下面项目数为0,确定是FAT32
	movw R30,R10
	ldd R2,z+17
	ldd R3,z+18
	tst R2
	breq X4
	xjmp L5
X4:
	tst R3
	breq X5
	xjmp L5
X5:
X2:
	.dbline 42
; 	{
	.dbline 43
; 	 	BlockSize=bootp32->BPB_BytesPerSec;		//获取每扇区字节数目							   
	ldd R2,z+11
	ldd R3,z+12
	sts _BlockSize+1,R3
	sts _BlockSize,R2
	.dbline 44
; 		FatFlags = FAT_Flg_32;	//Fat32文件系统
	ldi R24,2
	sts _FatFlags,R24
	.dbline 45
; 		fat_offset = bootp32->BPB_RsvdSecCnt + VBRadd;	//FAT1的起始扇区号
	ldd R2,z+14
	ldd R3,z+15
	add R2,R12
	adc R3,R13
	clr R4
	clr R5
	sts _fat_offset+1,R3
	sts _fat_offset,R2
	sts _fat_offset+2+1,R5
	sts _fat_offset+2,R4
	.dbline 47
; 		//根目录区(FDT)的起始扇区号=保留扇区+FAT占用扇区:
; 		FirstRootDirSecNum=VBRadd+(bootp32->BPB_RsvdSecCnt+(bootp32->BPB_NumFATs*bootp32->BPB_FATSz32));
	ldd R2,z+36
	ldd R3,z+37
	ldd R4,z+38
	ldd R5,z+39
	ldd R16,z+16
	clr R17
	clr R18
	clr R19
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	xcall empy32u
	movw R30,R14
	ldd R2,z+14
	ldd R3,z+15
	clr R4
	clr R5
	add R2,R16
	adc R3,R17
	adc R4,R18
	adc R5,R19
	movw R6,R12
	clr R8
	clr R9
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	sts _FirstRootDirSecNum+1,R7
	sts _FirstRootDirSecNum,R6
	sts _FirstRootDirSecNum+2+1,R9
	sts _FirstRootDirSecNum+2,R8
	.dbline 48
; 		SecPerClus = bootp32->BPB_SecPerClus;	//每个簇占用的扇区数目,SD卡应为8
	ldd R2,z+13
	sts _SecPerClus,R2
	.dbline 50
; 	    //数据区的起始扇区数,FAT32的根目录区和数据区重合:
; 		data_offset = FirstRootDirSecNum;	
	movw R2,R6
	movw R4,R8
	sts _data_offset+1,R3
	sts _data_offset,R2
	sts _data_offset+2+1,R5
	sts _data_offset+2,R4
	.dbline 51
; 	}
	xjmp L6
L5:
	.dbline 53
; 	else	//FAT16或者FAT12文件系统
; 	{
	.dbline 54
; 	    BlockSize=bootp->BPB_BytesPerSec;		//获取每扇区字节数目	
	movw R30,R10
	ldd R2,z+11
	ldd R3,z+12
	sts _BlockSize+1,R3
	sts _BlockSize,R2
	.dbline 55
; 		if(bootp->BPB_SysID[4] == '2')  //根据扩展FAT12/FAT16的系统ID部分,判断
	ldd R24,z+58
	cpi R24,50
	brne L7
X3:
	.dbline 56
; 			FatFlags = FAT_Flg_12;		//FAT12
	clr R2
	sts _FatFlags,R2
	xjmp L8
L7:
	.dbline 58
; 		else
; 			FatFlags = FAT_Flg_16;		//FAT16
	ldi R24,1
	sts _FatFlags,R24
L8:
	.dbline 59
; 		fat_offset = bootp->BPB_RsvdSecCnt + VBRadd;
	movw R30,R10
	ldd R2,z+14
	ldd R3,z+15
	add R2,R12
	adc R3,R13
	clr R4
	clr R5
	sts _fat_offset+1,R3
	sts _fat_offset,R2
	sts _fat_offset+2+1,R5
	sts _fat_offset+2,R4
	.dbline 61
; 		//根目录区(FDT)的起始扇区号=保留扇区+FAT占用扇区:
; 		FirstRootDirSecNum=VBRadd+(bootp->BPB_RsvdSecCnt+(bootp->BPB_NumFATs*bootp->BPB_FATSz16));
	ldd R18,z+22
	ldd R19,z+23
	ldd R16,z+16
	clr R17
	xcall empy16s
	movw R30,R10
	ldd R2,z+14
	ldd R3,z+15
	add R2,R16
	adc R3,R17
	movw R4,R12
	add R4,R2
	adc R5,R3
	movw R2,R4
	clr R4
	clr R5
	sts _FirstRootDirSecNum+1,R3
	sts _FirstRootDirSecNum,R2
	sts _FirstRootDirSecNum+2+1,R5
	sts _FirstRootDirSecNum+2,R4
	.dbline 62
; 		SecPerClus = bootp->BPB_SecPerClus;		//每个簇占用的扇区数目,SD卡应为8
	ldd R2,z+13
	sts _SecPerClus,R2
	.dbline 64
; 	    //数据区的起始扇区数,FAT16/FAT12的根目录,一般占用32个扇区的大小:
; 		data_offset = FirstRootDirSecNum + 32;	
	ldi R20,32
	ldi R21,0
	ldi R22,0
	ldi R23,0
	lds R4,_FirstRootDirSecNum+2
	lds R5,_FirstRootDirSecNum+2+1
	lds R2,_FirstRootDirSecNum
	lds R3,_FirstRootDirSecNum+1
	add R2,R20
	adc R3,R21
	adc R4,R22
	adc R5,R23
	sts _data_offset+1,R3
	sts _data_offset,R2
	sts _data_offset+2+1,R5
	sts _data_offset+2,R4
	.dbline 65
; 	}
L6:
	.dbline 66
; 	return(FirstRootDirSecNum);	 //返回根目录区的起始扇区号
	lds R18,_FirstRootDirSecNum+2
	lds R19,_FirstRootDirSecNum+2+1
	lds R16,_FirstRootDirSecNum
	lds R17,_FirstRootDirSecNum+1
	.dbline -2
L1:
	.dbline 0 ; func end
	adiw R28,2
	xjmp pop_xgsetF0FC
	.dbsym r VBRadd 12 i
	.dbsym r bootp32 14 pS[BootSec32]
	.dbsym r bootp 10 pS[BootSec]
	.dbsym r buff 14 pc
	.dbend
	.dbfunc e fat_load _fat_load fV
;            Tmp -> y+6
; FAT_Block_Addresse -> y+2
; FAT_Byte_Addresse -> R14,R15
;     TMP_Buffer -> R12,R13
;          Block -> R10,R11
;        Cluster -> y+20
	.even
_fat_load::
	xcall push_arg4
	xcall push_xgsetF0FC
	sbiw R28,10
	ldd R10,y+24
	ldd R11,y+25
	ldd R12,y+26
	ldd R13,y+27
	.dbline -1
	.dbline 75
; }
; 
; //############################################################################
; //解析FAT链表
; void fat_load(unsigned long Cluster, 		//文件起始扇区
; 				unsigned long *Block,		//返回文件下一扇区
; 				unsigned char *TMP_Buffer) 	//函数所需buffer
; //############################################################################
; {
	.dbline 80
; 	unsigned int FAT_Byte_Addresse;	
; 	unsigned long FAT_Block_Addresse;
; 
; 	//读取FAT表,根据FAT制式搜寻扇区
; 	if(FatFlags == FAT_Flg_16)
	lds R24,_FatFlags
	cpi R24,1
	breq X18
	xjmp L10
X18:
X6:
	.dbline 81
; 	{
	.dbline 82
; 		if(Cluster == 0xFFFF)
	ldi R20,255
	ldi R21,255
	ldi R22,0
	ldi R23,0
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	cp R2,R20
	cpc R3,R21
	cpc R4,R22
	cpc R5,R23
	brne L12
X7:
	.dbline 83
; 		{
	.dbline 84
; 			return; //文件已经到达末尾
	xjmp L9
L12:
	.dbline 86
; 		}
; 		FAT_Byte_Addresse = ((Cluster<<1) & 0x1FF);
	ldi R20,255
	ldi R21,1
	ldi R22,0
	ldi R23,0
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	lsl R2
	rol R3
	rol R4
	rol R5
	and R2,R20
	and R3,R21
	and R4,R22
	and R5,R23
	movw R14,R2
	.dbline 87
; 		FAT_Block_Addresse = ((Cluster<<1)/BlockSize) + fat_offset;
	lds R2,_BlockSize
	lds R3,_BlockSize+1
	clr R4
	clr R5
	ldd R16,y+20
	ldd R17,y+21
	ldd R18,y+22
	ldd R19,y+23
	lsl R16
	rol R17
	rol R18
	rol R19
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	xcall div32u
	movw R2,R16
	movw R4,R18
	lds R8,_fat_offset+2
	lds R9,_fat_offset+2+1
	lds R6,_fat_offset
	lds R7,_fat_offset+1
	add R2,R6
	adc R3,R7
	adc R4,R8
	adc R5,R9
	std y+2,R2
	std y+3,R3
	std y+4,R4
	std y+5,R5
	.dbline 88
; 		MMC_SD_ReadSingleBlock(FAT_Block_Addresse,TMP_Buffer);
	std y+1,R13
	std y+0,R12
	ldd R16,y+2
	ldd R17,y+3
	ldd R18,y+4
	ldd R19,y+5
	xcall _MMC_SD_ReadSingleBlock
	.dbline 89
; 		*Block = (TMP_Buffer[FAT_Byte_Addresse + 1] << 8) + TMP_Buffer[FAT_Byte_Addresse];
	movw R30,R14
	add R30,R12
	adc R31,R13
	ldd R2,z+0
	movw R30,R14
	adiw R30,1
	add R30,R12
	adc R31,R13
	ldd R3,z+0
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	movw R30,R10
	std z+0,R2
	std z+1,R3
	std z+2,R4
	std z+3,R5
	.dbline 90
; 		if(*Block == 0xFFFF)
	ldi R20,255
	ldi R21,255
	ldi R22,0
	ldi R23,0
	cp R2,R20
	cpc R3,R21
	cpc R4,R22
	cpc R5,R23
	breq X19
	xjmp L9
X19:
X8:
	.dbline 91
; 			*Block = 0xFFFFFFFF;
	ldi R20,255
	ldi R21,255
	ldi R22,255
	ldi R23,255
	std z+0,R20
	std z+1,R21
	std z+2,R22
	std z+3,R23
	.dbline 92
; 	}
	xjmp L9
L10:
	.dbline 93
; 	else if(FatFlags == FAT_Flg_12)
	lds R2,_FatFlags
	tst R2
	breq X20
	xjmp L16
X20:
X9:
	.dbline 94
; 	{
	.dbline 95
; 		if(Cluster == 0xFFF)
	ldi R20,255
	ldi R21,15
	ldi R22,0
	ldi R23,0
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	cp R2,R20
	cpc R3,R21
	cpc R4,R22
	cpc R5,R23
	brne L18
X10:
	.dbline 96
; 		{
	.dbline 97
; 			return; //文件已经到达末尾
	xjmp L9
L18:
	.dbline 99
; 		}
; 		FAT_Byte_Addresse = (((Cluster*3)>>1) & 0x1FF);
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	ldi R20,3
	ldi R21,0
	ldi R22,0
	ldi R23,0
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	movw R16,R20
	movw R18,R22
	xcall empy32u
	movw R2,R16
	movw R4,R18
	lsr R5
	ror R4
	ror R3
	ror R2
	ldi R20,255
	ldi R21,1
	ldi R22,0
	ldi R23,0
	and R2,R20
	and R3,R21
	and R4,R22
	and R5,R23
	movw R14,R2
	.dbline 100
; 		FAT_Block_Addresse = (((Cluster*3)>>1) / BlockSize) + fat_offset;
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	ldi R20,3
	ldi R21,0
	ldi R22,0
	ldi R23,0
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	movw R16,R20
	movw R18,R22
	xcall empy32u
	lsr R19
	ror R18
	ror R17
	ror R16
	lds R2,_BlockSize
	lds R3,_BlockSize+1
	clr R4
	clr R5
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	xcall div32u
	movw R2,R16
	movw R4,R18
	lds R8,_fat_offset+2
	lds R9,_fat_offset+2+1
	lds R6,_fat_offset
	lds R7,_fat_offset+1
	add R2,R6
	adc R3,R7
	adc R4,R8
	adc R5,R9
	std y+2,R2
	std y+3,R3
	std y+4,R4
	std y+5,R5
	.dbline 101
; 		if(FAT_Byte_Addresse == 0x1FF)
	movw R24,R14
	cpi R24,255
	ldi R26,1
	cpc R25,R26
	breq X21
	xjmp L20
X21:
X11:
	.dbline 102
; 		{
	.dbline 103
; 			MMC_SD_ReadSingleBlock(FAT_Block_Addresse,TMP_Buffer);
	std y+1,R13
	std y+0,R12
	ldd R16,y+2
	ldd R17,y+3
	ldd R18,y+4
	ldd R19,y+5
	xcall _MMC_SD_ReadSingleBlock
	.dbline 104
; 			if((Cluster % 2) == 0)
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	mov R16,R2
	andi R16,1
	brne L22
X12:
	.dbline 105
; 			{
	.dbline 106
; 				*Block = TMP_Buffer[FAT_Byte_Addresse];
	movw R30,R14
	add R30,R12
	adc R31,R13
	ldd R2,z+0
	clr R3
	clr R4
	clr R5
	movw R30,R10
	std z+0,R2
	std z+1,R3
	std z+2,R4
	std z+3,R5
	.dbline 107
; 			}
	xjmp L23
L22:
	.dbline 109
; 			else
; 			{
	.dbline 110
; 				*Block = (TMP_Buffer[FAT_Byte_Addresse] >> 4);
	movw R30,R14
	add R30,R12
	adc R31,R13
	ldd R2,z+0
	clr R3
	asr R3
	ror R2
	asr R3
	ror R2
	asr R3
	ror R2
	asr R3
	ror R2
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	movw R30,R10
	std z+0,R2
	std z+1,R3
	std z+2,R4
	std z+3,R5
	.dbline 111
; 			}
L23:
	.dbline 112
; 			MMC_SD_ReadSingleBlock(FAT_Block_Addresse+1,TMP_Buffer);
	std y+1,R13
	std y+0,R12
	ldi R20,1
	ldi R21,0
	ldi R22,0
	ldi R23,0
	ldd R16,y+2
	ldd R17,y+3
	ldd R18,y+4
	ldd R19,y+5
	add R16,R20
	adc R17,R21
	adc R18,R22
	adc R19,R23
	xcall _MMC_SD_ReadSingleBlock
	.dbline 113
; 			if((Cluster % 2) == 0)
	ldd R2,y+20
	ldd R3,y+21
	ldd R4,y+22
	ldd R5,y+23
	mov R16,R2
	andi R16,1
	brne L24

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -