📄 libchain.lst
字号:
}
WORD *StringCopy16(WORD *target, WORD *source)
{
while(*source)
{
*target = *source;
target ++;
source ++;
}
*target = 0;
return target;
}
WORD *StringCopy0816(WORD *target, BYTE *source)
{
while(*source)
{
*target = (WORD)*source;
target ++;
source ++;
}
*target = 0;
C51 COMPILER V8.01 LIBCHAIN 04/17/2008 09:45:56 PAGE 10
return target;
}
#endif
553
554 /////////////////utility/////////////////////////////////
555
556 /*
557 *******************************************************************************
558 * LOCAL FUNCTIONS
559 *******************************************************************************
560 */
561
562
563 // move the chain point to the start of the chain
564 void ChainSeekSet(CHAIN *chain)
565 {
566 1 chain->Current = chain->Start;
567 1 chain->Point = 0;
568 1 }
569 #if 0
// move the chain point to the end of the chain
void ChainSeekEnd(DRIVE *drv, CHAIN *chain)
{
DWORD john;
chain->Point = chain->Size - 1;
// if not in the root of FAT12/FAT16
if(chain->Current < 2) return;
john = chain->Current;
while((john != 0xffffffff) && (john >= 2))
{
chain->Current = john;
// john = drv->FatRead(drv, john);
ReadFatxx(drv, john);
}
}
#endif
588
589 //根据distance更新chain->Current,chain->Point
590 BYTE ChainSeekForward(CHAIN *chain, DWORD distance)
591 {
592 1 DWORD john, mary;
593 1 BYTE retVal;
594 1 DRIVE *drv = &Drive[0];
595 1
596 1 retVal = FS_SUCCEED;
597 1 //Figure out the logical cluster location counter of the old chain pointer.
598 1 john = chain->Point >> (drv->ClusterExp + drv->bBytesPerSectorExp);
599 1 //update the chain pointer.
600 1 chain->Point += distance;
601 1
602 1 //Whether the new chain pointer is out fo range.
603 1 if(chain->Point > chain->Size)
604 1 {
605 2 retVal = OUT_OF_RANGE;
606 2 chain->Point = chain->Size-1;
607 2 }
608 1 //Figure out the logical cluster location counter of the new chain pointer.
609 1 mary = chain->Point >> (drv->ClusterExp + drv->bBytesPerSectorExp);
610 1
611 1 // if at root of FAT12/FAT16
C51 COMPILER V8.01 LIBCHAIN 04/17/2008 09:45:56 PAGE 11
612 1 if(!chain->Start) return retVal;
613 1
614 1 while(john < mary) // move to the specified cluster position
615 1 {
616 2 // chain->Current = drv->FatRead(drv, chain->Current);
617 2 chain->Current = ReadFatxx(chain->Current);
618 2 john ++;
619 2 }
620 1
621 1 return retVal;
622 1 }
623
624
625 // move the chain point to the specified position
626 BYTE ChainSeek(CHAIN *chain, DWORD position)
627 {
628 1 DRIVE *drv = &Drive[0];
629 1
630 1 //If find the previous node, reset the CHAIN structure.
631 1 if(position < chain->Point) ChainSeekSet(chain);
632 1
633 1
634 1 return ChainSeekForward(chain, position - chain->Point);
635 1 }
636
637
638 #if 0
// set the chain point align to the sector boundary
void ChainSeekAlign(CHAIN *chain)
{
chain->Point &= ~(SECTOR_SIZE - 1);
}
// after the function call, chain->Point will point to the end
int ChainChangeSize(DRIVE *drv, CHAIN *chain, DWORD size)
{
DWORD john, mary;
// if at root of FAT12/FAT16
if(!chain->Start)
{
if(size > (drv->DataStart - drv->RootStart) << drv->bBytesPerSectorExp)
return OVER_ROOT_BOUNDARY;
chain->Size = size;
chain->Point = size;
return FS_SUCCEED;
}
// convert the byte count to cluster count
john = chain->Size >> ( drv->bBytesPerSectorExp + drv->ClusterExp );
if(chain->Size << (32 - drv->bBytesPerSectorExp - drv->ClusterExp)) john ++;
if(!chain->Size)
{
john ++; // even the zero size have at least one cluster
WriteFatxx(drv, chain->Current, 0xffffffff); // set terminator of this chain
}
mary = size >> ( drv->bBytesPerSectorExp + drv->ClusterExp );
if(size << (32 - drv->bBytesPerSectorExp - drv->ClusterExp)) mary ++;
C51 COMPILER V8.01 LIBCHAIN 04/17/2008 09:45:56 PAGE 12
if(mary > john) // test if requested cluster greater than original cluster
{
john = mary - john; // A = needed new cluster count
if(john > drv->FreeClusters)
return DISK_FULL;
ChainSeekEnd(drv, chain); // move to tail of the chain
while(john)
{
mary = DriveNewClusGet(drv);
if(mary == 0xffffffff)
return DISK_FULL;
WriteFatxx(drv, chain->Current, mary); // extend this chain on cluster
chain->Current = mary;
john --;
}
WriteFatxx(drv, chain->Current, 0xffffffff); // set terminator of this chain
}
else if(john > mary) // test if the original cluster greater than the requested cluster
{
ChainSeek(drv, chain, size);
// john = drv->FatRead(drv, chain->Current);
john = ReadFatxx(drv, chain->Current);
WriteFatxx(drv, chain->Current, 0xffffffff); // terminate this chain
while(john != 0xffffffff) // free the following clusters
{
// mary = drv->FatRead(drv, john);
mary = ReadFatxx(drv, john);
WriteFatxx(drv, john, 0);
john = mary;
}
}
chain->Size = size;
chain->Point = size;
return FS_SUCCEED;
}
// extend the specified chain one cluster and clear the extended part
int ChainExtending(DRIVE *drv, CHAIN *chain)
{
DWORD john, mary;
// if at root of FAT12/FAT16
if(!chain->Start) return OVER_ROOT_BOUNDARY;
john = chain->Point; // save the chain->Point
ChainSeekEnd(drv, chain); // move to tail of the chain
mary = DriveNewClusGet(drv);
if(mary == 0xffffffff) return DISK_FULL;
WriteFatxx(drv, chain->Current, mary); // extend this chain one cluster
// chain->Current = mary;
C51 COMPILER V8.01 LIBCHAIN 04/17/2008 09:45:56 PAGE 13
WriteFatxx(drv, mary, 0xffffffff); // set terminator of this chain
chain->Point = john;
chain->Size += (drv->ClusterSize << drv->bBytesPerSectorExp); // update the cha
-in size
// clear the extended part
SectorClear(drv, ((mary - 2) << drv->ClusterExp) + drv->DataStart, drv->ClusterSize);
return FS_SUCCEED;
}
#endif
747
748 // return the lba that the chain point located
749 DWORD ChainCurrentSector(CHAIN *chain)
750 {
751 1 DWORD lba;
752 1 DRIVE *drv = &Drive[0];
753 1
754 1 if(!chain->Start) // if at the root of FAT12/FAT16
755 1 lba = drv->RootStart + ( chain->Point >> drv->bBytesPerSectorExp ); // at the first time, chain-
->Point is 0
756 1 else{ // FAT32
757 2 lba = (chain->Point >> drv->bBytesPerSectorExp) & (drv->ClusterSize - 1); // calculate the sect
-or offset in a cluster.
758 2 lba += (chain->Current - 2) << drv->ClusterExp; // add current cluster address
759 2 lba += drv->DataStart; // add the data area base address
760 2 }
761 1
762 1 return lba;
763 1 }
764 #if 0
BYTE ChainGet1Sector(DRIVE *drv, CHAIN *chain)
{
DWORD addend, result;
DWORD current;
result = 1;
#if 1 //?????????????????
// get the sector offset of the current point within the current cluster
addend = chain->Point << (32 - drv->ClusterExp - 9);
addend = addend >> (32 - drv->ClusterExp);
//UartOutText("chain->Point: "); UartOutValue(chain->Point, 8);
//UartOutText("addend: "); UartOutValue(addend, 8);
addend = drv->ClusterSize - addend;
if(addend <= 1){ //The last sector in the current cluster, should update the chain->Current
current = ReadFatxx(drv, chain->Current);
if(current != 0xffffffff){
chain->Current = current;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -