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

📄 disk.cpp

📁 一个微型操作系统源码
💻 CPP
字号:
#ifndef _disk_
#define _disk_

#include "disk.h"
#include "inout.cpp"
#include "shell.cpp"
#include "fs.cpp"
#define RW 33
#define RO 32


#define File_Not_Found 1
#define Folder_Not_Found 2
#define Destination_File_Exist 3
#define Destination_Folder_Exist 4
#define Access_Violation    5

char Error_Code;
char curr_dir_cnum;
extern Directory curr_dir;
extern char *path;
extern  char floppy_hardd_tog;
char Drive_No=0x80;

		  // Initialise Routine //
			Disk disk;
			Drive d[4];

//To check whether the entered drive is valid or not
struct Entry_details Disk::validate_drive(char* str)
{
int dr_num;
struct Entry_details file_details;
dr_num = path[0]-'A';
if((dr_num==2)||(dr_num==3))
   {
    file_details.lba = curr_dir.dir_lba;
    file_details   = d[dr_num-2].validate_entry(str,file_details,dr_num);
    return file_details;
   }
}


//Convertion of chs to lba addressing
long Disk::chs_to_lba(int track,int head,int sector)
{
  long lba;
  lba = (track*255*63) + head*63 + sector;
  return(lba);
}

//Convertion of chs to lba addressing
long Disk::chs_to_lba(char track,char head,char sector)
{
  int h,t,s,temp;
  long lba;
  h=head;
  s=(sector & 0x3f);
  temp = (sector & 0xc0)<<2;
  t=track+temp;
  lba =(255*63*(long)t);
  lba+= s+ (63*h);
  return(lba);
}


//Constructor for Disk class
Disk::Disk()
  {
  char head,track,sector,buf[512];
  int i,j,read_flag,inc=446;
  long lba;
  num_of_drives=2;//Number of drives assumed to be 2
  read_flag = get_sector(lba = 1,0x01,buf);//MBR is on t=0,h=0,s=1;
  for(i=0;i<4;i++)
    for(j=0;j<16;j++)
      partition[i][j] = buf[inc++];
  head=partition[1][1];
  sector=partition[1][2];
  track=partition[1][3];
  lba = chs_to_lba(track,head,sector);
  read_flag = get_sector(lba,0x01,buf);
  inc=446;
  for(i=1;i<4;i++)
    for(j=0;j<16;j++)
      partition[i][j] = buf[inc++];
  }

//Read sectors with a given lba
int Disk::get_sector(long lba,char num_sectors,char *buf)
{
 char num;
 int h,t,s,temp;
 char head,sector,track;
 if((lba==50)&&(priority!=1)) {Error_Code=Access_Violation;return 0;}
 t = lba/(255*63);
 h = (lba%(255*63))/63;
 s = lba%63;
 head = h;
 sector = (t & 0x300)>>2;
 sector+=s;
 track = t;
 asm mov cx,0x3;
 lp:
 asm push cx;
 asm mov ah,0x02
 asm mov al,num_sectors
 asm mov ch,track
 asm mov cl,sector
 asm mov dh,head
 asm mov dl,Drive_No
 asm mov bx,buf
 asm push ds
 asm int 0x13
 asm pop es
 asm jnc nerror;
 num=0;
 asm pop cx;
 asm dec cx;
 asm jnz lp;
 asm mov num,ah
 return num;
 nerror:
 asm mov num,ah
 return num;
}


//Write sectors with a given lba
int Disk::put_sector(long lba,char num_sectors,char *buf)
{
 char num;
 int h,t,s,temp;
 char head,sector,track;
 if((lba==50)&&(priority!=1)) {Error_Code=Access_Violation;return 0;}
 t = lba/(255*63);
 h = (lba%(255*63))/63;
 s = lba%63;
 head = h;
 sector = (t & 0x300)>>2;
 sector+=s;
 track = t;
 asm mov cx,0x3;
 lp:
 asm push cx;
 asm mov ah,0x03
 asm mov al,num_sectors
 asm mov ch,track
 asm mov cl,sector
 asm mov dh,head
 asm mov dl,Drive_No
 asm mov bx,buf
 asm push ds
 asm int 0x13
 asm pop es
 asm jnc nerror;
 num=0;
 asm pop cx;
 asm dec cx;
 asm jnz lp;
 asm mov num,ah
 return num;
 nerror:
 asm mov num,ah
 return num;
 }

//Validate a given relative path
struct Entry_details Drive::validate_entry(char* str,struct Entry_details file_details,int dr_num)
{
Directory dir;
file_details = dir.get_lba(str,file_details,dr_num);
return file_details;
}



//Validate a given absolute path
struct Entry_details Disk::validate_drive_abs(char* path)
{
int dr_num;
struct Entry_details file_details;
dr_num = *path - 'A';
if((dr_num==2)||(dr_num==3))
   {
    file_details.lba = d[dr_num-2].rootdir_lba;
    file_details   = d[dr_num-2].validate_entry_abs(path+3,file_details,dr_num);
    return file_details;
   }
}

//Get a fat entry with the given lba
long Drive::get_fat_entry(long lba_num,int dr_num)
{
int read_flag,fat_entry;
char buf[512];
long lba,cluster;
cluster=((lba_num-d[dr_num-2].rootdir_lba)/d[dr_num-2].get_spc())+2;
lba = fat1_lba+(cluster)/128;
read_flag = disk.get_sector(lba ,0x01,buf);
fat_entry = (cluster%128)*4;
cluster =
   rev_cat(
      rev_cat(buf[fat_entry],buf[fat_entry+1]),
      rev_cat(buf[fat_entry+2],buf[fat_entry+3])
	  );
if(cluster>=0x0ffffff8) return(cluster);
else
   return(d[dr_num-2].rootdir_lba+(cluster-2)*d[dr_num-2].get_spc());
}

//Read data from a given lba
char* Drive::dataread(long lba)
{
char buf[512];
int read_flag;
read_flag = disk.get_sector(lba ,0x01,buf);
return(buf);
}

//Initialise drive parameters
void Drive::initialise(int drive_num)
{
long lba;
char buf[512];
int read_flag;
lba=disk.chs_to_lba(disk.partition[drive_num-2][3],disk.partition[drive_num-2][1],
		disk.partition[drive_num-2][2]);
read_flag = disk.get_sector(lba ,0x01,drive_buf);
fat1_lba=lba + rev_cat(drive_buf[14],drive_buf[15]);
rootdir_lba = fat1_lba +
	(2 *
	(rev_cat
	     (rev_cat(drive_buf[36],drive_buf[37]),
		       rev_cat(drive_buf[38],drive_buf[39]))));
}

//Get free fat entries
long Drive::get_free_fat_entry()
{
int read_flag,fat_entry=0;
char buf[512];
long lba,cluster;
lba = fat1_lba;
while(1)
{
read_flag = disk.get_sector(lba++,0x01,buf);
fat_entry = 0;
while(fat_entry<128)
{
cluster =
   rev_cat(
      rev_cat(buf[fat_entry],buf[fat_entry+1]),
      rev_cat(buf[fat_entry+2],buf[fat_entry+3])
	  );
fat_entry += 4;
if(cluster==0)
{
fat_entry -= 4;
lba--;
cluster = (lba-fat1_lba)*128 + (fat_entry/4);
return(cluster);
}
}
}
}

//Get sector per cluster value for the partition
char Drive :: get_spc()
{
return drive_buf[13];
}

//Sets a fat entry to a given value
Drive::set_fat_entry(long l_lba,long r_lba,int drive)// set the link og l_lba to r_lba
{
int read_flag,fat_entry;
char* temp;
char buf[512];
long lba,clusterl,clusterr;
clusterl=((l_lba-d[drive-2].rootdir_lba)/d[drive-2].get_spc())+2;
if(r_lba<0x0ffffff8)
clusterr=((r_lba-d[drive-2].rootdir_lba)/d[drive-2].get_spc())+2;
else clusterr=r_lba;
lba = fat1_lba+(clusterl)/128;
read_flag = disk.get_sector(lba ,0x01,buf);
fat_entry = ((clusterl)%128)*4;
	temp = (char*)buf;
	temp+=fat_entry;
	temp[0] = clusterr;
	temp[1] = clusterr>>8;
	temp[2] = clusterr>>16;
	temp[3] = clusterr>>24;
disk.put_sector(lba ,0x01,buf);
}



