aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/ds/arm9/source/fat/io_fcsr.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/ds/arm9/source/fat/io_fcsr.c')
-rw-r--r--backends/platform/ds/arm9/source/fat/io_fcsr.c658
1 files changed, 658 insertions, 0 deletions
diff --git a/backends/platform/ds/arm9/source/fat/io_fcsr.c b/backends/platform/ds/arm9/source/fat/io_fcsr.c
new file mode 100644
index 0000000000..8ca311ac92
--- /dev/null
+++ b/backends/platform/ds/arm9/source/fat/io_fcsr.c
@@ -0,0 +1,658 @@
+/*
+ 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.
+
+ This software is completely free. No warranty is provided.
+ If you use it, please give me credit and email me about your
+ project at chishm@hotmail.com
+
+ See gba_nds_fat.txt for help and license details.
+
+ The file system must be 512 byte aligned, in cart address space.
+ SRAM is supported.
+*/
+
+
+#include "io_fcsr.h"
+
+#ifdef SUPPORT_FCSR
+#include <string.h>
+
+//---------------------------------------------------------------
+// DMA
+#ifdef _CF_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
+-----------------------------------------------------------------*/
+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
+-----------------------------------------------------------------*/
+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
+u8 numSecs IN: number of 512 byte sectors to read,
+ 1 to 256 sectors can be read, 0 = 256
+void* buffer OUT: pointer to 512 byte buffer to store data in
+bool return OUT: true if successful
+-----------------------------------------------------------------*/
+bool FCSR_ReadSectors (u32 sector, u8 numSecs, void* buffer)
+{
+ int i;
+ bool flagSramSector = false;
+ int numSectors = (numSecs > 0 ? numSecs : 256);
+ int readLength = numSectors * BYTE_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]) * BYTE_PER_READ;
+ } else {
+ src = FCSR_FileSysPointer + sector * BYTE_PER_READ;
+ }
+ dst = (u8*)buffer;
+
+ if (flagSramSector)
+ {
+ while (readLength--)
+ {
+ *dst++ = *src++;
+ }
+ } else { // Reading from Cart ROM
+
+#ifdef _CF_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 // !_CF_USE_DMA
+ memcpy (buffer, src, readLength);
+#endif // _CF_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
+u8 numSecs IN: number of 512 byte sectors to read,
+ 1 to 256 sectors can be read, 0 = 256
+void* buffer IN: pointer to 512 byte buffer to read data from
+bool return OUT: true if successful
+-----------------------------------------------------------------*/
+bool FCSR_WriteSectors (u32 sector, u8 numSecs, void* buffer)
+{
+ int i;
+ bool flagSramSector = false;
+ int writeLength = (numSecs > 0 ? numSecs : 256) * BYTE_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 + (numSecs > 0 ? numSecs : 256)) > FCSR_SramSectorEnd[i])
+ return false;
+
+ // Copy data to SRAM
+ dst = FCSR_SramSectorPointer[i] + (sector - FCSR_SramSectorStart[i]) * BYTE_PER_READ;
+ while (writeLength--)
+ {
+ *dst++ = *src++;
+ }
+
+ return true;
+}
+
+/*-----------------------------------------------------------------
+FCSR_Shutdown
+unload the Flash Cart interface
+-----------------------------------------------------------------*/
+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
+-----------------------------------------------------------------*/
+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] * BYTE_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] * BYTE_PER_READ);
+ destByte = FCSR_SramSectorPointer[i];
+ while (srcByte < FCSR_FileSysPointer + (FCSR_SramSectorEnd[i] * BYTE_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
+-----------------------------------------------------------------*/
+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
+} ;
+
+/*-----------------------------------------------------------------
+FCSR_GetInterface
+returns the interface structure to host
+-----------------------------------------------------------------*/
+LPIO_INTERFACE FCSR_GetInterface(void) {
+ return &io_fcsr ;
+} ;
+
+#endif // SUPPORT_FCSR
+/*
+ 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.
+
+ This software is completely free. No warranty is provided.
+ If you use it, please give me credit and email me about your
+ project at chishm@hotmail.com
+
+ See gba_nds_fat.txt for help and license details.
+
+ The file system must be 512 byte aligned, in cart address space.
+ SRAM is supported.
+*/
+
+
+#include "io_fcsr.h"
+
+#ifdef SUPPORT_FCSR
+#include <string.h>
+
+//---------------------------------------------------------------
+// DMA
+#ifdef _CF_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
+-----------------------------------------------------------------*/
+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
+-----------------------------------------------------------------*/
+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
+u8 numSecs IN: number of 512 byte sectors to read,
+ 1 to 256 sectors can be read, 0 = 256
+void* buffer OUT: pointer to 512 byte buffer to store data in
+bool return OUT: true if successful
+-----------------------------------------------------------------*/
+bool FCSR_ReadSectors (u32 sector, u8 numSecs, void* buffer)
+{
+ int i;
+ bool flagSramSector = false;
+ int numSectors = (numSecs > 0 ? numSecs : 256);
+ int readLength = numSectors * BYTE_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]) * BYTE_PER_READ;
+ } else {
+ src = FCSR_FileSysPointer + sector * BYTE_PER_READ;
+ }
+ dst = (u8*)buffer;
+
+ if (flagSramSector)
+ {
+ while (readLength--)
+ {
+ *dst++ = *src++;
+ }
+ } else { // Reading from Cart ROM
+
+#ifdef _CF_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 // !_CF_USE_DMA
+ memcpy (buffer, src, readLength);
+#endif // _CF_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
+u8 numSecs IN: number of 512 byte sectors to read,
+ 1 to 256 sectors can be read, 0 = 256
+void* buffer IN: pointer to 512 byte buffer to read data from
+bool return OUT: true if successful
+-----------------------------------------------------------------*/
+bool FCSR_WriteSectors (u32 sector, u8 numSecs, void* buffer)
+{
+ int i;
+ bool flagSramSector = false;
+ int writeLength = (numSecs > 0 ? numSecs : 256) * BYTE_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 + (numSecs > 0 ? numSecs : 256)) > FCSR_SramSectorEnd[i])
+ return false;
+
+ // Copy data to SRAM
+ dst = FCSR_SramSectorPointer[i] + (sector - FCSR_SramSectorStart[i]) * BYTE_PER_READ;
+ while (writeLength--)
+ {
+ *dst++ = *src++;
+ }
+
+ return true;
+}
+
+/*-----------------------------------------------------------------
+FCSR_Shutdown
+unload the Flash Cart interface
+-----------------------------------------------------------------*/
+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
+-----------------------------------------------------------------*/
+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] * BYTE_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] * BYTE_PER_READ);
+ destByte = FCSR_SramSectorPointer[i];
+ while (srcByte < FCSR_FileSysPointer + (FCSR_SramSectorEnd[i] * BYTE_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
+-----------------------------------------------------------------*/
+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
+} ;
+
+/*-----------------------------------------------------------------
+FCSR_GetInterface
+returns the interface structure to host
+-----------------------------------------------------------------*/
+LPIO_INTERFACE FCSR_GetInterface(void) {
+ return &io_fcsr ;
+} ;
+
+#endif // SUPPORT_FCSR