📄 lowl.c
字号:
}
else
{
/* Not mapped, we have to read it in */
if (pfs->n_blocks_used != pfs->n_blocks_total)
{
/* If we haven't reached steady state: use core until we
get there. */
data_block_to_use = pfs->n_blocks_used;
pfs->n_blocks_used += (word)1;
}
else
{
/* Flush the buffer
Later make this more selective by only flushing the block we
are swapping */
#if (RTFS_WRITE)
if (!pc_pfflush(pdr))
return(0);
#endif
/* Select the block to swap out. Use a simple round-robin
selection algorithm: pfs->n_to_swap is the current
target for swapping (block 0 is never swapped out) */
if (!pfs->n_to_swap)
pfs->n_to_swap += (word)1;
if (pfs->n_to_swap >= pdr->secpfat)
pfs->n_to_swap = 1;
data_block_to_use = 0;
while (data_block_to_use == 0)
{
for (i = pfs->n_to_swap; i < pdr->secpfat; i++)
{
if (pfs->data_map[(int)i])
{
/* swap this one out */
data_block_to_use = pfs->data_map[(int)i];
pfs->data_map[(int)i] = 0;
pfs->n_to_swap =(word)(i+1);
break;
}
}
if (!data_block_to_use)
pfs->n_to_swap = 1; /* Start at the beginining */
}
} /* END IF we had to swap */
/* Whether we are reusing a block or still coming up to speed.
if the block is not currently in our pool we must mark the
data block used and read it in */
pfs->data_map[block_offset_in_fat] = (byte) data_block_to_use;
newblock = pdr->fatblock + block_offset_in_fat;
ltemp = (dword) data_block_to_use;
#if (FAT_BUFFER_SIZE > 63) /* Ugly conditional until sure */
pdata = pfs->data_array + (ltemp << 9);
#else
pdata = pfs->data_array + (word) (ltemp << 9);
#endif
/* READ */
if (!devio_read(pdr->driveno,newblock,pdata,1, FALSE))
{
pfs->data_map[(int)block_offset_in_fat] = 0;
return(0);
}
pfs->block_0_is_valid = TRUE;
} /* END IF the data needed reading in */
/* If we should mark it dirty do so in the bit map */
#if (RTFS_WRITE)
if (for_write)
{
byte_offset = (word) (block_offset_in_fat >> 3); /* divide by 8 */
bit_offset = (word) (block_offset_in_fat & 0x7); /* mod 8 */
uc = 1;
uc <<= bit_offset;
pfs->pdirty[byte_offset] |= uc;
}
#endif
return(pdata);
}
/* Put or get a WORD value into the fat at index */
BOOLEAN pc_fword(DDRIVE *pdr, CLUSTERTYPE index, word *pvalue, BOOLEAN putting) /*__fn__*/
{
word *ppage;
word offset;
/* Make sure we have access to the page. Mark it for writing (if a put) */
ppage = (word *)pc_pfswap(pdr,index,putting);
if (!ppage)
return(FALSE);
else
{
/* there are 256 entries per page */
offset = (word) (index & 0xff);
if (putting)
ppage[offset] = *pvalue;
else
*pvalue = ppage[offset];
}
return(TRUE);
}
#if (FAT32)
#if RTFS_WRITE
/* Put a DWORD value into the fat at index */
BOOLEAN pc_pfpdword(DDRIVE *pdr, dword index, dword *pvalue) /*__fn__*/
{
dword KS_FAR *ppage;
dword offset;
/* Make sure we have access to the page. Mark it for writing */
ppage = (dword KS_FAR *)pc_pfswap(pdr,index,TRUE);
if (!ppage)
return(FALSE);
else
{
/* there are 128 entries per page */
offset = (dword) (index & 0x7f);
ppage[(int)offset] = *pvalue;
}
return(TRUE);
}
#endif
/* Get a DWORD value from the fat at index */
BOOLEAN pc_pfgdword(DDRIVE *pdr, dword index, dword *value) /*__fn__*/
{
dword KS_FAR *ppage;
dword offset;
/* Make sure we have access to the page. Don't Mark it for writing */
ppage = (dword KS_FAR *)pc_pfswap(pdr,index,FALSE);
if (!ppage)
return(FALSE);
else
{
/* there are 128 entries per page */
offset = (dword) (index & 0x7f);
*value = ppage[(int)offset];
}
return(TRUE);
}
#endif /* FAT32 */
#if (RTFS_WRITE)
/* Consult the dirty fat block list and write any. write all copies
of the fat */
/* Note: The caller locks the fat before calling this routine */
BOOLEAN pc_pfflush(DDRIVE *pdr) /*__fn__*/
{
FATSWAP *pfs = &pdr->fat_swap_structure;
byte *pdata;
int i;
word j;
byte uc;
byte bit_in_array;
word offset_div_8;
BLOCKT blockno;
word offset_in_block_map;
dword data_offset;
dword baseblock; /* BUG FIX */
for (j = 0; j < pdr->numfats;j++)
{
baseblock = (dword) j; /* BUG FIX */
baseblock *= pdr->secpfat; /* BUG FIX */
baseblock += pdr->fatblock; /* BUG FIX */
#if (FAT_BUFFER_SIZE > 63) /* Ugly conditional until sure */
for (offset_div_8 = 0,i = 0; i < FAT_BUFFER_SIZE/8; i++,offset_div_8 += 8)
#else
for (offset_div_8 = 0,i = 0; i < 32; i++,offset_div_8 += (word)8)
#endif
{
uc = pfs->pdirty[i];
bit_in_array = 0;
while (uc)
{
if (uc & 0x01) /* If bit is dirty. */
{
/* add (by oring) the byte index and the bit index
to get the block offset in the fat */
offset_in_block_map = (word)(offset_div_8 | bit_in_array);
/* map the offset to data through our map */
data_offset = (dword) pfs->data_map[offset_in_block_map];
#if (FAT32)
if (pdr->fasize == 8)
{
data_offset = (dword) offset_in_block_map;
if (data_offset >= pfs->n_blocks_total) return(FALSE);
}
#endif
/* Convert block offset to byte offset */
data_offset <<= 9;
/* Get its address in our data array */
#if (FAT_BUFFER_SIZE > 63) /* Ugly conditional until sure */
pdata = pfs->data_array + (word) data_offset;
#else
pdata = pfs->data_array + (word) data_offset;
#endif
/* Convert offset in fat to logical disk block */
blockno = baseblock + offset_in_block_map; /* BUG FIX */
#if (FAT32)
if (pdr->fasize == 8)
{
blockno = baseblock + (offset_in_block_map +
((((dword*)pfs->data_map)[offset_in_block_map] &
0x7ffffffful) * pfs->n_blocks_total));
}
#endif
/* WRITE IT */
if(!devio_write(pdr->driveno,blockno,pdata,1, FALSE))
{
pc_report_error(PCERR_FAT_FLUSH);
return(FALSE);
}
}
uc >>= 1;
bit_in_array++;
}
}
}
/* Clear the dirty map */
#if (FAT_BUFFER_SIZE > 63) /* Ugly conditional until sure */
pc_memfill(pfs->pdirty, FAT_BUFFER_SIZE/8, (byte) 0);
#else
pc_memfill(pfs->pdirty, 32, (byte) 0);
#endif
return (TRUE);
}
#endif /* (RTFS_WRITE) - for fflush */
RTFS_FILE(gblk0.c, pc_gblk0)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/****************************************************************************
PC_GBLK0 - Read block 0 and load values into a a structure
Description
Given a valid drive number, read block zero and convert
its contents from intel to native byte order.
Returns
Returns TRUE if all went well.
****************************************************************************/
/* read block zero */
BOOLEAN pc_gblk0(word driveno, struct pcblk0 *pbl0) /*__fn__*/
{
BLKBUFF *buf;
byte *b;
#if (FAT32)
word i;
#endif
/* Zero fill pbl0 so we don't get any surprises */
pc_memfill(pbl0, sizeof(struct pcblk0), (byte) 0);
/* Grab a buffer to play with */
buf = pc_scratch_blk();
if (!buf)
return(FALSE);
b = buf->data; /* Now we don't have to use the stack */
/* get 1 block starting at 0 from driveno */
/* READ */
if (!devio_read(driveno, 0L ,b,1, FALSE))
{
pc_free_buf(buf, TRUE);
return(FALSE);
}
#if (0)
{
int i;
tm_printf("Dump of block 0 \n");
for (i = 0; i < 512; i += 16)
{
tm_printf("%-2.2d %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %-2.2x %2.2x\n",
i,
(int)b[i+0],(int)b[i+1],(int)b[i+2],(int)b[i+3],
(int)b[i+4],(int)b[i+5],(int)b[i+6],(int)b[i+7],
(int)b[i+8],(int)b[i+9],(int)b[i+10],(int)b[i+11],
(int)b[i+12],(int)b[i+13],(int)b[i+14],(int)b[i+15]);
}
}
#endif
/* Now load the structure from the buffer */
pbl0->jump = b[0];
copybuff( &pbl0->oemname[0],b+3,8);
pbl0->oemname[8] = '\0';
pbl0->secpalloc = b[0xd];
pbl0->numfats = b[0x10];
pbl0->mediadesc = b[0x15];
pbl0->physdrv = b[0x24]; /* Physical Drive No. (4.0) */
pbl0->filler = b[0x25]; /* Reserved (4.0) */
pbl0->xtbootsig = b[0x26]; /* Extended signt 29H if 4.0 stuf valid */
/* BUG FIX 12-1-99 - Add KS_LITTLE_ODD_PTR_OK flag to split between
big endian and little endian system. The top section works on little
endian systems that do not require even alligned word accesses like
the x86 but for example on Little endian ARM systems these assignments
derefrencing a pointer to word at an odd address which gives bad data .*/
#if (KS_LITTLE_ENDIAN && KS_LITTLE_ODD_PTR_OK)
pbl0->bytspsector = *( (word *)(b+0xb));
pbl0->secreserved = *( (word *)(b+0xe ));
pbl0->numroot = *( (word *)(b+0x11));
pbl0->numsecs = *( (word *)(b+0x13));
pbl0->secpfat = *( (word *)(b+0x16));
pbl0->secptrk = *( (word *)(b+0x18));
pbl0->numhead = *( (word *)(b+0x1a));
#if (FAT32)
if (pbl0->numroot == 0)
{
pbl0->secpfat2 = *( (dword *)(b+0x24));
pbl0->flags = *( (word *)(b+0x28));
pbl0->fs_version = *( (word *)(b+0x2a));
pbl0->rootbegin = *( (dword *)(b+0x2c));
pbl0->infosec = *( (word *)(b+0x30));
pbl0->backup = *( (word *)(b+0x32));
}
#endif /* FAT32 */
pbl0->numhide = *( (word *)(b+0x1c));
pbl0->numhide2 = *( (word *)(b+0x1e));
pbl0->numsecs2 = *( (dword *)(b+0x20)); /* # secs if > 32M (4.0) */
pbl0->volid = *( (dword *)(b+0x27)); /* Unique number per volume (4.0) */
#else
pbl0->bytspsector = to_WORD(b+0xb); /*X*/
pbl0->secreserved = to_WORD(b+0xe); /*X*/
pbl0->numroot = to_WORD(b+0x11); /*X*/
pbl0->numsecs = to_WORD(b+0x13); /*X*/
pbl0->secpfat = to_WORD(b+0x16); /*X*/
pbl0->secptrk = to_WORD(b+0x18); /*X*/
pbl0->numhead = to_WORD(b+0x1a); /*X*/
#if (FAT32)
if (pbl0->numroot == 0)
{
pbl0->secpfat2 = to_DWORD(b+0x24);
pbl0->flags = to_WORD(b+0x28);
pbl0->fs_version = to_WORD(b+0x2a);
pbl0->rootbegin = to_DWORD(b+0x2c);
pbl0->infosec = to_WORD(b+0x30);
pbl0->backup = to_WORD(b+0x32);
}
#endif /* FAT32 */
pbl0->numhide = to_WORD(b+0x1c); /*X*/
pbl0->numhide2 = to_WORD(b+0x1e); /*X*/
pbl0->numsecs2 = to_DWORD(b+0x20);/*X*/ /* # secs if > 32M (4.0) */
pbl0->volid = to_DWORD(b+0x27);/*X*/ /* Unique number per volume (4.0) */
#endif
if(pbl0->numroot==0)
copybuff( &pbl0->vollabel[0],b+0x47,11); /* Volume label FAT32 */
else
copybuff( &pbl0->vollabel[0],b+0x2b,11); /* Volume label (4.0) */
#if (FAT32)
if (pbl0->numroot == 0)
{
if (!devio_read(driveno,(BLOCKT)(pbl0->infosec) ,b,1, FALSE))
{
pc_free_buf(buf, TRUE);
return(FALSE);
}
#if KS_LITTLE_ENDIAN
for (i=0; *((dword *)b) != FSINFOSIG && i<512; b++,i++);
pbl0->free_alloc = ((struct fat32_info *)b)->free_alloc;
pbl0->next_alloc = ((struct fat32_info *)b)->next_alloc;
#else
for (i=0; to_DWORD((void KS_FAR *)b) != FSINFOSIG && i<512; b++,i++);
pbl0->free_alloc = to_DWORD((void KS_FAR *)&((struct fat32_info *)b)->free_alloc);
pbl0->next_alloc = to_DWORD((void KS_FAR *)&((struct fat32_info *)b)->next_alloc);
#endif
}
#endif /* FAT32 */
#if (1)
// =====
tm_printf("Jump %x\n", (int) b[0]);
tm_printf("Oemname %s\n", &pbl0->oemname[0]);
tm_printf("bytspsector %d\n", (int) pbl0->bytspsector);
tm_printf("Secpalloc %d\n", pbl0->secpalloc);
tm_printf("Numfats %d\n", pbl0->numfats);
tm_printf("Mediadesc %x\n", pbl0->mediadesc);
tm_printf("physdrv %x\n", pbl0->physdrv);
tm_printf("filler %x\n", pbl0->filler);
tm_printf("bootsig %x\n", pbl0->xtbootsig);
tm_printf("secreserved %d\n", (int) pbl0->secreserved);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -