fsys.c
来自「MMURTL(tm) Computer Operating System Ver」· C语言 代码 · 共 2,101 行 · 第 1/5 页
C
2,101 行
U32 nHeads; /* heads per drives */
U32 nSecPerTrk; /* Sectors per track */
U16 BS1Cyl; /* Cyl of 1st boot sector on disk */
U8 BS1Head; /* Head of 1st boot sector on disk */
U8 BS1Sect; /* Sector of 1st boot sector on disk */
} PDrvs[nPDrvs];
/* This array of structures keeps track of logical drive data (A-J). */
#define nLDrvs 10
struct {
U32 LBA0; /* lba for Start of LDrive (bootSect) */
U32 LBAData; /* lba for Start of Data Area */
U32 LBAMax; /* Max lba for logical drive */
U32 LBARoot; /* lba of the Root directory */
U32 LBAFAT; /* lba of first FAT */
U16 nHeads; /* Setup after boot sector is read */
U16 nSecPerTrk; /* Setup after boot sector is read */
U16 nRootDirEnt; /* Number of Root directory entries */
U16 sFAT; /* nSectors in a FAT */
U8 DevNum; /* Device Number for this ldrv FF = NONE */
U8 SecPerClstr; /* For each logical drive */
U8 nFATS; /* number of FATs */
U8 fFAT16; /* True for FAT16 else FAT12 */
} Ldrv[nLDrvs];
/* This is the Hard Disk Device Status record.
It is peculiar to the HD Drvr */
struct {
U32 erc;
U32 blocks_done;
U32 BlocksMax;
U8 fNewMedia;
U8 type_now; /* current fdisk_table for drive selected */
U8 resvd0[2]; /* padding for DWord align */
U32 nCyl; /* total physical cylinders (we really don't care) */
U32 nHead; /* total heads on device */
U32 nSectors; /* Sectors per track */
U32 nBPS; /* Number of bytes per sect. 32 bytes out to here.*/
U32 LastRecalErc0;
U32 LastSeekErc0;
U8 LastStatByte0;
U8 LastErcByte0;
U8 fIntOnReset; /* Interrupt was received on HDC_RESET */
U8 filler0;
U32 LastRecalErc1;
U32 LastSeekErc1;
U8 LastStatByte1;
U8 LastErcByte1;
U8 ResetStatByte; /* Status Byte immediately after RESET */
U8 filler1;
U32 resvd1[2]; /* out to 64 bytes */
} HDDevStat;
/* This is the Floppy Device Status record.
It is peculiar to the FD Drvr */
struct {
U32 erc;
U32 blocks_done;
U32 BlocksMax;
U8 fNewMedia;
U8 type_now; /* current fdisk_table for drive selected */
U8 resvd1[2]; /* padding for DWord align */
U32 nCyl; /* total physical cylinders */
U32 nHead; /* total heads on device */
U32 nSectors; /* Sectors per track */
U32 nBPS; /* Number of bytes per sect */
U8 params[16]; /* begin device specific fields */
U8 STATUS[8]; /* status returned from FDC (for user status) */
U32 resvd3;
U32 resvd4; /* 64 bytes total */
} FDDevStat;
long FSysStack[256]; /* 1024 byte stack for Fsys task */
long FSysExch;
struct reqtype { /* 64 byte request block structure */
long ServiceExch;
long RespExch;
long RqOwnerJob;
long ServiceRoute;
char *pRqHndlRet;
long dData0;
long dData1;
long dData2;
int ServiceCode;
char npSend;
char npRecv;
char *pData1;
long cbData1;
char *pData2;
long cbData2;
long RQBRsvd1;
long RQBRsvd2;
long RQBRsvd3;
};
struct reqtype *pRQB;
char *fsysname = "FILESYSM";
unsigned long keycode; /* for testing */
/*========================== BEGIN CODE ============================*/
/************************************************
Called from read_PE, this gets the starting
cylinder, head and sector for the first boot
sector on a physical drive and stores it in the
phydrv array. d is the drive, i is the index
into the partition table we read in.
*************************************************/
void GetBSInfo(U32 d, U32 i)
{
PDrvs[d].BS1Head = partab[i].HeadStart;
PDrvs[d].BS1Sect = partab[i].SecStart;
PDrvs[d].BS1Cyl = partab[i].CylStart;
if (!i) { /* primary partition info - use it for PDrv info */
PDrvs[d].nHeads = partab[i].HeadEnd;
PDrvs[d].nSecPerTrk = partab[i].nFirstSector & 0xff;
}
}
/** InitFloppy *********************************
This gets status from the floppy drive (device d)
and sets the physical & logical drive parameters
for the type. It is called when the file system
is first initialized and when a new floppy is
mounted.
*************************************************/
U32 InitFloppy(U8 ld)
{
U32 erc, i;
/* Set gets status for the floppy type from the FDD and
sets logical paramters for Ldrvs.
*/
Ldrv[0].DevNum= 10; /* Device Numbers for floppies */
Ldrv[1].DevNum= 11;
erc = DeviceStat(ld+10, &FDDevStat, 64, &i);
if (!erc) {
PDrvs[ld].nHeads = FDDevStat.nHead;
PDrvs[ld].nSecPerTrk = FDDevStat.nSectors;
Ldrv[ld].LBA0 = 0; /* Floppy Boot Sector - always 0 */
Ldrv[ld].LBAMax= FDDevStat.BlocksMax-1; /* Max lba for logical drive 0 */
Ldrv[ld].nHeads = FDDevStat.nHead;
Ldrv[ld].nSecPerTrk = FDDevStat.nSectors;
/*
Dump(&FDDevStat, 64);
ReadKbd(&keycode, 1);
*/
erc = 0;
}
else
Ldrv[ld].DevNum = 0xff;
return erc;
}
/** StatFloppy *********************************
Before each operation on a floppy we status it
to see if we have changed media. If so, we
reinit the floppy system.
*************************************************/
U32 StatFloppy(U8 ld)
{
U32 erc, i;
erc = DeviceStat(ld+10, &FDDevStat, 64, &i);
return erc;
}
/************************************************
Reads the partition table entries from hard
drives and sets up some of the the logical
drive array variables for hard Disks.
It also saves first cylinder, head and sector
of the first partiton on each physical drive
so we can get more info for the LDrv arrays
from the boot sector of that partition.
*************************************************/
U32 read_PE(void)
{
U32 erc, ercD12, ercD13, i, j;
U8 fFound1, fFound2;
fFound1 = 0; /* Have we found first valid partition on drive */
fFound2 = 0;
/* Set defaults for 4 physical drives. This info will be set
correctly when the partition table and boot sectors are read.
*/
for (i=2; i< nLDrvs; i++) { /* default to no logical hard drives */
Ldrv[i].DevNum = 0xff;
}
i = 2; /* first Logical Number for hard drives "C" */
for (j=2; j<4; j++) { /* Array index Numbers for 2 physical hard Disks */
erc = DeviceOp(j+10, 1, 0, 1, abRawSector); /* add 10 for Disk device nums */
if (j==2) ercD12 = erc;
else ercD13 = erc;
if (!erc) {
CopyData(&abRawSector[0x01fe], &partsig, 2);
/* It MUST have a partition table or we can't use it! */
if (partsig != 0xAA55) return ErcNoParTable;
CopyData(&abRawSector[0x01be], &partab[0].fBootable, 64);
/*
Dump(&partab[0].fBootable, 64);
ReadKbd(&keycode, 1);
*/
if (partab[0].nSectorsTotal > 0) {
Ldrv[i].LBA0 =partab[0].nFirstSector; /* lba for Start of LDrv (bootSect) */
Ldrv[i].LBAMax =partab[0].nSectorsTotal; /* Max lba for logical drive */
Ldrv[i].LBAMax =partab[0].nSectorsTotal; /* Max lba for logical drive */
if (partab[0].FATType > 3)
Ldrv[i].fFAT16 = 1;
Ldrv[i].DevNum = j+10;
if ((j==2) && (!fFound1)) { GetBSInfo(2, 0); fFound1=1; }
if ((j==3) && (!fFound2)) { GetBSInfo(3, 0); fFound2=1; }
i++; /* if valid partition go to next LDrv */
}
if (partab[1].nSectorsTotal > 0) {
Ldrv[i].LBA0 = partab[1].nFirstSector;
Ldrv[i].LBAMax = partab[1].nSectorsTotal;
if (partab[1].FATType > 3)
Ldrv[i].fFAT16 = 1;
Ldrv[i].DevNum = j+10;
if ((j==2) && (!fFound1)) { GetBSInfo(2, 1); fFound1=1; }
if ((j==3) && (!fFound2)) { GetBSInfo(3, 1); fFound2=1; }
i++; /* if we had a valid partition go to next */
}
if (partab[2].nSectorsTotal > 0) {
Ldrv[i].LBA0 = partab[2].nFirstSector;
Ldrv[i].LBAMax = partab[2].nSectorsTotal;
if (partab[2].FATType > 3)
Ldrv[i].fFAT16 = 1;
Ldrv[i].DevNum = j+10;
if ((j==2) && (!fFound1)) { GetBSInfo(2, 2); fFound1=1; }
if ((j==3) && (!fFound2)) { GetBSInfo(3, 2); fFound2=1; }
i++; /* if we had a valid partition go to next */
}
if (partab[3].nSectorsTotal > 0) {
Ldrv[i].LBA0 = partab[3].nFirstSector;
Ldrv[i].LBAMax = partab[3].nSectorsTotal;
if (partab[3].FATType > 3)
Ldrv[i].fFAT16 = 1;
Ldrv[i].DevNum = j+10;
if ((j==2) && (!fFound1)) { GetBSInfo(2, 3); fFound1=1; }
if ((j==3) && (!fFound2)) { GetBSInfo(3, 3); fFound2=1; }
i++; /* if we had a valid partition go to next */
}
}
}
if (ercD12) return ercD12; /* there may be no Device 13 */
else return 0;
}
/********************************************************************
Reads in the first boot sector from each physical drive to get
drive geometry info not available in partition table. This includes
number of heads and sectors per track. Then we call DeviceInit
for each physical device to set its internal drive geometry.
This must be done before we even try to read the other boot sectors
if the disk has mulitple partitions (otherwise it fails).
*********************************************************************/
U32 SetDriveGeometry(U32 d) /* d is the device number (12 or 13) */
{
U32 erc, i;
if (d==12) {
erc = DeviceStat(12, &HDDevStat, 64, &i);
if (!erc) {
HDDevStat.nHead = PDrvs[2].nHeads;
HDDevStat.nSectors = PDrvs[2].nSecPerTrk;
erc = DeviceInit(12, &HDDevStat, 64); /* Set up drive geometry */
}
}
if (d==13) {
erc = DeviceStat(13, &HDDevStat, 64, &i);
if (!erc) {
HDDevStat.nHead = PDrvs[3].nHeads;
HDDevStat.nSectors = PDrvs[3].nSecPerTrk;
erc = DeviceInit(13, &HDDevStat, 64); /* Set up drive geometry */
}
}
return erc;
}
/********************************************************************
Read boot sector from logical drive (i) and sets up logical and
physical drive array variables for the FAT file system found on
the logical drive (described in the boot sector).
*********************************************************************/
U32 read_BS(U32 i)
{
U32 erc, j;
if (Ldrv[i].DevNum != 0xff) {
j = Ldrv[i].DevNum; /* j is MMURTL Device number */
erc = DeviceOp(j, 1, Ldrv[i].LBA0, 1, abRawSector);
if (i<2)
xprintf("Erc1 from FDD %d\r\n", erc);
if ((erc==ErcNewMedia) && (i<2)) {
erc = DeviceOp(j, 1, Ldrv[i].LBA0, 1, abRawSector);
xprintf("Erc2 from FDD %d\r\n", erc);
}
CopyData(abRawSector, &fsb.Jmp, 62);
/*
if (i<2) {
Dump(&fsb.Jmp, 62);
ReadKbd(&keycode, 1);
}
*/
if (erc==0) {
Ldrv[i].LBARoot = fsb.ResSectors + Ldrv[i].LBA0 +
(fsb.FATs * fsb.SecPerFAT);
Ldrv[i].nRootDirEnt = fsb.RootDirEnts; /* n Root dir entries */
Ldrv[i].SecPerClstr = fsb.SecPerClstr;
Ldrv[i].nHeads = fsb.Heads;
Ldrv[i].nSecPerTrk = fsb.SecPerTrack;
Ldrv[i].sFAT = fsb.SecPerFAT; /* nSectors in a FAT */
Ldrv[i].nFATS = fsb.FATs; /* number of FATs */
Ldrv[i].LBAFAT = Ldrv[i].LBA0 + fsb.ResSectors;
Ldrv[i].LBAData = Ldrv[i].LBARoot + (fsb.RootDirEnts / 16);
if (fsb.FileSysType[4] == '2')
Ldrv[i].fFAT16 = 0;
/* else Ldrv[i].fFAT16 = 1; */
} /* if erc */
} /* if valid logical device */
return 0;
}
/*******************************************************
This gets the CMOS date & time and converts it into the
format for the DOS FAT file system. This is two words
with bits representing Year/Mo/day & Hr/Min/SecDIV2.
********************************************************/
void GetFATTime(U16 *pTimeRet, U16 *pDateRet)
{
U32 date, time;
U16 DDate, DTime, w;
GetCMOSDate(&date);
GetCMOSTime(&time);
/* Do the date */
DDate = (((date >> 12) & 0x0f) * 10) + ((date >> 8) & 0x0f); /* day */
w = (((date >> 20) & 0x0f) * 10) + ((date>>16) & 0x0f) + 2; /* month */
DDate |= (w << 4);
w = (((date >> 28) & 0x0f) * 10) + ((date >> 24) & 0x0f); /* year */
DDate |= (w + 1900 - 1980) << 9;
/* Do the time */
DTime = (((((time >> 4) & 0x0f) * 10) + (time & 0x0f))/2); /* secs/2 */
w = (((time >> 12) & 0x0f) * 10) + ((time >> 8) & 0x0f);
DTime |= (w << 5); /* mins */
w = (((time >> 20) & 0x0f) * 10) + ((time >> 16) & 0x0f); /* hours */
DTime |= (w << 11);
*pTimeRet = DTime;
*pDateRet = DDate;
}
/*******************************************************
This updates a directory entry by reading in the
sector it came from and placing the modifed entry
into it then writing it back to disk. The date is
also updated at this time.
********************************************************/
U32 UpdateDirEnt(U32 iFCB)
{
U32 erc, i, j;
U8 Drive;
Drive = paFCB[iFCB]->Ldrv; /* What logical drive are we on? */
i = paFCB[iFCB]->LBADirSect; /* Sector on disk */
j = paFCB[iFCB]->oSectDirEnt; /* offset in sector */
/* update time in dir entry */
GetFATTime(&paFCB[iFCB].Time, &paFCB[iFCB].Date);
/* Read sector into a buffer */
erc = DeviceOp(Ldrv[Drive].DevNum, 1, i, 1, abDirSectBuf);
if (!erc) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?