from stdint import * import string import fat32_types as types import fat32_time as ftime import fat32_mkfs as mkfs_mod import fat32_part as part import fat32_diskio as diskio import sched.sched as sched import t, c default_fs: types.volinfo = types.volinfo() _fs_lock: t.CInt = 0 def lock(): global _fs_lock while True: c.Asm("cli") if _fs_lock == 0: _fs_lock = 1 c.Asm("sti") return c.Asm("sti") sched.Scheduler._yield() def unlock(): global _fs_lock _fs_lock = 0 def mount() -> types.FRESULT: default_fs.pdrv = 0 default_fs.hidden_sectors = 0 buf: t.CArray[t.CUInt8T, 512] dres: types.DRESULT = diskio.read(0, c.Addr(buf[0]), 0, 1) if dres == types.DRESULT.RES_OK: if buf[0] == 0xEB or buf[0] == 0xE9: default_fs.hidden_sectors = 0 else: sig: t.CUInt16T = t.CUInt16T(buf[510]) | (t.CUInt16T(buf[511]) << 8) if sig == 0xAA55: ptype: t.CUInt8T = buf[450] if ptype != 0: slba: t.CUInt32T = t.CUInt32T(buf[454]) | (t.CUInt32T(buf[455]) << 8) | (t.CUInt32T(buf[456]) << 16) | (t.CUInt32T(buf[457]) << 24) default_fs.hidden_sectors = slba if default_fs.mounted: return types.FRESULT.FR_OK dsk_res: types.DRESULT = diskio.status(default_fs.pdrv) if dsk_res != types.DRESULT.RES_OK: dsk_res = diskio.init(default_fs.pdrv) if dsk_res != types.DRESULT.RES_OK: return types.FRESULT.FR_NOT_READY default_fs.winsect = 0xFFFFFFFFFFFFFFFF default_fs.fat_winsect = 0xFFFFFFFFFFFFFFFF wres: types.FRESULT = default_fs.win_read(0) if wres != types.FRESULT.FR_OK: return types.FRESULT.FR_DISK_ERR bps: t.CUInt16T = default_fs.win[11] | (t.CUInt16T(default_fs.win[12]) << 8) spc: t.CUInt8T = default_fs.win[13] rsc: t.CUInt16T = default_fs.win[14] | (t.CUInt16T(default_fs.win[15]) << 8) nf: t.CUInt8T = default_fs.win[16] if bps != 512: return types.FRESULT.FR_NO_FILESYSTEM if spc == 0 or (spc & (spc - 1)) != 0: return types.FRESULT.FR_NO_FILESYSTEM if rsc == 0: return types.FRESULT.FR_NO_FILESYSTEM if nf == 0: return types.FRESULT.FR_NO_FILESYSTEM root_ent: t.CUInt16T = default_fs.win[17] | (t.CUInt16T(default_fs.win[18]) << 8) fat16sz: t.CUInt16T = default_fs.win[22] | (t.CUInt16T(default_fs.win[23]) << 8) tot32: t.CUInt32T = t.CUInt32T(default_fs.win[32]) | (t.CUInt32T(default_fs.win[33]) << 8) | (t.CUInt32T(default_fs.win[34]) << 16) | (t.CUInt32T(default_fs.win[35]) << 24) fat32sz: t.CUInt32T = t.CUInt32T(default_fs.win[36]) | (t.CUInt32T(default_fs.win[37]) << 8) | (t.CUInt32T(default_fs.win[38]) << 16) | (t.CUInt32T(default_fs.win[39]) << 24) root_clus: t.CUInt32T = t.CUInt32T(default_fs.win[44]) | (t.CUInt32T(default_fs.win[45]) << 8) | (t.CUInt32T(default_fs.win[46]) << 16) | (t.CUInt32T(default_fs.win[47]) << 24) if root_ent != 0 or fat16sz != 0: return types.FRESULT.FR_NO_FILESYSTEM if fat32sz == 0: return types.FRESULT.FR_NO_FILESYSTEM if tot32 == 0: return types.FRESULT.FR_NO_FILESYSTEM if default_fs.win[510] != 0x55 or default_fs.win[511] != 0xAA: return types.FRESULT.FR_NO_FILESYSTEM fsinfo_sec: t.CUInt16T = default_fs.win[48] | (t.CUInt16T(default_fs.win[49]) << 8) bkboot_sec: t.CUInt16T = default_fs.win[50] | (t.CUInt16T(default_fs.win[51]) << 8) default_fs.sector_size = 512 default_fs.cluster_sectors = spc default_fs.cluster_size = t.CUInt32T(spc) * 512 default_fs.num_fats = nf default_fs.reserved_sectors = rsc default_fs.fat_size = fat32sz default_fs.fat_start = t.CUInt64T(rsc) default_fs.total_sectors = t.CUInt64T(tot32) default_fs.root_cluster = root_clus default_fs.fsinfo_sector = fsinfo_sec default_fs.backup_sector = bkboot_sec default_fs.vol_id = t.CUInt32T(default_fs.win[67]) | (t.CUInt32T(default_fs.win[68]) << 8) | (t.CUInt32T(default_fs.win[69]) << 16) | (t.CUInt32T(default_fs.win[70]) << 24) data_sectors: t.CUInt64T = default_fs.total_sectors - t.CUInt64T(rsc) - t.CUInt64T(t.CUInt64T(nf) * t.CUInt64T(fat32sz)) default_fs.total_clusters = t.CUInt32T(data_sectors / t.CUInt64T(spc)) default_fs.data_start = default_fs.fat_start + t.CUInt64T(t.CUInt64T(nf) * t.CUInt64T(fat32sz)) default_fs.last_alloc = 2 default_fs.free_clusters = 0xFFFFFFFF if fsinfo_sec != 0: default_fs.fsinfo_read() default_fs.mounted = 1 return types.FRESULT.FR_OK def unmount() -> types.FRESULT: return default_fs.unmount() def format(sec_per_clus: t.CUInt8T = 0, vol_id: t.CUInt32T = 0) -> types.FRESULT: return mkfs_mod.mkfs(default_fs.pdrv, sec_per_clus, vol_id) def open(path: t.CConst | str, mode: t.CUInt8T) -> types.fileobj | t.CPtr: return default_fs.file_open(path, mode) def close(fp: types.fileobj | t.CPtr) -> types.FRESULT: return fp.close() def read(fp: types.fileobj | t.CPtr, buff: t.CVoid | t.CPtr, btr: t.CUInt32T) -> t.CUInt32T: br: t.CUInt32T = 0 fp.read(buff, btr, c.Addr(br)) return br def write(fp: types.fileobj | t.CPtr, buff: t.CConst | t.CVoid | t.CPtr, btw: t.CUInt32T) -> t.CUInt32T: bw: t.CUInt32T = 0 fp.write(buff, btw, c.Addr(bw)) return bw def seek(fp: types.fileobj | t.CPtr, offset: t.CUInt32T) -> types.FRESULT: return fp.seek(offset) def tell(fp: types.fileobj | t.CPtr) -> t.CUInt32T: return fp.tell() def size(fp: types.fileobj | t.CPtr) -> t.CUInt32T: return fp.size() def truncate(fp: types.fileobj | t.CPtr) -> types.FRESULT: return fp.truncate() def remove(path: t.CConst | str) -> types.FRESULT: return default_fs.file_delete(path) def rename(old_path: t.CConst | str, new_path: t.CConst | str) -> types.FRESULT: return default_fs.file_rename(old_path, new_path) def move(old_path: t.CConst | str, new_path: t.CConst | str) -> types.FRESULT: return default_fs.file_rename(old_path, new_path) def stat(path: t.CConst | str, info: types.fileinfo | t.CPtr) -> types.FRESULT: return default_fs.file_stat(path, info) def mkdir(path: t.CConst | str) -> types.FRESULT: return default_fs.dir_make(path) def rmdir(path: t.CConst | str) -> types.FRESULT: return default_fs.dir_remove(path) def opendir(path: t.CConst | str, dp: types.dirobj | t.CPtr) -> types.FRESULT: return default_fs.dir_open_path(path, dp) def readdir(dp: types.dirobj | t.CPtr, info: types.fileinfo | t.CPtr) -> types.FRESULT: return default_fs.dir_read(dp, info) def closedir(dp: types.dirobj | t.CPtr): dp.is_open = 0 def chmod(path: t.CConst | str, attr: t.CUInt8T, mask: t.CUInt8T) -> types.FRESULT: return default_fs.chmod(path, attr, mask) def utime(path: t.CConst | str, mtime: t.CUInt16T, mdate: t.CUInt16T) -> types.FRESULT: return default_fs.utime(path, mtime, mdate) def get_free() -> t.CUInt32T: if not default_fs.mounted: return 0 if default_fs.free_clusters == 0xFFFFFFFF: return default_fs.count_free_clusters() return default_fs.free_clusters def get_total() -> t.CUInt32T: if not default_fs.mounted: return 0 return default_fs.total_clusters def get_cluster_size() -> t.CUInt32T: if not default_fs.mounted: return 0 return default_fs.cluster_size def is_mounted() -> t.CInt: return default_fs.mounted def last_error() -> t.CUInt32T: return default_fs.last_error def get_fattime() -> t.CUInt32T: return ftime.get_fattime() def get_metadata() -> t.CUInt32T: return default_fs.metadata def set_metadata(val: t.CUInt32T): default_fs.metadata = val def scan_drives() -> types.FRESULT: return part.scan_drives() def get_drive_count() -> t.CInt: return part.get_drive_count() def get_drive_letter(idx: t.CInt) -> t.CChar: return part.get_drive_letter(idx) def set_drive_letter(idx: t.CInt, letter: t.CChar) -> types.FRESULT: return part.set_drive_letter(idx, letter) def get_partition_count(letter: t.CChar) -> t.CInt: return part.get_partition_count(letter) def is_partition_fat32(letter: t.CChar, part_idx: t.CInt) -> t.CInt: return part.is_partition_fat32(letter, part_idx)