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

📄 main.c

📁 详细介绍了关于CF卡的存储结构
💻 C
📖 第 1 页 / 共 5 页
字号:
#include "reg668.h"
#include <stdio.h>


#include <stdlib.h>
#include "cf.h"
#include <string.h>

//#define CLEAR_FAT
//#define DEBUG
//#define DEBUG_LINK
//#define WRITE_IN_OPEN

#ifdef TEST_RAM 
unsigned char *ram_addr=&XBYTE[0x2000];
unsigned char *ram_1=&XBYTE[0x0000];
unsigned char *ram_2=&XBYTE[0x2000];
#endif

static xdata unsigned char data_buf[512];		//the buffer for read or write CF card's sector
static xdata struct sFileInfo s_fileinfo;		//use to save opened file infomation
static xdata unsigned char write_buf[512];		//the buffer for write to CF
static xdata unsigned int buf_pos=0;			//current position of write_buf
static xdata struct sBootInformation bootinfo;
unsigned char num;

#define USE_PRINTF

void CommInit()
{
	unsigned char temp;
	temp=TMOD;
	temp&=0x0f;
	temp|=0x20;
	TMOD=temp;
	TH1=0xFF; 

	S0CON=0X50;
	PCON=0X80;
	TR1=1;

#ifdef USE_PRINTF
	TI=1;
	ES0=0;
#else
	ES0=0;
	TI=0;
#endif
	RI=0;
}

char zxPutChar (char c)
{
	while (!TI)
		;
  	TI = 0;
  	return (S0BUF = c);
}



unsigned char  CheckCFStatu()
{
	return CF_STATUS;		
}

//read 512 bytes from CF,
//sec_num:sector No.
//512 bytes data put in data_buf
//return: 1 success,0 error
bit ReadOneSec(unsigned long sec_num)
{
	volatile unsigned long temp;
	volatile unsigned int i,time_out;	
	CF_CYLINDER_HIGH=sec_num/65536;
	temp=sec_num%65536;
	CF_CYLINDER_LOW=temp/256;
	CF_SECTOR_NUM=temp%256;
	CF_SECTOR_COUNT=1;
	CF_DRV_HEAD=0xe0;
//	CF_DRV_HEAD=0x10;
	CF_COMM=0x20;
	for(i=0;i<512;i++)
	{
		time_out=0;	
		while((CF_STATUS & 0xf1)!=0x50)
		{
			if(time_out++>0xf000)
				return 0;	
		}
		data_buf[i]=CF_DATA;
	}
	for(i=0;i<0x01ff;i++)
	{
		time_out++;
	}
	return 1;
}

//return value: 1 success, 0 error
bit ReadCIS()
{
	unsigned int i,time_out;
	CF_COMM=0xec;
	for(i=0;i<512;i++)
	{
		time_out=0;	
		while((CF_STATUS & 0xf1)!=0x50)
		{
			if(time_out++>0x8000)
				return 0;	
		}
		data_buf[i]=CF_DATA;
	}
	for(i=0;i<0x01ff;i++)
	{
		time_out++;
	}
	return 1;
}

// write 512 bytes to CF card
//return: 1 success,0 error
bit WriteOneSec(unsigned char* dat,unsigned long sec_num)
{
	unsigned int i,time_out;	
	unsigned long temp;
	CF_CYLINDER_HIGH=sec_num/65536;
	temp=sec_num%65536;
	CF_CYLINDER_LOW=temp/256;
	CF_SECTOR_NUM=temp%256;
	CF_SECTOR_COUNT=1;
	CF_DRV_HEAD=0xe0;
//	CF_DRV_HEAD=0x10;
	CF_COMM=0x30;
	for(i=0;i<512;i++)
	{
		time_out=0;	
		while((CF_STATUS & 0xf1)!=0x50)
		{	
			if(time_out++>0xf000)
				return 0;
		}
		CF_DATA=dat[i];
//		CF_DATA=data_buf[i];
	}
	for(i=0;i<0x01ff;i++)
	{
		time_out++;
	}
	return 1;
}

