📄 lowl.c
字号:
cluster = nextcluster;
ret_stat = pc_clnext(&nextcluster, pdr, nextcluster);
}
}
return(ret_stat);
}
/************************************************************************
* FUNCTION
*
* pc_get_chain
*
* DESCRIPTION
*
* Starting at start_cluster return the number of contiguous
* clusters allocated in the chain containing start_cluster or
* n_clusters, whichever is less.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *pdr Drive information
* start cluster Start of the serch cluster
* *pnext_cluster Next cluster number
* n_clusters Number of the cluster that
* is needed.
*
* OUTPUTS
*
* on an error. This function should always return at least one.
* (start_cluster). Unless an error occurs.
*
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
INT32 pc_get_chain(DDRIVE *pdr, UINT32 start_cluster, UINT32 *pnext_cluster,
UINT32 n_clusters)
{
STATUS ret_stat;
UINT32 clno;
UINT32 n_contig;
UINT32 value;
INT16 nibs_per_entry;
if (start_cluster < 2L)
return(NUF_INTERNAL);
if (start_cluster > pdr->maxfindex)
return(NUF_INTERNAL);
nibs_per_entry = pdr->fasize;
clno = start_cluster;
n_contig = 1L;
*pnext_cluster = 0L;
/* Get each FAT entry. If its value points to the next contiguous entry
continue. Otherwise we have reached the end of the contiguous chain.
At which point we return the number of contig's found and by reference
the address of the FAT entry beginning the next chain segment.
*/
while (1)
{
ret_stat = pc_faxx(pdr, clno, &value);
if (ret_stat != NU_SUCCESS)
return(ret_stat);
/* check for a bad cluster and skip it if we see it */
if ( (value == 0xff7 && nibs_per_entry == 3)
|| (value == 0xfff7 && nibs_per_entry == 4)
|| (value == 0x0ffffff7) )
{
clno += 1L;
}
/* check for end markers set next cluster to the last
cluster in the chain if we are at the end */
else if ( (value > 0xff7 && nibs_per_entry == 3)
|| (value > 0xfff7 && nibs_per_entry == 4)
|| (value > 0x0ffffff7) )
{
value = clno;
break;
}
else if (value == ++clno)
{
if (n_contig >= n_clusters)
break;
n_contig++;
}
else
break;
}
*pnext_cluster = value;
return(n_contig);
}
/************************************************************************
* FUNCTION
*
* pc_pfaxx
*
* DESCRIPTION
*
* Given a DDRIVE,cluster number and value. Write the value in the
* fat at clusterno. Handle 32, 16 and 12 bit fats correctly.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *pdr Drive information.
* clno Cluster number to get FAT
* entry value.
* pvalue FAT entry value.
*
* OUTPUTS
*
* If any error occured while FAT swapping return negative value
* else return NU_SUCCESS
*
* NU_SUCCESS If service is successful.
* NUF_NO_MEMORY Can't allocate FAT cache
* buffer. (FAT12 only )
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_pfaxx(DDRIVE *pdr, UINT32 clno, UINT32 value)
{
STATUS ret_stat = NU_SUCCESS;
UINT16 wtry;
UINT32 ltry;
UINT8 wrdbuf[4]; /* Temp storage area */
UINT8 FAR *fat_data = pdr->fat_swap_structure.data_array;
UINT32 FAR *ppage;
UINT32 offset;
INT16 driveno;
UINT16 wvalue;
pdr->fat_is_dirty = YES;
driveno = pdr->driveno;
/* ======================== FAT12 ======================== */
if (pdr->fasize == 3) /* 3 nibble ? */
{
if ( (fat_data == NULL) || ((fat_data[0] & (UINT8)0xF0) != (UINT8)0xF0) )
{
if (fat_data == NULL)
{
pdr->fat_swap_structure.data_array =
(UINT8 FAR *)NUF_Alloc(NUF_Drive_Fat_Size[driveno] << 9 );
#ifdef DEBUG
DEBUG_PRINT("pc_faxx 12bit FAT fat_data == NULL %d %s \r\n", __LINE__, __FILE__);
#endif
if (pdr->fat_swap_structure.data_array == NULL)
{
#ifdef DEBUG
DEBUG_PRINT("pc_faxx 12bit FAT can't read all FAT %d %s \r\n", __LINE__, __FILE__);
#endif
return(NUF_NO_MEMORY);
}
}
#ifdef DEBUG
else
DEBUG_PRINT("pc_faxx 12bit FAT fat_data[0] != 0xF9 %d %s \r\n", __LINE__, __FILE__);
#endif
PC_DRIVE_IO_ENTER(driveno)
if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32)pdr->fatblock,
pdr->fat_swap_structure.data_array, (UINT16) pdr->secpfat, YES) )
{
PC_DRIVE_IO_EXIT(driveno)
pc_report_error(PCERR_FATREAD);
NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
return(NUF_IO_ERROR);
}
PC_DRIVE_IO_EXIT(driveno)
}
value &= 0x0fff; /* 3 nibble clusters */
wtry = (UINT16) (clno + (UINT16) (clno >> 1)); /* multiply by 1.5 */
if ( (UINT16)((clno << 1) + clno) == (wtry << 1) ) /* If whole number */
{
fat_data[wtry] = (UINT8)((UINT8)value & 0xff); /* Low Byte to NIBBLE 1 & 2 */
fat_data[wtry+1] &= 0xf0; /* clr low NIBBLE of next byte */
/* Put the high nibble of value in the low nibble ofnext byte */
fat_data[wtry+1] |= ( ((UINT8)(value >> 8)) & 0x0f );
}
else
{
fat_data[wtry+1]= (UINT8)((UINT8)(value >> 4) & 0xff); /* high to NIB 2 & 3*/
fat_data[wtry] &= 0x0f; /* clr high NIBBLE of byte */
/* Put the low nibble of value in the high nibble of byte */
fat_data[wtry] |= ( ((UINT8)(value & 0xf) << 4) & 0xf0 );
}
/* Now mark the dirty flags block == index/512 */
/* Note try >> 9 and try+1 >> 9 are usually the same */
/* NOTE: data_map is a byte map of dirty fat blocks */
pdr->fat_swap_structure.data_map[(wtry >> 9)] = (UINT8) 1;
pdr->fat_swap_structure.data_map[(wtry+1) >> 9] = (UINT8) 1;
}
/* ======================== FAT16 ======================== */
else if (pdr->fasize == 4)
{
value &= 0xffff; /* 4 nibble clusters */
/* Use temp buffer since fat_data is far , can't call fr word with
it directly in intel small model */
wvalue = value;
SWAP16((UINT16 *)&wrdbuf[0],&wvalue);
if (!pdr->use_fatbuf)
{
/* Using the in-memory FAT Buffers */
/* 16 BIT entries */
/* Byte offset in fat ==s cluster number * 2 */
ltry = (UINT32) clno;
ltry <<= 1;
fat_data[ltry] = wrdbuf[0];
fat_data[ltry+1] = wrdbuf[1];
/* Now mark the dirty flags block == index/512 */
/* NOTE: data_map is a byte map of dirty fat blocks */
pdr->fat_swap_structure.data_map[(ltry >> 9)] = (UINT8) 1;
}
else
{ /* fat swapping. Always 16 or 32 bit entries */
/* Now put the values back into the FAT */
ret_stat = pc_pfpword(pdr, (UINT16)clno, (UINT16 *) &wrdbuf[0]);
if (ret_stat != NU_SUCCESS)
{
return(ret_stat);
}
}
}
/* ======================== FAT32 ======================== */
else if (pdr->fasize == 8)
{ /* 32 BIT entries */
value &= 0x0fffffff; /* 7 nibble clusters */
SWAP32((UINT32 *)&wrdbuf[0],&value);
if (!pdr->use_fatbuf)
{
/* Using the in-memory FAT Buffers */
/* Byte offset in fat ==s cluster number * 4 */
ltry = (UINT32) clno;
ltry <<= 2;
/* Use temp buffer since fat_data is far , can't call fr word with
it directly in intel small model */
fat_data[ltry] = wrdbuf[0];
fat_data[ltry+1] = wrdbuf[1];
fat_data[ltry+2] = wrdbuf[2];
fat_data[ltry+3] = wrdbuf[3];
/* Now mark the dirty flags block == index/512 */
/* NOTE: data_map is a byte map of dirty fat blocks */
pdr->fat_swap_structure.data_map[(ltry >> 9)] = (UINT8) 1;
}
else
{ /* fat swapping. Always 16 or 32 bit entries */
/* Make sure we have access to the page. Mark it for writing */
ret_stat = pc_pfswap((UINT8 FAR **)&ppage, pdr, clno, YES);
if (ret_stat != NU_SUCCESS)
{
#ifdef DEBUG
DEBUG_PRINT("pc_pfswap returned error %d %s \r\n", __LINE__, __FILE__);
#endif
return(ret_stat);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -