📄 fat.s
字号:
.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 + -