📄 storage.c
字号:
#include "..\define.h"
#include "..\all.h"
//================================================================================================
data U8 gc_ReadWriteTimeOut;
data U8 gc_CurrentCard;
data U8 gc_ReadWriteDataArea;
xdata U8 gc_CurrentExistMedia;
xdata U8 gc_DOS_FileSystemType _at_ 0x68c0;
xdata U16 gw_DOS_SectorSize _at_ 0x68c1;
xdata U8 gc_DOS_SectorPerCluster _at_ 0x68c3;
xdata U32 gdw_DOS_SectorPerFAT _at_ 0x68c4;
xdata U32 gdw_DOS_RootDirAddr _at_ 0x68c8;
xdata U32 gdw_DOS_Fat1Addr _at_ 0x6010;
xdata U32 gdw_DOS_DataAddr _at_ 0x68D0;
xdata U32 gdw_DOS_Fat1EndAddr;
xdata U32 gdw_DOS_Fat2Addr;
xdata U32 gdw_CARD_TotalSizeMB;
xdata U32 gdw_DOS_RootDirClus;
xdata U32 gdw_DOS_FatMaxCluster;
xdata U32 gdw_DOS_SectorPerCard;
void FlashExchang(U8 ActFlash, U8 InactFlash,U8 PageSize);
bit USR_Check_Character(U8 *SourceArray,U8 offset,U8 *CompareArray,U8 Numbyte);
U8 DOS_Initialize(void);
U8 SMC_STORAGE_Initialize(void);
U8 DOS_Initialize(void)
{
U8 tc_IniCode;
U8 tc_Status,tc_Count;
U8 tc_FileSystem,tc_ActiveFlag;
U16 tw_RootDirSize;
U16 tw_DOS_ReserveSector;
U32 tdw_PBRAddr;
U32 tdw_PartitionSectorSize;
U32 tdw_PBRAddr1,tdw_PBRAddr2;
U16 tw_offset;
U32 tdw_ParSize;
gdw_TotalFreeClusCounter=0;
gdw_TotalFreeClusNumber=0;
tdw_PBRAddr=0;
tc_IniCode=0;
tdw_PBRAddr1 = 0;
tdw_PBRAddr2 = 0;
tc_Count = 0;
gc_StartSearchFreeCluster=1;
gc_ReadWriteDataArea = 0;
tc_Status = DOS_Read_LogicSector(0, 1);
if(!tc_Status)
{
if(((gc_PlayRecordDataBuf[0x1fe]==0x55)&&(gc_PlayRecordDataBuf[0x1ff]==0xaa))||((gc_PlayRecordDataBuf[0x3fe]==0x55)&&(gc_PlayRecordDataBuf[0x3ff]==0xaa))) // maxliao 20070409
{//mark ok
if((USR_Check_Character(gc_PlayRecordDataBuf,0x36,FAT_String,3)!=0)&&(USR_Check_Character(gc_PlayRecordDataBuf,0x52,FAT_String,3)!=0))
{
for(tw_offset=0x1C2;tw_offset<0x1ff;)
{
tc_ActiveFlag = gc_PlayRecordDataBuf[tw_offset-4];
tc_FileSystem = gc_PlayRecordDataBuf[tw_offset];
((U8 *)(&tdw_PBRAddr))[0] = gc_PlayRecordDataBuf[tw_offset+7];
((U8 *)(&tdw_PBRAddr))[1] = gc_PlayRecordDataBuf[tw_offset+6];
((U8 *)(&tdw_PBRAddr))[2] = gc_PlayRecordDataBuf[tw_offset+5];
((U8 *)(&tdw_PBRAddr))[3] = gc_PlayRecordDataBuf[tw_offset+4];
((U8 *)(&tdw_ParSize))[0] = gc_PlayRecordDataBuf[tw_offset+11];
((U8 *)(&tdw_ParSize))[1] = gc_PlayRecordDataBuf[tw_offset+10];
((U8 *)(&tdw_ParSize))[2] = gc_PlayRecordDataBuf[tw_offset+9];
((U8 *)(&tdw_ParSize))[3] = gc_PlayRecordDataBuf[tw_offset+8];
tc_Count ++;
if((tc_ActiveFlag==0x80)||tc_ActiveFlag==0x00||tc_ActiveFlag==0x70)
{
// if((tc_FileSystem == 0x01)||(tc_FileSystem == 0x04)||(tc_FileSystem == 0x06)||(tc_FileSystem == 0x0b)||(tc_FileSystem == 0x0c)||(tc_FileSystem == 0x0e))
{
if(tdw_PBRAddr&&tdw_ParSize)
{
if((tdw_PBRAddr<tdw_PBRAddr1)||(tdw_PBRAddr>tdw_PBRAddr2))
{//tdw_PBRAddr1:the stat Addr of last par,tdw_PBRAddr2:the end Addr of last par
tc_Count--;
tdw_PBRAddr1 = tdw_PBRAddr; //save the stat Addr of current partion
tdw_PBRAddr2 = tdw_PBRAddr+tdw_ParSize; //save the last Addr of current partion
}
}
}
}
tw_offset += 0x10;
if(tc_Count>=4)
{
tc_Status = 1;
}
}
}
else
{
tc_Status = 1;
}
if(tc_Status == 1)
{//the disk has no MBS,
tdw_PBRAddr = 0;
}
else
{
tdw_PBRAddr = tdw_PBRAddr1;
if(DOS_Read_LogicSector(tdw_PBRAddr, 1)!=0)
{//read PBR sector error.
return DOS_READ_PBS_ERR;
}
if(((gc_PlayRecordDataBuf[0x1fe]!=0x55)||(gc_PlayRecordDataBuf[0x1ff]!=0xaa))&&((gc_PlayRecordDataBuf[0x3fe]!=0x55)&&(gc_PlayRecordDataBuf[0x3ff]!=0xaa))) // maxliao 20070409
{
return DOS_PBS_MARK_ERR;
}
}
if(USR_Check_Character(gc_PlayRecordDataBuf, 0x36, FAT_String, 3) == 0)
{
//check PBR
if( (gc_PlayRecordDataBuf[0x39] == '1') && (gc_PlayRecordDataBuf[0x3a] == '2') )
{//FAT12
gc_DOS_FileSystemType = 0x00;
}else if( (gc_PlayRecordDataBuf[0x39] == '1') && (gc_PlayRecordDataBuf[0x3a] == '6') )
{//FAT16
gc_DOS_FileSystemType = 0x01;
}
else
{
return DOS_UNKNOW_FILESYSTEM_ERR;
}
}
else
{//check if FAT32
if((USR_Check_Character(gc_PlayRecordDataBuf, 0x52, FAT_String, 3) == 0) &&
((gc_PlayRecordDataBuf[0x55] == '3') && (gc_PlayRecordDataBuf[0x56] == '2')))
{//FAT32
gc_DOS_FileSystemType = 0x02;
}
else
{//not FAT12/16/32
return DOS_UNKNOW_FILESYSTEM_ERR;
}
}
//initialize global varible according to the parameters in PBR.
((U8 *)(&gw_DOS_SectorSize))[0] = gc_PlayRecordDataBuf[0x0c];
((U8 *)(&gw_DOS_SectorSize))[1] = gc_PlayRecordDataBuf[0x0b];
gc_DOS_SectorPerCluster = gc_PlayRecordDataBuf[0x0d];
((U8 *)(&tw_DOS_ReserveSector))[0] = gc_PlayRecordDataBuf[0x0f];
((U8 *)(&tw_DOS_ReserveSector))[1] = gc_PlayRecordDataBuf[0x0e];
((U8 *)(&gdw_DOS_SectorPerFAT))[0] = 0;
((U8 *)(&gdw_DOS_SectorPerFAT))[1] = 0;
((U8 *)(&gdw_DOS_SectorPerFAT))[2] = gc_PlayRecordDataBuf[0x17];
((U8 *)(&gdw_DOS_SectorPerFAT))[3] = gc_PlayRecordDataBuf[0x16];
if (gdw_DOS_SectorPerFAT == 0)
{//FAT32
((U8 *)(&gdw_DOS_SectorPerFAT))[0] = gc_PlayRecordDataBuf[0x27];
((U8 *)(&gdw_DOS_SectorPerFAT))[1] = gc_PlayRecordDataBuf[0x26];
((U8 *)(&gdw_DOS_SectorPerFAT))[2] = gc_PlayRecordDataBuf[0x25];
((U8 *)(&gdw_DOS_SectorPerFAT))[3] = gc_PlayRecordDataBuf[0x24];
}
((U8 *)(&tw_RootDirSize))[0] = gc_PlayRecordDataBuf[0x12];
((U8 *)(&tw_RootDirSize))[1] = gc_PlayRecordDataBuf[0x11];
//tw_RootDirSize = (tw_RootDirSize/gw_DOS_SectorSize)*32;//for large root061222//Ching
tw_RootDirSize = ((U32)tw_RootDirSize * 32) / (U32)gw_DOS_SectorSize;
gdw_DOS_Fat1Addr = tdw_PBRAddr + tw_DOS_ReserveSector;
if(gc_PlayRecordDataBuf[0x10] == 0x01)
{
gdw_DOS_Fat2Addr = gdw_DOS_Fat1Addr;
}
else
{
gdw_DOS_Fat2Addr = gdw_DOS_Fat1Addr + gdw_DOS_SectorPerFAT;
}
((U8 *)(&tdw_PartitionSectorSize))[0] = 0;
((U8 *)(&tdw_PartitionSectorSize))[1] = 0;
((U8 *)(&tdw_PartitionSectorSize))[2] = gc_PlayRecordDataBuf[0x014];
((U8 *)(&tdw_PartitionSectorSize))[3] = gc_PlayRecordDataBuf[0x013];
if (tdw_PartitionSectorSize == 0)
{//partition larger than 32M.
((U8 *)(&tdw_PartitionSectorSize))[0] = gc_PlayRecordDataBuf[0x23];
((U8 *)(&tdw_PartitionSectorSize))[1] = gc_PlayRecordDataBuf[0x22];
((U8 *)(&tdw_PartitionSectorSize))[2] = gc_PlayRecordDataBuf[0x21];
((U8 *)(&tdw_PartitionSectorSize))[3] = gc_PlayRecordDataBuf[0x20];
}
if (gc_DOS_FileSystemType != 0x02) //lzp add
{//FAT12/16
gdw_DOS_RootDirAddr = gdw_DOS_Fat2Addr + gdw_DOS_SectorPerFAT;//xyq040811
gdw_DOS_DataAddr = gdw_DOS_RootDirAddr + tw_RootDirSize;//xyq040811
//FAT12/16 have no root dir cluster. starting cluster '2' is in the beginning of data area
gdw_DOS_RootDirClus = 0;
}
else
{//FAT32
gdw_DOS_DataAddr = gdw_DOS_Fat2Addr + gdw_DOS_SectorPerFAT;
((U8 *)(&gdw_DOS_RootDirClus))[0] = gc_PlayRecordDataBuf[0x2f];
((U8 *)(&gdw_DOS_RootDirClus))[1] = gc_PlayRecordDataBuf[0x2e];
((U8 *)(&gdw_DOS_RootDirClus))[2] = gc_PlayRecordDataBuf[0x2d];
((U8 *)(&gdw_DOS_RootDirClus))[3] = gc_PlayRecordDataBuf[0x2c];
gdw_DOS_RootDirAddr = gdw_DOS_DataAddr + ((gdw_DOS_RootDirClus-2) * (U32)gc_DOS_SectorPerCluster);//start from cluster 2
}
if (tdw_PartitionSectorSize != 0)
{
if(gc_PlayRecordDataBuf[0x10] == 0x01)
{
gdw_DOS_FatMaxCluster = tdw_PartitionSectorSize - tw_DOS_ReserveSector - (tw_RootDirSize) - gdw_DOS_SectorPerFAT;
}
else
{
gdw_DOS_FatMaxCluster = tdw_PartitionSectorSize - tw_DOS_ReserveSector - (tw_RootDirSize) - ( gdw_DOS_SectorPerFAT << 1 );
}
gdw_DOS_FatMaxCluster = gdw_DOS_FatMaxCluster / gc_DOS_SectorPerCluster;
gdw_DOS_FatMaxCluster = gdw_DOS_FatMaxCluster + 2;
if (gdw_DOS_FatMaxCluster == 0 || gdw_DOS_FatMaxCluster > 0x0fffffff)
{//0x0fffffff means last cluster in chain in FAT32.
gdw_DOS_FatMaxCluster = 0x0fffffff;
}
if (gc_DOS_FileSystemType == 0)
{// FAT 12
gdw_DOS_Fat1EndAddr = gdw_DOS_Fat1Addr + ((gdw_DOS_FatMaxCluster * 3L / 2) >> 9);
}
else if(gc_DOS_FileSystemType == 1)
{// FAT 16
gdw_DOS_Fat1EndAddr = gdw_DOS_Fat1Addr + (gdw_DOS_FatMaxCluster >> 8);
}
else if (gc_DOS_FileSystemType == 2)
{// FAT 32
gdw_DOS_Fat1EndAddr = gdw_DOS_Fat1Addr + (gdw_DOS_FatMaxCluster >> 7);
}
if(gc_CurrentCard<2)
{
//FAT area check.
if(DOS_Read_LogicSector(gdw_DOS_Fat1Addr,1) == 0)
{//check FAT1
if (gc_PlayRecordDataBuf[0] != 0xf8 || gc_PlayRecordDataBuf[1] != 0xff)
{
if(DOS_Read_LogicSector(gdw_DOS_Fat2Addr,1) == 0)
{
if (gc_PlayRecordDataBuf[0] != 0xf8 || gc_PlayRecordDataBuf[1] != 0xff)
{//FAT1 and FAT2 error
return DOS_FAT_ERR;
}
else
{// copy fat2 to fat1
DOS_Copy_FATtoFAT(0x02,0x0fffffff,0);
}
}
else
{
return DOS_READ_FAT2_ERR;
}
}
else
{// check FAT2
if(DOS_Read_LogicSector(gdw_DOS_Fat2Addr,1) == 0)
{
if (gc_PlayRecordDataBuf[0] != 0xf8 || gc_PlayRecordDataBuf[1] != 0xff)
{// copy fat1 to fat2
DOS_Copy_FATtoFAT(0x02,0x0fffffff,1);
}
}
else
{
return DOS_READ_FAT2_ERR;
}
}
}
else
{
return DOS_READ_FAT1_ERR;
}
}
}
else
{
//tdw_PartitionSectorSize == 0, not FAT12/16/32
return DOS_PARTITIONSIZE_ERR;
}
}
else
{
//marker "0x55aa" error.
return DOS_MBS_MARK_ERR;
}
}
else
{
//read MBR sector error.
return DOS_READ_MBS_ERR;
}
return DOS_SUCCESS;
}
void FlashExchang(U8 ActFlash, U8 InactFlash,U8 PageSize)
{
switch(InactFlash)
{
case 0: InactFlash = 0x01; break;
case 1: InactFlash = 0x04; break;
case 2: InactFlash = 0x0C; break;
case 3: InactFlash = 0x0C; break;
case 4: break;
case 5: InactFlash = 0x0C; break;
default : InactFlash = 0; break;
}
XBYTE[0xB401] |= InactFlash;
XBYTE[0xB405] |= InactFlash;
switch(ActFlash)
{
case 0:
XBYTE[0xB08B] |=0x08;
XBYTE[0xB400] = 0x01;
XBYTE[0xB422] = 0x00;
break;
case 1:
XBYTE[0xB08B] |=0x08;
XBYTE[0xB400] = 0x01;
XBYTE[0xB422] = 0x01;
break;
case 2:
XBYTE[0xB08B] &=0xF7;
XBYTE[0xB400] = 0x06;
XBYTE[0xB450] = 0x03;
break;
case 3:
XBYTE[0xB08B] &=0xF7;
XBYTE[0xB400] = 0x06;
XBYTE[0xB450] = 0x03;
break;
}
switch(PageSize)
{
case 1:
XBYTE[0xB4A3] = 0x01;
XBYTE[0xB455] = 0x00;
XBYTE[0xB456] = 0x02;
break;
}
if(ActFlash < 2)
{
XBYTE[0xB4A3] = 0x01;//512byte/page ECC mode
//3.set read/write pause width
XBYTE[0xB421] = 0x33;
//4.set cmd time
XBYTE[0xB802] = 0x66; //cmd time
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -