+ return AO_FAT_SUCCESS;
+}
+
+/*
+ * ao_fat_root_init
+ *
+ * Initialize a root directory entry
+ */
+void
+ao_fat_root_init(uint8_t *dent, char name[11], uint8_t attr)
+{
+ memset(dent, '\0', 0x20);
+ memmove(dent, name, 11);
+
+ dent[0x0b] = 0x00;
+ dent[0x0c] = 0x00;
+ dent[0x0d] = 0x00;
+
+ /* XXX fix time */
+ put_u16(dent + 0x0e, 0);
+ /* XXX fix date */
+ put_u16(dent + 0x10, 0);
+ /* XXX fix date */
+ put_u16(dent + 0x12, 0);
+
+ /* XXX fix time */
+ put_u16(dent + 0x16, 0);
+ /* XXX fix date */
+ put_u16(dent + 0x18, 0);
+
+ /* cluster number */
+ /* Low cluster bytes */
+ put_u16(dent + 0x1a, 0);
+ /* FAT32 high cluster bytes */
+ put_u16(dent + 0x14, 0);
+
+ /* size */
+ put_u32(dent + 0x1c, 0);
+}
+
+
+static void
+ao_fat_dirent_init(uint8_t *dent, uint16_t entry, struct ao_fat_dirent *dirent)
+{
+ memcpy(dirent->name, dent + 0x00, 11);
+ dirent->attr = dent[0x0b];
+ dirent->size = get_u32(dent+0x1c);
+ dirent->cluster = get_u16(dent+0x1a);
+ dirent->entry = entry;
+}
+
+/*
+ * Public API
+ */
+
+/*
+ * ao_fat_open
+ *
+ * Open an existing file.
+ */
+int8_t
+ao_fat_open(char name[11], uint8_t mode)
+{
+ uint16_t entry = 0;
+ struct ao_fat_dirent dirent;
+
+ if (ao_file_opened)
+ return -AO_FAT_EMFILE;
+
+ while (ao_fat_readdir(&entry, &dirent)) {
+ if (!memcmp(name, dirent.name, 11)) {
+ if (AO_FAT_IS_DIR(dirent.attr))
+ return -AO_FAT_EISDIR;
+ if (!AO_FAT_IS_FILE(dirent.attr))
+ return -AO_FAT_EPERM;
+ if (mode > AO_FAT_OPEN_READ && (dirent.attr & AO_FAT_FILE_READ_ONLY))
+ return -AO_FAT_EACCESS;
+ ao_file_dirent = dirent;
+ ao_file_offset = 0;
+ ao_file_opened = 1;
+ return AO_FAT_SUCCESS;
+ }
+ }
+ return -AO_FAT_ENOENT;