#include "icsneo/disk/fat.h" #include "icsneo/disk/diskdriver.h" #include "ff.h" #include "diskio.h" #include using namespace icsneo; // The FAT driver can only be accessed by one caller at a time, since it relies on globals static std::mutex fatDriverMutex; static std::function< std::optional(uint64_t pos, uint8_t* into, uint64_t amount) > diskReadFn; extern "C" DRESULT disk_read(BYTE, BYTE* buff, LBA_t sector, UINT count) { static_assert(Disk::SectorSize == 512, "FatFs expects 512 byte sectors"); const uint64_t expected = count * uint64_t(Disk::SectorSize); const auto res = diskReadFn(sector * uint64_t(Disk::SectorSize), buff, expected); if (!res.has_value()) return RES_NOTRDY; return res == expected ? RES_OK : RES_ERROR; } extern "C" DSTATUS disk_initialize(BYTE) { return RES_OK; } extern "C" DSTATUS disk_status(BYTE) { return RES_OK; } static uint64_t ClusterToSector(const FATFS& fs, DWORD cluster) { return fs.database + (LBA_t)fs.csize * (cluster - 2); } std::optional Disk::FindVSAInFAT(std::function< std::optional(uint64_t pos, uint8_t* into, uint64_t amount) > diskRead) { std::lock_guard lk(fatDriverMutex); diskReadFn = diskRead; FATFS fs = {}; if (f_mount(&fs, (const TCHAR*)_TEXT(""), 0) != FR_OK) return std::nullopt; FIL logData = {}; if (f_open(&logData, (const TCHAR*)_TEXT("0:\\LOG_DATA.VSA"), FA_READ) != FR_OK) return std::nullopt; return ClusterToSector(fs, logData.obj.sclust) * uint64_t(Disk::SectorSize); }