source: rtems/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_fcsr.c @ 32b8506

4.104.115
Last change on this file since 32b8506 was 32b8506, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/29/09 at 14:53:02

Whitespace removal.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/*
2        io_fcsr.c based on
3
4        compact_flash.c
5        By chishm (Michael Chisholm)
6
7        Hardware Routines for using a GBA Flash Cart and SRAM as a
8        block device.
9
10        The file system must be 512 byte aligned, in cart address space.
11        SRAM is supported.
12
13 Copyright (c) 2006 Michael "Chishm" Chisholm
14
15 Redistribution and use in source and binary forms, with or without modification,
16 are permitted provided that the following conditions are met:
17
18  1. Redistributions of source code must retain the above copyright notice,
19     this list of conditions and the following disclaimer.
20  2. Redistributions in binary form must reproduce the above copyright notice,
21     this list of conditions and the following disclaimer in the documentation and/or
22     other materials provided with the distribution.
23  3. The name of the author may not be used to endorse or promote products derived
24     from this software without specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
27 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
29 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
34 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*/
36
37
38#include "io_fcsr.h"
39
40#include <string.h>
41
42//---------------------------------------------------------------
43// DMA
44#ifdef _IO_USE_DMA
45 #ifndef NDS
46  #include "gba_dma.h"
47 #else
48  #include <nds/dma.h>
49  #ifdef ARM9
50   #include <nds/arm9/cache.h>
51  #endif
52 #endif
53#endif
54
55#ifdef NDS
56 #define SRAM_START 0x0A000000
57#else
58 #define SRAM_START 0x0E000000
59#endif
60
61#define NO_SRAM 0xFFFFFFFF
62
63#define FCSR 0x52534346
64const char _FCSR_LabelString[] = " Chishm FAT";
65
66u8* _FCSR_FileSysPointer = 0;
67u8* _FCSR_SramSectorPointer[4] = {0,0,0,0};
68u32 _FCSR_SramSectorStart[4] = {0,0,0,0};
69u32 _FCSR_SramSectorEnd[4] = {0,0,0,0};
70
71/*-----------------------------------------------------------------
72_FCSR_isInserted
73Is a GBA Flash Cart with a valid file system inserted?
74bool return OUT:  true if a GBA FC card is inserted
75-----------------------------------------------------------------*/
76bool _FCSR_isInserted (void)
77{
78        bool flagFoundFileSys = false;
79
80        u32* fileSysPointer = (u32*)0x08000100;         // Start at beginning of cart address space, offset by expected location of string
81
82        // Search for file system
83        while ((fileSysPointer < (u32*)0x0A000000) && !flagFoundFileSys)        // Only search while not at end of cart address space
84        {
85                while ((*fileSysPointer != FCSR) && (fileSysPointer < (u32*)0x0A000000))
86                        fileSysPointer += 0x40;
87                if ((strncmp(_FCSR_LabelString, (char*)(fileSysPointer + 1), 12) == 0) && (fileSysPointer < (u32*)0x0A000000))
88                {
89                        flagFoundFileSys = true;
90                } else {
91                        fileSysPointer += 0x80;
92                }
93        }
94
95        return flagFoundFileSys;
96}
97
98
99/*-----------------------------------------------------------------
100_FCSR_clearStatus
101Finish any pending operations
102bool return OUT:  always true for GBA FC
103-----------------------------------------------------------------*/
104bool _FCSR_clearStatus (void)
105{
106        return true;
107}
108
109
110/*-----------------------------------------------------------------
111_FCSR_readSectors
112Read 512 byte sector numbered "sector" into "buffer"
113u32 sector IN: address of first 512 byte sector on Flash Cart to read
114u32 numSectors IN: number of 512 byte sectors to read,
115 1 to 256 sectors can be read
116void* buffer OUT: pointer to 512 byte buffer to store data in
117bool return OUT: true if successful
118-----------------------------------------------------------------*/
119bool _FCSR_readSectors (u32 sector, u32 numSectors, void* buffer)
120{
121        int i;
122        bool flagSramSector = false;
123        int readLength = numSectors * BYTES_PER_READ;
124        u8* src;;
125        u8* dst;
126
127        // Find which region this read is in
128        for (i = 0; (i < 4) && !flagSramSector; i++)
129        {
130                if ((sector >= _FCSR_SramSectorStart[i]) && (sector < _FCSR_SramSectorEnd[i]))
131                {
132                        flagSramSector = true;
133                        break;
134                }
135        }
136
137        // Make sure read will be completely in SRAM range if it is partially there
138        if ( flagSramSector && ((sector + numSectors) > _FCSR_SramSectorEnd[i]))
139                return false;
140
141        // Copy data to buffer
142        if (flagSramSector)
143        {
144                src = _FCSR_SramSectorPointer[i] + (sector - _FCSR_SramSectorStart[i]) * BYTES_PER_READ;
145        } else {
146                src = _FCSR_FileSysPointer + sector * BYTES_PER_READ;
147        }
148        dst = (u8*)buffer;
149
150        if (flagSramSector)
151        {
152                while (readLength--)
153                {
154                        *dst++ = *src++;
155                }
156        } else {        // Reading from Cart ROM
157
158#ifdef _IO_USE_DMA
159 #ifdef NDS
160  #ifdef ARM9
161                DC_FlushRange( buffer, readLength);
162  #endif        // ARM9
163                DMA3_SRC = (u32)src;
164                DMA3_DEST = (u32)buffer;
165                DMA3_CR = (readLength >> 1) | DMA_COPY_HALFWORDS;
166 #else  // ! NDS
167                DMA3COPY ( src, buffer, (readLength >> 1) | DMA16 | DMA_ENABLE);
168 #endif // NDS
169#else   // !_IO_USE_DMA
170                memcpy (buffer, src, readLength);
171#endif  // _IO_USE_DMA
172
173        }       // if (flagSramSector)
174
175        return true;
176}
177
178/*-----------------------------------------------------------------
179_FCSR_writeSectors
180Write 512 byte sector numbered "sector" from "buffer"
181u32 sector IN: address of 512 byte sector on Flash Cart to read
182u32 numSectors IN: number of 512 byte sectors to read,
183 1 to 256 sectors can be read
184void* buffer IN: pointer to 512 byte buffer to read data from
185bool return OUT: true if successful
186-----------------------------------------------------------------*/
187bool _FCSR_writeSectors (u32 sector, u8 numSectors, void* buffer)
188{
189        int i;
190        bool flagSramSector = false;
191        u32 writeLength = numSectors * BYTES_PER_READ;
192        u8* src = (u8*) buffer;
193        u8* dst;
194
195        // Find which region this sector belongs in
196        for (i = 0; (i < 4) && !flagSramSector; i++)
197        {
198                if ((sector >= _FCSR_SramSectorStart[i]) && (sector < _FCSR_SramSectorEnd[i]))
199                {
200                        flagSramSector = true;
201                        break;
202                }
203        }
204
205        if (!flagSramSector)
206                return false;
207
208        // Entire write must be within an SRAM region
209        if ((sector + numSectors) > _FCSR_SramSectorEnd[i])
210                return false;
211
212        // Copy data to SRAM
213        dst = _FCSR_SramSectorPointer[i] + (sector - _FCSR_SramSectorStart[i]) * BYTES_PER_READ;
214        while (writeLength--)
215        {
216                *dst++ = *src++;
217        }
218
219        return true;
220}
221
222/*-----------------------------------------------------------------
223_FCSR_shutdown
224unload the Flash Cart interface
225-----------------------------------------------------------------*/
226bool _FCSR_shutdown(void)
227{
228        int i;
229        if (_FCSR_clearStatus() == false)
230                return false;
231
232        _FCSR_FileSysPointer = 0;
233
234        for (i=0; i < 4; i++)
235        {
236                _FCSR_SramSectorPointer[i] = 0;
237                _FCSR_SramSectorStart[i] = 0;
238                _FCSR_SramSectorEnd[i] = 0;
239        }
240        return true;
241}
242
243/*-----------------------------------------------------------------
244_FCSR_startUp
245initializes the Flash Cart interface, returns true if successful,
246otherwise returns false
247-----------------------------------------------------------------*/
248bool _FCSR_startUp(void)
249{
250        bool flagFoundFileSys = false;
251        int i;
252        int SramRegionSize[4];
253        u8* srcByte;
254        u8* destByte;
255
256        u32* fileSysPointer = (u32*)0x08000100;         // Start at beginning of cart address space, offset by expected location of string
257
258        // Search for file system
259        while ((fileSysPointer < (u32*)0x0A000000) && !flagFoundFileSys)        // Only search while not at end of cart address space
260        {
261                while ((*fileSysPointer != FCSR) && (fileSysPointer < (u32*)0x0A000000))
262                        fileSysPointer += 0x40;
263                if ((strncmp(_FCSR_LabelString, (char*)(fileSysPointer + 1), 12) == 0) && (fileSysPointer < (u32*)0x0A000000))
264                {
265                        flagFoundFileSys = true;
266                } else {
267                        fileSysPointer += 0x80;
268                }
269        }
270
271        if (!flagFoundFileSys)
272                return false;
273
274        // Flash cart file system pointer has been found
275        _FCSR_FileSysPointer = (u8*)(fileSysPointer - 0x40);
276
277        // Get SRAM sector regions from header block
278        for (i = 0; i < 4; i++)
279        {
280                _FCSR_SramSectorStart[i] = fileSysPointer[i+4];
281                SramRegionSize[i] = fileSysPointer[i+8];
282                _FCSR_SramSectorEnd[i] = _FCSR_SramSectorStart[i] + SramRegionSize[i];
283        }
284
285        // Calculate SRAM region pointers
286        _FCSR_SramSectorPointer[0] = (u8*)(SRAM_START + 4);
287        for (i = 1; i < 4; i++)
288        {
289                _FCSR_SramSectorPointer[i] = _FCSR_SramSectorPointer[i-1] + (SramRegionSize[i-1] * BYTES_PER_READ);
290        }
291
292        // Initialise SRAM with overlay if it hasn't been done so
293        if ( (*((u8*)SRAM_START) != 'F')  || (*((u8*)(SRAM_START+1)) != 'C') || (*((u8*)(SRAM_START+2)) != 'S') || (*((u8*)(SRAM_START+3)) != 'R') )
294        {
295                *((u8*)SRAM_START) = 'F';
296                *((u8*)(SRAM_START+1)) = 'C';
297                *((u8*)(SRAM_START+2)) = 'S';
298                *((u8*)(SRAM_START+3)) = 'R';
299
300                for (i = 0; i < 4; i++)
301                {
302                        srcByte = _FCSR_FileSysPointer + (_FCSR_SramSectorStart[i] * BYTES_PER_READ);
303                        destByte = _FCSR_SramSectorPointer[i];
304                        while (srcByte < _FCSR_FileSysPointer + (_FCSR_SramSectorEnd[i] * BYTES_PER_READ) )
305                                *destByte++ = *srcByte++;
306                }
307        }
308
309                // Get SRAM sector regions from header block
310        for (i = 0; i < 4; i++)
311        {
312                if (SramRegionSize[i] == 0)
313                {
314                        _FCSR_SramSectorStart[i] = NO_SRAM;
315                        _FCSR_SramSectorEnd[i] = NO_SRAM;
316                }
317        }
318
319        return true;
320}
321
322/*-----------------------------------------------------------------
323the actual interface structure
324-----------------------------------------------------------------*/
325const IO_INTERFACE _io_fcsr = {
326        DEVICE_TYPE_FCSR,       // 'FCSR'
327        FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
328        (FN_MEDIUM_STARTUP)&_FCSR_startUp,
329        (FN_MEDIUM_ISINSERTED)&_FCSR_isInserted,
330        (FN_MEDIUM_READSECTORS)&_FCSR_readSectors,
331        (FN_MEDIUM_WRITESECTORS)&_FCSR_writeSectors,
332        (FN_MEDIUM_CLEARSTATUS)&_FCSR_clearStatus,
333        (FN_MEDIUM_SHUTDOWN)&_FCSR_shutdown
334} ;
Note: See TracBrowser for help on using the repository browser.