📄 main.c
字号:
#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 + -