//stacks 2
bit EraseSec(unsigned long sec_num,unsigned char num)
{
	unsigned long temp;
	unsigned int time_out,i;
	CF_CYLINDER_HIGH=sec_num/65536;
	temp=sec_num%65536;
	CF_CYLINDER_LOW=temp/256;
	CF_SECTOR_NUM=temp%256;
	CF_SECTOR_COUNT=num;
	CF_DRV_HEAD=0xe0;
//	CF_DRV_HEAD=0x10;
	CF_COMM=0xC0;
	time_out=0;	
	while((CF_STATUS & 0xf0)!=0x50)
	{	
		if(time_out++>0xf000)
			return 0;
	}
	for(i=0;i<0x01ff;i++)
	{
		time_out++;
	}
	return 1;
}

//stacks 2
void CFInit()
{
	reg_select=1;
	reg=0;
	CF_CONFIG=0x80;
	reg_select=0;
	reg=1;
//	CF_STATUS=0xff;
}

void PrintBoot()
{
	unsigned int temp;
	printf("Oem:");
	for(temp=0;temp<8;temp++)
	{
		printf("%c",((struct sBoot*)data_buf)->OemName[temp]);
	}
	printf("\nBytes/Sec:%u",((struct sBoot*)data_buf)->bsBytesPerSec[1]*256
							+((struct sBoot*)data_buf)->bsBytesPerSec[0]);
	printf("\nSec/Clustor:");
	putchar(((struct sBoot*)data_buf)->bsSecPerClust+'0');

	printf("\nTotal Sec:%u",((struct sBoot*)data_buf)->bsSectors[1]*256
							+((struct sBoot*)data_buf)->bsSectors[0]);
	printf("\nVolume:");
	for(temp=0;temp<11;temp++)
	{
		printf("%c",((struct sBoot*)data_buf)->bsVolumeLabel[temp]);
	}
	printf("\nFileSystem:");
	for(temp=0;temp<8;temp++)
	{
		printf("%c",((struct sBoot*)data_buf)->bsFileSysType[temp]);
	}
}

//用于读取BOOT扇区的磁盘信息,在ReadOneSec后使用,得到的磁盘信息放在bootinfo结构中


char CFGetBoot()
{
	unsigned char i;
	if(ReadOneSec(0)==0)
	{
		return -1;
	}
	bootinfo.byte_per_sec=((struct sBoot*)data_buf)->bsBytesPerSec[1]*256+((struct sBoot*)data_buf)->bsBytesPerSec[0];
	bootinfo.sec_per_clust=((struct sBoot*)data_buf)->bsSecPerClust;
	bootinfo.reserved_sector=((struct sBoot*)data_buf)->bsResSectors[1]*256+((struct sBoot*)data_buf)->bsResSectors[0];
	bootinfo.fat_num=((struct sBoot*)data_buf)->bsFATs;
	bootinfo.root_dir_size=((struct sBoot*)data_buf)->bsRootDirEnts[1]*256+((struct sBoot*)data_buf)->bsRootDirEnts[0];
	bootinfo.total_sector=((struct sBoot*)data_buf)->bsSectors[1]*256+((struct sBoot*)data_buf)->bsSectors[0];
	bootinfo.media_flag=((struct sBoot*)data_buf)->bsMedia;
	bootinfo.fat_size=((struct sBoot*)data_buf)->bsFATsecs[1]*256+((struct sBoot*)data_buf)->bsFATsecs[0];
	bootinfo.sec_per_track=((struct sBoot*)data_buf)->bsSecPerTrack[1]*256+((struct sBoot*)data_buf)->bsSecPerTrack[0];
	bootinfo.heads=((struct sBoot*)data_buf)->bsHeads[1]*256+((struct sBoot*)data_buf)->bsHeads[0];
	bootinfo.hidden_sector=((struct sBoot*)data_buf)->bsHiddenSecs[1]*256+((struct sBoot*)data_buf)->bsHiddenSecs[0];
	bootinfo.boot_code=((struct sBoot*)data_buf)->bsBootCode[1]*256+((struct sBoot*)data_buf)->bsBootCode[0];
	bootinfo.huge_sec=((struct sBoot*)data_buf)->bsHugeSectors[3]*16777216
					  +((struct sBoot*)data_buf)->bsHugeSectors[2]*65536
					  +((struct sBoot*)data_buf)->bsHugeSectors[1]*256
					  +((struct sBoot*)data_buf)->bsHugeSectors[0];
	bootinfo.drive_num=((struct sBoot*)data_buf)->bsDriveNumber;
	bootinfo.boot_signature=((struct sBoot*)data_buf)->bsBootSignature;
	for(i=0;i<4;i++)
	{
		bootinfo.volume_id[i]=((struct sBoot*)data_buf)->bsVolumeID[i];
	}
	for(i=0;i<11;i++)
	{
		bootinfo.volume_lab[i]=((struct sBoot*)data_buf)->bsVolumeLabel[i];
	}
	for(i=0;i<8;i++)
	{
		bootinfo.file_sys_type[i]=((struct sBoot*)data_buf)->bsFileSysType[i];
	}
	return 1;
}