//Validate a given absolute path
struct Entry_details Drive::validate_entry_abs(char* path,struct Entry_details file_details,int dr_num)
{
char *name;
Directory dir;
if(*path == 0) return(file_details);
name = path;
while((*path != ':')&&(*path != 0))path++;
if(*path != 0)
{
*path = 0;
path++;
}
file_details = dir.get_lba_abs(name,file_details,dr_num);
file_details = validate_entry_abs(path,file_details,dr_num);
return file_details;
}


//Get entry details
struct Entry_details Directory::get_lba_abs(char* name,struct Entry_details file_details,int dr_num)
{
char *f_d;
char buf[64][32];
int flag=1,k;
long cluster;
int index;
disk.get_sector(file_details.lba,0x04,(char *)buf);
for(int i=0;i<64;i++)
{
for(int j=0,k=-1;j<11;j++)
   {
      if(k==-1) k++;
     else if(name[k])k++;
   if(name[k] == '.') {j=8;k++;}

   if((buf[i][j] == 0x20 && name[k] == 0) || buf[i][j] == name[k])
       {flag=0;}
   else {flag = 1;break;}
   }
   if(!flag && (j == 11 || name[k] == 0))
   break;
 }
cluster =
   rev_cat(rev_cat(buf[i][26],buf[i][27]),rev_cat(buf[i][20],buf[i][21]));
if(!flag)
 {
 f_d =(char*) &file_details;
 index = 0;
 while(index<32){*f_d = buf[i][index];index++;f_d++;}
 file_details.lba = d[dr_num-2].rootdir_lba+(cluster-2)*d[dr_num-2].get_spc();
 return(file_details);
 }
else
{
file_details.lba = 0;
return file_details;
}
}



Directory::Directory(){}


Directory::Directory(char dr_num)
{
drive = dr_num;
}


Directory::Directory(char *path)
{
drive = *path-'A';
if(path[0] == 'C' && path[1] == ':')
dir_details = disk.validate_drive_abs(path);
else
dir_details = disk.validate_drive(path);
dir_lba = dir_details.lba;
found=1;
}

//Gets a directory with a given dir name
Directory Directory::get_dir(char *dir_name)
{
long cluster;
int j,k;
static Directory dir_ret(drive);
char buf[64][32];
int flag = 1;
disk.get_sector(dir_lba,0x04,(char *)buf);

for(int i=0;i<64;i++)
{
for(j=0,k=-1;j<11;j++)
   {
   if(k==-1) k++;
   else if(dir_name[k])k++;
   if((buf[i][j] == 0x20 && dir_name[k] == 0) || buf[i][j] == dir_name[k])
       {flag=0;}
   else {flag = 1;break;}
   }
   if(!flag && (j == 11 || dir_name[k] == 0))
   break;
 }
if(!flag)
{

cluster =
   rev_cat(rev_cat(buf[i][26],buf[i][27]),rev_cat(buf[i][20],buf[i][21]));
 dir_ret.dir_lba = d[drive-2].rootdir_lba+(cluster-2)*d[drive-2].get_spc();
 char *temp = (char*)(&dir_ret.dir_details);
 for(j=0;j<32;j++)temp[j] = buf[i][j];
 dir_ret.dir_details.lba = dir_ret.dir_lba;
 dir_ret.found=1;
 return(dir_ret);
}
else
{
dir_ret.found=0;
 return(dir_ret);
 }
}

//Gets entries of a dir
Dir_Entries* Directory::dir_read()
{
static char buf[64][32];
char cnt=0;
int j,i,read_flag;
Dir_Entries dir_entries[64];
for(i=0;i<64;i++)
 for(j=0;j<32;j++)
    buf[i][j]=0;
if(dir_details.lba==0) found=0;
else
{
read_flag=disk.get_sector(dir_details.lba,4,(char*)buf);
for(i=0;i<64;i++)
  {
  j=0;
  if(buf[i][j]==0) break;
  if((buf[i][j]=='

⌨️ 快捷键说明

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