146 lines
2.8 KiB
HolyC
Executable File
146 lines
2.8 KiB
HolyC
Executable File
I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1)
|
|
{//Return next cnt'th clus in chain.
|
|
Bool unlock;
|
|
DrvChk(dv);
|
|
if (cnt<=0) return c;
|
|
try {
|
|
unlock=DrvLock(dv);
|
|
switch (dv->fs_type) {
|
|
case FSt_REDSEA:
|
|
c+=cnt;
|
|
break;
|
|
case FSt_FAT32:
|
|
while (cnt-->0 && 0<c<0x0FFFFFF8) {
|
|
DrvFATBlkSet(dv,c);
|
|
c=dv->cur_fat_blk[c & (BLK_SIZE/4-1)];
|
|
}
|
|
if (!(0<c<0x0FFFFFF8))
|
|
c=INVALID_CLUS;
|
|
break;
|
|
default:
|
|
throw('Drv');
|
|
}
|
|
if (unlock)
|
|
DrvUnlock(dv);
|
|
} catch
|
|
if (unlock)
|
|
DrvUnlock(dv);
|
|
return c;
|
|
}
|
|
|
|
I64 Clus2Blk(CDrv *dv,I64 c)
|
|
{//Drv clus num to blk num.
|
|
DrvChk(dv);
|
|
switch (dv->fs_type) {
|
|
case FSt_REDSEA:
|
|
return c;
|
|
case FSt_FAT32:
|
|
return dv->data_area+c*dv->spc;
|
|
default:
|
|
throw('Drv');
|
|
}
|
|
}
|
|
|
|
I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks)
|
|
{//Accepts blk count, so padding on last clus is not read.
|
|
I64 i;
|
|
Bool unlock;
|
|
DrvChk(dv);
|
|
if (blks<=0) return c;
|
|
try {
|
|
unlock=DrvLock(dv);
|
|
switch (dv->fs_type) {
|
|
case FSt_REDSEA:
|
|
BlkRead(dv,buf,c,blks);
|
|
c+=blks;
|
|
break;
|
|
case FSt_FAT32:
|
|
while (blks && 0<c<0x0FFFFFF8) {
|
|
i=blks;
|
|
if (i>dv->spc)
|
|
i=dv->spc;
|
|
BlkRead(dv,buf,dv->data_area+c*dv->spc,i);
|
|
buf+=i<<BLK_SIZE_BITS;
|
|
c=ClusNumNext(dv,c,1);
|
|
blks-=i;
|
|
}
|
|
if (blks)
|
|
throw('Drv');
|
|
break;
|
|
default:
|
|
throw('Drv');
|
|
}
|
|
if (unlock)
|
|
DrvUnlock(dv);
|
|
} catch
|
|
if (unlock)
|
|
DrvUnlock(dv);
|
|
return c;
|
|
}
|
|
|
|
I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt)
|
|
{//Read clus cnt from drv to buf.
|
|
return ClusBlkRead(dv,buf,c,cnt*dv->spc);
|
|
}
|
|
|
|
I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks)
|
|
{//Accepts blk count, so padding on last clus is not written.
|
|
I64 i;
|
|
Bool unlock;
|
|
DrvChk(dv);
|
|
if (blks<=0) return c;
|
|
try {
|
|
unlock=DrvLock(dv);
|
|
switch (dv->fs_type) {
|
|
case FSt_REDSEA:
|
|
BlkWrite(dv,buf,c,blks);
|
|
c=0;
|
|
break;
|
|
case FSt_FAT32:
|
|
while (blks) {
|
|
if (!(0<c<0x0FFFFFF8))
|
|
throw('Drv');
|
|
i=blks;
|
|
if (i>dv->spc)
|
|
i=dv->spc;
|
|
BlkWrite(dv,buf,dv->data_area+c*dv->spc,i);
|
|
buf+=i<<BLK_SIZE_BITS;
|
|
c=ClusNumNext(dv,c);
|
|
blks-=i;
|
|
}
|
|
break;
|
|
default:
|
|
throw('Drv');
|
|
}
|
|
if (unlock)
|
|
DrvUnlock(dv);
|
|
} catch
|
|
if (unlock)
|
|
DrvUnlock(dv);
|
|
return c;
|
|
}
|
|
|
|
I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt)
|
|
{//Write clus cnt from buf to drv.
|
|
return ClusBlkWrite(dv,buf,c,cnt*dv->spc);
|
|
}
|
|
|
|
I64 ClusAlloc(CDrv *dv,I64 c=0,I64 cnt=1,Bool contiguous=FALSE)
|
|
{//Alloc clus cnt into chain.
|
|
//c=0 means first clus in chain
|
|
DrvChk(dv);
|
|
if (cnt<=0) return c;
|
|
switch (dv->fs_type) {
|
|
case FSt_REDSEA:
|
|
return RedSeaAllocClus(dv,cnt);
|
|
case FSt_FAT32:
|
|
if (contiguous) {
|
|
if (c) throw('File');
|
|
return FAT32AllocContiguousClus(dv,cnt);
|
|
} else
|
|
return FAT32AllocClus(dv,c,cnt);
|
|
default:
|
|
throw('Drv');
|
|
}
|
|
}
|