📄 fat.s
字号:
.module fat.c
.area text(rom, con, rel)
.dbfile D:\桌面\mp3\FAT\fat.c
.dbfunc e FAT_Init _FAT_Init fV
.even
_FAT_Init::
.dbline -1
.dbline 23
;
;
; #include "config.h"
;
;
; uint8 FAT_ReadBlock(uint32 LBA);
; uint8 FAT_WriteBlock(uint32 LBA);
; uint8 IsEqual(void* A, void* B, uint8 Size);
; void ReadBPB(void);
; uint32 ClusConvLBA(uint16 ClusID);
; uint16 FAT_ReadFAT(uint16 Index);
; uint8 GetFileID(uint8 Name[11], DIR* ID);
;
;
;
; static uint8 BUFFER[512];
; static FileSystemInfo Info;
; static FATFileIndex FileIndex;
; //********************************************************************************************
; //初始化驱动,建立必要数据结构
; //void FAT_Init(void);
; //********************************************************************************************
; void FAT_Init(void) {
.dbline 24
; ReadBPB();
xcall _ReadBPB
.dbline -2
L7:
.dbline 0 ; func end
ret
.dbend
.dbfunc e FAT_ReadBlock _FAT_ReadBlock fc
; LBA -> y+2
.even
_FAT_ReadBlock::
xcall push_arg4
sbiw R28,2
.dbline -1
.dbline 30
; }
;
; //********************************************************************************************
; //读一个扇区
; //********************************************************************************************
; uint8 FAT_ReadBlock(uint32 LBA) {
.dbline 31
; return(MMC_Read_Sector(LBA , BUFFER));
ldi R24,<_BUFFER
ldi R25,>_BUFFER
std y+1,R25
std y+0,R24
movw R30,R28
ldd R16,z+2
ldd R17,z+3
ldd R18,z+4
ldd R19,z+5
xcall _MMC_Read_Sector
.dbline -2
L8:
adiw R28,6
.dbline 0 ; func end
ret
.dbsym l LBA 2 l
.dbend
.dbfunc e FAT_WriteBlock _FAT_WriteBlock fc
; LBA -> y+2
.even
_FAT_WriteBlock::
xcall push_arg4
sbiw R28,2
.dbline -1
.dbline 38
; }
; //********************************************************************************************
; //写一个扇区
; //********************************************************************************************
;
; uint8 FAT_WriteBlock(uint32 LBA)
; {
.dbline 39
; return(MMC_Write_Sector(LBA, BUFFER));
ldi R24,<_BUFFER
ldi R25,>_BUFFER
std y+1,R25
std y+0,R24
movw R30,R28
ldd R16,z+2
ldd R17,z+3
ldd R18,z+4
ldd R19,z+5
xcall _MMC_Write_Sector
.dbline -2
L9:
adiw R28,6
.dbline 0 ; func end
ret
.dbsym l LBA 2 l
.dbend
.dbfunc e IsEqual _IsEqual fc
; b -> R20,R21
; a -> R22,R23
; i -> R10
; Size -> R12
; B -> R18,R19
; A -> R16,R17
.even
_IsEqual::
xcall push_gset4
ldd R12,y+8
.dbline -1
.dbline 43
; }
;
; uint8 IsEqual(void* A, void* B, uint8 Size)
; {
.dbline 44
; uint8 i, *a = A, *b = B;
movw R22,R16
.dbline 44
movw R20,R18
.dbline 45
; for(i = 0; i < Size; i++)
clr R10
xjmp L14
L11:
.dbline 46
; if(*a++!= *b++)
movw R30,R20
ld R2,Z+
movw R20,R30
movw R30,R22
ld R3,Z+
movw R22,R30
cp R3,R2
breq L15
.dbline 47
; return FALSE;
clr R16
xjmp L10
L15:
L12:
.dbline 45
inc R10
L14:
.dbline 45
cp R10,R12
brlo L11
.dbline 48
; return TRUE;
ldi R16,1
.dbline -2
L10:
xcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r b 20 pc
.dbsym r a 22 pc
.dbsym r i 10 c
.dbsym r Size 12 c
.dbsym r B 18 pV
.dbsym r A 16 pV
.dbend
.dbfunc e ReadBPB _ReadBPB fV
.dbstruct 0 512 .3
.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 BS_DrvNum c
.dbfield 37 BS_Reservedl c
.dbfield 38 BS_BootSig c
.dbfield 39 BS_VolID l
.dbfield 43 BS_VolLab A[11:11]c
.dbfield 54 BS_FilSysType A[8:8]c
.dbfield 62 ExecutableCode A[448:448]c
.dbfield 510 ExecutableMarker A[2:2]c
.dbend
; BPB -> R10,R11
.even
_ReadBPB::
xcall push_gset3
.dbline -1
.dbline 56
; }
; //********************************************************************************************
; //读取BPB数据结构
; //static void ReadBPB(void)
; //********************************************************************************************
;
; void ReadBPB(void)
; {
.dbline 57
; FAT_BPB* BPB = (FAT_BPB*)BUFFER;
ldi R24,<_BUFFER
ldi R25,>_BUFFER
movw R10,R24
.dbline 58
; FAT_ReadBlock(0);
ldi R16,0
ldi R17,0
ldi R18,0
ldi R19,0
xcall _FAT_ReadBlock
.dbline 61
;
; //缓存相关参数
; Info.BPB_SecPerClus = BPB->BPB_SecPerClus;
movw R30,R10
ldd R2,z+13
sts _Info,R2
.dbline 62
; Info.BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt;
movw R30,R10
ldd R2,z+14
ldd R3,z+15
sts _Info+1+1,R3
sts _Info+1,R2
.dbline 63
; Info.BPB_NumFATs = BPB->BPB_NumFATs;
movw R30,R10
ldd R2,z+16
sts _Info+3,R2
.dbline 64
; Info.BPB_RootEntCnt = BPB->BPB_RootEntCnt;
movw R30,R10
ldd R2,z+17
ldd R3,z+18
sts _Info+4+1,R3
sts _Info+4,R2
.dbline 65
; Info.BPB_TotSec16 = BPB->BPB_TotSec16;
movw R30,R10
ldd R2,z+19
ldd R3,z+20
sts _Info+6+1,R3
sts _Info+6,R2
.dbline 66
; Info.BPB_FATSz16 = BPB->BPB_FATSz16;
movw R30,R10
ldd R2,z+22
ldd R3,z+23
sts _Info+8+1,R3
sts _Info+8,R2
.dbline 67
; Info.BPB_HiddSec = BPB->BPB_HiddSec;
movw R30,R10
ldd R2,z+28
ldd R3,z+29
ldd R4,z+30
ldd R5,z+31
sts _Info+10+1,R3
sts _Info+10,R2
sts _Info+10+2+1,R5
sts _Info+10+2,R4
.dbline 69
;
; Info.DirStartSec = Info.BPB_RsvdSecCnt + Info.BPB_NumFATs * Info.BPB_FATSz16; //获取根目录开始扇区号
lds R18,_Info+8
lds R19,_Info+8+1
lds R16,_Info+3
clr R17
xcall empy16s
lds R2,_Info+1
lds R3,_Info+1+1
add R2,R16
adc R3,R17
clr R4
clr R5
sts _Info+14+1,R3
sts _Info+14,R2
sts _Info+14+2+1,R5
sts _Info+14+2,R4
.dbline 70
; Info.DataStartSec = Info.DirStartSec + Info.BPB_RootEntCnt * 32 / 512; //获取数据区开始扇区号
lds R18,_Info+4
lds R19,_Info+4+1
ldi R16,32
ldi R17,0
xcall empy16s
ldi R18,9
ldi R19,0
xcall lsr16
movw R2,R16
clr R4
clr R5
lds R8,_Info+14+2
lds R9,_Info+14+2+1
lds R6,_Info+14
lds R7,_Info+14+1
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
sts _Info+18+1,R7
sts _Info+18,R6
sts _Info+18+2+1,R9
sts _Info+18+2,R8
.dbline 71
; Info.DirSecCount = Info.BPB_RootEntCnt * 32 / 512; //目录项占用的扇区数
lds R18,_Info+4
lds R19,_Info+4+1
ldi R16,32
ldi R17,0
xcall empy16s
ldi R18,9
ldi R19,0
xcall lsr16
sts _Info+22+1,R17
sts _Info+22,R16
.dbline -2
L17:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r BPB 10 pS[.3]
.dbend
.dbfunc e ClusConvLBA _ClusConvLBA fl
; ClusID -> R10,R11
.even
_ClusConvLBA::
xcall push_gset3
movw R10,R16
.dbline -1
.dbline 78
; }
; //********************************************************************************************
; //获取一个簇的开始扇区
; //********************************************************************************************
;
; uint32 ClusConvLBA(uint16 ClusID)
; {
.dbline 79
; return Info.DataStartSec + Info.BPB_SecPerClus * (ClusID - 2);
movw R18,R10
subi R18,2
sbci R19,0
lds R16,_Info
clr R17
xcall empy16s
movw R2,R16
clr R4
clr R5
lds R8,_Info+18+2
lds R9,_Info+18+2+1
lds R6,_Info+18
lds R7,_Info+18+1
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
movw R16,R6
movw R18,R8
.dbline -2
L33:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r ClusID 10 i
.dbend
.dbfunc e FAT_ReadFAT _FAT_ReadFAT fi
; RAM -> R20,R21
; Index -> R22,R23
.even
_FAT_ReadFAT::
xcall push_gset2
movw R22,R16
.dbline -1
.dbline 85
; }
; //********************************************************************************************
; //读取文件分配表的指定项
; //********************************************************************************************
; uint16 FAT_ReadFAT(uint16 Index)
; {
.dbline 86
; uint16 *RAM = (uint16*)BUFFER;
ldi R20,<_BUFFER
ldi R21,>_BUFFER
.dbline 87
; FAT_ReadBlock(Info.BPB_RsvdSecCnt + Index / 256);
movw R2,R22
mov R2,R3
clr R3
lds R4,_Info+1
lds R5,_Info+1+1
add R4,R2
adc R5,R3
movw R2,R4
clr R4
clr R5
movw R16,R2
movw R18,R4
xcall _FAT_ReadBlock
.dbline 88
; return RAM[Index % 256];
movw R18,R22
andi R19,0
ldi R16,2
ldi R17,0
xcall empy16s
movw R30,R16
add R30,R20
adc R31,R21
ldd R16,z+0
ldd R17,z+1
.dbline -2
L35:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r RAM 20 pi
.dbsym r Index 22 i
.dbend
.dbfunc e GetFileID _GetFileID fc
.dbstruct 0 32 .4
.dbfield 0 FileName A[11:11]c
.dbfield 11 FileAttrib c
.dbfield 12 UnUsed A[10:10]c
.dbfield 22 FileUpdateTime A[2:2]c
.dbfield 24 FileUpdateData A[2:2]c
.dbfield 26 Start i
.dbfield 28 Size l
.dbend
; DirStart -> R20,R21
; DirSecCut -> R22,R23
; i -> R10,R11
; m -> R14,R15
; ID -> R12,R13
; Name -> y+11
.even
_GetFileID::
xcall push_arg4
xcall push_gset5
movw R12,R18
sbiw R28,1
.dbline -1
.dbline 94
; }
; //********************************************************************************************
; //获得和文件名对应的目录项
; //********************************************************************************************
; uint8 GetFileID(uint8 * Name, DIR* ID)
; {
.dbline 96
; uint16 DirSecCut, DirStart, i, m;
; DirSecCut = Info.DirSecCount; //目录占扇区总数
lds R22,_Info+22
lds R23,_Info+22+1
.dbline 97
; DirStart = Info.DirStartSec; //目录开始扇区
lds R20,_Info+14
lds R21,_Info+14+1
.dbline 98
; for(i = 0; i < DirSecCut; i++)
clr R10
clr R11
xjmp L43
L40:
.dbline 99
; {
.dbline 100
; if(!FAT_ReadBlock(DirStart + i))
movw R2,R20
add R2,R10
adc R3,R11
clr R4
clr R5
movw R16,R2
movw R18,R4
xcall _FAT_ReadBlock
tst R16
brne L44
.dbline 101
; {
.dbline 102
; break;
xjmp L42
L44:
.dbline 104
; }
; for(m = 0; m <16; m++)
clr R14
clr R15
xjmp L49
L46:
.dbline 105
; {
.dbline 107
; // if(IsEqual(Name, &((DIR*)&BUFFER[m * 32])->FileName, 11))
; if(IsEqual(Name, &BUFFER[m * 32], 11))
ldi R24,11
std y+0,R24
ldi R16,32
ldi R17,0
movw R18,R14
xcall empy16s
movw R18,R16
ldi R24,<_BUFFER
ldi R25,>_BUFFER
add R18,R24
adc R19,R25
ldd R16,y+11
ldd R17,y+12
xcall _IsEqual
tst R16
breq L50
.dbline 108
; {
.dbline 109
; *ID = *((DIR*)&BUFFER[m * 32]);
ldi R16,32
ldi R17,0
movw R18,R14
xcall empy16s
movw R2,R16
ldi R24,<_BUFFER
ldi R25,>_BUFFER
add R2,R24
adc R3,R25
ldi R16,32
ldi R17,0
st -y,R13
st -y,R12
st -y,R3
st -y,R2
xcall asgnblk
.dbline 110
; return TRUE;
ldi R16,1
xjmp L37
L50:
.dbline 112
L47:
.dbline 104
movw R24,R14
adiw R24,1
movw R14,R24
L49:
.dbline 104
movw R24,R14
cpi R24,16
ldi R30,0
cpc R25,R30
brlo L46
.dbline 113
L41:
.dbline 98
movw R24,R10
adiw R24,1
movw R10,R24
L43:
.dbline 98
cp R10,R22
cpc R11,R23
brsh X0
xjmp L40
X0:
L42:
.dbline 114
; }
; }
; }
; return FALSE;
clr R16
.dbline -2
L37:
adiw R28,1
xcall pop_gset5
adiw R28,4
.dbline 0 ; func end
ret
.dbsym r DirStart 20 i
.dbsym r DirSecCut 22 i
.dbsym r i 10 i
.dbsym r m 14 i
.dbsym r ID 12 pS[.4]
.dbsym l Name 11 pc
.dbend
.dbfunc e FAT_FileOpen _FAT_FileOpen fl
; FileDir -> y+0
; BytePerClus -> R10,R11
; ClusNum -> R12,R13
; Start -> y+40
; Name -> R12,R13
.even
_FAT_FileOpen::
st -y,r19
st -y,r18
xcall push_gset4
movw R12,R16
sbiw R28,32
.dbline -1
.dbline 120
; }
; //********************************************************************************************
; //打开指定文件
; //********************************************************************************************
; uint32 FAT_FileOpen(uint8 * Name, uint32 Start)
; {
.dbline 123
; uint16 BytePerClus, ClusNum;
; DIR FileDir;
; BytePerClus = Info.BPB_SecPerClus * 512; // 每簇的字节数
lds R18,_Info
clr R19
ldi R16,512
ldi R17,2
xcall empy16s
movw R10,R16
.dbline 124
; if (!GetFileID(Name, &FileDir))
movw R18,R28
movw R16,R12
xcall _GetFileID
tst R16
brne L53
.dbline 125
; {
.dbline 126
; return FALSE;
ldi R16,0
ldi R17,0
ldi R18,0
ldi R19,0
xjmp L52
L53:
.dbline 130
; }
;
; //计算开始位置所在簇的簇号
; ClusNum = Start / BytePerClus;
movw R2,R10
clr R4
clr R5
movw R30,R28
ldd R6,z+40
ldd R7,z+41
ldd R8,z+42
ldd R9,z+43
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R6
movw R18,R8
xcall div32u
movw R12,R16
.dbline 131
; FileIndex.ClusID = FileDir.Start;
ldd R2,y+26
ldd R3,y+27
sts _FileIndex+6+1,R3
sts _FileIndex+6,R2
.dbline 132
; for(FileIndex.i = 0; FileIndex.i < ClusNum; FileIndex.i++)
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -