diff options
Diffstat (limited to 'c/src/lib/libbsp/arm/nds/libfat/source')
50 files changed, 0 insertions, 9178 deletions
diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/bit_ops.h b/c/src/lib/libbsp/arm/nds/libfat/source/bit_ops.h deleted file mode 100644 index 1bc0ab7538..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/bit_ops.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - bit_ops.h - Functions for dealing with conversion of data between types - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _BIT_OPS_H -#define _BIT_OPS_H - -/*----------------------------------------------------------------- -Functions to deal with little endian values stored in u8 arrays ------------------------------------------------------------------*/ -static inline u16 u8array_to_u16 (const u8* item, int offset) { - return ( item[offset] | (item[offset + 1] << 8)); -} - -static inline u32 u8array_to_u32 (const u8* item, int offset) { - return ( item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24)); -} - -static inline void u16_to_u8array (u8* item, int offset, u16 value) { - item[offset] = (u8)value; - item[offset + 1] = (u8)(value >> 8); -} - -static inline void u32_to_u8array (u8* item, int offset, u32 value) { - item[offset] = (u8)value; - item[offset + 1] = (u8)(value >> 8); - item[offset + 2] = (u8)(value >> 16); - item[offset + 3] = (u8)(value >> 24); -} - -#endif // _BIT_OPS_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/cache.c b/c/src/lib/libbsp/arm/nds/libfat/source/cache.c deleted file mode 100644 index a1a597c284..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/cache.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - cache.c - The cache is not visible to the user. It should be flushed - when any file is closed or changes are made to the filesystem. - - This cache implements a least-used-page replacement policy. This will - distribute sectors evenly over the pages, so if less than the maximum - pages are used at once, they should all eventually remain in the cache. - This also has the benefit of throwing out old sectors, so as not to keep - too many stale pages around. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include <string.h> - -#include "common.h" -#include "cache.h" -#include "disc_io/disc.h" - -#include "mem_allocate.h" - -#define CACHE_FREE 0xFFFFFFFF - -CACHE* _FAT_cache_constructor (u32 numberOfPages, const IO_INTERFACE* discInterface) { - CACHE* cache; - u32 i; - CACHE_ENTRY* cacheEntries; - - if (numberOfPages < 2) { - numberOfPages = 2; - } - - cache = (CACHE*) _FAT_mem_allocate (sizeof(CACHE)); - if (cache == NULL) { - return false; - } - - cache->disc = discInterface; - cache->numberOfPages = numberOfPages; - - - cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages); - if (cacheEntries == NULL) { - _FAT_mem_free (cache); - return false; - } - - for (i = 0; i < numberOfPages; i++) { - cacheEntries[i].sector = CACHE_FREE; - cacheEntries[i].count = 0; - cacheEntries[i].dirty = false; - } - - cache->cacheEntries = cacheEntries; - - cache->pages = (u8*) _FAT_mem_allocate ( CACHE_PAGE_SIZE * numberOfPages); - if (cache->pages == NULL) { - _FAT_mem_free (cache->cacheEntries); - _FAT_mem_free (cache); - return false; - } - - return cache; -} - -void _FAT_cache_destructor (CACHE* cache) { - // Clear out cache before destroying it - _FAT_cache_flush(cache); - - // Free memory in reverse allocation order - _FAT_mem_free (cache->pages); - _FAT_mem_free (cache->cacheEntries); - _FAT_mem_free (cache); - - return; -} - -/* -Retrieve a sector's page from the cache. If it is not found in the cache, -load it into the cache and return the page it was loaded to. -Return CACHE_FREE on error. -*/ -static u32 _FAT_cache_getSector (CACHE* cache, u32 sector) { - u32 i; - CACHE_ENTRY* cacheEntries = cache->cacheEntries; - u32 numberOfPages = cache->numberOfPages; - - u32 leastUsed = 0; - u32 lowestCount = 0xFFFFFFFF; - - for (i = 0; (i < numberOfPages) && (cacheEntries[i].sector != sector); i++) { - // While searching for the desired sector, also search for the leased used page - if ( (cacheEntries[i].sector == CACHE_FREE) || (cacheEntries[i].count < lowestCount) ) { - leastUsed = i; - lowestCount = cacheEntries[i].count; - } - } - - // If it found the sector in the cache, return it - if ((i < numberOfPages) && (cacheEntries[i].sector == sector)) { - // Increment usage counter - cacheEntries[i].count += 1; - return i; - } - - // If it didn't, replace the least used cache page with the desired sector - if ((cacheEntries[leastUsed].sector != CACHE_FREE) && (cacheEntries[leastUsed].dirty == true)) { - // Write the page back to disc if it has been written to - if (!_FAT_disc_writeSectors (cache->disc, cacheEntries[leastUsed].sector, 1, cache->pages + CACHE_PAGE_SIZE * leastUsed)) { - return CACHE_FREE; - } - cacheEntries[leastUsed].dirty = false; - } - - // Load the new sector into the cache - if (!_FAT_disc_readSectors (cache->disc, sector, 1, cache->pages + CACHE_PAGE_SIZE * leastUsed)) { - return CACHE_FREE; - } - cacheEntries[leastUsed].sector = sector; - // Increment the usage count, don't reset it - // This creates a paging policy of least used PAGE, not sector - cacheEntries[leastUsed].count += 1; - return leastUsed; -} - -/* -Reads some data from a cache page, determined by the sector number -*/ -bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, u32 sector, u32 offset, u32 size) { - u32 page; - - if (offset + size > BYTES_PER_READ) { - return false; - } - - page = _FAT_cache_getSector (cache, sector); - if (page == CACHE_FREE) { - return false; - } - memcpy (buffer, cache->pages + (CACHE_PAGE_SIZE * page) + offset, size); - return true; -} - -/* -Writes some data to a cache page, making sure it is loaded into memory first. -*/ -bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, u32 sector, u32 offset, u32 size) { - u32 page; - - if (offset + size > BYTES_PER_READ) { - return false; - } - - page = _FAT_cache_getSector (cache, sector); - if (page == CACHE_FREE) { - return false; - } - - memcpy (cache->pages + (CACHE_PAGE_SIZE * page) + offset, buffer, size); - cache->cacheEntries[page].dirty = true; - - return true; -} - -/* -Writes some data to a cache page, zeroing out the page first -*/ -bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, u32 sector, u32 offset, u32 size) { - u32 page; - - if (offset + size > BYTES_PER_READ) { - return false; - } - - page = _FAT_cache_getSector (cache, sector); - if (page == CACHE_FREE) { - return false; - } - - memset (cache->pages + (CACHE_PAGE_SIZE * page), 0, CACHE_PAGE_SIZE); - memcpy (cache->pages + (CACHE_PAGE_SIZE * page) + offset, buffer, size); - cache->cacheEntries[page].dirty = true; - - return true; -} - - -/* -Flushes all dirty pages to disc, clearing the dirty flag. -Also resets all pages' page count to 0. -*/ -bool _FAT_cache_flush (CACHE* cache) { - u32 i; - - for (i = 0; i < cache->numberOfPages; i++) { - if (cache->cacheEntries[i].dirty) { - if (!_FAT_disc_writeSectors (cache->disc, cache->cacheEntries[i].sector, 1, cache->pages + CACHE_PAGE_SIZE * i)) { - return CACHE_FREE; - } - } - cache->cacheEntries[i].count = 0; - cache->cacheEntries[i].dirty = false; - } - - return true; -} - -void _FAT_cache_invalidate (CACHE* cache) { - int i; - for (i = 0; i < cache->numberOfPages; i++) { - cache->cacheEntries[i].sector = CACHE_FREE; - cache->cacheEntries[i].count = 0; - cache->cacheEntries[i].dirty = false; - } -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/cache.h b/c/src/lib/libbsp/arm/nds/libfat/source/cache.h deleted file mode 100644 index 5d08022b1e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/cache.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - cache.h - The cache is not visible to the user. It should be flushed - when any file is closed or changes are made to the filesystem. - - This cache implements a least-used-page replacement policy. This will - distribute sectors evenly over the pages, so if less than the maximum - pages are used at once, they should all eventually remain in the cache. - This also has the benefit of throwing out old sectors, so as not to keep - too many stale pages around. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _CACHE_H -#define _CACHE_H - -#include "common.h" -#include "disc_io/disc_io.h" - -#define CACHE_PAGE_SIZE BYTES_PER_READ - -typedef struct { - u32 sector; - u32 count; - bool dirty; -} CACHE_ENTRY; - -typedef struct { - const IO_INTERFACE* disc; - u32 numberOfPages; - CACHE_ENTRY* cacheEntries; - u8* pages; -} CACHE; - - -/* -Read data from a sector in the cache -If the sector is not in the cache, it will be swapped in -offset is the position to start reading from -size is the amount of data to read -Precondition: offset + size <= BYTES_PER_READ -*/ -bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, u32 sector, u32 offset, u32 size); - -/* -Write data to a sector in the cache -If the sector is not in the cache, it will be swapped in. -When the sector is swapped out, the data will be written to the disc -offset is the position to start reading from -size is the amount of data to read -Precondition: offset + size <= BYTES_PER_READ -*/ -bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, u32 sector, u32 offset, u32 size); - -/* -Write data to a sector in the cache, zeroing the sector first -If the sector is not in the cache, it will be swapped in. -When the sector is swapped out, the data will be written to the disc -offset is the position to start reading from -size is the amount of data to read -Precondition: offset + size <= BYTES_PER_READ -*/ -bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, u32 sector, u32 offset, u32 size); - -/* -Read a full sector from the cache -*/ -static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, u32 sector) { - return _FAT_cache_readPartialSector (cache, buffer, sector, 0, BYTES_PER_READ); -} - -/* -Write a full sector to the cache -*/ -static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, u32 sector) { - return _FAT_cache_writePartialSector (cache, buffer, sector, 0, BYTES_PER_READ); -} - -/* -Write any dirty sectors back to disc and clear out the contents of the cache -*/ -bool _FAT_cache_flush (CACHE* cache); - -/* -Clear out the contents of the cache without writing any dirty sectors first -*/ -void _FAT_cache_invalidate (CACHE* cache); - -CACHE* _FAT_cache_constructor (u32 numberOfPages, const IO_INTERFACE* discInterface); - -void _FAT_cache_destructor (CACHE* cache); - -#endif // _CACHE_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/common.h b/c/src/lib/libbsp/arm/nds/libfat/source/common.h deleted file mode 100644 index 0cdfa55b6b..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/common.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - common.h - Common definitions and included files for the FATlib - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _COMMON_H -#define _COMMON_H - -// When compiling for NDS, make sure NDS is defined -#ifndef NDS - #if defined ARM9 || defined ARM7 - #define NDS - #endif -#endif - -#ifdef NDS - #include <nds/jtypes.h> -#else - #include "gba_types.h" -#endif - -#define BYTES_PER_READ 512 - -#ifndef NULL - #define NULL 0 -#endif - -#endif // _COMMON_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/directory.c b/c/src/lib/libbsp/arm/nds/libfat/source/directory.c deleted file mode 100644 index 495ca51c57..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/directory.c +++ /dev/null @@ -1,902 +0,0 @@ -/* - directory.c - Reading, writing and manipulation of the directory structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-14 - Chishm - * entryFromPath correctly finds "" and "." now - - 2006-08-17 - Chishm - * entryFromPath doesn't look for "" anymore - use "." to refer to the current directory - - 2006-08-19 - Chishm - * Fixed entryFromPath bug when looking for "." in root directory - - 2006-10-01 - Chishm - * Now clears the whole new cluster when linking in more clusters for a directory - - 2006-10-28 - Chishm - * stat returns the hostType for the st_dev value -*/ - -#include <string.h> -#include <ctype.h> - -#include "directory.h" -#include "common.h" -#include "partition.h" -#include "file_allocation_table.h" -#include "bit_ops.h" -#include "filetime.h" - -// Directory entry codes -#define DIR_ENTRY_LAST 0x00 -#define DIR_ENTRY_FREE 0xE5 - - -// Long file name directory entry -enum LFN_offset { - LFN_offset_ordinal = 0x00, // Position within LFN - LFN_offset_char0 = 0x01, - LFN_offset_char1 = 0x03, - LFN_offset_char2 = 0x05, - LFN_offset_char3 = 0x07, - LFN_offset_char4 = 0x09, - LFN_offset_flag = 0x0B, // Should be equal to ATTRIB_LFN - LFN_offset_reserved1 = 0x0C, // Always 0x00 - LFN_offset_checkSum = 0x0D, // Checksum of short file name (alias) - LFN_offset_char5 = 0x0E, - LFN_offset_char6 = 0x10, - LFN_offset_char7 = 0x12, - LFN_offset_char8 = 0x14, - LFN_offset_char9 = 0x16, - LFN_offset_char10 = 0x18, - LFN_offset_reserved2 = 0x1A, // Always 0x0000 - LFN_offset_char11 = 0x1C, - LFN_offset_char12 = 0x1E -}; -const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E}; - -#define LFN_END 0x40 -#define LFN_DEL 0x80 - -bool _FAT_directory_isValidLfn (const char* name) { - u32 i; - u32 nameLength; - // Make sure the name is short enough to be valid - if ( strnlen(name, MAX_FILENAME_LENGTH) >= MAX_FILENAME_LENGTH) { - return false; - } - // Make sure it doesn't contain any invalid characters - if (strpbrk (name, "\\/:*?\"<>|") != NULL) { - return false; - } - nameLength = strnlen(name, MAX_FILENAME_LENGTH); - // Make sure the name doesn't contain any control codes - for (i = 0; i < nameLength; i++) { - if (name[i] < 0x20) { - return false; - } - } - // Otherwise it is valid - return true; -} - -bool _FAT_directory_isValidAlias (const char* name) { - u32 i; - u32 nameLength; - const char* dot; - - // Make sure the name is short enough to be valid - if ( strnlen(name, MAX_ALIAS_LENGTH) >= MAX_ALIAS_LENGTH) { - return false; - } - // Make sure it doesn't contain any invalid characters - if (strpbrk (name, "\\/:;*?\"<>|&+,=[]") != NULL) { - return false; - } - nameLength = strnlen(name, MAX_ALIAS_LENGTH); - // Make sure the name doesn't contain any control codes - for (i = 0; i < nameLength; i++) { - if (name[i] < 0x20) { - return false; - } - } - - dot = strchr ( name, '.'); - // Make sure there is only one '.' - if ((dot != NULL) && (strrchr ( name, '.') != dot)) { - return false; - } - // If there is a '.': - if (dot != NULL) { - // Make sure the filename portion is 1-8 characters long - if (((dot - 1 - name) > 8) || ((dot - 1 - name) < 1)) { - return false; - } - // Make sure the extension is 1-3 characters long, if it exists - if ((strnlen(dot + 1, MAX_ALIAS_LENGTH) > 3) || (strnlen(dot + 1, MAX_ALIAS_LENGTH) < 1)) { - return false; - } - } else { - // Make sure the entire file name is 1-8 characters long - if ((nameLength > 8) || (nameLength < 1)) { - return false; - } - } - - // Since we made it through all those tests, it must be valid - return true; -} - -static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) { - int i=0; - int j=0; - - destName[0] = '\0'; - if (entryData[0] != DIR_ENTRY_FREE) { - if (entryData[0] == '.') { - destName[0] = '.'; - if (entryData[1] == '.') { - destName[1] = '.'; - destName[2] = '\0'; - } else { - destName[1] = '\0'; - } - } else { - // Copy the filename from the dirEntry to the string - for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) { - destName[i] = entryData[DIR_ENTRY_name + i]; - } - // Copy the extension from the dirEntry to the string - if (entryData[DIR_ENTRY_extension] != ' ') { - destName[i++] = '.'; - for ( j = 0; (j < 3) && (entryData[DIR_ENTRY_extension + j] != ' '); j++) { - destName[i++] = entryData[DIR_ENTRY_extension + j]; - } - } - destName[i] = '\0'; - } - } - - return (destName[0] != '\0'); -} - -u32 _FAT_directory_entryGetCluster (const u8* entryData) { - return u8array_to_u16(entryData,DIR_ENTRY_cluster) | (u8array_to_u16(entryData, DIR_ENTRY_clusterHigh) << 16); -} - -static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_ENTRY_POSITION* entryPosition, bool extendDirectory) { - DIR_ENTRY_POSITION position; - position = *entryPosition; - u32 tempCluster; - - // Increment offset, wrapping at the end of a sector - ++ position.offset; - if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) { - position.offset = 0; - // Increment sector when wrapping - ++ position.sector; - // But wrap at the end of a cluster - if ((position.sector == partition->sectorsPerCluster) && (position.cluster != FAT16_ROOT_DIR_CLUSTER)) { - position.sector = 0; - // Move onto the next cluster, making sure there is another cluster to go to - tempCluster = _FAT_fat_nextCluster(partition, position.cluster); - if (tempCluster == CLUSTER_EOF) { - if (extendDirectory) { - tempCluster = _FAT_fat_linkFreeClusterCleared (partition, position.cluster); - if (tempCluster == CLUSTER_FREE) { - return false; // This will only happen if the disc is full - } - } else { - return false; // Got to the end of the directory, not extending it - } - } - position.cluster = tempCluster; - } else if ((position.cluster == FAT16_ROOT_DIR_CLUSTER) && (position.sector == (partition->dataStart - partition->rootDirStart))) { - return false; // Got to end of root directory, can't extend it - } - } - *entryPosition = position; - return true; -} - -bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - - u8 entryData[0x20]; - - bool notFound, found; - u32 maxSectors; - int lfnPos; - u8 lfnChkSum, chkSum; - char* filename; - bool lfnExists; - - int i; - - lfnChkSum = 0; - - entryStart = entry->dataEnd; - - // Make sure we are using the correct root directory, in case of FAT32 - if (entryStart.cluster == FAT16_ROOT_DIR_CLUSTER) { - entryStart.cluster = partition->rootDirCluster; - } - - entryEnd = entryStart; - filename = entry->filename; - - // Can only be FAT16_ROOT_DIR_CLUSTER if it is the root directory on a FAT12 or FAT16 partition - if (entryStart.cluster == FAT16_ROOT_DIR_CLUSTER) { - maxSectors = partition->dataStart - partition->rootDirStart; - } else { - maxSectors = partition->sectorsPerCluster; - } - - lfnExists = false; - - found = false; - notFound = false; - - while (!found && !notFound) { - if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) { - notFound = true; - } - - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector, entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - if (entryData[DIR_ENTRY_attributes] == ATTRIB_LFN) { - // It's an LFN - if (entryData[LFN_offset_ordinal] & LFN_DEL) { - lfnExists = false; - } else if (entryData[LFN_offset_ordinal] & LFN_END) { - // Last part of LFN, make sure it isn't deleted using previous if(Thanks MoonLight) - entryStart = entryEnd; // This is the start of a directory entry - lfnExists = true; - filename[(entryData[LFN_offset_ordinal] & ~LFN_END) * 13] = '\0'; // Set end of lfn to null character - lfnChkSum = entryData[LFN_offset_checkSum]; - } if (lfnChkSum != entryData[LFN_offset_checkSum]) { - lfnExists = false; - } - if (lfnExists) { - lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - for (i = 0; i < 13; i++) { - filename[lfnPos + i] = entryData[LFN_offset_table[i]]; // modify this for unicode support; - } - } - } else if (entryData[DIR_ENTRY_attributes] & ATTRIB_VOL) { - // This is a volume name, don't bother with it - } else if (entryData[0] == DIR_ENTRY_LAST) { - notFound = true; - } else if ((entryData[0] != DIR_ENTRY_FREE) && (entryData[0] > 0x20) && !(entryData[DIR_ENTRY_attributes] & ATTRIB_VOL)) { - if (lfnExists) { - // Calculate file checksum - chkSum = 0; - for (i=0; i < 11; i++) { - // NOTE: The operation is an unsigned char rotate right - chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + entryData[i]; - } - if (chkSum != lfnChkSum) { - lfnExists = false; - filename[0] = '\0'; - } - } - if (!lfnExists) { - entryStart = entryEnd; - _FAT_directory_entryGetAlias (entryData, filename); - } - found = true; - } - } - - // If no file is found, return false - if (notFound) { - return false; - } else { - // Fill in the directory entry struct - entry->dataStart = entryStart; - entry->dataEnd = entryEnd; - memcpy (entry->entryData, entryData, DIR_ENTRY_DATA_SIZE); - return true; - } -} - -bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster) { - entry->dataStart.cluster = dirCluster; - entry->dataStart.sector = 0; - entry->dataStart.offset = -1; // Start before the beginning of the directory - - entry->dataEnd = entry->dataStart; - - return _FAT_directory_getNextEntry (partition, entry); -} - -bool _FAT_directory_getRootEntry (PARTITION* partition, DIR_ENTRY* entry) { - entry->dataStart.cluster = 0; - entry->dataStart.sector = 0; - entry->dataStart.offset = 0; - - entry->dataEnd = entry->dataStart; - - memset (entry->filename, '\0', MAX_FILENAME_LENGTH); - entry->filename[0] = '.'; - - memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE); - memset (entry->entryData, ' ', 11); - entry->entryData[0] = '.'; - - entry->entryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - - u16_to_u8array (entry->entryData, DIR_ENTRY_cluster, partition->rootDirCluster); - u16_to_u8array (entry->entryData, DIR_ENTRY_clusterHigh, partition->rootDirCluster >> 16); - - return true; -} - -bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - entryStart = entry->dataStart; - entryEnd = entry->dataEnd; - bool entryStillValid; - bool finished; - - int i; - int lfnPos; - - u8 entryData[DIR_ENTRY_DATA_SIZE]; - - memset (entry->filename, '\0', MAX_FILENAME_LENGTH); - - // Create an empty directory entry to overwrite the old ones with - for ( entryStillValid = true, finished = false; - entryStillValid && !finished; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false)) - { - _FAT_cache_readPartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, - entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - if ((entryStart.cluster == entryEnd.cluster) - && (entryStart.sector == entryEnd.sector) - && (entryStart.offset == entryEnd.offset)) { - // Copy the entry data and stop, since this is the last section of the directory entry - memcpy (entry->entryData, entryData, DIR_ENTRY_DATA_SIZE); - finished = true; - } else { - // Copy the long file name data - lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - for (i = 0; i < 13; i++) { - entry->filename[lfnPos + i] = entryData[LFN_offset_table[i]]; // modify this for unicode support; - } - } - } - - if (!entryStillValid) { - return false; - } - - if ((entryStart.cluster == entryEnd.cluster) - && (entryStart.sector == entryEnd.sector) - && (entryStart.offset == entryEnd.offset)) { - // Since the entry doesn't have a long file name, extract the short filename - if (!_FAT_directory_entryGetAlias (entry->entryData, entry->filename)) { - return false; - } - } - - return true; -} - - - -bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd) { - size_t dirnameLength; - const char* pathPosition; - const char* nextPathPosition; - u32 dirCluster; - bool foundFile; - - char alias[MAX_ALIAS_LENGTH]; - - bool found, notFound; - - pathPosition = path; - - found = false; - notFound = false; - - if (pathEnd == NULL) { - // Set pathEnd to the end of the path string - pathEnd = strchr (path, '\0'); - } - - if (pathPosition[0] == DIR_SEPARATOR) { - // Start at root directory - dirCluster = partition->rootDirCluster; - // Consume separator(s) - while (pathPosition[0] == DIR_SEPARATOR) { - pathPosition++; - } - // If the path is only specifying a directory in the form of "/" return it - if (pathPosition >= pathEnd) { - _FAT_directory_getRootEntry (partition, entry); - found = true; - } - } else { - // Start in current working directory - dirCluster = partition->cwdCluster; - } - - // If the path is only specifying a directory in the form "." - // and this is the root directory, return it - if ((dirCluster == partition->rootDirCluster) && (strncasecmp(".", pathPosition, 2) == 0)) { - _FAT_directory_getRootEntry (partition, entry); - found = true; - } - - while (!found && !notFound) { - // Get the name of the next required subdirectory within the path - nextPathPosition = strchr (pathPosition, DIR_SEPARATOR); - if (nextPathPosition != NULL) { - dirnameLength = nextPathPosition - pathPosition; - } else { - dirnameLength = strlen(pathPosition); - } - - if (dirnameLength > MAX_FILENAME_LENGTH) { - // The path is too long to bother with - return false; - } - - // Look for the directory within the path - foundFile = _FAT_directory_getFirstEntry (partition, entry, dirCluster); - - while (foundFile && !found && !notFound) { // It hasn't already found the file - // Check if the filename matches - if ((dirnameLength == strnlen(entry->filename, MAX_FILENAME_LENGTH)) - && (strncasecmp(entry->filename, pathPosition, dirnameLength) == 0)) { - found = true; - } - - // Check if the alias matches - _FAT_directory_entryGetAlias (entry->entryData, alias); - if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) - && (strncasecmp(alias, pathPosition, dirnameLength) == 0)) { - found = true; - } - - if (found && !(entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) && (nextPathPosition != NULL)) { - // Make sure that we aren't trying to follow a file instead of a directory in the path - found = false; - } - - if (!found) { - foundFile = _FAT_directory_getNextEntry (partition, entry); - } - } - - if (!foundFile) { - // Check that the search didn't get to the end of the directory - notFound = true; - found = false; - } else if ((nextPathPosition == NULL) || (nextPathPosition >= pathEnd)) { - // Check that we reached the end of the path - found = true; - } else if (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) { - dirCluster = _FAT_directory_entryGetCluster (entry->entryData); - pathPosition = nextPathPosition; - // Consume separator(s) - while (pathPosition[0] == DIR_SEPARATOR) { - pathPosition++; - } - // The requested directory was found - if (pathPosition >= pathEnd) { - found = true; - } else { - found = false; - } - } - } - - if (found && !notFound) { - return true; - } else { - return false; - } -} - -bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - entryStart = entry->dataStart; - entryEnd = entry->dataEnd; - bool entryStillValid; - bool finished; - - u8 entryData[DIR_ENTRY_DATA_SIZE]; - - // Create an empty directory entry to overwrite the old ones with - for ( entryStillValid = true, finished = false; - entryStillValid && !finished; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false)) - { - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - entryData[0] = DIR_ENTRY_FREE; - _FAT_cache_writePartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset == entryEnd.offset)) { - finished = true; - } - } - - if (!entryStillValid) { - return false; - } - - return true; -} - -static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster, u32 size) { - DIR_ENTRY_POSITION gapStart; - DIR_ENTRY_POSITION gapEnd; - - u8 entryData[DIR_ENTRY_DATA_SIZE]; - - u32 dirEntryRemain; - - bool endOfDirectory, entryStillValid; - - // Scan Dir for free entry - gapEnd.offset = 0; - gapEnd.sector = 0; - gapEnd.cluster = dirCluster; - - gapStart = gapEnd; - - entryStillValid = true; - dirEntryRemain = size; - endOfDirectory = false; - - while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0)) { - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector, gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - if (entryData[0] == DIR_ENTRY_LAST) { - gapStart = gapEnd; - -- dirEntryRemain; - endOfDirectory = true; - } else if (entryData[0] == DIR_ENTRY_FREE) { - if (dirEntryRemain == size) { - gapStart = gapEnd; - } - -- dirEntryRemain; - } else { - dirEntryRemain = size; - } - - if (!endOfDirectory && (dirEntryRemain > 0)) { - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true); - } - } - - // Make sure the scanning didn't fail - if (!entryStillValid) { - return false; - } - - // Save the start entry, since we know it is valid - entry->dataStart = gapStart; - - if (endOfDirectory) { - memset (entryData, DIR_ENTRY_LAST, DIR_ENTRY_DATA_SIZE); - dirEntryRemain += 1; // Increase by one to take account of End Of Directory Marker - while ((dirEntryRemain > 0) && entryStillValid) { - // Get the gapEnd before incrementing it, so the second to last one is saved - entry->dataEnd = gapEnd; - // Increment gapEnd, moving onto the next entry - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true); - -- dirEntryRemain; - // Fill the entry with blanks - _FAT_cache_writePartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector, gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } - if (!entryStillValid) { - return false; - } - } else { - entry->dataEnd = gapEnd; - } - - return true; -} - -static bool _FAT_directory_entryExists (PARTITION* partition, const char* name, u32 dirCluster) { - DIR_ENTRY tempEntry; - bool foundFile; - char alias[MAX_ALIAS_LENGTH]; - u32 dirnameLength; - - dirnameLength = strnlen(name, MAX_FILENAME_LENGTH); - - if (dirnameLength >= MAX_FILENAME_LENGTH) { - return false; - } - - // Make sure the entry doesn't already exist - foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster); - - while (foundFile) { // It hasn't already found the file - // Check if the filename matches - if ((dirnameLength == strnlen(tempEntry.filename, MAX_FILENAME_LENGTH)) - && (strcasecmp(tempEntry.filename, name) == 0)) { - return true; - } - - // Check if the alias matches - _FAT_directory_entryGetAlias (tempEntry.entryData, alias); - if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) - && (strcasecmp(alias, name) == 0)) { - return true; - } - foundFile = _FAT_directory_getNextEntry (partition, &tempEntry); - } - return false; -} - - - -bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster) { - u32 entrySize; - u8 lfnEntry[DIR_ENTRY_DATA_SIZE]; - s32 i,j; // Must be signed for use when decrementing in for loop - char *tmpCharPtr; - DIR_ENTRY_POSITION curEntryPos; - bool entryStillValid; - u8 aliasCheckSum = 0; - char alias [MAX_ALIAS_LENGTH]; - - // Make sure the filename is not 0 length - if (strnlen (entry->filename, MAX_FILENAME_LENGTH) < 1) { - return false; - } - - // Make sure the filename is at least a valid LFN - if ( !(_FAT_directory_isValidLfn (entry->filename))) { - return false; - } - - // Remove trailing spaces - for (i = strlen (entry->filename) - 1; (i > 0) && (entry->filename[i] == ' '); --i) { - entry->filename[i] = '\0'; - } - // Remove leading spaces - for (i = 0; (i < strlen (entry->filename)) && (entry->filename[i] == ' '); ++i) ; - if (i > 0) { - memmove (entry->filename, entry->filename + i, strlen (entry->filename + i)); - } - - // Remove junk in filename - i = strlen (entry->filename); - memset (entry->filename + i, '\0', MAX_FILENAME_LENGTH - i); - - // Make sure the entry doesn't already exist - if (_FAT_directory_entryExists (partition, entry->filename, dirCluster)) { - return false; - } - - // Clear out alias, so we can generate a new one - memset (entry->entryData, ' ', 11); - - if ( strncmp(entry->filename, ".", MAX_FILENAME_LENGTH) == 0) { - // "." entry - entry->entryData[0] = '.'; - entrySize = 1; - } else if ( strncmp(entry->filename, "..", MAX_FILENAME_LENGTH) == 0) { - // ".." entry - entry->entryData[0] = '.'; - entry->entryData[1] = '.'; - entrySize = 1; - } else if ( _FAT_directory_isValidAlias (entry->filename)) { - // Short filename - strupr (entry->filename); - entrySize = 1; - // Copy into alias - for (i = 0, j = 0; (j < 8) && (entry->filename[i] != '.') && (entry->filename[i] != '\0'); i++, j++) { - entry->entryData[j] = entry->filename[i]; - } - while (j < 8) { - entry->entryData[j] = ' '; - ++ j; - } - if (entry->filename[i] == '.') { - // Copy extension - ++ i; - while ((entry->filename[i] != '\0') && (j < 11)) { - entry->entryData[j] = entry->filename[i]; - ++ i; - ++ j; - } - } - while (j < 11) { - entry->entryData[j] = ' '; - ++ j; - } - } else { - // Long filename needed - entrySize = ((strnlen (entry->filename, MAX_FILENAME_LENGTH) + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1; - // Generate alias - tmpCharPtr = strrchr (entry->filename, '.'); - if (tmpCharPtr == NULL) { - tmpCharPtr = strrchr (entry->filename, '\0'); - } - for (i = 0, j = 0; (j < 6) && (entry->filename + i < tmpCharPtr); i++) { - if ( isalnum(entry->filename[i])) { - alias[j] = entry->filename[i]; - ++ j; - } - } - while (j < 8) { - alias[j] = '_'; - ++ j; - } - tmpCharPtr = strrchr (entry->filename, '.'); - if (tmpCharPtr != NULL) { - alias[8] = '.'; - // Copy extension - while ((tmpCharPtr != '\0') && (j < 12)) { - alias[j] = tmpCharPtr[0]; - ++ tmpCharPtr; - ++ j; - } - alias[j] = '\0'; - } else { - for (j = 8; j < MAX_ALIAS_LENGTH; j++) { - alias[j] = '\0'; - } - } - - // Get a valid tail number - alias[5] = '~'; - i = 0; - do { - i++; - alias[6] = '0' + ((i / 10) % 10); // 10's digit - alias[7] = '0' + (i % 10); // 1's digit - } while (_FAT_directory_entryExists (partition, alias, dirCluster) && (i < 100)); - if (i == 100) { - // Couldn't get a tail number - return false; - } - - // Make it upper case - strupr (alias); - - // Now copy it into the directory entry data - memcpy (entry->entryData, alias, 8); - memcpy (entry->entryData + 8, alias + 9, 3); - for (i = 0; i < 10; i++) { - if (entry->entryData[i] < 0x20) { - // Replace null and control characters with spaces - entry->entryData[i] = 0x20; - } - } - // Generate alias checksum - for (i=0; i < 11; i++) - { - // NOTE: The operation is an unsigned char rotate right - aliasCheckSum = ((aliasCheckSum & 1) ? 0x80 : 0) + (aliasCheckSum >> 1) + entry->entryData[i]; - } - - } - - // Find or create space for the entry - if (_FAT_directory_findEntryGap (partition, entry, dirCluster, entrySize) == false) { - return false; - } - - // Write out directory entry - curEntryPos = entry->dataStart; - - for (entryStillValid = true, i = entrySize; entryStillValid && i > 0; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &curEntryPos, false), -- i ) - { - if (i > 1) { - // Long filename entry - lfnEntry[LFN_offset_ordinal] = (i - 1) | (i == entrySize ? LFN_END : 0); - for (j = 0; j < 13; j++) { - if (entry->filename [(i - 2) * 13 + j] == '\0') { - if ((j > 1) && (entry->filename [(i - 2) * 13 + (j-1)] == '\0')) { - u16_to_u8array (lfnEntry, LFN_offset_table[j], 0xffff); // Padding - } else { - u16_to_u8array (lfnEntry, LFN_offset_table[j], 0x0000); // Terminating null character - } - } else { - u16_to_u8array (lfnEntry, LFN_offset_table[j], entry->filename [(i - 2) * 13 + j]); - } - } - - lfnEntry[LFN_offset_checkSum] = aliasCheckSum; - lfnEntry[LFN_offset_flag] = ATTRIB_LFN; - lfnEntry[LFN_offset_reserved1] = 0; - u16_to_u8array (lfnEntry, LFN_offset_reserved2, 0); - _FAT_cache_writePartialSector (partition->cache, lfnEntry, _FAT_fat_clusterToSector(partition, curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } else { - // Alias & file data - _FAT_cache_writePartialSector (partition->cache, entry->entryData, _FAT_fat_clusterToSector(partition, curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } - } - - return true; -} - -bool _FAT_directory_chdir (PARTITION* partition, const char* path) { - DIR_ENTRY entry; - - if (!_FAT_directory_entryFromPath (partition, &entry, path, NULL)) { - return false; - } - - if (!(entry.entryData[DIR_ENTRY_attributes] & ATTRIB_DIR)) { - return false; - } - - partition->cwdCluster = _FAT_directory_entryGetCluster (entry.entryData); - - return true; -} - -void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *st) { - // Fill in the stat struct - // Some of the values are faked for the sake of compatibility - st->st_dev = _FAT_disc_hostType(partition->disc); // The device is the 32bit ioType value - st->st_ino = (ino_t)(_FAT_directory_entryGetCluster(entry->entryData)); // The file serial number is the start cluster - st->st_mode = (_FAT_directory_isDirectory(entry) ? S_IFDIR : S_IFREG) | - (S_IRUSR | S_IRGRP | S_IROTH) | - (_FAT_directory_isWritable (entry) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0); // Mode bits based on dirEntry ATTRIB byte - st->st_nlink = 1; // Always one hard link on a FAT file - st->st_uid = 1; // Faked for FAT - st->st_gid = 2; // Faked for FAT - st->st_rdev = st->st_dev; - st->st_size = u8array_to_u32 (entry->entryData, DIR_ENTRY_fileSize); // File size - st->st_atime = _FAT_filetime_to_time_t ( - 0, - u8array_to_u16 (entry->entryData, DIR_ENTRY_aDate) - ); - st->st_spare1 = 0; - st->st_mtime = _FAT_filetime_to_time_t ( - u8array_to_u16 (entry->entryData, DIR_ENTRY_mTime), - u8array_to_u16 (entry->entryData, DIR_ENTRY_mDate) - ); - st->st_spare2 = 0; - st->st_ctime = _FAT_filetime_to_time_t ( - u8array_to_u16 (entry->entryData, DIR_ENTRY_cTime), - u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate) - ); - st->st_spare3 = 0; - st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size - st->st_blocks = (st->st_size + BYTES_PER_READ - 1) / BYTES_PER_READ; // File size in blocks - st->st_spare4[0] = 0; - st->st_spare4[1] = 0; -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/directory.h b/c/src/lib/libbsp/arm/nds/libfat/source/directory.h deleted file mode 100644 index 3c75658e7e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/directory.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - directory.h - Reading, writing and manipulation of the directory structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _DIRECTORY_H -#define _DIRECTORY_H - -#include <sys/stat.h> - -#include "common.h" -#include "partition.h" - -#define DIR_ENTRY_DATA_SIZE 0x20 -#define MAX_FILENAME_LENGTH 256 -#define MAX_ALIAS_LENGTH 13 -#define LFN_ENTRY_LENGTH 13 -#define FAT16_ROOT_DIR_CLUSTER 0 - -#define DIR_SEPARATOR '/' - -// File attributes -#define ATTRIB_ARCH 0x20 // Archive -#define ATTRIB_DIR 0x10 // Directory -#define ATTRIB_LFN 0x0F // Long file name -#define ATTRIB_VOL 0x08 // Volume -#define ATTRIB_SYS 0x04 // System -#define ATTRIB_HID 0x02 // Hidden -#define ATTRIB_RO 0x01 // Read only - -typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE; - -typedef struct { - u32 cluster; - u32 sector; - s32 offset; -} DIR_ENTRY_POSITION; - -typedef struct { - u8 entryData[DIR_ENTRY_DATA_SIZE]; - DIR_ENTRY_POSITION dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN - DIR_ENTRY_POSITION dataEnd; // Always points to the file/directory's alias entry - char filename[MAX_FILENAME_LENGTH]; -} DIR_ENTRY; - -// Directory entry offsets -enum DIR_ENTRY_offset { - DIR_ENTRY_name = 0x00, - DIR_ENTRY_extension = 0x08, - DIR_ENTRY_attributes = 0x0B, - DIR_ENTRY_reserved = 0x0C, - DIR_ENTRY_cTime_ms = 0x0D, - DIR_ENTRY_cTime = 0x0E, - DIR_ENTRY_cDate = 0x10, - DIR_ENTRY_aDate = 0x12, - DIR_ENTRY_clusterHigh = 0x14, - DIR_ENTRY_mTime = 0x16, - DIR_ENTRY_mDate = 0x18, - DIR_ENTRY_cluster = 0x1A, - DIR_ENTRY_fileSize = 0x1C -}; - -/* -Returns true if the file specified by entry is a directory -*/ -static inline bool _FAT_directory_isDirectory (DIR_ENTRY* entry) { - return ((entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) != 0); -} - -static inline bool _FAT_directory_isWritable (DIR_ENTRY* entry) { - return ((entry->entryData[DIR_ENTRY_attributes] & ATTRIB_RO) == 0); -} - -static inline bool _FAT_directory_isDot (DIR_ENTRY* entry) { - return ((entry->filename[0] == '.') && ((entry->filename[1] == '\0') || - ((entry->filename[1] == '.') && entry->filename[2] == '\0'))); -} - -/* -Reads the first directory entry from the directory starting at dirCluster -Places result in entry -entry will be destroyed even if no directory entry is found -Returns true on success, false on failure -*/ -bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster); - -/* -Reads the next directory entry after the one already pointed to by entry -Places result in entry -entry will be destroyed even if no directory entry is found -Returns true on success, false on failure -*/ -bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry); - -/* -Gets the directory entry corrsponding to the supplied path -entry will be destroyed even if no directory entry is found -pathEnd specifies the end of the path string, for cutting strings short if needed - specify NULL to use the full length of path - pathEnd is only a suggestion, and the path string will be searched up until the next PATH_SEPARATOR - after pathEND. -Returns true on success, false on failure -*/ -bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd); - -/* -Changes the current directory to the one specified by path -Returns true on success, false on failure -*/ -bool _FAT_directory_chdir (PARTITION* partition, const char* path); - -/* -Removes the directory entry specified by entry -Assumes that entry is valid -Returns true on success, false on failure -*/ -bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry); - -/* -Add a directory entry to the directory specified by dirCluster -The fileData, dataStart and dataEnd elements of the DIR_ENTRY struct are -updated with the new directory entry position and alias. -Returns true on success, false on failure -*/ -bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster); - -/* -Get the start cluster of a file from it's entry data -*/ -u32 _FAT_directory_entryGetCluster (const u8* entryData); - -/* -Fill in the file name and entry data of DIR_ENTRY* entry. -Assumes that the entry's dataStart and dataEnd are correct -Returns true on success, false on failure -*/ -bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry); - -/* -Fill in a stat struct based on a file entry -*/ -void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *st); - -#endif // _DIRECTORY_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc.c deleted file mode 100644 index 8eea5fcaba..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - - disc.c - - uniformed io-interface to work with Chishm's FAT library - - Written by MightyMax - - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2005-11-06 - Chishm - * Added WAIT_CR modifications for NDS - - 2006-02-03 www.neoflash.com - * Added SUPPORT_* defines, comment out any of the SUPPORT_* defines in disc_io.h to remove support - for the given interface and stop code being linked to the binary - - * Added support for MK2 MMC interface - - * Added disc_Cache* functions - - 2006-02-05 - Chishm - * Added Supercard SD support - - 2006-02-26 - Cytex - * Added EFA2 support - - 2006-05-18 - Chishm - * Rewritten for FATlib disc.c - - 2006-06-19 - Chishm - * Changed read and write interface to accept a u32 instead of a u8 for the number of sectors - - 2006-07-11 - Chishm - * Removed disc_Cache* functions, since there is now a proper unified cache - * Removed SUPPORT_* defines - * Rewrote device detection functions - * First libfat release - - 2006-07-25 - Chishm - * Changed IO_INTERFACEs to const - - 2006-08-02 - Chishm - * Added NinjaDS - - 2006-12-25 - Chishm - * Added DLDI - * Removed experimental interfaces - - 2007-05-01 - Chishm - * Removed FCSR -*/ - -#include "disc.h" -#include "disc_io.h" - -#ifdef NDS - #include <nds.h> -#endif - - -// Include known io-interfaces: -#include "io_dldi.h" -#include "io_njsd.h" -#include "io_nmmc.h" -#include "io_mpcf.h" -#include "io_m3cf.h" -#include "io_sccf.h" -#include "io_scsd.h" -#include "io_m3sd.h" - -const IO_INTERFACE* ioInterfaces[] = { - &_io_dldi, // Reserved for new interfaces -#ifdef NDS - // Place Slot 1 (DS Card) interfaces here - &_io_njsd, &_io_nmmc, -#endif - // Place Slot 2 (GBA Cart) interfaces here - &_io_mpcf, &_io_m3cf, &_io_sccf, &_io_scsd, &_io_m3sd -}; - -/* - - Hardware level disc funtions - -*/ - -const IO_INTERFACE* _FAT_disc_gbaSlotFindInterface (void) -{ - // If running on an NDS, make sure the correct CPU can access - // the GBA cart. First implemented by SaTa. -#ifdef NDS - #ifdef ARM9 - sysSetCartOwner(BUS_OWNER_ARM9); - #endif -#endif - - int i; - - for (i = 0; i < (sizeof(ioInterfaces) / sizeof(IO_INTERFACE*)); i++) { - if ((ioInterfaces[i]->features & FEATURE_SLOT_GBA) && (ioInterfaces[i]->fn_startup())) { - return ioInterfaces[i]; - } - } - return NULL; -} - -#ifdef NDS -/* - * Check the DS card slot for a valid memory card interface - * If an interface is found, it is set as the default interace - * and it returns true. Otherwise the default interface is left - * untouched and it returns false. - */ -const IO_INTERFACE* _FAT_disc_dsSlotFindInterface (void) -{ -#ifdef ARM9 - sysSetCardOwner(BUS_OWNER_ARM9); -#endif - int i; - - for (i = 0; i < (sizeof(ioInterfaces) / sizeof(IO_INTERFACE*)); i++) { - if ((ioInterfaces[i]->features & FEATURE_SLOT_NDS) && (ioInterfaces[i]->fn_startup())) { - return ioInterfaces[i]; - } - } - - return NULL; -} -#endif - -/* - * When running on an NDS, check the either slot for a valid memory - * card interface. - * When running on a GBA, call _FAT_disc_gbaSlotFindInterface - * If an interface is found, it is set as the default interace - * and it returns true. Otherwise the default interface is left - * untouched and it returns false. - */ -#ifdef NDS -const IO_INTERFACE* _FAT_disc_findInterface (void) -{ -#ifdef ARM9 - sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9); -#endif - - int i; - - for (i = 0; i < (sizeof(ioInterfaces) / sizeof(IO_INTERFACE*)); i++) { - if (ioInterfaces[i]->fn_startup()) { - return ioInterfaces[i]; - } - } - - return NULL; -} -#else -const IO_INTERFACE* _FAT_disc_findInterface (void) -{ - return _FAT_disc_gbaSlotFindInterface(); -} -#endif diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc.h deleted file mode 100644 index 5bb21f171f..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - disc.h - Interface to the low level disc functions. Used by the higher level - file system code. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - -*/ -#ifndef _DISC_H -#define _DISC_H - -#include "../common.h" -#include "disc_io.h" - -/* -Search for a block based device in the GBA slot. -Return a pointer to a usable interface if one is found, -NULL if not. -*/ -extern const IO_INTERFACE* _FAT_disc_gbaSlotFindInterface (void); - -/* -Search for a block based device in the DS slot. -Return a pointer to a usable interface if one is found, -NULL if not. -*/ -#ifdef NDS -extern const IO_INTERFACE* _FAT_disc_dsSlotFindInterface (void); -#endif - -/* -Search for a block based device in the both slots. -Return a pointer to a usable interface if one is found, -NULL if not. -*/ -extern const IO_INTERFACE* _FAT_disc_findInterface (void); - -/* -Check if a disc is inserted -Return true if a disc is inserted and ready, false otherwise -*/ -static inline bool _FAT_disc_isInserted (const IO_INTERFACE* disc) { - return disc->fn_isInserted(); -} - -/* -Read numSectors sectors from a disc, starting at sector. -numSectors is between 1 and 256 -sector is from 0 to 2^28 -buffer is a pointer to the memory to fill -*/ -static inline bool _FAT_disc_readSectors (const IO_INTERFACE* disc, u32 sector, u32 numSectors, void* buffer) { - return disc->fn_readSectors (sector, numSectors, buffer); -} - -/* -Write numSectors sectors to a disc, starting at sector. -numSectors is between 1 and 256 -sector is from 0 to 2^28 -buffer is a pointer to the memory to read from -*/ -static inline bool _FAT_disc_writeSectors (const IO_INTERFACE* disc, u32 sector, u32 numSectors, const void* buffer) { - return disc->fn_writeSectors (sector, numSectors, buffer); -} - -/* -Reset the card back to a ready state -*/ -static inline bool _FAT_disc_clearStatus (const IO_INTERFACE* disc) { - return disc->fn_clearStatus(); -} - -/* -Initialise the disc to a state ready for data reading or writing -*/ -static inline bool _FAT_disc_startup (const IO_INTERFACE* disc) { - return disc->fn_startup(); -} - -/* -Put the disc in a state ready for power down. -Complete any pending writes and disable the disc if necessary -*/ -static inline bool _FAT_disc_shutdown (const IO_INTERFACE* disc) { - return disc->fn_shutdown(); -} - -/* -Return a 32 bit value unique to each type of interface -*/ -static inline u32 _FAT_disc_hostType (const IO_INTERFACE* disc) { - return disc->ioType; -} - -/* -Return a 32 bit value that specifies the capabilities of the disc -*/ -static inline u32 _FAT_disc_features (const IO_INTERFACE* disc) { - return disc->features; -} - -#endif // _DISC_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc_io.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc_io.h deleted file mode 100644 index 916f94e5a3..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/disc_io.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - disc_io.h - Interface template for low level disc functions. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-16 - Chishm - * Renamed _CF_USE_DMA to _IO_USE_DMA - * Renamed _CF_ALLOW_UNALIGNED to _IO_ALLOW_UNALIGNED -*/ - -#ifndef _DISC_IO_H -#define _DISC_IO_H - -#include "../common.h" - -//---------------------------------------------------------------------- -// Customisable features - -// Use DMA to read the card, remove this line to use normal reads/writes -// #define _IO_USE_DMA - -// Allow buffers not alligned to 16 bits when reading files. -// Note that this will slow down access speed, so only use if you have to. -// It is also incompatible with DMA -#define _IO_ALLOW_UNALIGNED - -#if defined _IO_USE_DMA && defined _IO_ALLOW_UNALIGNED - #error "You cannot use both DMA and unaligned memory" -#endif - -#define FEATURE_MEDIUM_CANREAD 0x00000001 -#define FEATURE_MEDIUM_CANWRITE 0x00000002 -#define FEATURE_SLOT_GBA 0x00000010 -#define FEATURE_SLOT_NDS 0x00000020 - -typedef bool (* FN_MEDIUM_STARTUP)(void) ; -typedef bool (* FN_MEDIUM_ISINSERTED)(void) ; -typedef bool (* FN_MEDIUM_READSECTORS)(u32 sector, u32 numSectors, void* buffer) ; -typedef bool (* FN_MEDIUM_WRITESECTORS)(u32 sector, u32 numSectors, const void* buffer) ; -typedef bool (* FN_MEDIUM_CLEARSTATUS)(void) ; -typedef bool (* FN_MEDIUM_SHUTDOWN)(void) ; - -struct IO_INTERFACE_STRUCT { - unsigned long ioType ; - unsigned long features ; - FN_MEDIUM_STARTUP fn_startup ; - FN_MEDIUM_ISINSERTED fn_isInserted ; - FN_MEDIUM_READSECTORS fn_readSectors ; - FN_MEDIUM_WRITESECTORS fn_writeSectors ; - FN_MEDIUM_CLEARSTATUS fn_clearStatus ; - FN_MEDIUM_SHUTDOWN fn_shutdown ; -} ; - -typedef struct IO_INTERFACE_STRUCT IO_INTERFACE ; - -#endif // define _DISC_IO_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_cf_common.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_cf_common.c deleted file mode 100644 index 386d24d5ed..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_cf_common.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - io_cf_common.c based on - - compact_flash.c - By chishm (Michael Chisholm) - - Common hardware routines for using a compact flash card. This is not reentrant - and does not do range checking on the supplied addresses. This is designed to - be as fast as possible. - - CF routines modified with help from Darkfader - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "io_cf_common.h" - -//--------------------------------------------------------------- -// DMA -#ifdef _IO_USE_DMA - #ifndef NDS - #include "gba_dma.h" - #else - #include <nds/dma.h> - #ifdef ARM9 - #include <nds/arm9/cache.h> - #endif - #endif -#endif - -//--------------------------------------------------------------- -// CF Addresses & Commands - -CF_REGISTERS cfRegisters = {0}; - - -/*----------------------------------------------------------------- -_CF_isInserted -Is a compact flash card inserted? -bool return OUT: true if a CF card is inserted ------------------------------------------------------------------*/ -bool _CF_isInserted (void) { - // Change register, then check if value did change - *(cfRegisters.status) = CF_STS_INSERTED; - return ((*(cfRegisters.status) & 0xff) == CF_STS_INSERTED); -} - - -/*----------------------------------------------------------------- -_CF_clearStatus -Tries to make the CF card go back to idle mode -bool return OUT: true if a CF card is idle ------------------------------------------------------------------*/ -bool _CF_clearStatus (void) { - int i; - - // Wait until CF card is finished previous commands - i=0; - while ((*(cfRegisters.command) & CF_STS_BUSY) && (i < CF_CARD_TIMEOUT)) { - i++; - } - - // Wait until card is ready for commands - i = 0; - while ((!(*(cfRegisters.status) & CF_STS_INSERTED)) && (i < CF_CARD_TIMEOUT)) { - i++; - } - if (i >= CF_CARD_TIMEOUT) - return false; - - return true; -} - - -/*----------------------------------------------------------------- -_CF_readSectors -Read 512 byte sector numbered "sector" into "buffer" -u32 sector IN: address of first 512 byte sector on CF card to read -u32 numSectors IN: number of 512 byte sectors to read, - 1 to 256 sectors can be read -void* buffer OUT: pointer to 512 byte buffer to store data in -bool return OUT: true if successful ------------------------------------------------------------------*/ -bool _CF_readSectors (u32 sector, u32 numSectors, void* buffer) { - int i; - - u16 *buff = (u16*)buffer; -#ifdef _IO_ALLOW_UNALIGNED - u8 *buff_u8 = (u8*)buffer; - int temp; -#endif - -#if (defined _IO_USE_DMA) && (defined NDS) && (defined ARM9) - DC_FlushRange( buffer, j * BYTES_PER_READ); -#endif - - // Wait until CF card is finished previous commands - i=0; - while ((*(cfRegisters.command) & CF_STS_BUSY) && (i < CF_CARD_TIMEOUT)) { - i++; - } - - // Wait until card is ready for commands - i = 0; - while ((!(*(cfRegisters.status) & CF_STS_INSERTED)) && (i < CF_CARD_TIMEOUT)) { - i++; - } - if (i >= CF_CARD_TIMEOUT) - return false; - - // Set number of sectors to read - *(cfRegisters.sectorCount) = (numSectors < 256 ? numSectors : 0); // Read a maximum of 256 sectors, 0 means 256 - - // Set read sector - *(cfRegisters.lba1) = sector & 0xFF; // 1st byte of sector number - *(cfRegisters.lba2) = (sector >> 8) & 0xFF; // 2nd byte of sector number - *(cfRegisters.lba3) = (sector >> 16) & 0xFF; // 3rd byte of sector number - *(cfRegisters.lba4) = ((sector >> 24) & 0x0F )| CF_CMD_LBA; // last nibble of sector number - - // Set command to read - *(cfRegisters.command) = CF_CMD_READ; - - - while (numSectors--) - { - // Wait until card is ready for reading - i = 0; - while (((*(cfRegisters.status) & 0xff)!= CF_STS_READY) && (i < CF_CARD_TIMEOUT)) - { - i++; - } - if (i >= CF_CARD_TIMEOUT) - return false; - - // Read data -#ifdef _IO_USE_DMA - #ifdef NDS - DMA3_SRC = (u32)(cfRegisters.data); - DMA3_DEST = (u32)buff; - DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_SRC_FIX; - #else - DMA3COPY ( (cfRegisters.data), buff, 256 | DMA16 | DMA_ENABLE | DMA_SRC_FIXED); - #endif - buff += BYTES_PER_READ / 2; -#elif defined _IO_ALLOW_UNALIGNED - i=256; - if ((u32)buff_u8 & 0x01) { - while(i--) - { - temp = *(cfRegisters.data); - *buff_u8++ = temp & 0xFF; - *buff_u8++ = temp >> 8; - } - } else { - while(i--) - *buff++ = *(cfRegisters.data); - } -#else - i=256; - while(i--) - *buff++ = *(cfRegisters.data); -#endif - } -#if (defined _IO_USE_DMA) && (defined NDS) - // Wait for end of transfer before returning - while(DMA3_CR & DMA_BUSY); -#endif - return true; -} - - - -/*----------------------------------------------------------------- -_CF_writeSectors -Write 512 byte sector numbered "sector" from "buffer" -u32 sector IN: address of 512 byte sector on CF card to read -u32 numSectors IN: number of 512 byte sectors to read, - 1 to 256 sectors can be read -void* buffer IN: pointer to 512 byte buffer to read data from -bool return OUT: true if successful ------------------------------------------------------------------*/ -bool _CF_writeSectors (u32 sector, u32 numSectors, void* buffer) { - int i; - - u16 *buff = (u16*)buffer; -#ifdef _IO_ALLOW_UNALIGNED - u8 *buff_u8 = (u8*)buffer; - int temp; -#endif - -#if defined _IO_USE_DMA && defined NDS && defined ARM9 - DC_FlushRange( buffer, j * BYTES_PER_READ); -#endif - - // Wait until CF card is finished previous commands - i=0; - while ((*(cfRegisters.command) & CF_STS_BUSY) && (i < CF_CARD_TIMEOUT)) - { - i++; - } - - // Wait until card is ready for commands - i = 0; - while ((!(*(cfRegisters.status) & CF_STS_INSERTED)) && (i < CF_CARD_TIMEOUT)) - { - i++; - } - if (i >= CF_CARD_TIMEOUT) - return false; - - // Set number of sectors to write - *(cfRegisters.sectorCount) = (numSectors < 256 ? numSectors : 0); // Write a maximum of 256 sectors, 0 means 256 - - // Set write sector - *(cfRegisters.lba1) = sector & 0xFF; // 1st byte of sector number - *(cfRegisters.lba2) = (sector >> 8) & 0xFF; // 2nd byte of sector number - *(cfRegisters.lba3) = (sector >> 16) & 0xFF; // 3rd byte of sector number - *(cfRegisters.lba4) = ((sector >> 24) & 0x0F )| CF_CMD_LBA; // last nibble of sector number - - // Set command to write - *(cfRegisters.command) = CF_CMD_WRITE; - - while (numSectors--) - { - // Wait until card is ready for writing - i = 0; - while (((*(cfRegisters.status) & 0xff) != CF_STS_READY) && (i < CF_CARD_TIMEOUT)) - { - i++; - } - if (i >= CF_CARD_TIMEOUT) - return false; - - // Write data -#ifdef _IO_USE_DMA - #ifdef NDS - DMA3_SRC = (u32)buff; - DMA3_DEST = (u32)(cfRegisters.data); - DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_DST_FIX; - #else - DMA3COPY( buff, (cfRegisters.data), 256 | DMA16 | DMA_ENABLE | DMA_DST_FIXED); - #endif - buff += BYTES_PER_READ / 2; -#elif defined _IO_ALLOW_UNALIGNED - i=256; - if ((u32)buff_u8 & 0x01) { - while(i--) - { - temp = *buff_u8++; - temp |= *buff_u8++ << 8; - *(cfRegisters.data) = temp; - } - } else { - while(i--) - *(cfRegisters.data) = *buff++; - } -#else - i=256; - while(i--) - *(cfRegisters.data) = *buff++; -#endif - } -#if defined _IO_USE_DMA && defined NDS - // Wait for end of transfer before returning - while(DMA3_CR & DMA_BUSY); -#endif - - return true; -} - -/*----------------------------------------------------------------- -_CF_shutdown -shutdown the CF interface ------------------------------------------------------------------*/ -bool _CF_shutdown(void) { - return _CF_clearStatus() ; -} - -/*----------------------------------------------------------------- -_CF_startUp -Initializes the CF interface using the supplied registers -returns true if successful, otherwise returns false ------------------------------------------------------------------*/ -bool _CF_startup(const CF_REGISTERS *usableCfRegs) { - cfRegisters = *usableCfRegs; - // See if there is a read/write register - u16 temp = *(cfRegisters.lba1); - *(cfRegisters.lba1) = (~temp & 0xFF); - temp = (~temp & 0xFF); - if (!(*(cfRegisters.lba1) == temp)) { - return false; - } - // Make sure it is 8 bit - *(cfRegisters.lba1) = 0xAA55; - if (*(cfRegisters.lba1) == 0xAA55) { - return false; - } - return true; -} - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_cf_common.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_cf_common.h deleted file mode 100644 index e08c1a9503..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_cf_common.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - io_cf_common.h - - By chishm (Michael Chisholm) - - Common Compact Flash card values - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-16 - Chishm - * Combined all CF interfaces into one common set of routines -*/ - -#ifndef IO_CF_COMMON_H -#define IO_CF_COMMON_H - -#include "disc_io.h" - -typedef struct { - vu16* data; - vu16* status; - vu16* command; - vu16* error; - vu16* sectorCount; - vu16* lba1; - vu16* lba2; - vu16* lba3; - vu16* lba4; -} CF_REGISTERS; - - -// CF Card status -#define CF_STS_INSERTED 0x50 -#define CF_STS_REMOVED 0x00 -#define CF_STS_READY 0x58 - -#define CF_STS_DRQ 0x08 -#define CF_STS_BUSY 0x80 - -// CF Card commands -#define CF_CMD_LBA 0xE0 -#define CF_CMD_READ 0x20 -#define CF_CMD_WRITE 0x30 - -#define CF_CARD_TIMEOUT 10000000 - -bool _CF_isInserted (void); -bool _CF_clearStatus (void); -bool _CF_readSectors (u32 sector, u32 numSectors, void* buffer); -bool _CF_writeSectors (u32 sector, u32 numSectors, void* buffer); -bool _CF_shutdown(void); -bool _CF_startup(const CF_REGISTERS *usableCfRegs); - -#endif // define IO_CF_COMMON_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_dldi.S b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_dldi.S deleted file mode 100644 index d087bbd94d..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_dldi.S +++ /dev/null @@ -1,73 +0,0 @@ -@--------------------------------------------------------------------------------- - .align 4 - .arm - .global _io_dldi -@--------------------------------------------------------------------------------- -.equ FEATURE_MEDIUM_CANREAD, 0x00000001 -.equ FEATURE_MEDIUM_CANWRITE, 0x00000002 -.equ FEATURE_SLOT_GBA, 0x00000010 -.equ FEATURE_SLOT_NDS, 0x00000020 - - -_dldi_start: - -@--------------------------------------------------------------------------------- -@ Driver patch file standard header -- 16 bytes - .word 0xBF8DA5ED @ Magic number to identify this region - .asciz " Chishm" @ Identifying Magic string (8 bytes with null terminator) - .byte 0x01 @ Version number - .byte 0x0F @32KiB @ Log [base-2] of the size of this driver in bytes. - .byte 0x00 @ Sections to fix - .byte 0x0F @32KiB @ Log [base-2] of the allocated space in bytes. - -@--------------------------------------------------------------------------------- -@ Text identifier - can be anything up to 47 chars + terminating null -- 16 bytes - .align 4 - .asciz "Default (No interface)" - -@--------------------------------------------------------------------------------- -@ Offsets to important sections within the data -- 32 bytes - .align 6 - .word _dldi_start @ data start - .word _dldi_end @ data end - .word 0x00000000 @ Interworking glue start -- Needs address fixing - .word 0x00000000 @ Interworking glue end - .word 0x00000000 @ GOT start -- Needs address fixing - .word 0x00000000 @ GOT end - .word 0x00000000 @ bss start -- Needs setting to zero - .word 0x00000000 @ bss end - -@--------------------------------------------------------------------------------- -@ IO_INTERFACE data -- 32 bytes -_io_dldi: - .ascii "DLDI" @ ioType - .word 0x00000000 @ Features - .word _DLDI_startup @ - .word _DLDI_isInserted @ - .word _DLDI_readSectors @ Function pointers to standard device driver functions - .word _DLDI_writeSectors @ - .word _DLDI_clearStatus @ - .word _DLDI_shutdown @ - -@--------------------------------------------------------------------------------- - -_DLDI_startup: -_DLDI_isInserted: -_DLDI_readSectors: -_DLDI_writeSectors: -_DLDI_clearStatus: -_DLDI_shutdown: - mov r0, #0x00 @ Return false for every function - bx lr - - - -@--------------------------------------------------------------------------------- - .align - .pool - -.space 32632 @ Fill to 32KiB - -_dldi_end: - .end -@--------------------------------------------------------------------------------- diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_dldi.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_dldi.h deleted file mode 100644 index 97483914ff..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_dldi.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - io_dldi.h - - Reserved space for post-compilation adding of an extra driver - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-12-22 - Chishm - * Original release -*/ - -#ifndef IO_DLDI_H -#define IO_DLDI_H - -// 'DLDD' -#define DEVICE_TYPE_DLDD 0x49444C44 - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_dldi ; - -#endif // define IO_DLDI_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c deleted file mode 100644 index f68e74a2ac..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c +++ /dev/null @@ -1,307 +0,0 @@ -/* -io_efa2.c by CyteX - -Based on io_mpfc.c by chishm (Michael Chisholm) - -Hardware Routines for reading the NAND flash located on -EFA2 flash carts - -This software is completely free. No warranty is provided. -If you use it, please give me credit and email me about your -project at cytex <at> gmx <dot> de and do not forget to also -drop chishm <at> hotmail <dot> com a line - - Use with permission by Michael "Chishm" Chisholm -*/ - -#include "io_efa2.h" - -// -// EFA2 register addresses -// - -// RTC registers -#define REG_RTC_CLK (*(vu16*)0x080000c4) -#define REG_RTC_EN (*(vu16*)0x080000c8) - -// "Magic" registers used for unlock/lock sequences -#define REG_EFA2_MAGIC_A (*(vu16*)0x09fe0000) -#define REG_EFA2_MAGIC_B (*(vu16*)0x08000000) -#define REG_EFA2_MAGIC_C (*(vu16*)0x08020000) -#define REG_EFA2_MAGIC_D (*(vu16*)0x08040000) -#define REG_EFA2_MAGIC_E (*(vu16*)0x09fc0000) - -// NAND flash lock/unlock register -#define REG_EFA2_NAND_LOCK (*(vu16*)0x09c40000) -// NAND flash enable register -#define REG_EFA2_NAND_EN (*(vu16*)0x09400000) -// NAND flash command write register -#define REG_EFA2_NAND_CMD (*(vu8*)0x09ffffe2) -// NAND flash address/data write register -#define REG_EFA2_NAND_WR (*(vu8*)0x09ffffe0) -// NAND flash data read register -#define REG_EFA2_NAND_RD (*(vu8*)0x09ffc000) - -// ID of Samsung K9K1G NAND flash chip -#define EFA2_NAND_ID 0xEC79A5C0 - -// first sector of udisk -#define EFA2_UDSK_START 0x40 - -// -// EFA2 access functions -// - -// deactivate RTC ports -static inline void _EFA2_rtc_deactivate(void) { - REG_RTC_EN = 0; -} - -// unlock register access -static void _EFA2_reg_unlock(void) { - REG_EFA2_MAGIC_A = 0x0d200; - REG_EFA2_MAGIC_B = 0x01500; - REG_EFA2_MAGIC_C = 0x0d200; - REG_EFA2_MAGIC_D = 0x01500; -} - -// finish/lock register access -static inline void _EFA2_reg_lock(void) { - REG_EFA2_MAGIC_E = 0x1500; -} - -// global reset/init/enable/unlock ? -static void _EFA2_global_unlock(void) { - _EFA2_reg_unlock(); - *(vu16*)0x09880000 = 0x08000; - _EFA2_reg_lock(); -} - -// global lock, stealth mode -/*static void _EFA2_global_lock(void) { - // quite sure there is such a sequence, but haven't had - // a look for it upto now -}*/ - -// unlock NAND Flash -static void _EFA2_nand_unlock(void) { - _EFA2_reg_unlock(); - REG_EFA2_NAND_LOCK = 0x01500; - _EFA2_reg_lock(); -} - -// lock NAND Flash -static void _EFA2_nand_lock(void) { - _EFA2_reg_unlock(); - REG_EFA2_NAND_LOCK = 0x0d200; - _EFA2_reg_lock(); -} - -// -// Set NAND Flash chip enable and write protection bits ? -// -// val | ~CE | ~WP | -// -----+-----+-----+ -// 0 | 0 | 0 | -// 1 | 1 | 0 | -// 3 | 1 | 1 | -// -----+-----+-----+ -// -static void _EFA2_nand_enable(u16 val) { - _EFA2_reg_unlock(); - REG_EFA2_NAND_EN = val; - _EFA2_reg_lock(); -} - -// -// Perform NAND reset -// NAND has to be unlocked and enabled when called -// -static inline void _EFA2_nand_reset(void) { - REG_EFA2_NAND_CMD = 0xff; // write reset command -} - -// -// Read out NAND ID information, could be used for card detection -// -// | EFA2 1GBit | -// ------------------+------------+ -// maker code | 0xEC | -// device code | 0x79 | -// don't care | 0xA5 | -// multi plane code | 0xC0 | -// ------------------+------------+ -// -static u32 _EFA2_nand_id(void) { - u8 byte; - u32 id; - - _EFA2_nand_unlock(); - _EFA2_nand_enable(1); - - REG_EFA2_NAND_CMD = 0x90; // write id command - REG_EFA2_NAND_WR = 0x00; // (dummy) address cycle - byte = REG_EFA2_NAND_RD; // read maker code - id = byte; - byte = REG_EFA2_NAND_RD; // read device code - id = (id << 8) | byte; - byte = REG_EFA2_NAND_RD; // read don't care - id = (id << 8) | byte; - byte = REG_EFA2_NAND_RD; // read multi plane code - id = (id << 8) | byte; - - _EFA2_nand_enable(0); - _EFA2_nand_lock(); - return (id); -} - -// -// Start of gba_nds_fat block device description -// - -/*----------------------------------------------------------------- -EFA2_clearStatus -Reads and checks NAND status information -bool return OUT: true if NAND is idle ------------------------------------------------------------------*/ -static bool _EFA2_clearStatus (void) -{ - // tbd: currently there is no write support, so always return - // true, there is no possibility for pending operations - return true; -} - -/*----------------------------------------------------------------- -EFA2_isInserted -Checks to see if the NAND chip used by the EFA2 is present -bool return OUT: true if the correct NAND chip is found ------------------------------------------------------------------*/ -static bool _EFA2_isInserted (void) -{ - _EFA2_clearStatus(); - return (_EFA2_nand_id() == EFA2_NAND_ID); -} - -/*----------------------------------------------------------------- -EFA2_readSectors -Read "numSecs" 512 byte sectors starting from "sector" into "buffer" -No error correction, no use of spare cells, no use of R/~B signal -u32 sector IN: number of first 512 byte sector to be read -u32 numSecs IN: number of 512 byte sectors to read, -void* buffer OUT: pointer to 512 byte buffer to store data in -bool return OUT: true if successful ------------------------------------------------------------------*/ -static bool _EFA2_readSectors (u32 sector, u32 numSecs, void* buffer) -{ - int i; - -#ifndef _IO_ALLOW_UNALIGNED - u8 byte; - u16 word; -#endif - - // NAND page 0x40 (EFA2_UDSK_START) contains the MBR of the - // udisk and thus is sector 0. The original EFA2 firmware - // does never look at this, it only watches page 0x60, which - // contains the boot block of the FAT16 partition. That is - // fixed, so the EFA2 udisk must not be reformated, else - // the ARK Octopus and also the original Firmware won't be - // able to access the udisk anymore and I have to write a - // recovery tool. - u32 page = EFA2_UDSK_START + sector; - - // future enhancement: wait for possible write operations to - // be finisched - if (!_EFA2_clearStatus()) return false; - - _EFA2_nand_unlock(); - _EFA2_nand_enable(1); - _EFA2_nand_reset(); - - // set NAND to READ1 operation mode and transfer page address - REG_EFA2_NAND_CMD = 0x00; // write READ1 command - REG_EFA2_NAND_WR = 0x00; // write address [7:0] - REG_EFA2_NAND_WR = (page ) & 0xff; // write address [15:8] - REG_EFA2_NAND_WR = (page >> 8 ) & 0xff; // write address[23:16] - REG_EFA2_NAND_WR = (page >> 16) & 0xff; // write address[26:24] - - // Due to a bug in EFA2 design there is need to waste some cycles - // "by hand" instead the possibility to check the R/~B port of - // the NAND flash via a register. The RTC deactivation is only - // there to make sure the loop won't be optimized by the compiler - for (i=0 ; i < 3 ; i++) _EFA2_rtc_deactivate(); - - while (numSecs--) - { - // read page data -#ifdef _IO_ALLOW_UNALIGNED - // slow byte access to RAM, but works in principle - for (i=0 ; i < 512 ; i++) - ((u8*)buffer)[i] = REG_EFA2_NAND_RD; -#else - // a bit faster, but DMA is not possible - for (i=0 ; i < 256 ; i++) { - byte = REG_EFA2_NAND_RD; // read lo-byte - word = byte; - byte = REG_EFA2_NAND_RD; // read hi-byte - word = word | (byte << 8); - ((u16*)buffer)[i] = word; - } -#endif - } - - _EFA2_nand_enable(0); - _EFA2_nand_lock(); - return true; -} - - -/*----------------------------------------------------------------- -EFA2_writeSectors -Write "numSecs" 512 byte sectors starting at "sector" from "buffer" -u32 sector IN: address of 512 byte sector on card to write -u32 numSecs IN: number of 512 byte sectors to write -1 to 256 sectors can be written, 0 = 256 -void* buffer IN: pointer to 512 byte buffer to read data from -bool return OUT: true if successful ------------------------------------------------------------------*/ -static bool _EFA2_writeSectors (u32 sector, u8 numSecs, void* buffer) -{ - // Upto now I focused on reading NAND, write operations - // will follow - return false; -} - -/*----------------------------------------------------------------- -EFA2_shutdown -unload the EFA2 interface ------------------------------------------------------------------*/ -static bool _EFA2_shutdown(void) -{ - return _EFA2_clearStatus(); -} - -/*----------------------------------------------------------------- -EFA2_startUp -initializes the EFA2 card, returns true if successful, -otherwise returns false ------------------------------------------------------------------*/ -static bool _EFA2_startUp(void) -{ - _EFA2_global_unlock(); - return (_EFA2_nand_id() == EFA2_NAND_ID); -} - -/*----------------------------------------------------------------- -the actual interface structure ------------------------------------------------------------------*/ -const IO_INTERFACE _io_efa2 = { - DEVICE_TYPE_EFA2, - FEATURE_MEDIUM_CANREAD | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_EFA2_startUp, - (FN_MEDIUM_ISINSERTED)&_EFA2_isInserted, - (FN_MEDIUM_READSECTORS)&_EFA2_readSectors, - (FN_MEDIUM_WRITESECTORS)&_EFA2_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_EFA2_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_EFA2_shutdown -}; diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.h deleted file mode 100644 index d3a5e29c31..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - io_efa2.h by CyteX - - Based on io_mpfc.h by chishm (Michael Chisholm) - - Hardware Routines for reading the NAND flash located on - EFA2 flash carts - - Used with permission from Cytex. -*/ - -#ifndef IO_EFA2_H -#define IO_EFA2_H - -// 'EFA2' -#define DEVICE_TYPE_EFA2 0x32414645 - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_efa2; - -#endif // define IO_EFA2_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.c deleted file mode 100644 index c888db0a0a..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - io_fcsr.c based on - - compact_flash.c - By chishm (Michael Chisholm) - - Hardware Routines for using a GBA Flash Cart and SRAM as a - block device. - - The file system must be 512 byte aligned, in cart address space. - SRAM is supported. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "io_fcsr.h" - -#include <string.h> - -//--------------------------------------------------------------- -// DMA -#ifdef _IO_USE_DMA - #ifndef NDS - #include "gba_dma.h" - #else - #include <nds/dma.h> - #ifdef ARM9 - #include <nds/arm9/cache.h> - #endif - #endif -#endif - -#ifdef NDS - #define SRAM_START 0x0A000000 -#else - #define SRAM_START 0x0E000000 -#endif - -#define NO_SRAM 0xFFFFFFFF - -#define FCSR 0x52534346 -const char _FCSR_LabelString[] = " Chishm FAT"; - -u8* _FCSR_FileSysPointer = 0; -u8* _FCSR_SramSectorPointer[4] = {0,0,0,0}; -u32 _FCSR_SramSectorStart[4] = {0,0,0,0}; -u32 _FCSR_SramSectorEnd[4] = {0,0,0,0}; - -/*----------------------------------------------------------------- -_FCSR_isInserted -Is a GBA Flash Cart with a valid file system inserted? -bool return OUT: true if a GBA FC card is inserted ------------------------------------------------------------------*/ -static bool _FCSR_isInserted (void) -{ - bool flagFoundFileSys = false; - - u32* fileSysPointer = (u32*)0x08000100; // Start at beginning of cart address space, offset by expected location of string - - // Search for file system - while ((fileSysPointer < (u32*)0x0A000000) && !flagFoundFileSys) // Only search while not at end of cart address space - { - while ((*fileSysPointer != FCSR) && (fileSysPointer < (u32*)0x0A000000)) - fileSysPointer += 0x40; - if ((strncmp(_FCSR_LabelString, (char*)(fileSysPointer + 1), 12) == 0) && (fileSysPointer < (u32*)0x0A000000)) - { - flagFoundFileSys = true; - } else { - fileSysPointer += 0x80; - } - } - - return flagFoundFileSys; -} - - -/*----------------------------------------------------------------- -_FCSR_clearStatus -Finish any pending operations -bool return OUT: always true for GBA FC ------------------------------------------------------------------*/ -static bool _FCSR_clearStatus (void) -{ - return true; -} - - -/*----------------------------------------------------------------- -_FCSR_readSectors -Read 512 byte sector numbered "sector" into "buffer" -u32 sector IN: address of first 512 byte sector on Flash Cart to read -u32 numSectors IN: number of 512 byte sectors to read, - 1 to 256 sectors can be read -void* buffer OUT: pointer to 512 byte buffer to store data in -bool return OUT: true if successful ------------------------------------------------------------------*/ -static bool _FCSR_readSectors (u32 sector, u32 numSectors, void* buffer) -{ - int i; - bool flagSramSector = false; - int readLength = numSectors * BYTES_PER_READ; - u8* src; - u8* dst; - - // Find which region this read is in - for (i = 0; (i < 4) && !flagSramSector; i++) - { - if ((sector >= _FCSR_SramSectorStart[i]) && (sector < _FCSR_SramSectorEnd[i])) - { - flagSramSector = true; - break; - } - } - - // Make sure read will be completely in SRAM range if it is partially there - if ( flagSramSector && ((sector + numSectors) > _FCSR_SramSectorEnd[i])) - return false; - - // Copy data to buffer - if (flagSramSector) - { - src = _FCSR_SramSectorPointer[i] + (sector - _FCSR_SramSectorStart[i]) * BYTES_PER_READ; - } else { - src = _FCSR_FileSysPointer + sector * BYTES_PER_READ; - } - dst = (u8*)buffer; - - if (flagSramSector) - { - while (readLength--) - { - *dst++ = *src++; - } - } else { // Reading from Cart ROM - -#ifdef _IO_USE_DMA - #ifdef NDS - #ifdef ARM9 - DC_FlushRange( buffer, readLength); - #endif // ARM9 - DMA3_SRC = (u32)src; - DMA3_DEST = (u32)buffer; - DMA3_CR = (readLength >> 1) | DMA_COPY_HALFWORDS; - #else // ! NDS - DMA3COPY ( src, buffer, (readLength >> 1) | DMA16 | DMA_ENABLE); - #endif // NDS -#else // !_IO_USE_DMA - memcpy (buffer, src, readLength); -#endif // _IO_USE_DMA - - } // if (flagSramSector) - - return true; -} - -/*----------------------------------------------------------------- -_FCSR_writeSectors -Write 512 byte sector numbered "sector" from "buffer" -u32 sector IN: address of 512 byte sector on Flash Cart to read -u32 numSectors IN: number of 512 byte sectors to read, - 1 to 256 sectors can be read -void* buffer IN: pointer to 512 byte buffer to read data from -bool return OUT: true if successful ------------------------------------------------------------------*/ -static bool _FCSR_writeSectors (u32 sector, u8 numSectors, void* buffer) -{ - int i; - bool flagSramSector = false; - u32 writeLength = numSectors * BYTES_PER_READ; - u8* src = (u8*) buffer; - u8* dst; - - // Find which region this sector belongs in - for (i = 0; (i < 4) && !flagSramSector; i++) - { - if ((sector >= _FCSR_SramSectorStart[i]) && (sector < _FCSR_SramSectorEnd[i])) - { - flagSramSector = true; - break; - } - } - - if (!flagSramSector) - return false; - - // Entire write must be within an SRAM region - if ((sector + numSectors) > _FCSR_SramSectorEnd[i]) - return false; - - // Copy data to SRAM - dst = _FCSR_SramSectorPointer[i] + (sector - _FCSR_SramSectorStart[i]) * BYTES_PER_READ; - while (writeLength--) - { - *dst++ = *src++; - } - - return true; -} - -/*----------------------------------------------------------------- -_FCSR_shutdown -unload the Flash Cart interface ------------------------------------------------------------------*/ -static bool _FCSR_shutdown(void) -{ - int i; - if (_FCSR_clearStatus() == false) - return false; - - _FCSR_FileSysPointer = 0; - - for (i=0; i < 4; i++) - { - _FCSR_SramSectorPointer[i] = 0; - _FCSR_SramSectorStart[i] = 0; - _FCSR_SramSectorEnd[i] = 0; - } - return true; -} - -/*----------------------------------------------------------------- -_FCSR_startUp -initializes the Flash Cart interface, returns true if successful, -otherwise returns false ------------------------------------------------------------------*/ -static bool _FCSR_startUp(void) -{ - bool flagFoundFileSys = false; - int i; - int SramRegionSize[4]; - u8* srcByte; - u8* destByte; - - u32* fileSysPointer = (u32*)0x08000100; // Start at beginning of cart address space, offset by expected location of string - - // Search for file system - while ((fileSysPointer < (u32*)0x0A000000) && !flagFoundFileSys) // Only search while not at end of cart address space - { - while ((*fileSysPointer != FCSR) && (fileSysPointer < (u32*)0x0A000000)) - fileSysPointer += 0x40; - if ((strncmp(_FCSR_LabelString, (char*)(fileSysPointer + 1), 12) == 0) && (fileSysPointer < (u32*)0x0A000000)) - { - flagFoundFileSys = true; - } else { - fileSysPointer += 0x80; - } - } - - if (!flagFoundFileSys) - return false; - - // Flash cart file system pointer has been found - _FCSR_FileSysPointer = (u8*)(fileSysPointer - 0x40); - - // Get SRAM sector regions from header block - for (i = 0; i < 4; i++) - { - _FCSR_SramSectorStart[i] = fileSysPointer[i+4]; - SramRegionSize[i] = fileSysPointer[i+8]; - _FCSR_SramSectorEnd[i] = _FCSR_SramSectorStart[i] + SramRegionSize[i]; - } - - // Calculate SRAM region pointers - _FCSR_SramSectorPointer[0] = (u8*)(SRAM_START + 4); - for (i = 1; i < 4; i++) - { - _FCSR_SramSectorPointer[i] = _FCSR_SramSectorPointer[i-1] + (SramRegionSize[i-1] * BYTES_PER_READ); - } - - // Initialise SRAM with overlay if it hasn't been done so - if ( (*((u8*)SRAM_START) != 'F') || (*((u8*)(SRAM_START+1)) != 'C') || (*((u8*)(SRAM_START+2)) != 'S') || (*((u8*)(SRAM_START+3)) != 'R') ) - { - *((u8*)SRAM_START) = 'F'; - *((u8*)(SRAM_START+1)) = 'C'; - *((u8*)(SRAM_START+2)) = 'S'; - *((u8*)(SRAM_START+3)) = 'R'; - - for (i = 0; i < 4; i++) - { - srcByte = _FCSR_FileSysPointer + (_FCSR_SramSectorStart[i] * BYTES_PER_READ); - destByte = _FCSR_SramSectorPointer[i]; - while (srcByte < _FCSR_FileSysPointer + (_FCSR_SramSectorEnd[i] * BYTES_PER_READ) ) - *destByte++ = *srcByte++; - } - } - - // Get SRAM sector regions from header block - for (i = 0; i < 4; i++) - { - if (SramRegionSize[i] == 0) - { - _FCSR_SramSectorStart[i] = NO_SRAM; - _FCSR_SramSectorEnd[i] = NO_SRAM; - } - } - - return true; -} - -/*----------------------------------------------------------------- -the actual interface structure ------------------------------------------------------------------*/ -const IO_INTERFACE _io_fcsr = { - DEVICE_TYPE_FCSR, // 'FCSR' - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_FCSR_startUp, - (FN_MEDIUM_ISINSERTED)&_FCSR_isInserted, - (FN_MEDIUM_READSECTORS)&_FCSR_readSectors, - (FN_MEDIUM_WRITESECTORS)&_FCSR_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_FCSR_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_FCSR_shutdown -} ; diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.h deleted file mode 100644 index 19b2537960..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - io_fcsr.h - - Hardware Routines for using a GBA Flash Cart with SRAM - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_FCSR_H -#define IO_FCSR_H - -// 'FCSR' -#define DEVICE_TYPE_FCSR 0x52534346 - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_fcsr ; - -#endif // define IO_FCSR_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3_common.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3_common.c deleted file mode 100644 index 9c8280c808..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3_common.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - io_m3_common.c - - Routines common to all version of the M3 - - Some code based on M3 SD drivers supplied by M3Adapter. - Some code written by SaTa may have been unknowingly used. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "io_m3_common.h" - -static u16 _M3_readHalfword (u32 addr) { - return *((vu16*)addr); -} - -void _M3_changeMode (u32 mode) { - _M3_readHalfword (0x08e00002); - _M3_readHalfword (0x0800000e); - _M3_readHalfword (0x08801ffc); - _M3_readHalfword (0x0800104a); - _M3_readHalfword (0x08800612); - _M3_readHalfword (0x08000000); - _M3_readHalfword (0x08801b66); - _M3_readHalfword (0x08000000 + (mode << 1)); - _M3_readHalfword (0x0800080e); - _M3_readHalfword (0x08000000); - - if ((mode & 0x0f) != 4) { - _M3_readHalfword (0x09000000); - } else { - _M3_readHalfword (0x080001e4); - _M3_readHalfword (0x080001e4); - _M3_readHalfword (0x08000188); - _M3_readHalfword (0x08000188); - } -} - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3_common.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3_common.h deleted file mode 100644 index 6d0c669783..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3_common.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - io_m3_common.h - - Routines common to all version of the M3 - - Some code based on M3 SD drivers supplied by M3Adapter. - Some code written by SaTa may have been unknowingly used. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_M3_COMMON_H -#define IO_M3_COMMON_H - -#include "disc_io.h" - -// Values for changing mode -#define M3_MODE_ROM 0x00400004 -#define M3_MODE_MEDIA 0x00400003 - -extern void _M3_changeMode (u32 mode); - -#endif // IO_M3_COMMON_H - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3cf.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3cf.c deleted file mode 100644 index 2db8eec894..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3cf.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - io_m3cf.c based on - - compact_flash.c - By chishm (Michael Chisholm) - - Hardware Routines for reading a compact flash card - using the M3 Perfect CF Adapter - - CF routines modified with help from Darkfader - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "io_m3cf.h" -#include "io_m3_common.h" -#include "io_cf_common.h" - -//--------------------------------------------------------------- -// DMA -#ifdef _IO_USE_DMA - #ifndef NDS - #include "gba_dma.h" - #else - #include <nds/dma.h> - #ifdef ARM9 - #include <nds/arm9/cache.h> - #endif - #endif -#endif - -//--------------------------------------------------------------- -// M3 CF Addresses -#define REG_M3CF_STS ((vu16*)0x080C0000) // Status of the CF Card / Device control -#define REG_M3CF_CMD ((vu16*)0x088E0000) // Commands sent to control chip and status return -#define REG_M3CF_ERR ((vu16*)0x08820000) // Errors / Features - -#define REG_M3CF_SEC ((vu16*)0x08840000) // Number of sector to transfer -#define REG_M3CF_LBA1 ((vu16*)0x08860000) // 1st byte of sector address -#define REG_M3CF_LBA2 ((vu16*)0x08880000) // 2nd byte of sector address -#define REG_M3CF_LBA3 ((vu16*)0x088A0000) // 3rd byte of sector address -#define REG_M3CF_LBA4 ((vu16*)0x088C0000) // last nibble of sector address | 0xE0 - -#define REG_M3CF_DATA ((vu16*)0x08800000) // Pointer to buffer of CF data transered from card - -static const CF_REGISTERS _M3CF_Registers = { - REG_M3CF_DATA, - REG_M3CF_STS, - REG_M3CF_CMD, - REG_M3CF_ERR, - REG_M3CF_SEC, - REG_M3CF_LBA1, - REG_M3CF_LBA2, - REG_M3CF_LBA3, - REG_M3CF_LBA4 -}; - - -static bool _M3CF_startup(void) { - _M3_changeMode (M3_MODE_MEDIA); - return _CF_startup (&_M3CF_Registers); -} - - -const IO_INTERFACE _io_m3cf = { - DEVICE_TYPE_M3CF, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_M3CF_startup, - (FN_MEDIUM_ISINSERTED)&_CF_isInserted, - (FN_MEDIUM_READSECTORS)&_CF_readSectors, - (FN_MEDIUM_WRITESECTORS)&_CF_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_CF_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_CF_shutdown -} ; diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3cf.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3cf.h deleted file mode 100644 index c72da0b4a2..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3cf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - io_m3cf.h - - Hardware Routines for reading a compact flash card - using the M3 CF - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_M3CF_H -#define IO_M3CF_H - -// 'M3CF' -#define DEVICE_TYPE_M3CF 0x4643334D - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_m3cf ; - -#endif // define IO_M3CF_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3sd.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3sd.c deleted file mode 100644 index b5b3173a9d..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3sd.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - io_m3sd.c - - Hardware Routines for reading a Secure Digital card - using the M3 SD - - Some code based on M3 SD drivers supplied by M3Adapter. - Some code written by SaTa may have been unknowingly used. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-25 - Chishm - * Improved startup function that doesn't delay hundreds of seconds - before reporting no card inserted. - * Fixed writeData function to timeout on error - * writeSectors function now wait until the card is ready before continuing with a transfer - - 2006-08-05 - Chishm - * Tries multiple times to get a Relative Card Address at startup - - 2006-08-07 - Chishm - * Moved the SD initialization to a common function -*/ - -#include "io_m3sd.h" -#include "io_sd_common.h" -#include "io_m3_common.h" - -//--------------------------------------------------------------- -// M3SD register addresses - -#define REG_M3SD_DIR (*(vu16*)0x08800000) // direction control register -#define REG_M3SD_DAT (*(vu16*)0x09000000) // SD data line, 8 bits at a time -#define REG_M3SD_CMD (*(vu16*)0x09200000) // SD command byte -#define REG_M3SD_ARGH (*(vu16*)0x09400000) // SD command argument, high halfword -#define REG_M3SD_ARGL (*(vu16*)0x09600000) // SD command argument, low halfword -#define REG_M3SD_STS (*(vu16*)0x09800000) // command and status register - -//--------------------------------------------------------------- -// Send / receive timeouts, to stop infinite wait loops -#define NUM_STARTUP_CLOCKS 100 // Number of empty (0xFF when sending) bytes to send/receive to/from the card -#define TRANSMIT_TIMEOUT 20000 // Time to wait for the M3 to respond to transmit or receive requests -#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up -#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing - -//--------------------------------------------------------------- -// Variables required for tracking SD state -static u32 _M3SD_relativeCardAddress = 0; // Preshifted Relative Card Address - -//--------------------------------------------------------------- -// Internal M3 SD functions - -static inline void _M3SD_unlock (void) { - _M3_changeMode (M3_MODE_MEDIA); -} - -static inline bool _M3SD_waitOnBusy (void) { - int i = 0; - while ( (REG_M3SD_STS & 0x01) == 0x00) { - i++; - if (i >= TRANSMIT_TIMEOUT) { - return false; - } - } - return true; -} - -static inline bool _M3SD_waitForDataReady (void) { - int i = 0; - while ( (REG_M3SD_STS & 0x40) == 0x00) { - i++; - if (i >= TRANSMIT_TIMEOUT) { - return false; - } - } - return true; -} - - -static bool _M3SD_sendCommand (u16 command, u32 argument) { - REG_M3SD_STS = 0x8; - REG_M3SD_CMD = 0x40 + command; // Include the start bit - REG_M3SD_ARGH = argument >> 16; - REG_M3SD_ARGL = argument; - // The CRC7 of the command is calculated by the M3 - - REG_M3SD_DIR=0x29; - if (!_M3SD_waitOnBusy()) { - REG_M3SD_DIR=0x09; - return false; - } - REG_M3SD_DIR=0x09; - return true; -} - -static bool _M3SD_sendByte (u8 byte) { - int i = 0; - REG_M3SD_DAT = byte; - REG_M3SD_DIR = 0x03; - REG_M3SD_STS = 0x01; - while ((REG_M3SD_STS & 0x04) == 0) { - i++; - if (i >= TRANSMIT_TIMEOUT) { - return false; - } - } - return true; -} - -static u8 _M3SD_getByte (void) { - int i; - // Request 8 bits of data from the SD's CMD pin - REG_M3SD_DIR = 0x02; - REG_M3SD_STS = 0x02; - // Wait for the data to be ready - i = 0; - while ((REG_M3SD_STS & 0x08) == 0) { - i++; - if (i >= TRANSMIT_TIMEOUT) { - // Return an empty byte if a timeout occurs - return 0xFF; - } - } - i = 0; - while ((REG_M3SD_STS & 0x08) != 0) { - i++; - if (i >= TRANSMIT_TIMEOUT) { - // Return an empty byte if a timeout occurs - return 0xFF; - } - } - // Return the data - return (REG_M3SD_DAT & 0xff); -} - -// Returns the response from the SD card to a previous command. -static bool _M3SD_getResponse (u8* dest, u32 length) { - u32 i; - u8 dataByte; - int shiftAmount; - - // Wait for the card to be non-busy - for (i = 0; i < RESPONSE_TIMEOUT; i++) { - dataByte = _M3SD_getByte(); - if (dataByte != SD_CARD_BUSY) { - break; - } - } - - if (dest == NULL) { - return true; - } - - // Still busy after the timeout has passed - if (dataByte == 0xff) { - return false; - } - - // Read response into buffer - for ( i = 0; i < length; i++) { - dest[i] = dataByte; - dataByte = _M3SD_getByte(); - } - // dataByte will contain the last piece of the response - - // Send 16 more clocks, 8 more than the delay required between a response and the next command - i = _M3SD_getByte(); - i = _M3SD_getByte(); - - // Shift response so that the bytes are correctly aligned - // The register may not contain properly aligned data - for (shiftAmount = 0; ((dest[0] << shiftAmount) & 0x80) != 0x00; shiftAmount++) { - if (shiftAmount >= 7) { - return false; - } - } - - for (i = 0; i < length - 1; i++) { - dest[i] = (dest[i] << shiftAmount) | (dest[i+1] >> (8-shiftAmount)); - } - // Get the last piece of the response from dataByte - dest[i] = (dest[i] << shiftAmount) | (dataByte >> (8-shiftAmount)); - - return true; -} - - -static inline bool _M3SD_getResponse_R1 (u8* dest) { - return _M3SD_getResponse (dest, 6); -} - -static inline bool _M3SD_getResponse_R1b (u8* dest) { - return _M3SD_getResponse (dest, 6); -} - -static inline bool _M3SD_getResponse_R2 (u8* dest) { - return _M3SD_getResponse (dest, 17); -} - -static inline bool _M3SD_getResponse_R3 (u8* dest) { - return _M3SD_getResponse (dest, 6); -} - -static inline bool _M3SD_getResponse_R6 (u8* dest) { - return _M3SD_getResponse (dest, 6); -} - -static void _M3SD_sendClocks (u32 numClocks) { - while (numClocks--) { - _M3SD_sendByte(0xff); - } -} - -static void _M3SD_getClocks (u32 numClocks) { - while (numClocks--) { - _M3SD_getByte(); - } -} - -static bool _M3SD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) { - _M3SD_sendCommand (command, data); - return _M3SD_getResponse (responseBuffer, 6); -} - -static bool _M3SD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) { - _M3SD_sendCommand (command, data); - return _M3SD_getResponse (responseBuffer, 17); -} - -static bool _M3SD_initCard (void) { - // Give the card time to stabilise - _M3SD_sendClocks (NUM_STARTUP_CLOCKS); - - // Reset the card - if (!_M3SD_sendCommand (GO_IDLE_STATE, 0)) { - return false; - } - - _M3SD_getClocks (NUM_STARTUP_CLOCKS); - - // Card is now reset, including it's address - _M3SD_relativeCardAddress = 0; - - // Init the card - return _SD_InitCard (_M3SD_cmd_6byte_response, - _M3SD_cmd_17byte_response, - true, - &_M3SD_relativeCardAddress); -} - -static bool _M3SD_readData (void* buffer) { - u32 i; - u8* buff_u8 = (u8*)buffer; - u16* buff = (u16*)buffer; - u16 temp; - - REG_M3SD_DIR = 0x49; - if (!_M3SD_waitForDataReady()) { - REG_M3SD_DIR = 0x09; - return false; - } - REG_M3SD_DIR = 0x09; - - REG_M3SD_DIR = 0x8; - REG_M3SD_STS = 0x4; - - i = REG_M3SD_DIR; - // Read data - i=256; - if ((u32)buff_u8 & 0x01) { - while(i--) - { - temp = REG_M3SD_DIR; - *buff_u8++ = temp & 0xFF; - *buff_u8++ = temp >> 8; - } - } else { - while(i--) - *buff++ = REG_M3SD_DIR; - } - // Read end checksum - i = REG_M3SD_DIR + REG_M3SD_DIR + REG_M3SD_DIR + REG_M3SD_DIR; - - return true; -} - -static void _M3SD_clkout (void) { - REG_M3SD_DIR = 0x4; - REG_M3SD_DIR = 0xc; -/* __asm volatile ( - "ldr r1, =0x08800000 \n" - "mov r0, #0x04 \n" - "strh r0, [r1] \n" - "mov r0, r0 \n" - "mov r0, r0 \n" - "mov r0, #0x0c \n" - "strh r0, [r1] \n" - : // Outputs - : // Inputs - : "r0", "r1" // Clobber list - );*/ -} - -static void _M3SD_clkin (void) { - REG_M3SD_DIR = 0x0; - REG_M3SD_DIR = 0x8; -/* __asm volatile ( - "ldr r1, =0x08800000 \n" - "mov r0, #0x00 \n" - "strh r0, [r1] \n" - "mov r0, r0 \n" - "mov r0, r0 \n" - "mov r0, #0x08 \n" - "strh r0, [r1] \n" - : // Outputs - : // Inputs - : "r0", "r1" // Clobber list - );*/ -} - -static bool _M3SD_writeData (u8* data, u8* crc) { - int i; - u8 temp; - - do { - _M3SD_clkin(); - } while ((REG_M3SD_DAT & 0x100) == 0); - - REG_M3SD_DAT = 0; // Start bit - - _M3SD_clkout(); - - for (i = 0; i < BYTES_PER_READ; i++) { - temp = (*data++); - REG_M3SD_DAT = temp >> 4; - _M3SD_clkout(); - REG_M3SD_DAT = temp; - _M3SD_clkout(); - } - - if (crc != NULL) { - for (i = 0; i < 8; i++) { - temp = (*crc++); - REG_M3SD_DAT = temp >> 4; - _M3SD_clkout(); - REG_M3SD_DAT = temp; - _M3SD_clkout(); - } - } - - i = 32; - while (i--) { - temp += 2; // a NOP to stop the compiler optimising out the loop - } - - for (i = 0; i < 32; i++) { - REG_M3SD_DAT = 0xff; - _M3SD_clkout(); - } - - do { - _M3SD_clkin(); - } while ((REG_M3SD_DAT & 0x100) == 0); - - return true; -} - -//--------------------------------------------------------------- -// Functions needed for the external interface - -static bool _M3SD_startUp (void) { - _M3SD_unlock(); - return _M3SD_initCard(); -} - -static bool _M3SD_isInserted (void) { - u8 responseBuffer [6]; - // Make sure the card receives the command - if (!_M3SD_sendCommand (SEND_STATUS, 0)) { - return false; - } - // Make sure the card responds - if (!_M3SD_getResponse_R1 (responseBuffer)) { - return false; - } - // Make sure the card responded correctly - if (responseBuffer[0] != SEND_STATUS) { - return false; - } - return true; -} - -static bool _M3SD_readSectors (u32 sector, u32 numSectors, void* buffer) { - u32 i; - u8* dest = (u8*) buffer; - u8 responseBuffer[6]; - - if (numSectors == 1) { - // If it's only reading one sector, use the (slightly faster) READ_SINGLE_BLOCK - if (!_M3SD_sendCommand (READ_SINGLE_BLOCK, sector * BYTES_PER_READ)) { - return false; - } - - if (!_M3SD_readData (buffer)) { - return false; - } - - } else { - // Stream the required number of sectors from the card - if (!_M3SD_sendCommand (READ_MULTIPLE_BLOCK, sector * BYTES_PER_READ)) { - return false; - } - - for(i=0; i < numSectors; i++, dest+=BYTES_PER_READ) { - if (!_M3SD_readData(dest)) { - return false; - } - REG_M3SD_STS = 0x8; - } - - // Stop the streaming - _M3SD_sendCommand (STOP_TRANSMISSION, 0); - _M3SD_getResponse_R1b (responseBuffer); - } - - return true; -} - -static bool _M3SD_writeSectors (u32 sector, u32 numSectors, const void* buffer) { - u8 crc[8]; - u8 responseBuffer[6]; - u32 offset = sector * BYTES_PER_READ; - u8* data = (u8*) buffer; - int i; - // Precalculate the data CRC - _SD_CRC16 ( data, BYTES_PER_READ, crc); - - while (numSectors--) { - // Send a single sector write command - _M3SD_sendCommand (WRITE_BLOCK, offset); - if (!_M3SD_getResponse_R1 (responseBuffer)) { - return false; - } - - REG_M3SD_DIR = 0x4; - REG_M3SD_STS = 0x0; - - // Send the data - if (! _M3SD_writeData( data, crc)) { - return false; - } - - if (numSectors > 0) { - offset += BYTES_PER_READ; - data += BYTES_PER_READ; - // Calculate the next CRC while waiting for the card to finish writing - _SD_CRC16 ( data, BYTES_PER_READ, crc); - } - - // Wait for the card to be ready for the next transfer - i = WRITE_TIMEOUT; - responseBuffer[3] = 0; - do { - _M3SD_sendCommand (SEND_STATUS, _M3SD_relativeCardAddress); - _M3SD_getResponse_R1 (responseBuffer); - i--; - if (i <= 0) { - return false; - } - } while (((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA))); - } - - return true; - -} - -static bool _M3SD_clearStatus (void) { - return _M3SD_initCard (); -} - -static bool _M3SD_shutdown (void) { - _M3_changeMode (M3_MODE_ROM); - return true; -} - -const IO_INTERFACE _io_m3sd = { - DEVICE_TYPE_M3SD, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_M3SD_startUp, - (FN_MEDIUM_ISINSERTED)&_M3SD_isInserted, - (FN_MEDIUM_READSECTORS)&_M3SD_readSectors, - (FN_MEDIUM_WRITESECTORS)&_M3SD_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_M3SD_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_M3SD_shutdown -} ; - - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3sd.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3sd.h deleted file mode 100644 index 0e4d32b540..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_m3sd.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - io_m3sd.h - - Hardware Routines for reading a Secure Digital card - using the M3 SD - - Some code based on M3 SD drivers supplied by M3Adapter. - Some code written by SaTa may have been unknowingly used. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_M3SD_H -#define IO_M3SD_H - -// 'M3SD' -#define DEVICE_TYPE_M3SD 0x4453334D - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_m3sd ; - -#endif // define IO_M3SD_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_mpcf.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_mpcf.c deleted file mode 100644 index 3dcafc193e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_mpcf.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - io_mpcf.c based on - - compact_flash.c - By chishm (Michael Chisholm) - - Hardware Routines for reading a compact flash card - using the GBA Movie Player - - CF routines modified with help from Darkfader - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "io_mpcf.h" -#include "io_cf_common.h" - -//--------------------------------------------------------------- -// DMA -#ifdef _IO_USE_DMA - #ifndef NDS - #include "gba_dma.h" - #else - #include <nds/dma.h> - #ifdef ARM9 - #include <nds/arm9/cache.h> - #endif - #endif -#endif - -//--------------------------------------------------------------- -// GBAMP CF Addresses -#define REG_MPCF_STS ((vu16*)0x098C0000) // Status of the CF Card / Device control -#define REG_MPCF_CMD ((vu16*)0x090E0000) // Commands sent to control chip and status return -#define REG_MPCF_ERR ((vu16*)0x09020000) // Errors / Features - -#define REG_MPCF_SEC ((vu16*)0x09040000) // Number of sector to transfer -#define REG_MPCF_LBA1 ((vu16*)0x09060000) // 1st byte of sector address -#define REG_MPCF_LBA2 ((vu16*)0x09080000) // 2nd byte of sector address -#define REG_MPCF_LBA3 ((vu16*)0x090A0000) // 3rd byte of sector address -#define REG_MPCF_LBA4 ((vu16*)0x090C0000) // last nibble of sector address | 0xE0 - -#define REG_MPCF_DATA ((vu16*)0x09000000) // Pointer to buffer of CF data transered from card - -static const CF_REGISTERS _MPCF_Registers = { - REG_MPCF_DATA, - REG_MPCF_STS, - REG_MPCF_CMD, - REG_MPCF_ERR, - REG_MPCF_SEC, - REG_MPCF_LBA1, - REG_MPCF_LBA2, - REG_MPCF_LBA3, - REG_MPCF_LBA4 -}; - -/*----------------------------------------------------------------- -_MPCF_startup -initializes the CF interface, returns true if successful, -otherwise returns false ------------------------------------------------------------------*/ -static bool _MPCF_startup(void) { - return _CF_startup(&_MPCF_Registers); -} - -/*----------------------------------------------------------------- -the actual interface structure ------------------------------------------------------------------*/ -const IO_INTERFACE _io_mpcf = { - DEVICE_TYPE_MPCF, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_MPCF_startup, - (FN_MEDIUM_ISINSERTED)&_CF_isInserted, - (FN_MEDIUM_READSECTORS)&_CF_readSectors, - (FN_MEDIUM_WRITESECTORS)&_CF_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_CF_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_CF_shutdown -} ; diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_mpcf.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_mpcf.h deleted file mode 100644 index fc5770e18d..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_mpcf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - io_mpcf.h - - Hardware Routines for reading a compact flash card - using the GBA Movie Player - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_MPCF_H -#define IO_MPCF_H - -// 'MPCF' -#define DEVICE_TYPE_MPCF 0x4643504D - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_mpcf ; - -#endif // define IO_MPCF_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_njsd.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_njsd.c deleted file mode 100644 index e394076e5c..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_njsd.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - io_njsd.c - - Hardware Routines for reading an SD card using - a NinjaDS SD adapter. - - Original code supplied by NinjaMod - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-05 - Chishm - * First release - - 2006-08-06 - Chishm - * Removed unneeded _NJSD_writeRAM function - * Removed casts for calls to cardWriteCommand - - 2006-08-07 - Chishm - * Moved the SD initialization to a common function -*/ - -#include "io_njsd.h" - -#ifdef NDS - -#include <nds.h> -#include <string.h> -#include "io_sd_common.h" - -#define _NJSD_SYNC - -//--------------------------------------------------------------- -// Card communication speeds -#define SD_CLK_167KHz 00 -#define SD_CLK_250KHz 01 -#define SD_CLK_5MHz 02 -#define SD_CLK_25MHz 03 - -//--------------------------------------------------------------- -// Response types -#define SD_RSP_48 0 -#define SD_RSP_136 1 -#define SD_RSP_DATA 2 -#define SD_RSP_STREAM 3 - -//--------------------------------------------------------------- -// Send / receive timeouts, to stop infinite wait loops -#define IRQ_TIMEOUT 1000000 -#define RESET_TIMEOUT 10000 -#define COMMAND_TIMEOUT 100000 -#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing - - -static const u8 _NJSD_read_cmd[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}; -static const u8 _NJSD_read_end_cmd[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x41}; - -static int _NJSD_speed = SD_CLK_5MHz; // Default speed; - -static u32 _NJSD_cardFlags; - -static u32 _NJSD_relativeCardAddress = 0; - -static inline bool _NJSD_waitIRQ(void) { - int i = IRQ_TIMEOUT; - while (!(REG_IF & 0x100000) && --i); - REG_IF = 0x100000; - if (i <= 0) { - return false; - } else { - return true; - } -} - -static inline void _NJSD_writeCardCommand - (u8 cmd0, u8 cmd1, u8 cmd2, u8 cmd3, u8 cmd4, u8 cmd5, u8 cmd6, u8 cmd7) -{ - CARD_COMMAND[0] = cmd0; - CARD_COMMAND[1] = cmd1; - CARD_COMMAND[2] = cmd2; - CARD_COMMAND[3] = cmd3; - CARD_COMMAND[4] = cmd4; - CARD_COMMAND[5] = cmd5; - CARD_COMMAND[6] = cmd6; - CARD_COMMAND[7] = cmd7; -} - -static bool _NJSD_reset (void) { - int i; - CARD_CR1H = CARD_CR1_ENABLE; - _NJSD_writeCardCommand (0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - CARD_CR2 = 0xA0406000; - i = RESET_TIMEOUT; - while ((CARD_CR2 & CARD_BUSY) && --i); - if (i <= 0) { - return false; - } - - return true; -} - -static bool _NJSD_init (u32 flags) { - _NJSD_cardFlags = flags; - - REG_IF = 0x100000; // Clear cart IRQ. - - irqDisable (IRQ_CARD_LINE); - - if (! _NJSD_reset() ) { - return false; - } - return true; -} - -static bool _NJSD_sendCMDR (int speed, u8 *rsp_buf, int type, u8 cmd, u32 param) { - int i; - u32 data; - -#ifdef _NJSD_SYNC - u32 old_REG_IME; - old_REG_IME = REG_IME; - REG_IME = 0; -#endif - - REG_IF = 0x100000; - - CARD_CR1H = CARD_CR1_ENABLE; - - if ((type & 3) < 2) { - CARD_COMMAND[0] = 0xF0 | (speed << 2) | 1 | (type << 1); - } else if ((type & 3) == 2) { - CARD_COMMAND[0] = 0xE0 | (speed << 2) | 0 | (1 << 1); - } else { - CARD_COMMAND[0] = 0xF0 | (speed << 2) | 0 | (1 << 1); - } - - CARD_COMMAND[1] = (type & 0x40) | ((( type >> 2) & 7) << 3); - CARD_COMMAND[2] = 0x40 | cmd; - CARD_COMMAND[3] = (param>>24) & 0xFF; - CARD_COMMAND[4] = (param>>16) & 0xFF; - CARD_COMMAND[5] = (param>>8) & 0xFF; - CARD_COMMAND[6] = (param>>0) & 0xFF; - CARD_COMMAND[7] = 0; // offset = 0 - - if ((type & 3) < 2) { - CARD_CR2 = _NJSD_cardFlags | 0x01000000; - - // wait for ninja DS to be done! - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - i = 0; - do { - // Read data if available - if (CARD_CR2 & CARD_DATA_READY) { - data=CARD_DATA_RD; - if (rsp_buf != NULL) { - if (i == 4) { - rsp_buf[0] = (data>>0)&0xFF; - rsp_buf[1] = (data>>8)&0xFF; - rsp_buf[2] = (data>>16)&0xFF; - rsp_buf[3] = (data>>24)&0xFF; - } else if (i == 5) { - rsp_buf[4] = (data>>0)&0xFF; - rsp_buf[5] = (data>>8)&0xFF; - } - } - i++; - } - } while (CARD_CR2 & CARD_BUSY); - } else { - CARD_CR2 = _NJSD_cardFlags; - while (CARD_CR2 & CARD_BUSY); - - // wait for ninja DS to be done! - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - } - -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return true; -} - -static bool _NJSD_writeSector (u8 *buffer, u8 *crc_buf, u32 offset) { - int i; - u8 responseBuffer[6]; - u32 data; - -#ifdef _NJSD_SYNC - u32 old_REG_IME; - old_REG_IME = REG_IME; - REG_IME = 0; -#endif - - CARD_CR1H = CARD_CR1_ENABLE; - _NJSD_writeCardCommand (0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - CARD_CR2 = 0xA0406000; - i = COMMAND_TIMEOUT; - while ((CARD_CR2 & CARD_BUSY) && --i); - if (i <= 0) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - for (i = 0; i < 65; i++) - { - CARD_CR1H = CARD_CR1_ENABLE; // | CARD_CR1_IRQ; - if (i < 64) - { - _NJSD_writeCardCommand (buffer[i*8+0], buffer[i*8+1], buffer[i*8+2], buffer[i*8+3], - buffer[i*8+4], buffer[i*8+5], buffer[i*8+6], buffer[i*8+7]); - } else { - _NJSD_writeCardCommand (crc_buf[0], crc_buf[1], crc_buf[2], crc_buf[3], - crc_buf[4], crc_buf[5], crc_buf[6], crc_buf[7]); - } - CARD_CR2 = 0xA7406000; - - do { - // Read data if available - if (CARD_CR2 & CARD_DATA_READY) { - data=CARD_DATA_RD; - } - } while (CARD_CR2 & CARD_BUSY); - } - - CARD_CR1H = CARD_CR1_ENABLE; - _NJSD_writeCardCommand (0xF0 | (1 << 2) | 1, 0x80, 0x40 | WRITE_BLOCK, (u8)(offset>>24), - (u8)(offset>>16), (u8)(offset>>8), (u8)(offset>>0), 0x00); - CARD_CR2 = 0xA7406000; - - // wait for ninja DS to be done! - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - i = 0; - do { - // Read data if available - if (CARD_CR2 & CARD_DATA_READY) { - data = CARD_DATA_RD; - if (i == 2) { - responseBuffer[0] = (u8)(data>>0); - responseBuffer[1] = (u8)(data>>8); - responseBuffer[2] = (u8)(data>>16); - responseBuffer[3] = (u8)(data>>24); - } else if (i == 3) { - responseBuffer[4] = (u8)(data>>0); - responseBuffer[5] = (u8)(data>>8); - } - i++; - } - } while (CARD_CR2 & CARD_BUSY); - - i = WRITE_TIMEOUT; - responseBuffer[3] = 0; - do { - _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SEND_STATUS, _NJSD_relativeCardAddress); - i--; - if (i <= 0) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - } while (((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA))); - - -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - - return true; -} - -static bool _NJSD_sendCLK (int speed, int count) { - int i; - -#ifdef _NJSD_SYNC - u32 old_REG_IME; - old_REG_IME = REG_IME; - REG_IME = 0; - - REG_IF = 0x100000; -#endif - - //CARD_CR1H = CARD_CR1_ENABLE; // | CARD_CR1_IRQ; - _NJSD_writeCardCommand (0xE0 | ((speed & 3) << 2), 0, (count - 1), 0, 0, 0, 0, 0); - - CARD_CR2 = _NJSD_cardFlags; - i = COMMAND_TIMEOUT; - while ((CARD_CR2 & CARD_BUSY) && --i); - if (i <= 0) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - // wait for ninja DS to be done! - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return true; -} - -static bool _NJSD_sendCMDN (int speed, u8 cmd, u32 param) { - int i; - -#ifdef _NJSD_SYNC - u32 old_REG_IME; - old_REG_IME = REG_IME; - REG_IME = 0; -#endif - - REG_IF = 0x100000; - - CARD_CR1H = CARD_CR1_ENABLE; // | CARD_CR1_IRQ; - _NJSD_writeCardCommand (0xF0 | ((speed & 3) << 2), 0x00, 0x40 | cmd, (param>>24) & 0xFF, - (param>>16) & 0xFF, (param>>8) & 0xFF, (param>>0) & 0xFF, 0x00); - - CARD_CR2 = _NJSD_cardFlags; - i = COMMAND_TIMEOUT; - while ((CARD_CR2 & CARD_BUSY) && --i); - if (i <= 0) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - // wait for ninja DS to be done! - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return true; -} - -static bool _NJSD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) { - return _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, command, data); -} - -static bool _NJSD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) { - return _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_136, command, data); -} - -static bool _NJSD_cardInit (void) { - // If the commands succeed the first time, assume they'll always succeed - if (! _NJSD_sendCLK (SD_CLK_167KHz, 256) ) { - return false; - } - if (! _NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0) ) { - return false; - } - _NJSD_sendCLK (SD_CLK_167KHz, 8); - - _NJSD_sendCLK (SD_CLK_167KHz, 256); - _NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0); - _NJSD_sendCLK (SD_CLK_167KHz, 8); - - return _SD_InitCard (_NJSD_cmd_6byte_response, - _NJSD_cmd_17byte_response, - true, - &_NJSD_relativeCardAddress); -} - - -static bool _NJSD_isInserted(void) { - u8 responseBuffer [8]; - _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SEND_STATUS, 0); - - // Make sure the card responded correctly - if (responseBuffer[0] != SEND_STATUS) { - return false; - } - return true; -} - -static bool _NJSD_clearStatus (void) { - return _NJSD_reset(); -} - -static bool _NJSD_shutdown(void) { - return _NJSD_clearStatus(); -} - -static bool _NJSD_startup(void) { - if (! _NJSD_init(0xA0406000) ) { - return false; - } - if (! _NJSD_cardInit() ) { - return false; - } - return true; -} - - -static bool _NJSD_writeSectors (u32 sector, u32 numSectors, const void* buffer) { - u8 crc[8]; - u32 offset = sector * BYTES_PER_READ; - u8* data = (u8*) buffer; - - while (numSectors--) { - _SD_CRC16 ( data, BYTES_PER_READ, crc); - - if (! _NJSD_writeSector (data, crc, offset)) { - return false; - } - offset += BYTES_PER_READ; - data += BYTES_PER_READ; - } - return true; -} - -#ifdef _IO_ALLOW_UNALIGNED -static bool _NJSD_readSectors (u32 sector, u32 numSectors, void* buffer) { - u32 tmp[BYTES_PER_READ>>2]; - int i; - -#ifdef _NJSD_SYNC - u32 old_REG_IME; -#endif - - u8* tbuf = (u8*)buffer; - - if (numSectors == 0) { - return false; - } - -#ifdef _NJSD_SYNC - old_REG_IME = REG_IME; - REG_IME = 0; -#endif - - if (numSectors > 1) { - _NJSD_sendCMDR (_NJSD_speed, NULL, SD_RSP_DATA, READ_MULTIPLE_BLOCK, sector * BYTES_PER_READ); - for (i = 0; i < numSectors - 2; i++) { - if (((int)buffer & 0x03) != 0){ - cardPolledTransfer (0xA1406000, tmp, BYTES_PER_READ, _NJSD_read_cmd); - memcpy (tbuf + i * BYTES_PER_READ, tmp, BYTES_PER_READ); - } else { - cardPolledTransfer (0xA1406000, (u32*)(tbuf + i * BYTES_PER_READ), BYTES_PER_READ, _NJSD_read_cmd); - } - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - } - if (((int)buffer & 0x03) != 0){ - cardPolledTransfer (0xA1406000, tmp, BYTES_PER_READ, _NJSD_read_end_cmd); - memcpy (tbuf + (numSectors - 2) * BYTES_PER_READ, tmp, BYTES_PER_READ); - } else { - cardPolledTransfer (0xA1406000, (u32*)(tbuf + (numSectors - 2) * BYTES_PER_READ), BYTES_PER_READ, _NJSD_read_end_cmd); - } - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - if (((int)buffer & 0x03) != 0){ - cardPolledTransfer (0xA1406000, tmp, BYTES_PER_READ, _NJSD_read_cmd); - memcpy (tbuf + (numSectors - 1) * BYTES_PER_READ, tmp, BYTES_PER_READ); - } else { - cardPolledTransfer (0xA1406000, (u32*)(tbuf + (numSectors - 1) * BYTES_PER_READ), BYTES_PER_READ, _NJSD_read_cmd); - } - } else { - _NJSD_sendCMDR (_NJSD_speed, NULL, SD_RSP_STREAM, READ_SINGLE_BLOCK, sector * BYTES_PER_READ); - if (((int)buffer & 0x03) != 0){ - cardPolledTransfer (0xA1406000, tmp, BYTES_PER_READ, _NJSD_read_cmd); - memcpy (tbuf, tmp, BYTES_PER_READ); - } else { - cardPolledTransfer (0xA1406000, (u32*)tbuf, BYTES_PER_READ, _NJSD_read_cmd); - } - } - -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return true; -} -#else // not defined _IO_ALLOW_UNALIGNED -bool _NJSD_readSectors (u32 sector, u32 numSectors, void* buffer) { - int i; - -#ifdef _NJSD_SYNC - u32 old_REG_IME; -#endif - - u8* tbuf = (u8*)buffer; - - if (numSectors == 0) { - return false; - } - -#ifdef _NJSD_SYNC - old_REG_IME = REG_IME; - REG_IME = 0; -#endif - - if (numSectors > 1) { - _NJSD_sendCMDR (_NJSD_speed, NULL, SD_RSP_DATA, READ_MULTIPLE_BLOCK, sector * BYTES_PER_READ); - for (i = 0; i < numSectors - 2; i++) { - cardPolledTransfer (0xA1406000, (u32*)(tbuf + i * BYTES_PER_READ), BYTES_PER_READ, _NJSD_read_cmd); - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - } - cardPolledTransfer (0xA1406000, (u32*)(tbuf + (numSectors - 2) * BYTES_PER_READ), BYTES_PER_READ, _NJSD_read_end_cmd); - if (!_NJSD_waitIRQ ()) { -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return false; - } - - cardPolledTransfer (0xA1406000, (u32*)(tbuf + (numSectors - 1) * BYTES_PER_READ), BYTES_PER_READ, _NJSD_read_cmd); - } else { - _NJSD_sendCMDR (_NJSD_speed, NULL, SD_RSP_STREAM, READ_SINGLE_BLOCK, sector * BYTES_PER_READ); - cardPolledTransfer (0xA1406000, (u32*)tbuf, BYTES_PER_READ, _NJSD_read_cmd); - } - -#ifdef _NJSD_SYNC - REG_IME = old_REG_IME; -#endif - return true; -} -#endif // _IO_ALLOW_UNALIGNED - -const IO_INTERFACE _io_njsd = { - DEVICE_TYPE_NJSD, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_NDS, - (FN_MEDIUM_STARTUP)&_NJSD_startup, - (FN_MEDIUM_ISINSERTED)&_NJSD_isInserted, - (FN_MEDIUM_READSECTORS)&_NJSD_readSectors, - (FN_MEDIUM_WRITESECTORS)&_NJSD_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_NJSD_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_NJSD_shutdown -} ; - -#endif // defined NDS diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_njsd.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_njsd.h deleted file mode 100644 index b668a510bc..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_njsd.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - io_njsd.h - - Hardware Routines for reading an SD card using - a NinjaDS SD adapter. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-02 - Chishm - * Original release -*/ - -#ifndef IO_NJSD_H -#define IO_NJSD_H - -#include "disc_io.h" - -#ifdef NDS - -// 'NJSD' -#define DEVICE_TYPE_NJSD 0x44534A4E - - -// export interface -extern const IO_INTERFACE _io_njsd; - -#endif // defined NDS - -#endif // define IO_NJSD_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_nmmc.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_nmmc.c deleted file mode 100644 index 88d8b48778..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_nmmc.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - io_nmmc.c - - Hardware Routines for reading an SD or MMC card using - a Neoflash MK2 or MK3. - - Written by www.neoflash.com - - Submit bug reports for this device to the NeoFlash forums - - See license.txt for license details. - - 2006-02-09 - www.neoflash.com: - * First stable release - - 2006-02-13 - Chishm - * Added ReadMK2Config function - * Added read config test to init function so no unnecessary card commands are sent - * Changed data read and write functions to use multiple block commands -*/ - -#include "io_nmmc.h" - -#ifdef NDS - -#include <nds/card.h> - -int _NMMC_spi_freq = 3; - -#define MK2_CONFIG_ZIP_RAM_CLOSE (1 << 5) -#define MK2_CONFIG_GAME_FLASH_CLOSE ((1 << 4) | (1 << 0)) -//#define MK2_CONFIG_ZIP_RAM_CLOSE ((1 << 5) | (1 << 1)) -//#define MK2_CONFIG_GAME_FLASH_CLOSE (1 << 4) - -#define MMC_READ_MULTIPLE_BLOCK 18 -#define MMC_READ_BLOCK 17 -#define MMC_WRITE_MULTIPLE_BLOCK 25 -#define MMC_WRITE_BLOCK 24 -#define MMC_STOP_TRANSMISSION 12 -#define MMC_SET_BLOCKLEN 16 -#define MMC_SET_BLOCK_COUNT 23 -#define MMC_SEND_CSD 9 - -// SPI functions - -static inline void _Neo_OpenSPI( u8 frequency ) -{ - CARD_CR1 = 0x0000A040 | frequency; -} - -static inline u8 _Neo_SPI( u8 dataByte ) -{ - CARD_EEPDATA = dataByte; - while (CARD_CR1 & 0x80); // card busy - return CARD_EEPDATA; -} - -static inline void _Neo_CloseSPI ( void ) -{ - CARD_CR1 = 0; -} - -static inline void _Neo_MK2GameMode(void) { - _Neo_OpenSPI(_NMMC_spi_freq); // Enable DS Card's SPI port - _Neo_SPI(0xF1); // Switch to game mode - _Neo_CloseSPI(); // Disable DS Card's SPI port -} - -static inline void _Neo_EnableEEPROM( bool enable ) { - _Neo_OpenSPI(_NMMC_spi_freq); - if(enable) _Neo_SPI(0x06); - else _Neo_SPI(0x0E); - _Neo_CloseSPI(); -} - -static void _Neo_WriteMK2Config(u8 config) { - _Neo_EnableEEPROM(true); - _Neo_OpenSPI(_NMMC_spi_freq); - _Neo_SPI(0xFA); // Send mem conf write command - _Neo_SPI(0x01); // Send high byte (0x01) - _Neo_SPI(config); // Send low byte - _Neo_CloseSPI(); - _Neo_EnableEEPROM(false); -} - -static u8 _Neo_ReadMK2Config(void) -{ - u8 config; - _Neo_EnableEEPROM(true); - _Neo_OpenSPI(_NMMC_spi_freq); - _Neo_SPI(0xf8); // Send mem conf read command - _Neo_SPI(0x01); // Send high byte - config = _Neo_SPI(0x00); // Get low byte - _Neo_CloseSPI(); - _Neo_EnableEEPROM(false); - return config; -} - -// Low level functions - -u8 selectMMC_command [8] = {0xFF, 0x00, 0x6A, 0xDF, 0x37, 0x59, 0x33, 0xA3}; - -static void _Neo_SelectMMC (u8 dataByte) -{ - selectMMC_command[1] = dataByte; // Set enable / disable byte - cardWriteCommand (selectMMC_command); // Send "5. Use the EEPROM CS to access the MK2 MMC/SD card" - CARD_CR2 = CARD_ACTIVATE | CARD_nRESET; - while (CARD_CR2 & CARD_BUSY); - return; -} - -static void _Neo_EnableMMC( bool enable ) -{ - if ( enable == false) { - _Neo_CloseSPI (); - _Neo_SelectMMC (0); - _Neo_SelectMMC (0); - } else { - _Neo_SelectMMC (1); - _Neo_SelectMMC (1); - _Neo_OpenSPI (_NMMC_spi_freq); - } - return; -} - -static void _Neo_SendMMCCommand( u8 command, u32 argument ) -{ - _Neo_SPI (0xFF); - _Neo_SPI (command | 0x40); - _Neo_SPI ((argument >> 24) & 0xff); - _Neo_SPI ((argument >> 16) & 0xff); - _Neo_SPI ((argument >> 8) & 0xff) ; - _Neo_SPI (argument & 0xff); - _Neo_SPI (0x95); - _Neo_SPI (0xFF); - return; -} - -static bool _Neo_CheckMMCResponse( u8 response, u8 mask ) { - u32 i; - for(i=0;i<256;i++) { - if( ( _Neo_SPI( 0xFF ) & mask ) == response ) - return true; - } - return false; -} - -// Neo MMC functions - -static bool _Neo_InitMMC(void) { - _Neo_MK2GameMode(); - _Neo_WriteMK2Config( MK2_CONFIG_ZIP_RAM_CLOSE | MK2_CONFIG_GAME_FLASH_CLOSE); - - // Make sure the configuration was accepted - if (_Neo_ReadMK2Config() != (MK2_CONFIG_ZIP_RAM_CLOSE | MK2_CONFIG_GAME_FLASH_CLOSE)) { - return false; // If not, then it wasn't initialised properly - } - - return true; -} - -// Neo MMC driver functions - -static bool _NMMC_isInserted(void) { - int i; - - _Neo_EnableMMC( true ); // Open SPI port to MMC card - _Neo_SendMMCCommand(MMC_SEND_CSD, 0); - if( _Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - _Neo_EnableMMC( false ); - return false; - } - if( _Neo_CheckMMCResponse( 0xFE, 0xFF ) == false ) { // Check for Start Block token - _Neo_EnableMMC( false ); - return false; - } - - // consume data from card, and send clocks. - for (i = 0; i < 28; i++) { - _Neo_SPI(0xff); - } - - return true; -} - -static bool _NMMC_clearStatus (void) { - u32 i; - - _Neo_EnableMMC( true ); // Open SPI port to MMC card - for (i = 0; i < 10; i++) { - _Neo_SPI(0xFF); // Send 10 0xFF bytes to MMC card - } - _Neo_SendMMCCommand(0, 0); // Send GO_IDLE_STATE command - if( _Neo_CheckMMCResponse( 0x01, 0xFF ) == false ) { // Check that it replied with 0x01 (not idle, no other error) - _Neo_EnableMMC( false ); - return false; - } - for(i=0;i<256;i++) { - _Neo_SendMMCCommand(1, 0); // Poll with SEND_OP_COND - if( _Neo_CheckMMCResponse( 0x00, 0x01 ) == true ) { // Check for idle state - _Neo_EnableMMC( false ); // Close SPI port to MMC card - return true; // Card is now idle - } - } - _Neo_EnableMMC( false ); - return false; -} - -static bool _NMMC_shutdown(void) { - return _NMMC_clearStatus(); -} - -static bool _NMMC_startUp(void) { - int i; - int transSpeed; - if (_Neo_InitMMC() == false) { - return false; - } - if (_NMMC_clearStatus() == false) { - return false; - } - _Neo_EnableMMC( true ); // Open SPI port to MMC card - - // Set block length - _Neo_SendMMCCommand(MMC_SET_BLOCKLEN, BYTES_PER_READ ); - if( _Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - _Neo_EnableMMC( false ); - return false; - } - - // Check if we can use a higher SPI frequency - _Neo_SendMMCCommand(MMC_SEND_CSD, 0); - if( _Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - _Neo_EnableMMC( false ); - return false; - } - if( _Neo_CheckMMCResponse( 0xFE, 0xFF ) == false ) { // Check for Start Block token - _Neo_EnableMMC( false ); - return false; - } - for (i = 0; i < 3; i++) { - _Neo_SPI(0xFF); - } - transSpeed = _Neo_SPI (0xFF); - for (i = 0; i < 24; i++) { - _Neo_SPI(0xFF); - } - if ((transSpeed & 0xf0) >= 0x30) { - _NMMC_spi_freq = 0; - } - - _Neo_EnableMMC( false ); - - return true; -} - - -static bool _NMMC_writeSectors (u32 sector, u32 totalSecs, const void* buffer) -{ - u32 i; - u8 *p=(u8*)buffer; - - sector *= BYTES_PER_READ; - - _Neo_EnableMMC( true ); // Open SPI port to MMC card - _Neo_SendMMCCommand( 25, sector ); - if( _Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - _Neo_EnableMMC( false ); - return false; - } - - while (totalSecs--) { - _Neo_SPI( 0xFC ); // Send Start Block token - for( i = 0; i < BYTES_PER_READ; i++ ) // Send a block of data - _Neo_SPI( *p++ ); - _Neo_SPI( 0xFF ); // Send fake CRC16 - _Neo_SPI( 0xFF ); // Send fake CRC16 - - if( ( _Neo_SPI( 0xFF ) & 0x0F ) != 0x05 ) { // Make sure the block was accepted - _Neo_EnableMMC( false ); - return false; - } - while( _Neo_SPI( 0xFF ) == 0x00 ); // Wait for the block to be written - } - - // Stop transmission block - _Neo_SPI( 0xFD ); // Send Stop Transmission Block token - for( i = 0; i < BYTES_PER_READ; i++ ) // Send a block of fake data - _Neo_SPI( 0xFF ); - _Neo_SPI( 0xFF ); // Send fake CRC16 - _Neo_SPI( 0xFF ); // Send fake CRC16 - - _Neo_SPI (0xFF); // Send 8 clocks - while( _Neo_SPI( 0xFF ) == 0x00 ); // Wait for the busy signal to clear - - - for ( i = 0; i < 0x10; i++) { - _Neo_SPI (0xFF); // Send clocks for the MMC card to finish what it's doing - } - - _Neo_EnableMMC( false ); // Close SPI port to MMC card - return true; -} - -static bool _NMMC_readSectors (u32 sector, u32 totalSecs, void* buffer) -{ - u32 i; - u8 *p=(u8*)buffer; - - sector *= BYTES_PER_READ; - - _Neo_EnableMMC( true ); // Open SPI port to MMC card - - while (totalSecs--) { - _Neo_SendMMCCommand(MMC_READ_BLOCK, sector ); - if( _Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - _Neo_EnableMMC( false ); - return false; - } - - if( _Neo_CheckMMCResponse( 0xFE, 0xFF ) == false ) { // Check for Start Block token - _Neo_EnableMMC( false ); - return false; - } - for( i = 0; i < BYTES_PER_READ; i++ ) // Read in a block of data - *p++ = _Neo_SPI( 0xFF ); - _Neo_SPI( 0xFF ); // Ignore CRC16 - _Neo_SPI( 0xFF ); // Ignore CRC16 - sector += BYTES_PER_READ; - } - - _Neo_EnableMMC( false ); // Close SPI port to MMC card - return true; -} - - -const IO_INTERFACE _io_nmmc = { - DEVICE_TYPE_NMMC, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_NDS, - (FN_MEDIUM_STARTUP)&_NMMC_startUp, - (FN_MEDIUM_ISINSERTED)&_NMMC_isInserted, - (FN_MEDIUM_READSECTORS)&_NMMC_readSectors, - (FN_MEDIUM_WRITESECTORS)&_NMMC_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_NMMC_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_NMMC_shutdown -} ; - -#endif // defined NDS diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_nmmc.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_nmmc.h deleted file mode 100644 index aeb2c64222..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_nmmc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - io_nmmc.h - - Hardware Routines for reading an SD or MMC card using - a Neoflash MK2 or MK3. - - Original version written by www.neoflash.com, - moddified and used with permission of www.neoflash.com - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_NMMC_H -#define IO_NMMC_H - -#include "disc_io.h" - -#ifdef NDS - -// 'NMMC' -#define DEVICE_TYPE_NMMC 0x434D4D4E - - -// export interface -extern const IO_INTERFACE _io_nmmc; - -#endif // defined NDS - -#endif // define IO_NMMC_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sc_common.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sc_common.c deleted file mode 100644 index 9dabbdcd84..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sc_common.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - io_m3_common.h - - Routines common to all version of the Super Card - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "io_sc_common.h" - -/*----------------------------------------------------------------- -_SC_changeMode (was SC_Unlock) -Added by MightyMax -Modified by Chishm -Modified again by loopy -1=ram(readonly), 5=ram, 3=SD interface? ------------------------------------------------------------------*/ -void _SC_changeMode(u8 mode) { - vu16 *unlockAddress = (vu16*)0x09FFFFFE; - *unlockAddress = 0xA55A ; - *unlockAddress = 0xA55A ; - *unlockAddress = mode ; - *unlockAddress = mode ; -} - - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sc_common.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sc_common.h deleted file mode 100644 index da30b7e5e3..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sc_common.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - io_sc_common.h - - Routines common to all version of the Super Card - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_SC_COMMON_H -#define IO_SC_COMMON_H - -#include "disc_io.h" - -// Values for changing mode -#define SC_MODE_RAM 0x5 -#define SC_MODE_MEDIA 0x3 -#define SC_MODE_RAM_RO 0x1 - -extern void _SC_changeMode (u8 mode); - -#endif // IO_SC_COMMON_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sccf.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sccf.c deleted file mode 100644 index 06d1378028..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sccf.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - io_sccf.c based on - - compact_flash.c - By chishm (Michael Chisholm) - - Hardware Routines for reading a compact flash card - using the Super Card CF - - CF routines modified with help from Darkfader - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "io_sccf.h" -#include "io_sc_common.h" -#include "io_cf_common.h" - -//--------------------------------------------------------------- -// SC CF Addresses -#define REG_SCCF_STS ((vu16*)0x098C0000) // Status of the CF Card / Device control -#define REG_SCCF_CMD ((vu16*)0x090E0000) // Commands sent to control chip and status return -#define REG_SCCF_ERR ((vu16*)0x09020000) // Errors / Features - -#define REG_SCCF_SEC ((vu16*)0x09040000) // Number of sector to transfer -#define REG_SCCF_LBA1 ((vu16*)0x09060000) // 1st byte of sector address -#define REG_SCCF_LBA2 ((vu16*)0x09080000) // 2nd byte of sector address -#define REG_SCCF_LBA3 ((vu16*)0x090A0000) // 3rd byte of sector address -#define REG_SCCF_LBA4 ((vu16*)0x090C0000) // last nibble of sector address | 0xE0 - -#define REG_SCCF_DATA ((vu16*)0x09000000) // Pointer to buffer of CF data transered from card - -static const CF_REGISTERS _SCCF_Registers = { - REG_SCCF_DATA, - REG_SCCF_STS, - REG_SCCF_CMD, - REG_SCCF_ERR, - REG_SCCF_SEC, - REG_SCCF_LBA1, - REG_SCCF_LBA2, - REG_SCCF_LBA3, - REG_SCCF_LBA4 -}; - - -static bool _SCCF_startup(void) { - _SC_changeMode (SC_MODE_MEDIA); - return _CF_startup(&_SCCF_Registers); -} - - -const IO_INTERFACE _io_sccf = { - DEVICE_TYPE_SCCF, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_SCCF_startup, - (FN_MEDIUM_ISINSERTED)&_CF_isInserted, - (FN_MEDIUM_READSECTORS)&_CF_readSectors, - (FN_MEDIUM_WRITESECTORS)&_CF_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_CF_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_CF_shutdown -} ; diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sccf.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sccf.h deleted file mode 100644 index 86e428bfd5..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sccf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - io_sccf.h - - Hardware Routines for reading a compact flash card - using the Supercard CF - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef IO_SCCF_H -#define IO_SCCF_H - -// 'SCCF' -#define DEVICE_TYPE_SCCF 0x46434353 - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_sccf; - -#endif // define IO_SCCF_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd.c deleted file mode 100644 index 231b93fc37..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - io_scsd.c - - Hardware Routines for reading a Secure Digital card - using the SC SD - - Some code based on scsd_c.c, written by Amadeus - and Jean-Pierre Thomasset as part of DSLinux. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-22 - Chishm - * First release of stable code - - 2006-07-25 - Chishm - * Improved startup function that doesn't delay hundreds of seconds - before reporting no card inserted. - - 2006-08-05 - Chishm - * Tries multiple times to get a Relative Card Address at startup - - 2006-08-07 - Chishm - * Moved the SD initialization to a common function - - 2006-08-19 - Chishm - * Added SuperCard Lite support -*/ - -#include "io_scsd.h" -#include "io_sd_common.h" -#include "io_sc_common.h" - -//--------------------------------------------------------------- -// SCSD register addresses -#define REG_SCSD_CMD (*(vu16*)(0x09800000)) - /* bit 0: command bit to read */ - /* bit 7: command bit to write */ - -#define REG_SCSD_DATAWRITE (*(vu16*)(0x09000000)) -#define REG_SCSD_DATAREAD (*(vu16*)(0x09100000)) -#define REG_SCSD_DATAREAD_32 (*(vu32*)(0x09100000)) -#define REG_SCSD_LITE_ENABLE (*(vu16*)(0x09440000)) -#define REG_SCSD_LOCK (*(vu16*)(0x09FFFFFE)) - /* bit 0: 1 */ - /* bit 1: enable IO interface (SD,CF) */ - /* bit 2: enable R/W SDRAM access */ - -//--------------------------------------------------------------- -// Responses -#define SCSD_STS_BUSY 0x100 -#define SCSD_STS_INSERTED 0x300 - -//--------------------------------------------------------------- -// Send / receive timeouts, to stop infinite wait loops -#define NUM_STARTUP_CLOCKS 100 // Number of empty (0xFF when sending) bytes to send/receive to/from the card -#define TRANSMIT_TIMEOUT 100000 // Time to wait for the SC to respond to transmit or receive requests -#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up -#define BUSY_WAIT_TIMEOUT 500000 -#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing -//--------------------------------------------------------------- -// Variables required for tracking SD state -static u32 _SCSD_relativeCardAddress = 0; // Preshifted Relative Card Address - -//--------------------------------------------------------------- -// Internal SC SD functions - -extern bool _SCSD_writeData_s (u8 *data, u16* crc); - -static inline void _SCSD_unlock (void) { - _SC_changeMode (SC_MODE_MEDIA); -} - -static inline void _SCSD_enable_lite (void) { - REG_SCSD_LITE_ENABLE = 0; -} - -static bool _SCSD_sendCommand (u8 command, u32 argument) { - u8 databuff[6]; - u8 *tempDataPtr = databuff; - int length = 6; - u16 dataByte; - int curBit; - int i; - - *tempDataPtr++ = command | 0x40; - *tempDataPtr++ = argument>>24; - *tempDataPtr++ = argument>>16; - *tempDataPtr++ = argument>>8; - *tempDataPtr++ = argument; - *tempDataPtr = _SD_CRC7 (databuff, 5); - - i = BUSY_WAIT_TIMEOUT; - while (((REG_SCSD_CMD & 0x01) == 0) && (--i)); - if (i == 0) { - return false; - } - - dataByte = REG_SCSD_CMD; - - tempDataPtr = databuff; - - while (length--) { - dataByte = *tempDataPtr++; - for (curBit = 7; curBit >=0; curBit--){ - REG_SCSD_CMD = dataByte; - dataByte = dataByte << 1; - } - } - - return true; -} - -// Returns the response from the SD card to a previous command. -static bool _SCSD_getResponse (u8* dest, u32 length) { - u32 i; - int dataByte; - int numBits = length * 8; - - // Wait for the card to be non-busy - i = BUSY_WAIT_TIMEOUT; - while (((REG_SCSD_CMD & 0x01) != 0) && (--i)); - if (dest == NULL) { - return true; - } - - if (i == 0) { - // Still busy after the timeout has passed - return false; - } - - // The first bit is always 0 - dataByte = 0; - numBits--; - // Read the remaining bits in the response. - // It's always most significant bit first - while (numBits--) { - dataByte = (dataByte << 1) | (REG_SCSD_CMD & 0x01); - if ((numBits & 0x7) == 0) { - // It's read a whole byte, so store it - *dest++ = (u8)dataByte; - dataByte = 0; - } - } - - // Send 16 more clocks, 8 more than the delay required between a response and the next command - for (i = 0; i < 16; i++) { - dataByte = REG_SCSD_CMD; - } - - return true; -} - -static inline bool _SCSD_getResponse_R1 (u8* dest) { - return _SCSD_getResponse (dest, 6); -} - -static inline bool _SCSD_getResponse_R1b (u8* dest) { - return _SCSD_getResponse (dest, 6); -} - -static inline bool _SCSD_getResponse_R2 (u8* dest) { - return _SCSD_getResponse (dest, 17); -} - -static inline bool _SCSD_getResponse_R3 (u8* dest) { - return _SCSD_getResponse (dest, 6); -} - -static inline bool _SCSD_getResponse_R6 (u8* dest) { - return _SCSD_getResponse (dest, 6); -} - -static void _SCSD_sendClocks (u32 numClocks) { - u16 temp; - do { - (void) temp; /* avoid set but not used warning */ - temp = REG_SCSD_CMD; - } while (numClocks--); -} - -static bool _SCSD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) { - _SCSD_sendCommand (command, data); - return _SCSD_getResponse (responseBuffer, 6); -} - -static bool _SCSD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) { - _SCSD_sendCommand (command, data); - return _SCSD_getResponse (responseBuffer, 17); -} - - -static bool _SCSD_initCard (void) { - _SCSD_enable_lite(); - - // Give the card time to stabilise - _SCSD_sendClocks (NUM_STARTUP_CLOCKS); - - // Reset the card - if (!_SCSD_sendCommand (GO_IDLE_STATE, 0)) { - return false; - } - - _SCSD_sendClocks (NUM_STARTUP_CLOCKS); - - // Card is now reset, including it's address - _SCSD_relativeCardAddress = 0; - - // Init the card - return _SD_InitCard (_SCSD_cmd_6byte_response, - _SCSD_cmd_17byte_response, - true, - &_SCSD_relativeCardAddress); -} - -static bool _SCSD_readData (void* buffer) { - u8* buff_u8 = (u8*)buffer; - u16* buff = (u16*)buffer; - volatile register u32 temp; - int i; - - i = BUSY_WAIT_TIMEOUT; - while ((REG_SCSD_DATAREAD & SCSD_STS_BUSY) && (--i)); - if (i == 0) { - return false; - } - - i=256; - if ((u32)buff_u8 & 0x01) { - while(i--) { - temp = REG_SCSD_DATAREAD_32; - temp = REG_SCSD_DATAREAD_32 >> 16; - *buff_u8++ = (u8)temp; - *buff_u8++ = (u8)(temp >> 8); - } - } else { - while(i--) { - temp = REG_SCSD_DATAREAD_32; - temp = REG_SCSD_DATAREAD_32 >> 16; - *buff++ = temp; - } - } - - - for (i = 0; i < 8; i++) { - temp = REG_SCSD_DATAREAD_32; - } - - temp = REG_SCSD_DATAREAD; - - return true; -} - -//--------------------------------------------------------------- -// Functions needed for the external interface - -static bool _SCSD_startUp (void) { - _SCSD_unlock(); - return _SCSD_initCard(); -} - -static bool _SCSD_isInserted (void) { - u8 responseBuffer [6]; - - // Make sure the card receives the command - if (!_SCSD_sendCommand (SEND_STATUS, 0)) { - return false; - } - // Make sure the card responds - if (!_SCSD_getResponse_R1 (responseBuffer)) { - return false; - } - // Make sure the card responded correctly - if (responseBuffer[0] != SEND_STATUS) { - return false; - } - return true; -} - -static bool _SCSD_readSectors (u32 sector, u32 numSectors, void* buffer) { - u32 i; - u8* dest = (u8*) buffer; - u8 responseBuffer[6]; - - if (numSectors == 1) { - // If it's only reading one sector, use the (slightly faster) READ_SINGLE_BLOCK - if (!_SCSD_sendCommand (READ_SINGLE_BLOCK, sector * BYTES_PER_READ)) { - return false; - } - - if (!_SCSD_readData (buffer)) { - return false; - } - - } else { - // Stream the required number of sectors from the card - if (!_SCSD_sendCommand (READ_MULTIPLE_BLOCK, sector * BYTES_PER_READ)) { - return false; - } - - for(i=0; i < numSectors; i++, dest+=BYTES_PER_READ) { - if (!_SCSD_readData(dest)) { - return false; - } - } - - // Stop the streaming - _SCSD_sendCommand (STOP_TRANSMISSION, 0); - _SCSD_getResponse_R1b (responseBuffer); - } - - _SCSD_sendClocks(0x10); - return true; -} - -static bool _SCSD_writeSectors (u32 sector, u32 numSectors, const void* buffer) { - u16 crc[4]; // One per data line - u8 responseBuffer[6]; - u32 offset = sector * BYTES_PER_READ; - u8* data = (u8*) buffer; - int i; - - while (numSectors--) { - // Calculate the CRC16 - _SD_CRC16 ( data, BYTES_PER_READ, (u8*)crc); - - // Send write command and get a response - _SCSD_sendCommand (WRITE_BLOCK, offset); - if (!_SCSD_getResponse_R1 (responseBuffer)) { - return false; - } - - // Send the data and CRC - if (! _SCSD_writeData_s (data, crc)) { - return false; - } - - // Send a few clocks to the SD card - _SCSD_sendClocks(0x10); - - offset += BYTES_PER_READ; - data += BYTES_PER_READ; - - // Wait until card is finished programming - i = WRITE_TIMEOUT; - responseBuffer[3] = 0; - do { - _SCSD_sendCommand (SEND_STATUS, _SCSD_relativeCardAddress); - _SCSD_getResponse_R1 (responseBuffer); - i--; - if (i <= 0) { - return false; - } - } while (((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA))); - } - - return true; -} - -static bool _SCSD_clearStatus (void) { - return _SCSD_initCard (); -} - -static bool _SCSD_shutdown (void) { - _SC_changeMode (SC_MODE_RAM_RO); - return true; -} - -const IO_INTERFACE _io_scsd = { - DEVICE_TYPE_SCSD, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_SCSD_startUp, - (FN_MEDIUM_ISINSERTED)&_SCSD_isInserted, - (FN_MEDIUM_READSECTORS)&_SCSD_readSectors, - (FN_MEDIUM_WRITESECTORS)&_SCSD_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_SCSD_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_SCSD_shutdown -} ; - - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd.h deleted file mode 100644 index 25a02544df..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - io_scsd.h - - Hardware Routines for reading a Secure Digital card - using the Supercard SD - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-22 - Chishm - * First release of stable code -*/ - -#ifndef IO_SCSD_H -#define IO_SCSD_H - -// 'SCSD' -#define DEVICE_TYPE_SCSD 0x44534353 - -#include "disc_io.h" - -// export interface -extern const IO_INTERFACE _io_scsd ; - -#endif // define IO_SCSD_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd_s.S b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd_s.S deleted file mode 100644 index 5ae8fdd2b8..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_scsd_s.S +++ /dev/null @@ -1,139 +0,0 @@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@ io_scsd_s.s -@ -@ Hardware Routines for reading a Secure Digital card -@ using the SC SD -@ -@ Based on code supplied by Romman -@ -@ Copyright (c) 2006 Michael "Chishm" Chisholm -@ -@ Redistribution and use in source and binary forms, with or without modification, -@ are permitted provided that the following conditions are met: -@ -@ 1. Redistributions of source code must retain the above copyright notice, -@ this list of conditions and the following disclaimer. -@ 2. Redistributions in binary form must reproduce the above copyright notice, -@ this list of conditions and the following disclaimer in the documentation and/or -@ other materials provided with the distribution. -@ 3. The name of the author may not be used to endorse or promote products derived -@ from this software without specific prior written permission. -@ -@ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -@ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -@ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -@ -@ 2006-07-22 - Chishm -@ * First release of stable code -@ -@ 2006-08-19 - Chishm -@ * Added SuperCard Lite support -@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - - .align 4 - .arm - - .equ REG_SCSD_DATAWRITE, 0x09000000 - .equ BYTES_PER_READ, 0x200 - .equ SCSD_STS_BUSY, 0x100 - .equ BUSY_WAIT_TIMEOUT, 0x10000 - .equ FALSE, 0 - .equ TRUE, 1 - -@ bool _SCSD_writeData_s (u8 *data, u16* crc) - - .global _SCSD_writeData_s - -_SCSD_writeData_s: - stmfd r13!, {r4-r5} - mov r5, #BYTES_PER_READ - mov r2, #REG_SCSD_DATAWRITE - -@ Wait for a free data buffer on the SD card - mov r4, #BUSY_WAIT_TIMEOUT -_SCSD_writeData_busy_wait: - @ Test for timeout - subs r4, r4, #1 - moveq r0, #FALSE @ return false on failure - beq _SCSD_writeData_return - @ Check the busy bit of the status register - ldrh r3, [r2] - tst r3, #SCSD_STS_BUSY - beq _SCSD_writeData_busy_wait - - ldrh r3, [r2] @ extra clock - - mov r3, #0 @ start bit - strh r3,[r2] - -@ Check if the data buffer is aligned on a halfword boundary - tst r0, #1 - beq _SCSD_writeData_data_loop - -@ Used when the source data is unaligned -_SCSD_writeData_data_loop_unaligned: - ldrb r3, [r0], #1 - ldrb r4, [r0], #1 - orr r3, r3, r4, lsl #8 - stmia r2, {r3-r4} - subs r5, r5, #2 - bne _SCSD_writeData_data_loop_unaligned - b _SCSD_writeData_crc - -@ Write the data to the card -@ 4 halfwords are transmitted to the Supercard at once, for timing purposes -@ Only the first halfword needs to contain data for standard SuperCards -@ For the SuperCard Lite, the data is split into 4 nibbles, one per halfword -_SCSD_writeData_data_loop: - ldrh r3, [r0], #2 - -@ This bit added for SCLite. Notice that the shift is not the same as in -@ the original (buggy) code supplied by Romman - add r3, r3, r3, lsl #20 - mov r4, r3, lsr #8 - - stmia r2, {r3-r4} - - subs r5, r5, #2 - bne _SCSD_writeData_data_loop - -@ Send the data CRC -_SCSD_writeData_crc: - cmp r1, #0 - movne r0, r1 - movne r1, #0 - movne r5, #8 - bne _SCSD_writeData_data_loop - - mov r3, #0xff @ end bit - strh r3, [r2] - -@ Wait for the SD card to signal that it is finished recieving - mov r4, #BUSY_WAIT_TIMEOUT -_SCSD_writeData_finished_wait: - @ Test for timeout - subs r4, r4, #1 - moveq r0, #FALSE @ return false on failure - beq _SCSD_writeData_return - @ Check the busy bit of the status register - ldrh r3, [r2] - tst r3, #0x100 - bne _SCSD_writeData_finished_wait - -@ Send 8 more clocks, as required by the SD card - ldmia r2, {r3-r4} - -@ return true for success - mov r0, #TRUE - -_SCSD_writeData_return: - ldmfd r13!,{r4-r5} - bx r14 - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sd_common.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sd_common.c deleted file mode 100644 index 86dd37355b..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sd_common.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - io_sd_common.c - - By chishm (Michael Chisholm) - - Common SD card routines - - SD routines partially based on sd.s by Romman - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-07 - Chishm - * Moved the SD initialization to a common function - * Increased timeouts for slower cards - - 2006-08-08 - Chishm - * Init aborts when it doesn't get a valid response to APP_CMD - speeds up detection when no card is inserted -*/ - -#include "io_sd_common.h" - -#define MAX_STARTUP_TRIES 1000 // Arbitrary value, check if the card is ready 20 times before giving up -#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up - -/* -Improved CRC7 function provided by cory1492 -Calculates the CRC of an SD command, and includes the end bit in the byte -*/ -u8 _SD_CRC7(u8* data, int cnt) { - int i, a; - u8 crc, temp; - - crc = 0; - for (a = 0; a < cnt; a++) - { - temp = data[a]; - for (i = 0; i < 8; i++) - { - crc <<= 1; - if ((temp & 0x80) ^ (crc & 0x80)) crc ^= 0x09; - temp <<= 1; - } - } - crc = (crc << 1) | 1; - return(crc); -} - -/* -Calculates the CRC16 for a sector of data. Calculates it -as 4 separate lots, merged into one buffer. This is used -for 4 SD data lines, not for 1 data line alone. -*/ -void _SD_CRC16 (u8* buff, int buffLength, u8* crc16buff) { - u32 a, b, c, d; - int count; - u32 bitPattern = 0x80808080; // r7 - u32 crcConst = 0x1021; // r8 - u32 dataByte = 0; // r2 - - a = 0; // r3 - b = 0; // r4 - c = 0; // r5 - d = 0; // r6 - - buffLength = buffLength * 8; - - - do { - if (bitPattern & 0x80) dataByte = *buff++; - - a = a << 1; - if ( a & 0x10000) a ^= crcConst; - if (dataByte & (bitPattern >> 24)) a ^= crcConst; - - b = b << 1; - if (b & 0x10000) b ^= crcConst; - if (dataByte & (bitPattern >> 25)) b ^= crcConst; - - c = c << 1; - if (c & 0x10000) c ^= crcConst; - if (dataByte & (bitPattern >> 26)) c ^= crcConst; - - d = d << 1; - if (d & 0x10000) d ^= crcConst; - if (dataByte & (bitPattern >> 27)) d ^= crcConst; - - bitPattern = (bitPattern >> 4) | (bitPattern << 28); - } while (buffLength-=4); - - count = 16; // r8 - - do { - bitPattern = bitPattern << 4; - if (a & 0x8000) bitPattern |= 8; - if (b & 0x8000) bitPattern |= 4; - if (c & 0x8000) bitPattern |= 2; - if (d & 0x8000) bitPattern |= 1; - - a = a << 1; - b = b << 1; - c = c << 1; - d = d << 1; - - count--; - - if (!(count & 0x01)) { - *crc16buff++ = (u8)(bitPattern & 0xff); - } - } while (count != 0); - - return; -} - -/* -Initialise the SD card, after it has been sent into an Idle state -cmd_6byte_response: a pointer to a function that sends the SD card a command and gets a 6 byte response -cmd_17byte_response: a pointer to a function that sends the SD card a command and gets a 17 byte response -use4bitBus: initialise card to use a 4 bit data bus when communicating with the card -RCA: a pointer to the location to store the card's Relative Card Address, preshifted up by 16 bits. -*/ -bool _SD_InitCard (_SD_FN_CMD_6BYTE_RESPONSE cmd_6byte_response, - _SD_FN_CMD_17BYTE_RESPONSE cmd_17byte_response, - bool use4bitBus, - u32 *RCA) -{ - u8 responseBuffer[17] = {0}; - int i; - - for (i = 0; i < MAX_STARTUP_TRIES ; i++) { - cmd_6byte_response (responseBuffer, APP_CMD, 0); - // Check that the card gave the correct response - if (responseBuffer[0] != APP_CMD) { - return false; - } - if ( - cmd_6byte_response (responseBuffer, SD_APP_OP_COND, SD_OCR_VALUE) && - ((responseBuffer[1] & 0x80) != 0)) - { - // Card is ready to receive commands now - break; - } - } - if (i >= MAX_STARTUP_TRIES) { - return false; - } - - // The card's name, as assigned by the manufacturer - cmd_17byte_response (responseBuffer, ALL_SEND_CID, 0); - - // Get a new address - for (i = 0; i < MAX_STARTUP_TRIES ; i++) { - cmd_6byte_response (responseBuffer, SEND_RELATIVE_ADDR, 0); - *RCA = (responseBuffer[1] << 24) | (responseBuffer[2] << 16); - if ((responseBuffer[3] & 0x1e) != (SD_STATE_STBY << 1)) { - break; - } - } - if (i >= MAX_STARTUP_TRIES) { - return false; - } - - // Some cards won't go to higher speeds unless they think you checked their capabilities - cmd_17byte_response (responseBuffer, SEND_CSD, *RCA); - - // Only this card should respond to all future commands - cmd_6byte_response (responseBuffer, SELECT_CARD, *RCA); - - if (use4bitBus) { - // Set a 4 bit data bus - cmd_6byte_response (responseBuffer, APP_CMD, *RCA); - cmd_6byte_response (responseBuffer, SET_BUS_WIDTH, 2); // 4-bit mode. - } - - // Use 512 byte blocks - cmd_6byte_response (responseBuffer, SET_BLOCKLEN, 512); // 512 byte blocks - - // Wait until card is ready for data - i = 0; - do { - if (i >= RESPONSE_TIMEOUT) { - return false; - } - i++; - } while (!cmd_6byte_response (responseBuffer, SEND_STATUS, *RCA) && ((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA))); - - return true; -} - - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sd_common.h b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sd_common.h deleted file mode 100644 index 887160e293..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_sd_common.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - io_sd_common.h - - By chishm (Michael Chisholm) - - Common SD card routines - - SD routines partially based on sd.s by Romman - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-28 - Chishm - * Changed voltage range that the SD card can use - - 2006-11-14 - Chishm - * Reduced voltage range again. Hopefully fixes MicroSD cards. -*/ - -#ifndef IO_SD_COMMON_H -#define IO_SD_COMMON_H - -#include "disc_io.h" - -/* SD commands */ -#define GO_IDLE_STATE 0 -#define ALL_SEND_CID 2 -#define SEND_RELATIVE_ADDR 3 -#define SELECT_CARD 7 -#define SEND_CSD 9 -#define STOP_TRANSMISSION 12 -#define SEND_STATUS 13 -#define GO_INACTIVE_STATE 15 -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define APP_CMD 55 - -/* SD App commands */ -#define SET_BUS_WIDTH 6 -#define SD_APP_OP_COND 41 - -/* OCR (Operating Conditions Register) send value */ -#define SD_OCR_VALUE 0x00030000 /* 2.8V to 3.0V */ -//#define SD_OCR_VALUE 0x003F8000 /* 2.7V to 3.4V */ -//#define SD_OCR_VALUE 0x00FC0000 - -/* SD Data repsonses */ -#define SD_CARD_BUSY 0xff - -/* SD states */ -#define SD_STATE_IDLE 0 // Idle state, after power on or GO_IDLE_STATE command -#define SD_STATE_READY 1 // Ready state, after card replies non-busy to SD_APP_OP_COND -#define SD_STATE_IDENT 2 // Identification state, after ALL_SEND_CID -#define SD_STATE_STBY 3 // Standby state, when card is deselected -#define SD_STATE_TRAN 4 // Transfer state, after card is selected and ready for data transfer -#define SD_STATE_DATA 5 // -#define SD_STATE_RCV 6 // Receive data state -#define SD_STATE_PRG 7 // Programming state -#define SD_STATE_DIS 8 // Disconnect state -#define SD_STATE_INA 9 // Inactive state, after GO_INACTIVE_STATE - -#define READY_FOR_DATA 1 // bit 8 in card status - -/* -Calculate the CRC7 of a command and return it preshifted with -an end bit added -*/ -extern u8 _SD_CRC7(u8* data, int size); - -/* -Calculate the CRC16 of a block of data, ready for transmission on -four data lines at once -*/ -extern void _SD_CRC16 (u8* buff, int buffLength, u8* crc16buff); - -typedef bool (*_SD_FN_CMD_6BYTE_RESPONSE) (u8* responseBuffer, u8 command, u32 data); -typedef bool (*_SD_FN_CMD_17BYTE_RESPONSE) (u8* responseBuffer, u8 command, u32 data); - -/* -Initialise the SD card, after it has been sent into an Idle state -cmd_6byte_response: a pointer to a function that sends the SD card a command and gets a 6 byte response -cmd_17byte_response: a pointer to a function that sends the SD card a command and gets a 17 byte response -use4bitBus: initialise card to use a 4 bit data bus when communicating with the card -RCA: a pointer to the location to store the card's Relative Card Address, preshifted up by 16 bits. -*/ -extern bool _SD_InitCard (_SD_FN_CMD_6BYTE_RESPONSE cmd_6byte_response, - _SD_FN_CMD_17BYTE_RESPONSE cmd_17byte_response, - bool use4bitBus, - u32 *RCA); - -#endif // define IO_SD_COMMON_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/fatdir.c b/c/src/lib/libbsp/arm/nds/libfat/source/fatdir.c deleted file mode 100644 index 78a2b14f9e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/fatdir.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - fatdir.c - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-13 - Chishm - * Moved all externally visible directory related functions to fatdir - * Added _FAT_mkdir_r - - 2006-08-14 - Chishm - * Added directory iterator functions - - 2006-08-19 - Chishm - * Updated dirnext return values to return correctly - - 2006-10-01 - Chishm - * Now clears the whole cluster when creating a new directory, bug found by Hermes - - 2007-01-10 - Chishm - * Updated directory iterator functions for DevkitPro r20 -*/ - -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <unistd.h> -#include <sys/dir.h> - -#include "fatdir.h" - -#include "cache.h" -#include "file_allocation_table.h" -#include "partition.h" -#include "directory.h" -#include "bit_ops.h" -#include "filetime.h" - - -int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) { - PARTITION* partition = NULL; - - DIR_ENTRY dirEntry; - - // Get the partition this file is on - partition = _FAT_partition_getPartitionFromPath (path); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Search for the file on the disc - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) { - r->_errno = ENOENT; - return -1; - } - - // Fill in the stat struct - _FAT_directory_entryStat (partition, &dirEntry, st); - - return 0; -} - -int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink) { - r->_errno = ENOTSUP; - return -1; -} - -int _FAT_unlink_r (struct _reent *r, const char *path) { - PARTITION* partition = NULL; - DIR_ENTRY dirEntry; - DIR_ENTRY dirContents; - u32 cluster; - bool nextEntry; - bool errorOccured = false; - - // Get the partition this directory is on - partition = _FAT_partition_getPartitionFromPath (path); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Make sure we aren't trying to write to a read-only disc - if (partition->readOnly) { - r->_errno = EROFS; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Search for the file on the disc - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) { - r->_errno = ENOENT; - return -1; - } - - cluster = _FAT_directory_entryGetCluster (dirEntry.entryData); - - - // If this is a directory, make sure it is empty - if (_FAT_directory_isDirectory (&dirEntry)) { - nextEntry = _FAT_directory_getFirstEntry (partition, &dirContents, cluster); - - while (nextEntry) { - if (!_FAT_directory_isDot (&dirContents)) { - // The directory had something in it that isn't a reference to itself or it's parent - r->_errno = EPERM; - return -1; - } - nextEntry = _FAT_directory_getNextEntry (partition, &dirContents); - } - } - - if (cluster != CLUSTER_FREE) { - // Remove the cluster chain for this file - if (!_FAT_fat_clearLinks (partition, cluster)) { - r->_errno = EIO; - errorOccured = true; - } - } - - // Remove the directory entry for this file - if (!_FAT_directory_removeEntry (partition, &dirEntry)) { - r->_errno = EIO; - errorOccured = true; - } - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush(partition->cache)) { - r->_errno = EIO; - errorOccured = true; - } - - if (errorOccured) { - return -1; - } else { - return 0; - } -} - -int _FAT_chdir_r (struct _reent *r, const char *path) { - PARTITION* partition = NULL; - - // Get the partition this directory is on - partition = _FAT_partition_getPartitionFromPath (path); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Set the default device to match this one - if (!_FAT_partition_setDefaultPartition (partition)) { - r->_errno = ENOENT; - return -1; - } - - // Try changing directory - if (_FAT_directory_chdir (partition, path)) { - // Successful - return 0; - } else { - // Failed - r->_errno = ENOTDIR; - return -1; - } -} - -int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) { - PARTITION* partition = NULL; - DIR_ENTRY oldDirEntry; - DIR_ENTRY newDirEntry; - const char *pathEnd; - u32 dirCluster; - - // Get the partition this directory is on - partition = _FAT_partition_getPartitionFromPath (oldName); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Make sure the same partition is used for the old and new names - if (partition != _FAT_partition_getPartitionFromPath (newName)) { - r->_errno = EXDEV; - return -1; - } - - // Make sure we aren't trying to write to a read-only disc - if (partition->readOnly) { - r->_errno = EROFS; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (oldName, ':') != NULL) { - oldName = strchr (oldName, ':') + 1; - } - if (strchr (oldName, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - if (strchr (newName, ':') != NULL) { - newName = strchr (newName, ':') + 1; - } - if (strchr (newName, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Search for the file on the disc - if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) { - r->_errno = ENOENT; - return -1; - } - - // Make sure there is no existing file / directory with the new name - if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) { - r->_errno = EEXIST; - return -1; - } - - // Create the new file entry - // Get the directory it has to go in - pathEnd = strrchr (newName, DIR_SEPARATOR); - if (pathEnd == NULL) { - // No path was specified - dirCluster = partition->cwdCluster; - pathEnd = newName; - } else { - // Path was specified -- get the right dirCluster - // Recycling newDirEntry, since it needs to be recreated anyway - if (!_FAT_directory_entryFromPath (partition, &newDirEntry, newName, pathEnd) || - !_FAT_directory_isDirectory(&newDirEntry)) { - r->_errno = ENOTDIR; - return -1; - } - dirCluster = _FAT_directory_entryGetCluster (newDirEntry.entryData); - // Move the pathEnd past the last DIR_SEPARATOR - pathEnd += 1; - } - - // Copy the entry data - memcpy (&newDirEntry, &oldDirEntry, sizeof(DIR_ENTRY)); - - // Set the new name - strncpy (newDirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); - - // Write the new entry - if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) { - r->_errno = ENOSPC; - return -1; - } - - // Remove the old entry - if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) { - r->_errno = EIO; - return -1; - } - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush (partition->cache)) { - r->_errno = EIO; - return -1; - } - - return 0; -} - -int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) { - PARTITION* partition = NULL; - bool fileExists; - DIR_ENTRY dirEntry; - const char* pathEnd; - u32 parentCluster, dirCluster; - u8 newEntryData[DIR_ENTRY_DATA_SIZE]; - - partition = _FAT_partition_getPartitionFromPath (path); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Search for the file/directory on the disc - fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL); - - // Make sure it doesn't exist - if (fileExists) { - r->_errno = EEXIST; - return -1; - } - - if (partition->readOnly) { - // We can't write to a read-only partition - r->_errno = EROFS; - return -1; - } - - // Get the directory it has to go in - pathEnd = strrchr (path, DIR_SEPARATOR); - if (pathEnd == NULL) { - // No path was specified - parentCluster = partition->cwdCluster; - pathEnd = path; - } else { - // Path was specified -- get the right parentCluster - // Recycling dirEntry, since it needs to be recreated anyway - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) || - !_FAT_directory_isDirectory(&dirEntry)) { - r->_errno = ENOTDIR; - return -1; - } - parentCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); - // Move the pathEnd past the last DIR_SEPARATOR - pathEnd += 1; - } - // Create the entry data - strncpy (dirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); - memset (dirEntry.entryData, 0, DIR_ENTRY_DATA_SIZE); - - // Set the creation time and date - dirEntry.entryData[DIR_ENTRY_cTime_ms] = 0; - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cDate, _FAT_filetime_getDateFromRTC()); - - // Set the directory attribute - dirEntry.entryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - - // Get a cluster for the new directory - dirCluster = _FAT_fat_linkFreeClusterCleared (partition, CLUSTER_FREE); - if (dirCluster == CLUSTER_FREE) { - // No space left on disc for the cluster - r->_errno = ENOSPC; - return -1; - } - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cluster, dirCluster); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_clusterHigh, dirCluster >> 16); - - // Write the new directory's entry to it's parent - if (!_FAT_directory_addEntry (partition, &dirEntry, parentCluster)) { - r->_errno = ENOSPC; - return -1; - } - - // Create the dot entry within the directory - memset (newEntryData, 0, DIR_ENTRY_DATA_SIZE); - memset (newEntryData, ' ', 11); - newEntryData[DIR_ENTRY_name] = '.'; - newEntryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - u16_to_u8array (newEntryData, DIR_ENTRY_cluster, dirCluster); - u16_to_u8array (newEntryData, DIR_ENTRY_clusterHigh, dirCluster >> 16); - - // Write it to the directory, erasing that sector in the process - _FAT_cache_eraseWritePartialSector ( partition->cache, newEntryData, - _FAT_fat_clusterToSector (partition, dirCluster), 0, DIR_ENTRY_DATA_SIZE); - - - // Create the double dot entry within the directory - newEntryData[DIR_ENTRY_name + 1] = '.'; - u16_to_u8array (newEntryData, DIR_ENTRY_cluster, parentCluster); - u16_to_u8array (newEntryData, DIR_ENTRY_clusterHigh, parentCluster >> 16); - - // Write it to the directory - _FAT_cache_writePartialSector ( partition->cache, newEntryData, - _FAT_fat_clusterToSector (partition, dirCluster), DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush(partition->cache)) { - r->_errno = EIO; - return -1; - } - - return 0; -} - -DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) { - DIR_ENTRY dirEntry; - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - bool fileExists; - - state->partition = _FAT_partition_getPartitionFromPath (path); - - if (state->partition == NULL) { - r->_errno = ENODEV; - return NULL; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return NULL; - } - // Get the start cluster of the directory - fileExists = _FAT_directory_entryFromPath (state->partition, &dirEntry, path, NULL); - - if (!fileExists) { - r->_errno = ENOENT; - return NULL; - } - - // Make sure it is a directory - if (! _FAT_directory_isDirectory (&dirEntry)) { - r->_errno = ENOTDIR; - return NULL; - } - - // Save the start cluster for use when resetting the directory data - state->startCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); - - // Get the first entry for use with a call to dirnext - state->validEntry = - _FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster); - - // We are now using this entry - state->inUse = true; - return (DIR_ITER*) state; -} - -int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) { - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - - // Make sure we are still using this entry - if (!state->inUse) { - r->_errno = EBADF; - return -1; - } - - // Get the first entry for use with a call to dirnext - state->validEntry = - _FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster); - - return 0; -} - -int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat) { - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - - // Make sure we are still using this entry - if (!state->inUse) { - r->_errno = EBADF; - return -1; - } - - // Make sure there is another file to report on - if (! state->validEntry) { - r->_errno = ENOENT; - return -1; - } - - // Get the filename - strncpy (filename, state->currentEntry.filename, MAX_FILENAME_LENGTH); - // Get the stats, if requested - if (filestat != NULL) { - _FAT_directory_entryStat (state->partition, &(state->currentEntry), filestat); - } - - // Look for the next entry for use next time - state->validEntry = - _FAT_directory_getNextEntry (state->partition, &(state->currentEntry)); - - return 0; -} - -int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState) { - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - - // We are no longer using this entry - state->inUse = false; - - return 0; -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/fatdir.h b/c/src/lib/libbsp/arm/nds/libfat/source/fatdir.h deleted file mode 100644 index 48d0cdf0dd..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/fatdir.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - fatdir.h - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-13 - Chishm - * Moved all externally visible directory related functions to fatdir - * Added _FAT_mkdir_r - - 2006-08-14 - Chishm - * Added directory iterator functions - - 2007-01-10 - Chishm - * Updated directory iterator functions for DevkitPro r20 -*/ - - -#ifndef _FATDIR_H -#define _FATDIR_H - -#include <sys/reent.h> -#include <sys/stat.h> -#include <sys/iosupport.h> -#include "common.h" -#include "directory.h" - -typedef struct { - PARTITION* partition; - DIR_ENTRY currentEntry; - u32 startCluster; - bool inUse; - bool validEntry; -} DIR_STATE_STRUCT; - -extern int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st); - -extern int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink); - -extern int _FAT_unlink_r (struct _reent *r, const char *name); - -extern int _FAT_chdir_r (struct _reent *r, const char *name); - -extern int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName); - -extern int _FAT_mkdir_r (struct _reent *r, const char *path, int mode); - -/* -Directory iterator functions -*/ -extern DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path); -extern int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState); -extern int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat); -extern int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState); - - -#endif // _FATDIR_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/fatfile.c b/c/src/lib/libbsp/arm/nds/libfat/source/fatfile.c deleted file mode 100644 index 17151ab6fa..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/fatfile.c +++ /dev/null @@ -1,815 +0,0 @@ -/* - fatfile.c - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-17 - Chishm - * Made all path inputs const char* - * Added _FAT_rename_r - - 2006-08-02 - Chishm - * Fixed _FAT_seek_r - - 2006-08-13 - Chishm - * Moved all externally visible directory related functions to fatdir -*/ - - -#include "fatfile.h" - -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <unistd.h> - -#include "cache.h" -#include "file_allocation_table.h" -#include "bit_ops.h" -#include "filetime.h" - -int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { - PARTITION* partition = NULL; - bool fileExists; - DIR_ENTRY dirEntry; - const char* pathEnd; - u32 dirCluster; - FILE_STRUCT* file = (FILE_STRUCT*) fileStruct; - partition = _FAT_partition_getPartitionFromPath (path); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Determine which mode the file is openned for - if ((flags & 0x03) == O_RDONLY) { - // Open the file for read-only access - file->read = true; - file->write = false; - file->append = false; - } else if ((flags & 0x03) == O_WRONLY) { - // Open file for write only access - file->read = false; - file->write = true; - file->append = false; - } else if ((flags & 0x03) == O_RDWR) { - // Open file for read/write access - file->read = true; - file->write = true; - file->append = false; - } else { - r->_errno = EACCES; - return -1; - } - - // Make sure we aren't trying to write to a read-only disc - if (file->write && partition->readOnly) { - r->_errno = EROFS; - return -1; - } - - // Search for the file on the disc - fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL); - - // The file shouldn't exist if we are trying to create it - if ((flags & O_CREAT) && (flags & O_EXCL) && fileExists) { - r->_errno = EEXIST; - return -1; - } - - // It should not be a directory if we're openning a file, - if (fileExists && _FAT_directory_isDirectory(&dirEntry)) { - r->_errno = EISDIR; - return -1; - } - - // If the file doesn't exist, create it if we're allowed to - if (!fileExists) { - if (flags & O_CREAT) { - if (partition->readOnly) { - // We can't write to a read-only partition - r->_errno = EROFS; - return -1; - } - // Create the file - // Get the directory it has to go in - pathEnd = strrchr (path, DIR_SEPARATOR); - if (pathEnd == NULL) { - // No path was specified - dirCluster = partition->cwdCluster; - pathEnd = path; - } else { - // Path was specified -- get the right dirCluster - // Recycling dirEntry, since it needs to be recreated anyway - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) || - !_FAT_directory_isDirectory(&dirEntry)) { - r->_errno = ENOTDIR; - return -1; - } - dirCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); - // Move the pathEnd past the last DIR_SEPARATOR - pathEnd += 1; - } - // Create the entry data - strncpy (dirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); - memset (dirEntry.entryData, 0, DIR_ENTRY_DATA_SIZE); - - // Set the creation time and date - dirEntry.entryData[DIR_ENTRY_cTime_ms] = 0; - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cDate, _FAT_filetime_getDateFromRTC()); - - if (!_FAT_directory_addEntry (partition, &dirEntry, dirCluster)) { - r->_errno = ENOSPC; - return -1; - } - } else { - // file doesn't exist, and we aren't creating it - r->_errno = ENOENT; - return -1; - } - } - - file->filesize = u8array_to_u32 (dirEntry.entryData, DIR_ENTRY_fileSize); - - /* Allow LARGEFILEs with undefined results - // Make sure that the file size can fit in the available space - if (!(flags & O_LARGEFILE) && (file->filesize >= (1<<31))) { - r->_errno = EFBIG; - return -1; - } - */ - - // Make sure we aren't trying to write to a read-only file - if (file->write && !_FAT_directory_isWritable(&dirEntry)) { - r->_errno = EROFS; - return -1; - } - - // Associate this file with a particular partition - file->partition = partition; - - file->startCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); - - // Truncate the file if requested - if ((flags & O_TRUNC) && file->write && (file->startCluster != 0)) { - _FAT_fat_clearLinks (partition, file->startCluster); - file->startCluster = 0; - file->filesize = 0; - } - - // Get a new cluster for the file if required - if (file->startCluster == 0) { - file->startCluster = _FAT_fat_linkFreeCluster (partition, CLUSTER_FREE); - } - - // Remember the position of this file's directory entry - file->dirEntryStart = dirEntry.dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN - file->dirEntryEnd = dirEntry.dataEnd; - - file->currentPosition = 0; - - file->rwPosition.cluster = file->startCluster; - file->rwPosition.sector = 0; - file->rwPosition.byte = 0; - - file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster); - file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ; - file->appendPosition.byte = file->filesize % BYTES_PER_READ; - - // Check if the end of the file is on the end of a cluster - if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){ - // Set flag to allocate a new cluster - file->appendPosition.sector = partition->sectorsPerCluster; - file->appendPosition.byte = 0; - } - - if (flags & O_APPEND) { - file->append = true; - } - - file->inUse = true; - - partition->openFileCount += 1; - - return (int) file; -} - -int _FAT_close_r (struct _reent *r, int fd) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - u8 dirEntryData[DIR_ENTRY_DATA_SIZE]; - - if (!file->inUse) { - r->_errno = EBADF; - return -1; - } - if (file->write) { - // Load the old entry - _FAT_cache_readPartialSector (file->partition->cache, dirEntryData, - _FAT_fat_clusterToSector(file->partition, file->dirEntryEnd.cluster) + file->dirEntryEnd.sector, - file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - // Write new data to the directory entry - // File size - u32_to_u8array (dirEntryData, DIR_ENTRY_fileSize, file->filesize); - - // Start cluster - u16_to_u8array (dirEntryData, DIR_ENTRY_cluster, file->startCluster); - u16_to_u8array (dirEntryData, DIR_ENTRY_clusterHigh, file->startCluster >> 16); - - // Modification time and date - u16_to_u8array (dirEntryData, DIR_ENTRY_mTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntryData, DIR_ENTRY_mDate, _FAT_filetime_getDateFromRTC()); - - // Access date - u16_to_u8array (dirEntryData, DIR_ENTRY_aDate, _FAT_filetime_getDateFromRTC()); - - // Write the new entry - _FAT_cache_writePartialSector (file->partition->cache, dirEntryData, - _FAT_fat_clusterToSector(file->partition, file->dirEntryEnd.cluster) + file->dirEntryEnd.sector, - file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush(file->partition->cache)) { - r->_errno = EIO; - return -1; - } - } - - file->inUse = false; - file->partition->openFileCount -= 1; - - return 0; -} - -int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - - PARTITION* partition; - CACHE* cache; - - FILE_POSITION position; - u32 tempNextCluster; - - int tempVar; - - u32 remain; - - bool flagNoError = true; - - // Make sure we can actually read from the file - if ((file == NULL) || !file->inUse || !file->read) { - r->_errno = EBADF; - return 0; - } - - // Don't try to read if the read pointer is past the end of file - if (file->currentPosition >= file->filesize) { - return 0; - } - - // Don't read past end of file - if (len + file->currentPosition > file->filesize) { - r->_errno = EOVERFLOW; - len = file->filesize - file->currentPosition; - } - - remain = len; - - position = file->rwPosition; - - partition = file->partition; - cache = file->partition->cache; - - // Align to sector - tempVar = BYTES_PER_READ - position.byte; - if (tempVar > remain) { - tempVar = remain; - } - - if ((tempVar < BYTES_PER_READ) && flagNoError) - { - _FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, - position.byte, tempVar); - - remain -= tempVar; - ptr += tempVar; - - position.byte += tempVar; - if (position.byte >= BYTES_PER_READ) { - position.byte = 0; - position.sector++; - } - } - - // align to cluster - // tempVar is number of sectors to read - if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) { - tempVar = partition->sectorsPerCluster - position.sector; - } else { - tempVar = remain / BYTES_PER_READ; - } - - if ((tempVar > 0) && flagNoError) { - _FAT_disc_readSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, - tempVar, ptr); - ptr += tempVar * BYTES_PER_READ; - remain -= tempVar * BYTES_PER_READ; - position.sector += tempVar; - } - - // Move onto next cluster - // It should get to here without reading anything if a cluster is due to be allocated - if (position.sector >= partition->sectorsPerCluster) { - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((remain == 0) && (tempNextCluster == CLUSTER_EOF)) { - position.sector = partition->sectorsPerCluster; - } else if (tempNextCluster == CLUSTER_FREE) { - r->_errno = EIO; - flagNoError = false; - } else { - position.sector = 0; - position.cluster = tempNextCluster; - } - } - - // Read in whole clusters - while ((remain >= partition->bytesPerCluster) && flagNoError) { - _FAT_disc_readSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster), partition->sectorsPerCluster, ptr); - ptr += partition->bytesPerCluster; - remain -= partition->bytesPerCluster; - - // Advance to next cluster - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((remain == 0) && (tempNextCluster == CLUSTER_EOF)) { - position.sector = partition->sectorsPerCluster; - } else if (tempNextCluster == CLUSTER_FREE) { - r->_errno = EIO; - flagNoError = false; - } else { - position.sector = 0; - position.cluster = tempNextCluster; - } - } - - // Read remaining sectors - tempVar = remain / BYTES_PER_READ; // Number of sectors left - if ((tempVar > 0) && flagNoError) { - _FAT_disc_readSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster), - tempVar, ptr); - ptr += tempVar * BYTES_PER_READ; - remain -= tempVar * BYTES_PER_READ; - position.sector += tempVar; - } - - // Last remaining sector - // Check if anything is left - if ((remain > 0) && flagNoError) { - _FAT_cache_readPartialSector ( cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - position.byte += remain; - remain = 0; - } - - // Length read is the wanted length minus the stuff not read - len = len - remain; - - // Update file information - file->rwPosition = position; - file->currentPosition += len; - return len; -} - -/* -Extend a file so that the size is the same as the rwPosition -*/ -static bool file_extend_r (struct _reent *r, FILE_STRUCT* file) { - PARTITION* partition = file->partition; - CACHE* cache = file->partition->cache; - - FILE_POSITION position; - - u32 remain; - - u8 zeroBuffer [BYTES_PER_READ] = {0}; - - u32 tempNextCluster; - - position.byte = file->filesize % BYTES_PER_READ; - position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ; - position.cluster = _FAT_fat_lastCluster (partition, file->startCluster); - - remain = file->currentPosition - file->filesize; - - - // Only need to clear to the end of the sector - if (remain + position.byte < BYTES_PER_READ) { - _FAT_cache_writePartialSector (cache, zeroBuffer, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain); - position.byte += remain; - } else { - if (position.byte > 0) { - _FAT_cache_writePartialSector (cache, zeroBuffer, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, - BYTES_PER_READ - position.byte); - remain -= (BYTES_PER_READ - position.byte); - position.byte = 0; - position.sector ++; - } - - while (remain >= BYTES_PER_READ) { - if (position.sector >= partition->sectorsPerCluster) { - position.sector = 0; - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE)) { - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - } - if (tempNextCluster == CLUSTER_FREE) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - return false; - } else { - position.cluster = tempNextCluster; - } - } - - _FAT_disc_writeSectors (partition->disc, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 1, zeroBuffer); - - remain -= BYTES_PER_READ; - position.sector ++; - } - - if (position.sector >= partition->sectorsPerCluster) { - position.sector = 0; - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE)) { - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - } - if (tempNextCluster == CLUSTER_FREE) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - return false; - } else { - position.cluster = tempNextCluster; - } - } - - if (remain > 0) { - _FAT_cache_writePartialSector (cache, zeroBuffer, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - position.byte = remain; - } - } - - file->rwPosition = position; - file->filesize = file->currentPosition; - return true; -} - - -int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - - PARTITION* partition; - CACHE* cache; - - FILE_POSITION position; - u32 tempNextCluster; - - int tempVar; - - u32 remain; - - bool flagNoError = true; - bool flagAppending = false; - - // Make sure we can actually write to the file - if ((file == NULL) || !file->inUse || !file->write) { - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - cache = file->partition->cache; - remain = len; - - if (file->append) { - position = file->appendPosition; - flagAppending = true; - } else { - // If the write pointer is past the end of the file, extend the file to that size - if (file->currentPosition > file->filesize) { - if (!file_extend_r (r, file)) { - return 0; - } - } - - // Write at current read pointer - position = file->rwPosition; - - // If it is writing past the current end of file, set appending flag - if (len + file->currentPosition > file->filesize) { - flagAppending = true; - } - } - - // Move onto next cluster if needed - if (position.sector >= partition->sectorsPerCluster) { - position.sector = 0; - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE)) { - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - } - if (tempNextCluster == CLUSTER_FREE) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - flagNoError = false; - } else { - position.cluster = tempNextCluster; - } - } - - // Align to sector - tempVar = BYTES_PER_READ - position.byte; - if (tempVar > remain) { - tempVar = remain; - } - - if ((tempVar < BYTES_PER_READ) && flagNoError) { - // Write partial sector to disk - _FAT_cache_writePartialSector (cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar); - - remain -= tempVar; - ptr += tempVar; - position.byte += tempVar; - - - // Move onto next sector - if (position.byte >= BYTES_PER_READ) { - position.byte = 0; - position.sector ++; - } - } - - // Align to cluster - // tempVar is number of sectors to write - if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) { - tempVar = partition->sectorsPerCluster - position.sector; - } else { - tempVar = remain / BYTES_PER_READ; - } - - if ((tempVar > 0) && flagNoError) { - _FAT_disc_writeSectors (partition->disc, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, tempVar, ptr); - ptr += tempVar * BYTES_PER_READ; - remain -= tempVar * BYTES_PER_READ; - position.sector += tempVar; - } - - if ((position.sector >= partition->sectorsPerCluster) && flagNoError && (remain > 0)) { - position.sector = 0; - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE)) { - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - } - if (tempNextCluster == CLUSTER_FREE) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - flagNoError = false; - } else { - position.cluster = tempNextCluster; - } - } - - // Write whole clusters - while ((remain >= partition->bytesPerCluster) && flagNoError) { - _FAT_disc_writeSectors (partition->disc, _FAT_fat_clusterToSector(partition, position.cluster), - partition->sectorsPerCluster, ptr); - ptr += partition->bytesPerCluster; - remain -= partition->bytesPerCluster; - if (remain > 0) { - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE)) { - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - } - if (tempNextCluster == CLUSTER_FREE) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - flagNoError = false; - } else { - position.cluster = tempNextCluster; - } - } else { - // Allocate a new cluster when next writing the file - position.sector = partition->sectorsPerCluster; - } - } - - // Write remaining sectors - tempVar = remain / BYTES_PER_READ; // Number of sectors left - if ((tempVar > 0) && flagNoError) { - _FAT_disc_writeSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster), - tempVar, ptr); - ptr += tempVar * BYTES_PER_READ; - remain -= tempVar * BYTES_PER_READ; - position.sector += tempVar; - } - - // Last remaining sector - if ((remain > 0) && flagNoError) { - if (flagAppending) { - _FAT_cache_eraseWritePartialSector ( cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - } else { - _FAT_cache_writePartialSector ( cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - } - position.byte += remain; - remain = 0; - } - - - // Amount read is the originally requested amount minus stuff remaining - len = len - remain; - - // Update file information - if (file->append) { - // Appending doesn't affect the read pointer - file->appendPosition = position; - file->filesize += len; - } else { - // Writing also shifts the read pointer - file->rwPosition = position; - file->currentPosition += len; - if (file->filesize < file->currentPosition) { - file->filesize = file->currentPosition; - } - } - - return len; -} - - -int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - - PARTITION* partition; - - u32 cluster, nextCluster; - int clusCount; - int position; - - if ((file == NULL) || (file->inUse == false)) { - // invalid file - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - - switch (dir) { - case SEEK_SET: - position = pos; - break; - case SEEK_CUR: - position = file->currentPosition + pos; - break; - case SEEK_END: - position = file->filesize + pos; - break; - default: - r->_errno = EINVAL; - return -1; - } - - if ((pos > 0) && (position < 0)) { - r->_errno = EOVERFLOW; - return -1; - } - - if (position < 0) { - r->_errno = EINVAL; - return -1; - } - - // Only change the read/write position if it is within the bounds of the current filesize - if (file->filesize > position) { - - // Calculate the sector and byte of the current position, - // and store them - file->rwPosition.sector = (position % partition->bytesPerCluster) / BYTES_PER_READ; - file->rwPosition.byte = position % BYTES_PER_READ; - - // Calculate where the correct cluster is - if (position >= file->currentPosition) { - clusCount = (position / partition->bytesPerCluster) - (file->currentPosition / partition->bytesPerCluster); - cluster = file->rwPosition.cluster; - } else { - clusCount = position / partition->bytesPerCluster; - cluster = file->startCluster; - } - - nextCluster = _FAT_fat_nextCluster (partition, cluster); - while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) { - clusCount--; - cluster = nextCluster; - nextCluster = _FAT_fat_nextCluster (partition, cluster); - } - - // Check if ran out of clusters, and the file is being written to - if ((clusCount > 0) && (file->write || file->append)) { - // Set flag to allocate a new cluster - file->rwPosition.sector = partition->sectorsPerCluster; - file->rwPosition.byte = 0; - } - - file->rwPosition.cluster = cluster; - } - - // Save position - file->currentPosition = position; - - return position; -} - - - -int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - - PARTITION* partition; - - DIR_ENTRY fileEntry; - - if ((file == NULL) || (file->inUse == false)) { - // invalid file - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - - // Get the file's entry data - fileEntry.dataStart = file->dirEntryStart; - fileEntry.dataEnd = file->dirEntryEnd; - - if (!_FAT_directory_entryFromPosition (partition, &fileEntry)) { - r->_errno = EIO; - return -1; - } - - // Fill in the stat struct - _FAT_directory_entryStat (partition, &fileEntry, st); - - // Fix stats that have changed since the file was openned - st->st_ino = (ino_t)(file->startCluster); // The file serial number is the start cluster - st->st_size = file->filesize; // File size - - return 0; -} - diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/fatfile.h b/c/src/lib/libbsp/arm/nds/libfat/source/fatfile.h deleted file mode 100644 index 2258045d7a..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/fatfile.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - fatfile.h - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-17 - Chishm - * Made all path inputs const char* - * Added _FAT_rename_r - - 2006-07-24 - Chishm - * Removed padding workaround from FILE_STRUCT - - 2006-08-13 - Chishm - * Moved all externally visible directory related functions to fatdir -*/ - - -#ifndef _FATFILE_H -#define _FATFILE_H - -#include <sys/reent.h> -#include <sys/stat.h> - -#include "common.h" -#include "partition.h" -#include "directory.h" - -typedef struct { - u32 cluster; - u32 sector; - s32 byte; -} FILE_POSITION; - -typedef struct { - u32 filesize; - u32 startCluster; - u32 currentPosition; - FILE_POSITION rwPosition; - FILE_POSITION appendPosition; - bool read; - bool write; - bool append; - bool inUse; - PARTITION* partition; - DIR_ENTRY_POSITION dirEntryStart; // Points to the start of the LFN entries of a file, or the alias for no LFN - DIR_ENTRY_POSITION dirEntryEnd; // Always points to the file's alias entry -} FILE_STRUCT; - -extern int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode); - -extern int _FAT_close_r (struct _reent *r, int fd); - -extern int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len); - -extern int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len); - -extern int _FAT_seek_r (struct _reent *r, int fd,int pos, int dir); - -extern int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st); - -extern int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st); - -extern int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink); - -extern int _FAT_unlink_r (struct _reent *r, const char *name); - -extern int _FAT_chdir_r (struct _reent *r, const char *name); - -extern int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName); - -#endif // _FATFILE_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/file_allocation_table.c b/c/src/lib/libbsp/arm/nds/libfat/source/file_allocation_table.c deleted file mode 100644 index f85ec3b196..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/file_allocation_table.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - file_allocation_table.c - Reading, writing and manipulation of the FAT structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-07-11 - Chishm - * Made several fixes related to free clusters, thanks to Loopy - - 2006-10-01 - Chishm - * Added _FAT_fat_linkFreeClusterCleared to clear a cluster when it is allocated -*/ - - -#include "file_allocation_table.h" -#include "partition.h" -#include <string.h> - -/* -Gets the cluster linked from input cluster -*/ -u32 _FAT_fat_nextCluster(PARTITION* partition, u32 cluster) -{ - u32 nextCluster = CLUSTER_FREE; - u32 sector; - int offset; - - switch (partition->filesysType) - { - case FS_UNKNOWN: - nextCluster = CLUSTER_FREE; - break; - - case FS_FAT12: - sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ); - offset = ((cluster * 3) / 2) % BYTES_PER_READ; - - - _FAT_cache_readPartialSector (partition->cache, &nextCluster, sector, offset, sizeof(u8)); - - offset++; - - if (offset >= BYTES_PER_READ) { - offset = 0; - sector++; - } - - _FAT_cache_readPartialSector (partition->cache, ((u8*)&nextCluster) + sizeof(u8), sector, offset, sizeof(u8)); - - if (cluster & 0x01) { - nextCluster = nextCluster >> 4; - } else { - nextCluster &= 0x0FFF; - } - - if (nextCluster >= 0x0FF7) - { - nextCluster = CLUSTER_EOF; - } - - break; - - case FS_FAT16: - sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ); - offset = (cluster % (BYTES_PER_READ >> 1)) << 1; - - _FAT_cache_readPartialSector (partition->cache, &nextCluster, sector, offset, sizeof(u16)); - - if (nextCluster >= 0xFFF7) - { - nextCluster = CLUSTER_EOF; - } - break; - - case FS_FAT32: - sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ); - offset = (cluster % (BYTES_PER_READ >> 2)) << 2; - - _FAT_cache_readPartialSector (partition->cache, &nextCluster, sector, offset, sizeof(u32)); - - if (nextCluster >= 0x0FFFFFF7) - { - nextCluster = CLUSTER_EOF; - } - break; - - default: - nextCluster = CLUSTER_FREE; - break; - } - - return nextCluster; -} - -/* -writes value into the correct offset within a partition's FAT, based -on the cluster number. -*/ -static bool _FAT_fat_writeFatEntry (PARTITION* partition, u32 cluster, u32 value) { - u32 sector; - int offset; - u8 oldValue; - - if ((cluster < 0x0002) || (cluster > partition->fat.lastCluster)) - { - return false; - } - - switch (partition->filesysType) - { - case FS_UNKNOWN: - return false; - break; - - case FS_FAT12: - sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ); - offset = ((cluster * 3) / 2) % BYTES_PER_READ; - - if (cluster & 0x01) { - - _FAT_cache_readPartialSector (partition->cache, &oldValue, sector, offset, sizeof(u8)); - - value = (value << 4) | (oldValue & 0x0F); - - _FAT_cache_writePartialSector (partition->cache, &value, sector, offset, sizeof(u8)); - - offset++; - if (offset >= BYTES_PER_READ) { - offset = 0; - sector++; - } - - _FAT_cache_writePartialSector (partition->cache, ((u8*)&value) + sizeof(u8), sector, offset, sizeof(u8)); - - } else { - - _FAT_cache_writePartialSector (partition->cache, &value, sector, offset, sizeof(u8)); - - offset++; - if (offset >= BYTES_PER_READ) { - offset = 0; - sector++; - } - - _FAT_cache_readPartialSector (partition->cache, &oldValue, sector, offset, sizeof(u8)); - - value = ((value >> 8) & 0x0F) | (oldValue & 0xF0); - - _FAT_cache_writePartialSector (partition->cache, &value, sector, offset, sizeof(u8)); - } - - break; - - case FS_FAT16: - sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ); - offset = (cluster % (BYTES_PER_READ >> 1)) << 1; - - _FAT_cache_writePartialSector (partition->cache, &value, sector, offset, sizeof(u16)); - - break; - - case FS_FAT32: - sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ); - offset = (cluster % (BYTES_PER_READ >> 2)) << 2; - - _FAT_cache_writePartialSector (partition->cache, &value, sector, offset, sizeof(u32)); - - break; - - default: - return false; - break; - } - - return true; -} - -/*----------------------------------------------------------------- -gets the first available free cluster, sets it -to end of file, links the input cluster to it then returns the -cluster number -If an error occurs, return CLUSTER_FREE ------------------------------------------------------------------*/ -u32 _FAT_fat_linkFreeCluster(PARTITION* partition, u32 cluster) { - u32 firstFree; - u32 curLink; - u32 lastCluster; - bool loopedAroundFAT = false; - - lastCluster = partition->fat.lastCluster; - - if (cluster > lastCluster) { - return CLUSTER_FREE; - } - - // Check if the cluster already has a link, and return it if so - curLink = _FAT_fat_nextCluster(partition, cluster); - if ((curLink >= CLUSTER_FIRST) && (curLink <= lastCluster)) { - return curLink; // Return the current link - don't allocate a new one - } - - // Get a free cluster - firstFree = partition->fat.firstFree; - // Start at first valid cluster - if (firstFree < CLUSTER_FIRST) { - firstFree = CLUSTER_FIRST; - } - - // Search until a free cluster is found - while (_FAT_fat_nextCluster(partition, firstFree) != CLUSTER_FREE) { - firstFree++; - if (firstFree > lastCluster) { - if (loopedAroundFAT) { - // If couldn't get a free cluster then return, saying this fact - partition->fat.firstFree = firstFree; - return CLUSTER_FREE; - } else { - // Try looping back to the beginning of the FAT - // This was suggested by loopy - firstFree = CLUSTER_FIRST; - loopedAroundFAT = true; - } - } - } - partition->fat.firstFree = firstFree; - - if ((cluster >= CLUSTER_FIRST) && (cluster < lastCluster)) - { - // Update the linked from FAT entry - _FAT_fat_writeFatEntry (partition, cluster, firstFree); - } - // Create the linked to FAT entry - _FAT_fat_writeFatEntry (partition, firstFree, CLUSTER_EOF); - - return firstFree; -} - -/*----------------------------------------------------------------- -gets the first available free cluster, sets it -to end of file, links the input cluster to it, clears the new -cluster to 0 valued bytes, then returns the cluster number -If an error occurs, return CLUSTER_FREE ------------------------------------------------------------------*/ -u32 _FAT_fat_linkFreeClusterCleared (PARTITION* partition, u32 cluster) { - u32 newCluster; - int i; - u8 emptySector[BYTES_PER_READ]; - - // Link the cluster - newCluster = _FAT_fat_linkFreeCluster(partition, cluster); - - if (newCluster == CLUSTER_FREE) { - return CLUSTER_FREE; - } - - // Clear all the sectors within the cluster - memset (emptySector, 0, BYTES_PER_READ); - for (i = 0; i < partition->sectorsPerCluster; i++) { - _FAT_disc_writeSectors (partition->disc, - _FAT_fat_clusterToSector (partition, newCluster) + i, - 1, emptySector); - } - - return newCluster; -} - - -/*----------------------------------------------------------------- -_FAT_fat_clearLinks -frees any cluster used by a file ------------------------------------------------------------------*/ -bool _FAT_fat_clearLinks (PARTITION* partition, u32 cluster) { - u32 nextCluster; - - if ((cluster < 0x0002) || (cluster > partition->fat.lastCluster)) - return false; - - // If this clears up more space in the FAT before the current free pointer, move it backwards - if (cluster < partition->fat.firstFree) { - partition->fat.firstFree = cluster; - } - - while ((cluster != CLUSTER_EOF) && (cluster != CLUSTER_FREE)) { - // Store next cluster before erasing the link - nextCluster = _FAT_fat_nextCluster (partition, cluster); - - // Erase the link - _FAT_fat_writeFatEntry (partition, cluster, CLUSTER_FREE); - - // Move onto next cluster - cluster = nextCluster; - } - - return true; -} - -/*----------------------------------------------------------------- -_FAT_fat_lastCluster -Trace the cluster links until the last one is found ------------------------------------------------------------------*/ -u32 _FAT_fat_lastCluster (PARTITION* partition, u32 cluster) { - while ((_FAT_fat_nextCluster(partition, cluster) != CLUSTER_FREE) && (_FAT_fat_nextCluster(partition, cluster) != CLUSTER_EOF)) { - cluster = _FAT_fat_nextCluster(partition, cluster); - } - return cluster; -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/file_allocation_table.h b/c/src/lib/libbsp/arm/nds/libfat/source/file_allocation_table.h deleted file mode 100644 index 21ed549e7e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/file_allocation_table.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - file_allocation_table.h - Reading, writing and manipulation of the FAT structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-10-01 - Chishm - * Added _FAT_fat_linkFreeClusterCleared to clear a cluster when it is allocated -*/ - -#ifndef _FAT_H -#define _FAT_H - -#include "common.h" -#include "partition.h" - -#define CLUSTER_EOF_16 0xFFFF -#define CLUSTER_EOF 0x0FFFFFFF -#define CLUSTER_FREE 0x0000 -#define CLUSTER_FIRST 0x0002 - -#define CLUSTERS_PER_FAT12 4085 -#define CLUSTERS_PER_FAT16 65525 - - -u32 _FAT_fat_nextCluster(PARTITION* partition, u32 cluster); - -u32 _FAT_fat_linkFreeCluster(PARTITION* partition, u32 cluster); -u32 _FAT_fat_linkFreeClusterCleared (PARTITION* partition, u32 cluster); - -bool _FAT_fat_clearLinks (PARTITION* partition, u32 cluster); - -u32 _FAT_fat_lastCluster (PARTITION* partition, u32 cluster); - -static inline u32 _FAT_fat_clusterToSector (PARTITION* partition, u32 cluster) { - return (cluster >= 2) ? ((cluster - 2) * partition->sectorsPerCluster) + partition->dataStart : partition->rootDirStart; -} - -#endif // _FAT_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/filetime.c b/c/src/lib/libbsp/arm/nds/libfat/source/filetime.c deleted file mode 100644 index 4619225d71..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/filetime.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - filetime.c - Conversion of file time and date values to various other types - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-09-30 - Chishm - * Validity checks performed on the time supplied by the IPC - * Cleaned up magic numbers - - 2006-10-01 - Chishm - * Fixed incorrect use of bitwise-or instead of logical-or -*/ - - -#include "filetime.h" - -#ifdef NDS -#include <nds/ipc.h> -#endif - -#define HOUR_PM_INDICATOR 40 - -#define MAX_HOUR 23 -#define MAX_MINUTE 59 -#define MAX_SECOND 59 - -#define MAX_YEAR 99 -#define MIN_YEAR 6 // The date is invalid if it's before this year -#define MAX_MONTH 12 -#define MIN_MONTH 1 -#define MAX_DAY 31 -#define MIN_DAY 1 - -// Second values are averages, so time value won't be 100% accurate, -// but should be within the correct month. -#define SECONDS_PER_MINUTE 60 -#define SECONDS_PER_HOUR 3600 -#define SECONDS_PER_DAY 86400 -#define SECONDS_PER_MONTH 2629743 -#define SECONDS_PER_YEAR 31556926 - -u16 _FAT_filetime_getTimeFromRTC (void) { -#ifdef NDS - int hour, minute, second; - hour = (IPC->time.rtc.hours >= HOUR_PM_INDICATOR ? IPC->time.rtc.hours - HOUR_PM_INDICATOR : IPC->time.rtc.hours); - minute = IPC->time.rtc.minutes; - second = IPC->time.rtc.seconds; - - // Check that the values are all in range. - // If they are not, return 0 (no timestamp) - if ((hour < 0) || (hour > MAX_HOUR)) return 0; - if ((minute < 0) || (minute > MAX_MINUTE)) return 0; - if ((second < 0) || (second > MAX_SECOND)) return 0; - - return ( - ((hour & 0x1F) << 11) | - ((minute & 0x3F) << 5) | - ((second >> 1) & 0x1F) - ); -#else - return 0; -#endif -} - - -u16 _FAT_filetime_getDateFromRTC (void) { -#ifdef NDS - int year, month, day; - - year = IPC->time.rtc.year; - month = IPC->time.rtc.month; - day = IPC->time.rtc.day; - - if ((year < MIN_YEAR) || (year > MAX_YEAR)) return 0; - if ((month < MIN_MONTH) || (month > MAX_MONTH)) return 0; - if ((day < MIN_DAY) || (day > MAX_DAY)) return 0; - - return ( - (((year + 20) & 0x7F) <<9) | // Adjust for MS-FAT base year (1980 vs 2000 for DS clock) - ((month & 0xF) << 5) | - (day & 0x1F) - ); -#else - return 0; -#endif -} - -time_t _FAT_filetime_to_time_t (u16 time, u16 date) { - int hour, minute, second; - int day, month, year; - - time_t result; - - hour = time >> 11; - minute = (time >> 5) & 0x3F; - second = (time & 0x1F) << 1; - - day = date & 0x1F; - month = (date >> 5) & 0x0F; - year = date >> 9; - - // Second values are averages, so time value won't be 100% accurate, - // but should be within the correct month. - result = second - + minute * SECONDS_PER_MINUTE - + hour * SECONDS_PER_HOUR - + day * SECONDS_PER_DAY - + month * SECONDS_PER_MONTH - + year * SECONDS_PER_YEAR - ; - - return result; -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/filetime.h b/c/src/lib/libbsp/arm/nds/libfat/source/filetime.h deleted file mode 100644 index a69521b4fc..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/filetime.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - filetime.h - Conversion of file time and date values to various other types - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _FILETIME_H -#define _FILETIME_H - -#include "common.h" -#include <sys/types.h> - -u16 _FAT_filetime_getTimeFromRTC (void); -u16 _FAT_filetime_getDateFromRTC (void); - -time_t _FAT_filetime_to_time_t (u16 time, u16 date); - - -#endif // _FILETIME_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/libfat.c b/c/src/lib/libbsp/arm/nds/libfat/source/libfat.c deleted file mode 100644 index 6b07236052..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/libfat.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - libfat.c - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-08-13 - Chishm - * Moved all externally visible directory related functions to fatdir - - 2006-08-14 - Chishm - * Added extended devoptab_t functions - - 2007-01-10 - Chishm - * fatInit now sets the correct path when setAsDefaultDevice - - 2007-01-11 - Chishm - * Added missing #include <unistd.h> -*/ - -#include <sys/iosupport.h> -#include <unistd.h> - -#include "common.h" -#include "partition.h" -#include "fatfile.h" -#include "fatdir.h" - -#define GBA_DEFAULT_CACHE_PAGES 2 -#define NDS_DEFAULT_CACHE_PAGES 8 - - -const devoptab_t dotab_fat = { - "fat", - sizeof (FILE_STRUCT), - _FAT_open_r, - _FAT_close_r, - _FAT_write_r, - _FAT_read_r, - _FAT_seek_r, - _FAT_fstat_r, - _FAT_stat_r, - _FAT_link_r, - _FAT_unlink_r, - _FAT_chdir_r, - _FAT_rename_r, - _FAT_mkdir_r, - sizeof (DIR_STATE_STRUCT), - _FAT_diropen_r, - _FAT_dirreset_r, - _FAT_dirnext_r, - _FAT_dirclose_r -}; - -bool fatInit (u32 cacheSize, bool setAsDefaultDevice) { -#ifdef NDS - bool slot1Device, slot2Device; - - // Try mounting both slots - slot1Device = _FAT_partition_mount (PI_SLOT_1, cacheSize); - slot2Device = _FAT_partition_mount (PI_SLOT_2, cacheSize); - - // Choose the default device - if (slot1Device) { - _FAT_partition_setDefaultInterface (PI_SLOT_1); - } else if (slot2Device) { - _FAT_partition_setDefaultInterface (PI_SLOT_2); - } else { - return false; - } - -#else // not defined NDS - bool cartSlotDevice; - - cartSlotDevice = _FAT_partition_mount (PI_CART_SLOT, cacheSize); - - if (cartSlotDevice) { - _FAT_partition_setDefaultInterface (PI_CART_SLOT); - } else { - return false; - } - -#endif // defined NDS - - AddDevice (&dotab_fat); - - if (setAsDefaultDevice) { - chdir ("fat:/"); - } - - return true; -} - -bool fatInitDefault (void) { -#ifdef NDS - return fatInit (NDS_DEFAULT_CACHE_PAGES, true); -#else - return fatInit (GBA_DEFAULT_CACHE_PAGES, true); -#endif -} - -bool fatMountNormalInterface (PARTITION_INTERFACE partitionNumber, u32 cacheSize) { - return _FAT_partition_mount (partitionNumber, cacheSize); -} - -bool fatMountCustomInterface (const IO_INTERFACE* device, u32 cacheSize) { - return _FAT_partition_mountCustomInterface (device, cacheSize); -} - -bool fatUnmount (PARTITION_INTERFACE partitionNumber) { - return _FAT_partition_unmount (partitionNumber); -} - - -bool fatUnsafeUnmount (PARTITION_INTERFACE partitionNumber) { - return _FAT_partition_unsafeUnmount (partitionNumber); -} - -bool fatSetDefaultInterface (PARTITION_INTERFACE partitionNumber) { - return _FAT_partition_setDefaultInterface (partitionNumber); -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/mem_allocate.h b/c/src/lib/libbsp/arm/nds/libfat/source/mem_allocate.h deleted file mode 100644 index 056023716e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/mem_allocate.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - mem_allocate.h - Memory allocation and destruction calls - Replace these calls with custom allocators if - malloc is unavailable - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _MEM_ALLOCATE_H -#define _MEM_ALLOCATE_H - -#include <malloc.h> - -static inline void* _FAT_mem_allocate (size_t size) { - return malloc (size); -} - -static inline void _FAT_mem_free (void* mem) { - return free (mem); -} - -#endif // _MEM_ALLOCATE_H diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/partition.c b/c/src/lib/libbsp/arm/nds/libfat/source/partition.c deleted file mode 100644 index 9d3862793e..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/partition.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - partition.c - Functions for mounting and dismounting partitions - on various block devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release - - 2006-08-10 - Chishm - * Fixed problem when openning files starting with "fat" - - 2006-10-28 - Chishm - * _partitions changed to _FAT_partitions to maintain the same style of naming as the functions -*/ - - -#include "partition.h" -#include "bit_ops.h" -#include "file_allocation_table.h" -#include "directory.h" - -#include <string.h> -#include <ctype.h> - -#include "mem_allocate.h" - -/* -This device name, as known by DevKitPro -*/ -const char* DEVICE_NAME = "fat"; - -/* -Data offsets -*/ - -// BIOS Parameter Block offsets -enum BPB { - BPB_jmpBoot = 0x00, - BPB_OEMName = 0x03, - // BIOS Parameter Block - BPB_bytesPerSector = 0x0B, - BPB_sectorsPerCluster = 0x0D, - BPB_reservedSectors = 0x0E, - BPB_numFATs = 0x10, - BPB_rootEntries = 0x11, - BPB_numSectorsSmall = 0x13, - BPB_mediaDesc = 0x15, - BPB_sectorsPerFAT = 0x16, - BPB_sectorsPerTrk = 0x18, - BPB_numHeads = 0x1A, - BPB_numHiddenSectors = 0x1C, - BPB_numSectors = 0x20, - // Ext BIOS Parameter Block for FAT16 - BPB_FAT16_driveNumber = 0x24, - BPB_FAT16_reserved1 = 0x25, - BPB_FAT16_extBootSig = 0x26, - BPB_FAT16_volumeID = 0x27, - BPB_FAT16_volumeLabel = 0x2B, - BPB_FAT16_fileSysType = 0x36, - // Bootcode - BPB_FAT16_bootCode = 0x3E, - // FAT32 extended block - BPB_FAT32_sectorsPerFAT32 = 0x24, - BPB_FAT32_extFlags = 0x28, - BPB_FAT32_fsVer = 0x2A, - BPB_FAT32_rootClus = 0x2C, - BPB_FAT32_fsInfo = 0x30, - BPB_FAT32_bkBootSec = 0x32, - // Ext BIOS Parameter Block for FAT32 - BPB_FAT32_driveNumber = 0x40, - BPB_FAT32_reserved1 = 0x41, - BPB_FAT32_extBootSig = 0x42, - BPB_FAT32_volumeID = 0x43, - BPB_FAT32_volumeLabel = 0x47, - BPB_FAT32_fileSysType = 0x52, - // Bootcode - BPB_FAT32_bootCode = 0x5A, - BPB_bootSig_55 = 0x1FE, - BPB_bootSig_AA = 0x1FF -}; - - -#ifdef NDS -#define MAXIMUM_PARTITIONS 4 -PARTITION* _FAT_partitions[MAXIMUM_PARTITIONS] = {NULL}; -#else // not defined NDS -#define MAXIMUM_PARTITIONS 1 -PARTITION* _FAT_partitions[MAXIMUM_PARTITIONS] = {NULL}; -#endif // defined NDS - -// Use a single static buffer for the partitions - - -static PARTITION* _FAT_partition_constructor ( const IO_INTERFACE* disc, u32 cacheSize) { - PARTITION* partition; - int i; - u32 bootSector; - u8 sectorBuffer[BYTES_PER_READ] = {0}; - - // Read first sector of disc - if ( !_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) { - return NULL; - } - - // Make sure it is a valid MBR or boot sector - if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) { - return NULL; - } - - // Check if there is a FAT string, which indicates this is a boot sector - if ((sectorBuffer[0x36] == 'F') && (sectorBuffer[0x37] == 'A') && (sectorBuffer[0x38] == 'T')) { - bootSector = 0; - } else if ((sectorBuffer[0x52] == 'F') && (sectorBuffer[0x53] == 'A') && (sectorBuffer[0x54] == 'T')) { - // Check for FAT32 - bootSector = 0; - } else { - // This is an MBR - // Find first valid partition from MBR - // First check for an active partition - for (i=0x1BE; (i < 0x1FE) && (sectorBuffer[i] != 0x80); i+= 0x10); - // If it didn't find an active partition, search for any valid partition - if (i == 0x1FE) { - for (i=0x1BE; (i < 0x1FE) && (sectorBuffer[i+0x04] == 0x00); i+= 0x10); - } - - // Go to first valid partition - if ( i != 0x1FE) { - // Make sure it found a partition - bootSector = u8array_to_u32(sectorBuffer, 0x8 + i); - } else { - bootSector = 0; // No partition found, assume this is a MBR free disk - } - } - - // Read in boot sector - if ( !_FAT_disc_readSectors (disc, bootSector, 1, sectorBuffer)) { - return NULL; - } - - partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION)); - if (partition == NULL) { - return NULL; - } - - // Set partition's disc interface - partition->disc = disc; - - // Store required information about the file system - partition->fat.sectorsPerFat = u8array_to_u16(sectorBuffer, BPB_sectorsPerFAT); - if (partition->fat.sectorsPerFat == 0) { - partition->fat.sectorsPerFat = u8array_to_u32( sectorBuffer, BPB_FAT32_sectorsPerFAT32); - } - - partition->numberOfSectors = u8array_to_u16( sectorBuffer, BPB_numSectorsSmall); - if (partition->numberOfSectors == 0) { - partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors); - } - - partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes - partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ; - partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster; - partition->fat.fatStart = bootSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors); - - partition->rootDirStart = partition->fat.fatStart + (sectorBuffer[BPB_numFATs] * partition->fat.sectorsPerFat); - partition->dataStart = partition->rootDirStart + (( u8array_to_u16(sectorBuffer, BPB_rootEntries) * DIR_ENTRY_DATA_SIZE) / partition->bytesPerSector); - - partition->totalSize = (partition->numberOfSectors - partition->dataStart) * partition->bytesPerSector; - - // Store info about FAT - partition->fat.lastCluster = (partition->numberOfSectors - partition->dataStart) / partition->sectorsPerCluster; - partition->fat.firstFree = CLUSTER_FIRST; - - if (partition->fat.lastCluster < CLUSTERS_PER_FAT12) { - partition->filesysType = FS_FAT12; // FAT12 volume - } else if (partition->fat.lastCluster < CLUSTERS_PER_FAT16) { - partition->filesysType = FS_FAT16; // FAT16 volume - } else { - partition->filesysType = FS_FAT32; // FAT32 volume - } - - if (partition->filesysType != FS_FAT32) { - partition->rootDirCluster = FAT16_ROOT_DIR_CLUSTER; - } else { - // Set up for the FAT32 way - partition->rootDirCluster = u8array_to_u32(sectorBuffer, BPB_FAT32_rootClus); - // Check if FAT mirroring is enabled - if (!(sectorBuffer[BPB_FAT32_extFlags] & 0x80)) { - // Use the active FAT - partition->fat.fatStart = partition->fat.fatStart + ( partition->fat.sectorsPerFat * (sectorBuffer[BPB_FAT32_extFlags] & 0x0F)); - } - } - - // Create a cache to use - partition->cache = _FAT_cache_constructor (cacheSize, partition->disc); - - // Set current directory to the root - partition->cwdCluster = partition->rootDirCluster; - - // Check if this disc is writable, and set the readOnly property appropriately - partition->readOnly = !(_FAT_disc_features(disc) & FEATURE_MEDIUM_CANWRITE); - - // There are currently no open files on this partition - partition->openFileCount = 0; - - return partition; -} - -static void _FAT_partition_destructor (PARTITION* partition) { - _FAT_cache_destructor (partition->cache); - _FAT_disc_shutdown (partition->disc); - _FAT_mem_free (partition); -} - -bool _FAT_partition_mount (PARTITION_INTERFACE partitionNumber, u32 cacheSize) { -#ifdef NDS - int i; - const IO_INTERFACE* disc = NULL; - - if (_FAT_partitions[partitionNumber] != NULL) { - return false; - } - - switch (partitionNumber) { - case PI_SLOT_1: - // Mount the disc in slot 1 - disc = _FAT_disc_dsSlotFindInterface (); - break; - case PI_SLOT_2: - // Mount the disc in slot 2 - disc = _FAT_disc_gbaSlotFindInterface (); - break; - case PI_DEFAULT: - case PI_CUSTOM: - default: - // Anything else has to be handled specially - return false; - break; - } - - if (disc == NULL) { - return false; - } - - // See if that disc is already in use, if so, then just copy the partition pointer - for (i = 0; i < MAXIMUM_PARTITIONS; i++) { - if ((_FAT_partitions[i] != NULL) && (_FAT_partitions[i]->disc == disc)) { - _FAT_partitions[partitionNumber] = _FAT_partitions[i]; - return true; - } - } - - _FAT_partitions[partitionNumber] = _FAT_partition_constructor (disc, cacheSize); - - if (_FAT_partitions[partitionNumber] == NULL) { - return false; - } - -#else // not defined NDS - const IO_INTERFACE* disc = NULL; - - if (_FAT_partitions[partitionNumber] != NULL) { - return false; - } - - // Only ever one partition on GBA - disc = _FAT_disc_gbaSlotFindInterface (); - _FAT_partitions[partitionNumber] = _FAT_partition_constructor (disc, cacheSize); - -#endif // defined NDS - - return true; -} - -bool _FAT_partition_mountCustomInterface (const IO_INTERFACE* device, u32 cacheSize) { -#ifdef NDS - int i; - - if (_FAT_partitions[PI_CUSTOM] != NULL) { - return false; - } - - if (device == NULL) { - return false; - } - - // See if that disc is already in use, if so, then just copy the partition pointer - for (i = 0; i < MAXIMUM_PARTITIONS; i++) { - if ((_FAT_partitions[i] != NULL) && (_FAT_partitions[i]->disc == device)) { - _FAT_partitions[PI_CUSTOM] = _FAT_partitions[i]; - return true; - } - } - - _FAT_partitions[PI_CUSTOM] = _FAT_partition_constructor (device, cacheSize); - - if (_FAT_partitions[PI_CUSTOM] == NULL) { - return false; - } - -#else // not defined NDS - if (_FAT_partitions[PI_CART_SLOT] != NULL) { - return false; - } - - if (device == NULL) { - return false; - } - - // Only ever one partition on GBA - _FAT_partitions[PI_CART_SLOT] = _FAT_partition_constructor (device, cacheSize); - -#endif // defined NDS - - return true; -} - -bool _FAT_partition_setDefaultInterface (PARTITION_INTERFACE partitionNumber) { -#ifdef NDS // Can only set the default partition when there is more than 1, so doesn't apply to GBA - if ((partitionNumber < 1) || (partitionNumber >= MAXIMUM_PARTITIONS)) { - return false; - } - - if (_FAT_partitions[partitionNumber] == NULL) { - return false; - } - - _FAT_partitions[PI_DEFAULT] = _FAT_partitions[partitionNumber]; -#endif - return true; -} - -bool _FAT_partition_setDefaultPartition (PARTITION* partition) { -#ifdef NDS // Can only set the default partition when there is more than 1, so doesn't apply to GBA - int i; - - if (partition == NULL) { - return false; - } - - // Ensure that this device is already in the list - for (i = 1; i < MAXIMUM_PARTITIONS; i++) { - if (_FAT_partitions[i] == partition) { - break; - } - } - - // It wasn't in the list, so fail - if (i == MAXIMUM_PARTITIONS) { - return false; - } - - // Change the default partition / device to this one - _FAT_partitions[PI_DEFAULT] = partition; - -#endif - return true; -} - -bool _FAT_partition_unmount (PARTITION_INTERFACE partitionNumber) { - int i; - PARTITION* partition = _FAT_partitions[partitionNumber]; - - if (partition == NULL) { - return false; - } - - if (partition->openFileCount > 0) { - // There are still open files that need closing - return false; - } - - // Remove all references to this partition - for (i = 0; i < MAXIMUM_PARTITIONS; i++) { - if (_FAT_partitions[i] == partition) { - _FAT_partitions[i] = NULL; - } - } - - _FAT_partition_destructor (partition); - return true; -} - -bool _FAT_partition_unsafeUnmount (PARTITION_INTERFACE partitionNumber) { - int i; - PARTITION* partition = _FAT_partitions[partitionNumber]; - - if (partition == NULL) { - return false; - } - - // Remove all references to this partition - for (i = 0; i < MAXIMUM_PARTITIONS; i++) { - if (_FAT_partitions[i] == partition) { - _FAT_partitions[i] = NULL; - } - } - - _FAT_cache_invalidate (partition->cache); - _FAT_partition_destructor (partition); - return true; -} - -PARTITION* _FAT_partition_getPartitionFromPath (const char* path) { -#ifdef NDS - int namelen; - int partitionNumber; - - // Device name extraction code taken from DevKitPro - namelen = strlen(DEVICE_NAME); - if (strchr (path, ':') == NULL) { - // No device specified - partitionNumber = PI_DEFAULT; - } else if( strncmp(DEVICE_NAME, path, namelen) == 0 ) { - if ( path[namelen] == ':' ) { - // Only the device name is specified - partitionNumber = PI_DEFAULT; - } else if (isdigit(path[namelen]) && path[namelen+1] ==':' ) { - // Device name and number specified - partitionNumber = path[namelen] - '0'; - } else { - // Incorrect device name - return NULL; - } - } else { - // Incorrect device name - return NULL; - } - - if ((partitionNumber < 0) || (partitionNumber >= MAXIMUM_PARTITIONS)) { - return NULL; - } - - return _FAT_partitions[partitionNumber]; -#else // not defined NDS - // Only one possible partition on GBA - return _FAT_partitions[PI_CART_SLOT]; -#endif // defined NDS -} diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/partition.h b/c/src/lib/libbsp/arm/nds/libfat/source/partition.h deleted file mode 100644 index 29f06f8a76..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/partition.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - partition.h - Functions for mounting and dismounting partitions - on various block devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-07-11 - Chishm - * Original release -*/ - -#ifndef _PARTITION_H -#define _PARTITION_H - -#include "common.h" - -#include "disc_io/disc.h" -#include "cache.h" - -// Device name -extern const char* DEVICE_NAME; - -// Filesystem type -typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE; - -#ifdef NDS -typedef enum {PI_DEFAULT, PI_SLOT_1, PI_SLOT_2, PI_CUSTOM} PARTITION_INTERFACE; -#else -typedef enum {PI_CART_SLOT} PARTITION_INTERFACE; -#endif - -typedef struct { - u32 fatStart; - u32 sectorsPerFat; - u32 lastCluster; - u32 firstFree; -} FAT; - -typedef struct { - const IO_INTERFACE* disc; - CACHE* cache; - // Info about the partition - bool readOnly; // If this is set, then do not try writing to the disc - FS_TYPE filesysType; - u32 totalSize; - u32 rootDirStart; - u32 rootDirCluster; - u32 numberOfSectors; - u32 dataStart; - u32 bytesPerSector; - u32 sectorsPerCluster; - u32 bytesPerCluster; - FAT fat; - // Values that may change after construction - u32 cwdCluster; // Current working directory cluser - u32 openFileCount; -} PARTITION; - -/* -Mount the device specified by partitionDevice -PD_DEFAULT is not allowed, use _FAT_partition_setDefaultDevice -PD_CUSTOM is not allowed, use _FAT_partition_mountCustomDevice -*/ -bool _FAT_partition_mount (PARTITION_INTERFACE partitionNumber, u32 cacheSize); - -/* -Mount a partition on a custom device -*/ -bool _FAT_partition_mountCustomInterface (const IO_INTERFACE* device, u32 cacheSize); - -/* -Unmount the partition specified by partitionNumber -If there are open files, it will fail -*/ -bool _FAT_partition_unmount (PARTITION_INTERFACE partitionNumber); - -/* -Forcibly unmount the partition specified by partitionNumber -Any open files on the partition will become invalid -The cache will be invalidated, and any unflushed writes will be lost -*/ -bool _FAT_partition_unsafeUnmount (PARTITION_INTERFACE partitionNumber); - -/* -Set the default device for access by fat: and fat0:, -based on the device number -*/ -bool _FAT_partition_setDefaultInterface (PARTITION_INTERFACE partitionNumber); - -/* -Set the default device for access by fat: and fat0:, -based on the partition pointer -*/ -bool _FAT_partition_setDefaultPartition (PARTITION* partition); - -/* -Return the partition specified in a path -For instance, "fat0:", "fat:", "/" and "fat:/" will all -return the default partition -*/ -PARTITION* _FAT_partition_getPartitionFromPath (const char* path); - -#endif // _PARTITION_H |