📄 lowl.c
字号:
*
* AUTHOR
*
* Kyoichiro Toda
*
* INPUTS
*
* *clno Return a new cluster number
* *pdr Drive information
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_NOSPC No free cluster.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_clalloc(UINT32 *clno, DDRIVE *pdr)
{
STATUS ret_stat;
*clno = 0L;
/* Look in the "fragmentable" region first from pc_find_free_cluster up */
ret_stat = pc_find_free_cluster(clno, pdr, pdr->free_contig_pointer, pdr->maxfindex);
/* Look in the "fragmentable" region up to pc_find_free_cluster */
if (ret_stat == NUF_NOSPC)
ret_stat = pc_find_free_cluster(clno, pdr, 2L, pdr->free_contig_pointer);
if (ret_stat != NU_SUCCESS)
return(ret_stat);
/* Mark the cluster in use */
ret_stat = pc_pfaxx(pdr, *clno, ((UINT32) -1));
if (ret_stat != NU_SUCCESS)
return(ret_stat);
if (pdr->free_clusters_count)
pdr->free_clusters_count -= 1L;
return(NU_SUCCESS);
}
/************************************************************************
* FUNCTION
*
* pc_clgrow
*
* DESCRIPTION
*
* Given a DDRIVE and a cluster, extend the chain containing the
* cluster by allocating a new cluster and linking clno to it. If
* clno is zero assume it is the start of a new file and allocate
* a new cluster.
*
* AUTHOR
*
* Kyoichiro Toda
*
* INPUTS
*
* *nxt Return new allocated cluster
* number
* *pdr Drive information
* clno Extend cluster number
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_NOSPC No free cluster.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_clgrow(UINT32 *nxt, DDRIVE *pdr, UINT32 clno)
{
STATUS ret_stat;
UINT32 nextcluster;
#ifdef DEBUG
if (!clno)
DEBUG_PRINT("Invalid cluster number specified %d %s \r\n"
, __LINE__, __FILE__);
#endif
/* Make sure we are at the end of chain */
ret_stat = pc_clnext(&nextcluster, pdr, clno);
if (ret_stat != NU_SUCCESS)
return(ret_stat);
while (nextcluster)
{
clno = nextcluster;
pc_clnext(&nextcluster, pdr, clno);
}
/* Get a cluster, clno provides a hint for more efficient cluster
allocation */
ret_stat = pc_clalloc(nxt, pdr);
if (ret_stat == NU_SUCCESS)
{
ret_stat = pc_pfaxx(pdr, clno, *nxt);
}
return(ret_stat);
}
/************************************************************************
* FUNCTION
*
* pc_clnext
*
* DESCRIPTION
*
* Given a DDRIVE and a cluster number, return the next cluster in
* the chain containing clno. Return 0 on end of chain.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *nxt Next cluster pointer(cluster
* value)
* *pdr Drive information
* clno Check the cluster number
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_DEFECTIVEC Defective cluster detected.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_clnext(UINT32 *nxt, DDRIVE *pdr, UINT32 clno)
{
STATUS ret_stat;
/* Get the value at clno. return 0 on any io errors */
ret_stat = pc_faxx(pdr, clno, nxt);
if (ret_stat == NU_SUCCESS)
{
if (pdr->fasize == 3) /* 3 nibble ? */
{
if ( (0xff7 < *nxt) && (*nxt <= 0xfff) )
*nxt = 0; /* end of chain */
if (*nxt == 0xff7) /* Defective Cluster */
ret_stat = NUF_DEFECTIVEC;
#ifdef DEBUG
if (*nxt > 0xfff)
DEBUG_PRINT("Invalid FAT entry %x %d %s \r\n",*nxt, __LINE__, __FILE__);
#endif
}
else if (pdr->fasize == 4) /* 4 nibble ? */
{
if (0xfff7 < *nxt)
*nxt = 0; /* end of chain */
if (*nxt == 0xfff7) /* Defective Cluster */
ret_stat = NUF_DEFECTIVEC;
#ifdef DEBUG
if (*nxt > 0xffff)
DEBUG_PRINT("Invalid FAT entry %x %d %s \r\n",*nxt, __LINE__, __FILE__);
#endif
}
else
{ /* FAT32 */
if (0x0ffffff7 < *nxt)
*nxt = 0; /* end of chain */
if (*nxt == 0x0ffffff7) /* Defective Cluster */
ret_stat = NUF_DEFECTIVEC;
#ifdef DEBUG
if (*nxt > 0x0fffffff)
DEBUG_PRINT("Invalid FAT entry %x %d %s \r\n",*nxt, __LINE__, __FILE__);
#endif
}
}
return(ret_stat);
}
/************************************************************************
* FUNCTION
*
* pc_clrelease
*
* DESCRIPTION
*
* Given a DDRIVE and a cluster, mark the cluster in the file
* allocation table as free. It will be used again by calls to
* pc_clalloc().
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *pdr Drive information
* clno Release the cluster number
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_clrelease(DDRIVE *pdr, UINT32 clno)
{
STATUS ret_stat;
/* Don't catch any lower level errors here. You'll catch them soon enough */
ret_stat = pc_pfaxx(pdr, clno, ((UINT32) 0)); /* Mark it as free */
if (ret_stat == NU_SUCCESS)
{
/* If freeing in the "contiguous" region reset the "hint" if we
free space earlier than it. */
if (pdr->fasize <= 4)
{
if (clno <= pdr->free_contig_pointer)
pdr->free_contig_pointer = clno;
}
if (pdr->free_clusters_count)
pdr->free_clusters_count += 1L;
}
return(ret_stat);
}
/************************************************************************
* FUNCTION
*
* pc_faxx
*
* DESCRIPTION
*
* Given a DDRIVE and a cluster number. Get the value in the fat at
* clusterno (the next cluster in a chain.)
*
* 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_faxx(DDRIVE *pdr, UINT32 clno, UINT32 *pvalue)
{
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;
UINT8 FAR *ppage;
UINT32 offset;
INT16 driveno;
UINT16 wvalue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -