Getting the Main Entry | Kickoff

Getting the Main Entry

25 Mar

Getting the Main Entry
The LoadDirAttrib function returns a file’s 8.3 entry in DIRENTRY structure. The function accepts a FILEOBJ pointer to a FILE structure (fo) and a pointer to the number of the file’s entry in its directory (fHandle). The function ignores any long-file-name entries.

The function calls the Cache_File_Entry function in this chapter. In the passed file structure, the dirclus member must contain the number of the first cluster of the file’s directory.

#define ATTR_LONG_NAME 0×0f
#define DIR_DEL 0xE5 // deleted entry
#define DIR_EMPTY 0 // all entries that follow are empty
#define NULL 0
DIRENTRY LoadDirAttrib(FILEOBJ fo, word *fHandle)
{
DIRENTRY dir;
byte a;
// Get the directory entry and store the sector with the entry
// in the FILE structure’s dsk -> buffer member.
dir = Cache_File_Entry( fo, fHandle, TRUE);
// Read the first character of the file name.
a = dir -> DIR_Name[0];
if (a == DIR_EMPTY)
dir = (DIRENTRY)NULL; // The entry is empty.
if (dir != (DIRENTRY)NULL)
{
if ( a == DIR_DEL)
dir = (DIRENTRY)NULL; // The entry is deleted.
else
{
// The entry exists. Get the directory’s attributes.
a = dir -> DIR_Attr;

// Get the first entry that isn’t a long-file-name entry.
while (a == ATTR_LONG_NAME)
{
(*fHandle)++;
// Retrieve a directory entry and get the attributes.
// The ForceRead parameter is false
// to prevent unnecessary sector reads.
dir = Cache_File_Entry( fo, fHandle, FALSE);
a = dir -> DIR_Attr;
}
}
}
return(dir);
}

Updating an Entry
The Write_File_Entry function accepts a FILEOBJ pointer to a FILE structure and a pointer to the number of the file’s entry in its directory (curEntry). The FILE structure’s dsk -> buffer member must contain the contents of the sector to be written, and the dirccls member must contain the number of the entry’s directory cluster. The function calculates the sector to write to and writes the contents of the buffer to the storage media.

The function calls the SectorWrite function from Chapter 5 and the Cluster2Sector function from Chapter 8.

byte Write_File_Entry( FILEOBJ fo, word *curEntry)
{
word ccls;
DISK *dsk;
byte offset2;
dword sector;
byte status;
// Save the FILE structure’s dsk member and directory cluster.
dsk = fo -> dsk;
ccls = fo -> dirccls;

// A sector can hold 16 directory entries.
// Shift right 4 times to get the number of the sector within the directory.
// If curEntry < 10h, it’s the directory’s first sector and offset2 = 0.
// If curEntry >= 10h and < 20h, it’s the directory’s second sector and offset2 = 1.
offset2 = (*curEntry >> 4);
// If it’s not the root directory,
// divide the sector number obtained above by the number of sectors per cluster.
// The remainder (offset2) is the sector number within the cluster.
if (ccls != 0)
offset2 = offset2 % (dsk -> SecPerClus);
// Get the sector number of the passed directory cluster.
sector = Cluster2Sector(dsk, ccls);
// Write the data in dsk -> buffer to the entry’s sector in the media.
if (SectorWrite(sector + offset2, dsk -> buffer) != sdcValid)
status = FALSE;
else
status = TRUE;
return(status);
}

Updating the Time and Date
The IncrementTimeStamp function accepts a DIRENTRY structure (dir) and writes time and date information in the fields that hold the file’s last-modified time and date.

The function emulates a real-time clock for systems that don’t have one. The function increments the time in units of two seconds on each write. A system with a real-time clock should of course obtain the current values from the clock and store these in the DIRENTRY structure.

void IncrementTimeStamp(DIRENTRY dir)
{
byte seconds;
byte minutes;
byte hours;
byte day;
byte month;
byte year;
// Get the time and date information from the passed DIRENTRY structure.
seconds = (dir -> DIR_WrtTime & 0×1f);
minutes = ((dir -> DIR_WrtTime & 0×07E0) >> 5);
hours = ((dir -> DIR_WrtTime & 0xF800) >> 11);
day = (dir -> DIR_WrtDate & 0×1f);
month = ((dir -> DIR_WrtDate & 0×01E0) >> 5);
year = ((dir -> DIR_WrtDate & 0xFE00) >> 9);
// Increment the time.
// Seconds is in units of 2 seconds (0-29).
if (seconds < 29)
seconds++;
else
{
seconds = 0×00; // It’s a new minute.
if (minutes < 59)
{
minutes++;
}
else
{
minutes = 0; // It’s a new hour.
if (hours < 23)
{
hours++;
}

else
{
hours = 0; // It’s a new day.
if (day < 28)
{
day++;
}
else
{
day = 1; // It’s a new month. (Assumes 28 days/month.)
if (month < 12)
{
month++;
}
else
{
month = 1; // It’s a new year.
year++;
}
}
}
}
}
dir->DIR_WrtTime = (word)(seconds);
dir->DIR_WrtTime |= ((word)(minutes) << 5);
dir->DIR_WrtTime |= ((word)(hours) << 11);
dir->DIR_WrtDate = (word)(day);
dir->DIR_WrtDate |= ((word)(month) << 5);
dir->DIR_WrtDate |= ((word)(year) << 9);
}

Random Posts

No comments yet

Leave a Reply

You must be logged in to post a comment.