📄 lowl.c
字号:
driveno= pdr->driveno;
/* ======================== FAT12 ======================== */
if (pdr->fasize == 3) /* 3 nibble ? */
{
/* We do not read FAT to FAT cache yet. */
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 allocate FAT cache buffer %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)
/* Read FAT sectors */
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)
}
wtry = (UINT16) (clno + (UINT16) (clno >> 1)); /* multiply by 1.5 */
/* And use the product as index */
wrdbuf[0] = fat_data[wtry]; /* Use a temp variable since in */
wrdbuf[1] = fat_data[wtry+1]; /* small model we can't call with
fat_data (it's a far pointer) */
SWAP16((UINT16 *)&wvalue, (UINT16 *)wrdbuf);
*pvalue = (UINT32) wvalue; /* And use the product as index */
if ( (UINT16)((clno << 1) + clno) == (wtry << 1) ) /* If whole number */
*pvalue &= 0xfff; /* Return it */
else
*pvalue =(UINT32) ((UINT16) (*pvalue >> 4) & 0xfff ); /* shift right 4 */
}
/* ======================== FAT16 ======================== */
else if (pdr->fasize == 4)
{
/* 16 BIT fat. ret the value at 2 * clno */
/* Some FAT data is cached */
if (pdr->use_fatbuf)
{
ret_stat = pc_pfgword(pdr, (UINT16)clno, (UINT16 *) &wrdbuf[0]);
if (ret_stat != NU_SUCCESS)
{
#ifdef DEBUG
DEBUG_PRINT("pc_pfgword returned error %d %s \r\n", __LINE__, __FILE__);
#endif
return(ret_stat);
}
}
/* All FAT data is cached */
else
{
ltry = (UINT32) clno;
ltry <<= 1;
wrdbuf[0] = fat_data[ltry]; /* Use a temp variable since in */
wrdbuf[1] = fat_data[ltry+1]; /* intel small model we can't call
with fat_data (it's a far pointer) */
}
SWAP16(&wvalue, (UINT16 *)wrdbuf);
*pvalue = wvalue;
}
/* ======================== FAT32 ======================== */
else if (pdr->fasize == 8)
{
/* Some FAT data is cached */
if (pdr->use_fatbuf)
{
/* Make sure we have access to the page. Don't Mark it for writing */
ret_stat = pc_pfswap(&ppage, pdr, clno, NO);
if (ret_stat != NU_SUCCESS)
{
#ifdef DEBUG
DEBUG_PRINT("pc_pfswap returned error %d %s \r\n", __LINE__, __FILE__);
#endif
return(ret_stat);
}
else
{
/* there are 128 entries per page */
offset = (UINT32) (clno & 0x7f);
*((UINT32 *)wrdbuf) = *((UINT32 *)ppage + offset);
}
}
/* All FAT data is cached */
else
{
/* 32-bit FAT */
ltry = (UINT32) clno;
ltry <<= 2;
wrdbuf[0] = fat_data[ltry]; /* Use a temp variable since in */
wrdbuf[1] = fat_data[ltry+1]; /* intel small model we can't call */
wrdbuf[2] = fat_data[ltry+2]; /* with fat_data (it's a far pointer) */
wrdbuf[3] = fat_data[ltry+3];
}
SWAP32(pvalue,(UINT32 *)&wrdbuf[0]); /* And use the product as index */
}
else
{
#ifdef DEBUG
DEBUG_PRINT("pdr->fasize error %d %s \r\n", __LINE__, __FILE__);
#endif
return(NUF_INTERNAL);
}
return(NU_SUCCESS);
}
/************************************************************************
* FUNCTION
*
* pc_flushfat
*
* DESCRIPTION
*
* Given a valid drive number. Write any fat blocks to disk that
* have been modified. Updates all copies of the fat.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *pdr Drive management structure
*
* OUTPUTS
*
* NU_SUCCESS FAT flush success.
* NU_IO_ERROR Write failed.
* NU_INTERNAL FAT cache is NULL
*
*************************************************************************/
STATUS pc_flushfat(DDRIVE *pdr)
{
FATSWAP *pfs;
UINT8 FAR *pf;
UINT16 *pd;
UINT32 i;
UINT32 imax;
UINT16 j;
UINT32 baseblock;
INT is_last;
STATUS ret_stat;
/* The FAT has no dirty block which heed to be write. */
if (!pdr->fat_is_dirty)
return(NU_SUCCESS);
/* Whether we uses the FAT cache as buffer ? */
if (pdr->use_fatbuf)
{
/* Flush FAT */
ret_stat = pc_pfflush(pdr);
if (ret_stat == NU_SUCCESS)
{
/* FAT flush successful compleate */
pdr->fat_is_dirty = NO;
}
/* status retuern. */
return(ret_stat);
}
/* else ... */
PC_DRIVE_IO_ENTER(pdr->driveno)
/* Move the number of FAT to local */
imax = (UINT32) pdr->secpfat;
for (j = 0; j < pdr->numfats; j++)
{
/* Work out start block number of FAT */
baseblock = (UINT32) j;
baseblock *= imax;
baseblock += pdr->fatblock;
/* Is this FAT last ? */
if ( j == (UINT16) (pdr->numfats - 1) )
is_last = YES;
else
is_last = NO;
/* NOTE: data_array is the fat data. data_map is a 2 bytes map of dirty
fat blocks */
pf = pdr->fat_swap_structure.data_array;
pd = pdr->fat_swap_structure.data_map;
pfs = &pdr->fat_swap_structure;
if (!pf)
{
PC_DRIVE_IO_EXIT(pdr->driveno)
pc_report_error(PCERR_FAT_NULLP);
return(NUF_INTERNAL);
}
/* Check each block in the fat */
for (i = 0; i < imax; i++,pd++,baseblock++)
{
/* If the block is dirty */
if ( (*pd) || ((i == 0) && (pfs->block_0_is_valid)) )
{
/* Write it */
if ( !pc_bdevsw[pdr->driveno].io_proc(pdr->driveno, baseblock+pfs->base_block, pf, (UINT16) 1, NO) )
{
PC_DRIVE_IO_EXIT(pdr->driveno)
pc_report_error(PCERR_FAT_FLUSH);
return(NUF_IO_ERROR);
}
if (is_last)
*pd = (UINT8) 0;
}
pf += 512;
}
}
pdr->fat_is_dirty = NO;
PC_DRIVE_IO_EXIT(pdr->driveno)
return(NU_SUCCESS);
}
/************************************************************************
* FUNCTION
*
* pc_freechain
*
* DESCRIPTION
*
* Trace the cluster chain starting at cluster and return all the
* clusters to the free state for re-use. The FAT is not flushed.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *pdr Drive information
* cluster Free start cluser number
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_freechain(DDRIVE *pdr, UINT32 cluster)
{
STATUS ret_stat;
UINT32 nextcluster;
ret_stat = pc_clnext(&nextcluster, pdr, cluster);
while ( (cluster) && (ret_stat == NU_SUCCESS) )
{
ret_stat = pc_clrelease(pdr, cluster);
if (ret_stat == NU_SUCCESS)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -