DWORD FATDrive::read_FAT(DWORD cluster, bool& ok) //@@ use exception handling { DWORD nClus; Buffer* FATBuf; DWORD nclus = (_boot_sector.Sectors32? _boot_sector.Sectors32: _boot_sector.Sectors16) / _boot_sector.SectorsPerCluster; ///@todo cache result if (cluster > nclus) { ok = false; return (DWORD)-1; } if (nclus >= 65536) { // FAT32 DWORD FATsec = cluster / (_boot_sector.BytesPerSector/4); DWORD z = (cluster - _boot_sector.BytesPerSector/4 * FATsec)*4; FATsec += _boot_sector.ReservedSectors; if (!read_cache(FATsec, &FATBuf)) ok = false; nClus = dpeek(&FATBuf->dat[z]); } else if (nclus >= 4096) { // 16 Bit-FAT DWORD FATsec = cluster / (_boot_sector.BytesPerSector/2); DWORD z = (cluster - _boot_sector.BytesPerSector/2 * FATsec)*2; FATsec += _boot_sector.ReservedSectors; if (!read_cache(FATsec, &FATBuf)) ok = false; nClus = wpeek(&FATBuf->dat[z]); if (nClus >= 0xfff0) nClus |= 0x0fff0000; } else { // 12 Bit-FAT DWORD FATsec = cluster*3 / (_boot_sector.BytesPerSector*2); DWORD z = (cluster*3 - _boot_sector.BytesPerSector*2*FATsec)/2; FATsec += _boot_sector.ReservedSectors; if (!read_cache(FATsec,&FATBuf)) ok = false; BYTE a = FATBuf->dat[z++]; if (z >= _boot_sector.BytesPerSector) if (!read_cache(FATsec+1,&FATBuf)) ok = false; z = 0; BYTE b = FATBuf->dat[z]; if (cluster & 1) nClus = (a>>4) | (b<<4); else nClus = a | ((b & 0xf)<<8); if (nClus >= 0xff0) nClus |= 0x0ffff000; }
inline cell factor_vm::unbox_array_size() { cell obj = dpeek(); if(TAG(obj) == FIXNUM_TYPE) { fixnum n = untag_fixnum(obj); if(n >= 0 && n < (fixnum)array_size_max) { dpop(); return n; } } return unbox_array_size_slow(); }
inline cell dpop() { cell value = dpeek(); ds -= sizeof(cell); return value; }