void SystemInit()
{
	CommInit();
	AUXR=0xfc;
	EA=1;
	CFInit();
}

unsigned int TestAddr(unsigned int len)
{
	int i;
	unsigned char num=0;
	for(i=len-1;i>=0;i--)
	{
#ifdef TEST_RAM
		ram_addr[i]=num;
#endif
		num++;
	}
	num=0;
	for(i=len-1;i>=0;i--)
	{
#ifdef TEST_RAM
		if(ram_addr[i]!=num)
#endif
			return i;
		num++;
	}
	return 0xffff;
}

char TestRam(unsigned int len,unsigned char num)
{
	data unsigned int i;		
	for(i=0;i<len;i++)
	{
#ifdef TEST_RAM
		ram_addr[i]=num;
#endif
	}
	for(i=0;i<len;i++)
	{
//		printf("%d,",(int)ram_addr[i]);
#ifdef TEST_RAM
		if(ram_addr[i]!=num)
#endif
			return 0;
	}
	return 1;
}

void ListFile()
{
	unsigned char i,j;
	xdata struct sRootDir root_directory;
	for(i=0;data_buf[32*i]!=0;i++)
	{
		memcpy(&root_directory,data_buf+i*32,32);
		if(root_directory.file_attribute==0x20			
			&& (unsigned char)root_directory.file_name[0]!=0xe5)	//list file
		{
			printf("\n");
			for(j=0;j<8;j++)
			{
				putchar(root_directory.file_name[j]);
			}
			putchar('.');
			for(j=0;j<3;j++)
			{
				putchar(root_directory.exten_name[j]);
			}
		}
		if(root_directory.file_attribute==0x10
			&& (unsigned char)root_directory.file_name[0]!=0xe5)	//list directory
		{
			printf("\n");
			for(j=0;j<8;j++)
			{
				putchar(root_directory.file_name[j]);
			}
			putchar('.');
			for(j=0;j<3;j++)
			{
				putchar(root_directory.exten_name[j]);
			}
			printf(" %x",root_directory.first_clust[1]*256+root_directory.first_clust[0]);			
		}
	}
}

//返回所指定文件或目录的首簇扇区号,范围为根目录,文件名为11 bytes定长,不足用空格填充
//未找到返回0xffff	
unsigned long CFFindFileInRoot(char *file_name,unsigned int *file_record_sec,unsigned int *file_record_pos)
{
	unsigned int i,j;
	xdata struct sRootDir root_directory;
	for(j=bootinfo.fat_size*2+1;j<=bootinfo.fat_size*2+1+bootinfo.root_dir_size*32/512;j++)
	{
		if(ReadOneSec(j)==0)
		{
			return 0xffffffff;
		}
//		for(i=0;data_buf[32*i]!=0 && i<=bootinfo.root_dir_size*32/512;i++)
		for(i=0;data_buf[32*i]!=0 && i<16;i++)
		{
			memcpy(&root_directory,data_buf+i*32,32);
			if((root_directory.file_attribute==0x20 || root_directory.file_attribute==0x10)			
				&& (unsigned char)root_directory.file_name[0]!=0xe5)	//list file
			{
				if(strncmp(file_name,root_directory.file_name,8)==0x00)
				{
					*file_record_sec=j;
					*file_record_pos=i;
//					return root_directory.first_clust[1]*256+root_directory.first_clust[0];  
					
					return (root_directory.first_clust[1]*256+root_directory.first_clust[0]-2)
							*bootinfo.sec_per_clust
							+(1+bootinfo.fat_size*bootinfo.fat_num+bootinfo.root_dir_size*32/512);
				}
			}
		}
//		if(data_buf[32*i]==0)
//			return 0xffff;
	}
	return 0xffffffff;
}

//note:in this version only 16 records could be stored in sub directory
//return value:error 0xffff,other case return file or directory first clustor in FAT table
unsigned int CFFindFileInDir(char *file_name,unsigned int dir_clustor,
						   unsigned int *file_record_sec,unsigned int *file_record_pos)
{
	xdata struct sSubDir sub_dir;
	xdata unsigned int fat_pos=0;
	xdata unsigned int fat_sector=0;
	xdata unsigned int in_sector_pos=0;
	xdata unsigned int next_clustor=0;
	xdata unsigned int current_clustor=0;
	xdata unsigned char out_count=0;
	unsigned int i;
	unsigned int k;
	unsigned int clustor;
	clustor=dir_clustor-(bootinfo.fat_num*bootinfo.fat_size+bootinfo.root_dir_size*32/512+1);
	clustor=clustor/bootinfo.sec_per_clust+2; 
#ifdef DEBUG
	printf("\ndir clus=%x,clus=%x",dir_clustor,clustor);
#endif
	fat_sector=(clustor*2)/512;
	in_sector_pos=(clustor*2)%512;
	if(ReadOneSec(fat_sector+1)==0)			//read FAT table
	{
		return 0xffff;
	}
	next_clustor=data_buf[in_sector_pos+1]*256+data_buf[in_sector_pos];
#ifdef DEBUG
	printf("fat_sector=%x,in_sec_pos=%x,next_clustor=%x",fat_sector,in_sector_pos,next_clustor);
#endif
	if(next_clustor==0xffff)						//the sub directory used only one clustor
	{
#ifdef DEBUG
		printf("\nno next clustor\n");
#endif
		clustor=dir_clustor;
		for(i=0;i<bootinfo.sec_per_clust;i++)		//read one clustor
		{
			if(ReadOneSec(i+dir_clustor)==0)		//read one sector
			{
				return 0xffff;
			}
			for(k=0;data_buf[32*k]!=0 && k<16;k++)
			{
#ifdef DEBUG
				printf("\nk=%x\n",k);
#endif
				memcpy(&sub_dir,data_buf+k*32,32);
				if((sub_dir.file_attribute==0x20 || sub_dir.file_attribute==0x10)			
					&& (unsigned char)sub_dir.file_name[0]!=0xe5)	
				{
					if(strncmp(file_name,(unsigned char*)(&sub_dir),11)==0x00)
					{
#ifdef DEBUG
						printf("succ\n");
#endif
						*file_record_sec=i+dir_clustor;
						*file_record_pos=k;
						return sub_dir.first_clust[1]*256+sub_dir.first_clust[0];								
					}
				}
			}
			if(data_buf[32*k]==0)
				return 0xffff;
		}
	}
	else if(next_clustor<0xfff0)					//the file use more then one sector
	{
		out_count=0;
		current_clustor=dir_clustor;
		while(next_clustor!=0xffff && out_count++<20)
		{
			for(i=0; i<bootinfo.sec_per_clust; i++)
			{
				if(ReadOneSec(i+current_clustor)==0)
				{
					return 0xffff;
				}
				for(k=0;data_buf[32*k]!=0 && k<16;k++)
				{
					memcpy(&sub_dir, data_buf+k*32,32);
					if((sub_dir.file_attribute==0x20 || sub_dir.file_attribute==0x10)			
						&& (unsigned char)sub_dir.file_name[0]!=0xe5)	
					{
						if(strncmp(file_name,(unsigned char*)(&sub_dir),11)==0x00)
						{
							*file_record_sec=i+current_clustor;
							*file_record_pos=k;
							return sub_dir.first_clust[1]*256+sub_dir.first_clust[0];								
						}
					}
				}
			}
			clustor=current_clustor-(bootinfo.fat_num*bootinfo.fat_size+bootinfo.root_dir_size*32/512+1);
			clustor=clustor/bootinfo.sec_per_clust+2; 
			fat_sector=(clustor*2)/512;
			in_sector_pos=(clustor*2)%512;

⌨️ 快捷键说明

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