mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-14 14:55:12 +01:00
227 lines
5.9 KiB
C
227 lines
5.9 KiB
C
|
/****************************************************************************
|
||
|
* FAT16 - VFAT Support
|
||
|
*
|
||
|
* NOTE: Only supports FAT16 with Long File Names
|
||
|
* I have no interest in adding FAT32
|
||
|
*
|
||
|
* Reference Documentation:
|
||
|
*
|
||
|
* FAT: General Overview of On-Disk Format
|
||
|
* Version 1.02 May 05, 1999
|
||
|
* Microsoft Corporation
|
||
|
*
|
||
|
* FAT: General Overview of On-Disk Format
|
||
|
* Version 1.03 December 06, 2000
|
||
|
* Microsoft Corporation
|
||
|
*
|
||
|
* This is targetted at MMC/SD cards.
|
||
|
*
|
||
|
* Copyright softdev 2007. All rights reserved.
|
||
|
*
|
||
|
* $Date: 2007-08-03 13:23:19 +0100 (Fri, 03 Aug 2007) $
|
||
|
* $Rev: 3 $
|
||
|
****************************************************************************/
|
||
|
#ifndef __FATVFAT__
|
||
|
#define __FATVFAT__
|
||
|
|
||
|
/* x86 type definitions */
|
||
|
typedef unsigned int DWORD;
|
||
|
typedef unsigned short WORD;
|
||
|
typedef unsigned char BYTE;
|
||
|
|
||
|
/* Big Endian Support */
|
||
|
#ifdef WORDS_BIGENDIAN
|
||
|
#define SWAP16(a) (((a&0xff)<<8) | ((a&0xff00)>>8))
|
||
|
#define SWAP32(a) (((a&0xff000000)>>24) | ((a&0xff0000) >> 8) | ((a&0xff00)<<8) |((a&0xff)<<24))
|
||
|
#else
|
||
|
#define SWAP16(a) (a)
|
||
|
#define SWAP32(a) (a)
|
||
|
#endif
|
||
|
|
||
|
/* General */
|
||
|
#define SECTOR_SIZE 512
|
||
|
#define SECTOR_SHIFT_BITS 9
|
||
|
#define LFN_LAST_ENTRY 0x40
|
||
|
#define LFN_ENTRY_MASK 0x3F
|
||
|
#define ROOTCLUSTER 0xdeadc0de
|
||
|
#define PSEP '/'
|
||
|
#define PSEPS "/"
|
||
|
#define DIR_ROOT "."
|
||
|
#define DIR_PARENT ".."
|
||
|
|
||
|
/* FSTYPES */
|
||
|
#define FS_TYPE_NONE 0
|
||
|
#define FS_TYPE_FAT16 1
|
||
|
|
||
|
/* Errors */
|
||
|
#define FS_FILE_OK 0
|
||
|
#define FS_SUCCESS FS_FILE_OK
|
||
|
#define FS_ERR_NOMEM -128
|
||
|
#define FS_NO_FILE -64
|
||
|
#define FS_ERR_IO -32
|
||
|
#define FS_ERR_PARAM -16
|
||
|
|
||
|
/* File modes */
|
||
|
#define FS_READ 1
|
||
|
|
||
|
/* Gamecube Specific */
|
||
|
#define FS_SLOTA 0
|
||
|
#define FS_SLOTB 1
|
||
|
|
||
|
/* FAT12/16 */
|
||
|
typedef struct
|
||
|
{
|
||
|
BYTE jmpBoot[3]; /* Always 0xEBxx90 or 0xE9xxxx */
|
||
|
BYTE OEMName[8]; /* OEM Name 'MSWIN4.1' or similar */
|
||
|
WORD bytesPerSec; /* Bytes per sector */
|
||
|
BYTE secPerClust; /* Sectors per cluster */
|
||
|
WORD reservedSec; /* Reserved Sector Count */
|
||
|
BYTE numFATs; /* Number of FAT copies */
|
||
|
WORD rootEntCount; /* FAT12/16 number of root entries. */
|
||
|
WORD totSec16; /* Sector count if < 0x10000 */
|
||
|
BYTE media; /* Media ID byte (HD == 0xF8) */
|
||
|
WORD FATsz16; /* Sectors occupied by one copy of FAT */
|
||
|
WORD secPerTrack; /* Sectors per track */
|
||
|
WORD numHeads; /* Number of heads */
|
||
|
DWORD hiddenSec; /* Hidden sector count */
|
||
|
DWORD totSec32; /* Total sectors when >= 0x10000 */
|
||
|
BYTE drvNum; /* BIOS Drive Number (0x80) */
|
||
|
BYTE reserved1; /* Unused - always zero */
|
||
|
BYTE bootSig; /* Boot signature */
|
||
|
DWORD volID; /* Volume serial number */
|
||
|
BYTE volName[11]; /* Volume Name */
|
||
|
BYTE FilSysType[8]; /* File system type */
|
||
|
BYTE filler[SECTOR_SIZE-64];
|
||
|
BYTE sigkey1; /* 0x55 */
|
||
|
BYTE sigkey2; /* 0xAA */
|
||
|
}
|
||
|
__attribute__((__packed__)) BPB16;
|
||
|
|
||
|
/* Partition entry */
|
||
|
typedef struct
|
||
|
{
|
||
|
BYTE bootindicator;
|
||
|
BYTE startCHS[3];
|
||
|
BYTE partitiontype;
|
||
|
BYTE endCHS[3];
|
||
|
DWORD partitionstart;
|
||
|
DWORD partitionsize;
|
||
|
}
|
||
|
__attribute__((__packed__)) PARTENTRY;
|
||
|
|
||
|
/* VFAT - Main structure */
|
||
|
typedef struct
|
||
|
{
|
||
|
DWORD BaseOffset;
|
||
|
DWORD SectorsPerCluster;
|
||
|
DWORD BytesPerSector;
|
||
|
DWORD ReservedSectors;
|
||
|
DWORD RootDirSectors;
|
||
|
DWORD SectorsPerFAT;
|
||
|
DWORD NumberOfFATs;
|
||
|
DWORD FirstDataSector;
|
||
|
DWORD TotalSectors;
|
||
|
DWORD CountOfClusters;
|
||
|
DWORD DataSectors;
|
||
|
DWORD RootDirOffset;
|
||
|
DWORD FirstFATOffset;
|
||
|
DWORD RootDirEntries;
|
||
|
WORD *FAT; /* Holds first FAT copy */
|
||
|
BYTE *rootDir; /* Holds entire root directory */
|
||
|
}
|
||
|
__attribute__((__packed__)) VFATFS;
|
||
|
|
||
|
/**
|
||
|
* Directory
|
||
|
*/
|
||
|
|
||
|
#define MAX_LONG_NAME 256
|
||
|
|
||
|
/* Directory entry attributes */
|
||
|
#define ATTR_READ_ONLY 0x01
|
||
|
#define ATTR_HIDDEN 0x02
|
||
|
#define ATTR_SYSTEM 0x04
|
||
|
#define ATTR_VOLUME_ID 0x08
|
||
|
#define ATTR_DIRECTORY 0x10
|
||
|
#define ATTR_ARCHIVE 0x20
|
||
|
#define ATTR_LONG_NAME (ATTR_READ_ONLY | \
|
||
|
ATTR_HIDDEN | \
|
||
|
ATTR_SYSTEM | \
|
||
|
ATTR_VOLUME_ID )
|
||
|
|
||
|
#define ATTR_LONG_NAME_MASK ( ATTR_READ_ONLY | \
|
||
|
ATTR_HIDDEN | \
|
||
|
ATTR_SYSTEM | \
|
||
|
ATTR_VOLUME_ID | \
|
||
|
ATTR_DIRECTORY | \
|
||
|
ATTR_ARCHIVE )
|
||
|
|
||
|
#define CLUSTER_END_CHAIN 0xFFF8
|
||
|
#define CLUSTER_BAD 0xFFF7
|
||
|
|
||
|
/* Short file name */
|
||
|
typedef struct
|
||
|
{
|
||
|
BYTE dirname[11]; /* Record name */
|
||
|
BYTE attribute; /* Attributes */
|
||
|
BYTE NTReserved; /* Reserved for Window NT - set 0 */
|
||
|
BYTE dirTenthSecs; /* Tenth of a second, 0-199 */
|
||
|
WORD dirCreateTime; /* Time of creation */
|
||
|
WORD dirCreateDate; /* Date of creation */
|
||
|
WORD dirLastAccDate;/* Date of last access */
|
||
|
WORD fstClustHigh; /* High word of first cluster - ZERO on FAT16 */
|
||
|
WORD dirWriteTime; /* Time of last write */
|
||
|
WORD dirWriteDate; /* Date of last write */
|
||
|
WORD fstClustLow; /* Low word of first cluster */
|
||
|
DWORD filesize; /* Filesize in bytes */
|
||
|
}
|
||
|
__attribute__((__packed__)) SFNDIRREC;
|
||
|
|
||
|
/* Long file name */
|
||
|
typedef struct
|
||
|
{
|
||
|
BYTE ordinal; /* Entry number */
|
||
|
BYTE dirname1[10];
|
||
|
BYTE attribute; /* Attributes */
|
||
|
BYTE type; /* Reserved */
|
||
|
BYTE checksum; /* SFN Checksum */
|
||
|
BYTE dirname2[12];
|
||
|
WORD fstClustLo; /* MUST BE ZERO */
|
||
|
BYTE dirname3[4];
|
||
|
}
|
||
|
__attribute__((__packed__)) LFNDIRREC;
|
||
|
|
||
|
/* User dir entry */
|
||
|
typedef struct
|
||
|
{
|
||
|
BYTE longname[MAX_LONG_NAME];
|
||
|
BYTE shortname[13]; /* Keep word aligned*/
|
||
|
DWORD fpos;
|
||
|
DWORD fsize;
|
||
|
DWORD driveid;
|
||
|
DWORD FirstCluster;
|
||
|
DWORD CurrentCluster;
|
||
|
DWORD CachedCluster;
|
||
|
DWORD CurrentDirEntry;
|
||
|
DWORD crosscluster;
|
||
|
BYTE *clusterdata;
|
||
|
/* Now a copy of the current directory entry */
|
||
|
SFNDIRREC dirent;
|
||
|
}
|
||
|
__attribute__((__packed__)) FSDIRENTRY;
|
||
|
|
||
|
/* VFAT API */
|
||
|
/* Directory */
|
||
|
int VFAT_opendir( int drive, FSDIRENTRY *d, char *search );
|
||
|
int VFAT_readdir( FSDIRENTRY *d );
|
||
|
void VFAT_closedir( FSDIRENTRY *d );
|
||
|
int VFAT_fopen( int drive, FSDIRENTRY *d, char *fname, int mode );
|
||
|
void VFAT_fclose( FSDIRENTRY *d );
|
||
|
int VFAT_fread( FSDIRENTRY *d, void *buffer, int length );
|
||
|
int VFAT_ftell( FSDIRENTRY *d );
|
||
|
int VFAT_fseek( FSDIRENTRY *d, int where, int whence );
|
||
|
int VFAT_mount( int driveid, VFATFS *v );
|
||
|
|
||
|
#endif
|
||
|
|