Subversion Repositories NaviCtrl

Rev

Rev 23 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ingob 1
/*#######################################################################################*/
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
3
/*#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + Copyright (c) 2008 Ingo Busker, Holger Buss
171 ingob 6
// + Nur für den privaten Gebrauch / NON-COMMERCIAL USE ONLY
1 ingob 7
// + FOR NON COMMERCIAL USE ONLY
8
// + www.MikroKopter.com
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
11
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
12
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt 
13
// + bzgl. der Nutzungsbedingungen aufzunehmen. 
14
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
15
// + Verkauf von Luftbildaufnahmen, usw.
16
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht, 
18
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
21
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
22
// + eindeutig als Ursprung verlinkt werden
23
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
25
// + Benutzung auf eigene Gefahr
26
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
27
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
171 ingob 28
// + Die Portierung oder Nutzung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur 
1 ingob 29
// + mit unserer Zustimmung zulässig
30
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
32
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33
// + Redistributions of source code (with or without modifications) must retain the above copyright notice, 
34
// + this list of conditions and the following disclaimer.
35
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
36
// +     from this software without specific prior written permission.
37
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permitted 
38
// +     for non-commercial use (directly or indirectly)
39
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted 
40
// +     with our written permission
41
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be 
42
// +     clearly linked as origin 
171 ingob 43
// +   * porting the sources to other systems or using the software on other systems (except hardware from www.mikrokopter.de) is not allowed
1 ingob 44
//
45
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55
// +  POSSIBILITY OF SUCH DAMAGE. 
56
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57
 
58
#include "main.h"
59
 
60
//________________________________________________________________________________________________________________________________________
61
// Module name:                 fat16.c 
62
// Compiler used:               avr-gcc 3.4.5
63
// Last Modifikation:   24.07.2007
64
// Version:                             1.24
65
// Authors:                             Stephan Busker  
66
// Description:                 Source files for FAT16 implementation with read and write-access using AVR-Mikrocontrollers
67
//                                              Copyright (C) 2007 Stephan Busker
68
//........................................................................................................................................
69
// Functions:                   extern u8       InitFat16(void);                
70
//                                              u8                      fopen_(u8 *fname,s8 mode, File *file);
71
//                                              void                                    fclose_(File *file);
72
//                                              u32                     fread_(void *buffer, u32 size, u32 count, File *file); 
73
//                                              u32                     fwrite_(void *buffer, u32 size, u32 count, File *file);
74
//                                              s16                                     fseek_(File *file, s32 offset, s16 origin);
75
//                                      s8                                      fgets8_(File *file);
76
//                                              u8                      fputchar_(File *file,s8 c);
77
//                                              u8                      fputs_(File *file,s8 *string);
78
//                                              s8 *                                    fgets(s8 *, s16, File);
79
//                                              u8                      fexist_(u8*, File *file);
80
//........................................................................................................................................
81
// ext. functions:              extern u8 SDC_GetSector  (u32,u8 *);            
82
//                                              extern u8 SDC_PutSector (u32,u8 *);
83
//........................................................................................................................................
84
//
85
// URL:                                 www.Mikro-Control.de
86
// mailto:                              stephan.busker@mikro-control.de
87
//________________________________________________________________________________________________________________________________________
88
 
89
 
90
 
91
 
92
//________________________________________________________________________________________________________________________________________
93
// 
94
// Global variables needed for read- or write-acces to the FAT16- filesystem.
95
//                              
96
//________________________________________________________________________________________________________________________________________
97
 
98
u8              SectorsPerCluster               = 0;                    // how many sectors does a cluster contain?
99
u8              FatCopies                               = 0;                    // Numbers of copies of the FAT
100
u16             PossibleRootEntries     = 0;                    // Possible number of entries in the root directory.
101
u16             SectorsPerFat                   = 0;                    // how many sectors does a fat16 contain?
102
u32             ReservedSectors                 = 0;                    // Sectors reserved by the filesystem.
103
u32             FirstPartitionSector    = 0;                    // Distance in sectors between the first partition and the master bootrecord.
104
u32             FileAllocationTable     = 0;                    // pointer to the first FAT
105
u32             RootDirectory                   = 0;                    // Pointer to the rootdirectory of the first partition.
106
u32             FirstDataCluster                = 0;                    // Pointer to the first cluster containing data (cluster0).
107
//u8    FileBuffer[512];                                                // Buffer for read and write operation from or to the mmc.
108
 
109
struct DirEntry         *DirectoryEntry;                        // Pointer to an entry of the directory.
110
struct FatEntry         *Fat;                                           // Pointer to an entry of the fat (next clusterposition).
111
 
112
File FilePointer[__MAX_FILES_USED];                             // Allocate Memmoryspace for each filepointer used.
113
 
114
 
115
 
116
 
117
//________________________________________________________________________________________________________________________________________
118
// Funtion:     InitFat16(void);
119
// 
120
// Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdirectory
121
//                              and stores the information in global variables.
122
//
123
// Returnvalue: The function returns "0" if the filesystem could not be initialized because no partition was found on the disc. 
124
//________________________________________________________________________________________________________________________________________
125
 
126
u8 InitFat16(void)
127
{      
128
        u8 retvalue = 0;
129
    u8  cnt     = 0;
130
        struct VBR_Entry *VBR;                                                                          // Pointer to the VolumeBootRecord.
131
        struct MBR_Entry *MBR;                                                                          // Pointer to the masterbootrecord.     
132
        File *file;
133
 
134
        for(cnt=0;cnt<__MAX_FILES_USED;cnt++)
135
        {
136
                FilePointer[cnt].state = _UNUSED;                                                               // declare the filepointers as unused.
137
        }
138
 
139
        file = &FilePointer[0];
140
 
141
        while((SDC_Init() != 0) && (cnt++<200));                                        // initialise the sdcard.
142
        if(cnt <200)                                                                                            //sdcard initialised succesfully
143
        {
144
                SDC_GetSector((u32)MBR_SECTOR,file->buffer);                    // Read the MasterBootRecord from mmc.
145
                MBR = (struct MBR_Entry *) file->buffer;
146
                FirstPartitionSector = MBR->PartitionEntry1.NoSectorsBeforePartition;
147
                SDC_GetSector(FirstPartitionSector,file->buffer);               // Read the volume bootrecord from mmc. 
148
 
149
 
150
                VBR = (struct VBR_Entry *) file->buffer;                                        // Enter the VBR using the structure VBR_Entry.
151
                SectorsPerCluster       = VBR->SectorsPerCluster;                       // Number of sectors per cluster. Depends on the memorysize of the sd-card.
152
                FatCopies                       = VBR->NoFATCopies;                                     // Number of fatcopies.
153
                PossibleRootEntries = VBR->MaxRootEntries;                              // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
154
                SectorsPerFat           = VBR->SectorsPerFAT;                           // The number of sectors per FAT.
155
                ReservedSectors         = VBR->ReservedSectors;                         // calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster.
156
 
157
                FileAllocationTable     =   (u32)(FirstPartitionSector + (u32)ReservedSectors);                                                         // Calculate the position of the FileAllocationTable.
158
                RootDirectory           =   (u32)((u32)FileAllocationTable + (u32)((u32)SectorsPerFat*(u32)FatCopies));         // Calculate the position of the Rootdirectory.
159
                FirstDataCluster        =   (u32)((u32)RootDirectory + ((u32)(PossibleRootEntries>>4)));                                        // Calculate the position of the first datacluster.
160
 
161
                if((file->buffer[0x36]=='F') &&(file->buffer[0x37]=='A')&&(file->buffer[0x38]=='T')&&(file->buffer[0x39]=='1')&&(file->buffer[0x3A]=='6'))
162
                {
163
                        retvalue = 1;
164
                }
165
        }
166
        return(retvalue);      
167
}
168
 
169
//________________________________________________________________________________________________________________________________________
170
// Funtion:     File * fopen_(u8*, u8 *, File *file);
171
// 
172
// Description: This function looks for the specified file in the rootdirectory of the drive. If the file is found the number of the 
173
//                              corrosponding datacluster is returned to main. Only modes 'r' (reading) and 'a' append are implemented yet.
174
//
175
//      Return:         0 = faild to open speicified file
176
//                              1 = file opened 
177
//________________________________________________________________________________________________________________________________________
178
 
179
File * fopen_(u8 *fname, s8 mode)
180
{
181
        u32 cluster_temp        = 0;
182
        u8 name[11]     = "           ";                       
183
        u16 temp                = 0;
184
        File *file;
185
 
186
        file=0;
187
        for(temp = 0;temp<__MAX_FILES_USED;temp++)
188
        {
189
                if(FilePointer[temp].state == _UNUSED)                                                                                  // free filepointer found?
190
                {
191
                        file = &FilePointer[temp];
192
                        FilePointer[temp].state = _USED;                                                                                        // mark as used.
193
                        break;
194
                }
195
        }
196
 
197
        if(file == 0)   return(file);                                                                                                   // no valid pointer 
198
 
199
        file->start_cluster                     = 0;                                                                                            // Sectorpointer to the first sector of the first datacluster of the file. 
200
        file->cluster_pointer           = 0;                                                                                            // Pointer to the cluster which is edited at the moment.
201
        file->sector_index                      = 0;                                                                                            // The sector which is edited at the moment (cluster_pointer + sector_index).
202
        file->byte_index                        = 0;                                                                                            // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
203
        file->mode                                      = mode;                                                                                         // mode of fileoperation (read,write)
204
        file->filesize                          = 0;                                                                                            // the size of the opend file in bytes.
205
        file->fileposition                      = 0;                                                                                            // pointer to a character within the file 0 < fileposition < filesize
206
        file->sector_in_buffer          = 0;                                                                                            // the last sector read, wich is still in the sectorbuffer.
207
        file->directory_sector          = 0;                                                                                            // the sectorposition where the directoryentry has been made.
208
        file->directory_index           = 0;                                                                                            // the index to the directoryentry within the specified sector.
209
        file->attribute                         = 0;                                                                                            // the attribute of the file opened.
210
 
211
        if(ScanSubDirectories(&fname[0], file))                                                                         // Is the specified filepath available?
212
        {
213
                SeperateFileName(&fname[0], &name[0]);                                                                          // seperate the filename and attribute from the filepath and bring them in the correct format.                  
214
                file->attribute = _FILE;
215
                if(SeekDirectoryEntry(&name[0], file))                                                                          // if file was found
216
                {
217
                        if(mode == 'a')                                                                                                                 // open existing file for writing (append data at the end of the file)
218
                        {      
219
                                fseek_(file, 0, SEEK_END);                                                                                      // fseek points to the end of the file
220
                        }
221
                        return(file);
222
                }
223
                else
224
                {
225
                        if((mode == 'a') || (mode == 'w'))                                                                              // specified file doesn't exist so create new file for writing data.
226
                        {      
227
                                cluster_temp = (u32)FindNextFreeCluster(file);                                          // the next free cluster on the disk.
228
                                if(cluster_temp)                                                                                                        // if a free cluster is available:
229
                                {
230
                                        temp = (u16)cluster_temp;                                                                               // remember the index of the free datacluster found for the directory entry.
231
                                        cluster_temp -=2;                                                                                               // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
232
                                        cluster_temp *= SectorsPerCluster;                                                              // Calculate relative sectorindex of first datacluster.
233
                                        file->start_cluster   = (FirstDataCluster + cluster_temp);              // Calculate absolute sectorposition of first datacluster.
234
                                        file->cluster_pointer = file->start_cluster;                                    // start reading the file with the first sector of the first datacluster.
235
                                        if(CreateDirectoryEntry(&name[0],temp,file,_FILE))                              // Could an entry for the new file in the rootdirectory be created?
236
                                        {
237
                                                return(file);
238
                                        }      
239
                                }                              
240
                        }
241
                }
242
        }
243
        return(0);
244
}
245
 
246
//________________________________________________________________________________________________________________________________________
247
// Funtion:     fflush_(File *file);
248
// 
249
// Description: This function writes the data already in the buffer but not yet written to the file. 
250
//                              
251
//________________________________________________________________________________________________________________________________________
252
 
253
s16     fflush_(File *file)
254
{
255
        u16 time=0;
256
        u16 date=0;
257
 
258
#ifdef __USE_TIME_DATE_ATTRIBUTE                                                                                                                        // has the date and time attribute of the file to be set?
259
 
260
        time = (((rtctime.hour)<<11)                    | ((rtctime.minute)<<5)         | rtctime.second);
261
        date = ((((rtctime.year)-1980) <<9)     | ((rtctime.month) <<5)         | rtctime.day);
262
 
263
#endif  
264
 
265
 
266
        if(file && file->mode =='a')
267
        {
268
                if(file->byte_index > 0)                                                                                                                        // has data been added to the file?             
269
                {
270
                        SDC_PutSector((u32)(file->cluster_pointer + file->sector_index),file->buffer);  // save the data still in the buffer    
271
                }      
272
                SDC_GetSector((u32)file->directory_sector,file->buffer);                        // read the directoryentry for this file.
273
                DirectoryEntry = (struct DirEntry *)file->buffer;
274
                DirectoryEntry[file->directory_index].size = (u32) file->filesize;
275
                DirectoryEntry[file->directory_index].time = (u16) time;
276
                DirectoryEntry[file->directory_index].date = (u16) date;
277
                SDC_PutSector((u32)file->directory_sector,file->buffer);
278
        }
279
        return(0);
280
}
281
 
282
//________________________________________________________________________________________________________________________________________
283
// Funtion:     fclose_(File *file);
284
// 
285
// Description: This function closes the open file by writing the remaining data from the buffer to the device and entering the filesize 
286
//                              in the directory entry.
287
//________________________________________________________________________________________________________________________________________
288
 
289
void fclose_(File *file)
290
{
291
        u8 cnt = 0;
292
 
293
        for(cnt=0;cnt<__MAX_FILES_USED;cnt++)
294
        {
295
                if(&FilePointer[cnt] == file)                                                                                   // filepointer to be freed found?
296
                {
297
                        FilePointer[cnt].state = _UNUSED;
298
                }
299
 
300
                fflush_(file);                                                                                                                  // save buffercontent to the sdcard
301
 
302
                file->start_cluster                     = 0;                                                                            // Sectorpointer to the first sector of the first datacluster of the file. 
303
                file->cluster_pointer           = 0;                                                                            // Pointer to the cluster which is edited at the moment.
304
                file->sector_index                      = 0;                                                                            // The sector which is edited at the moment (cluster_pointer + sector_index).
305
                file->byte_index                        = 0;                                                                            // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
306
                file->mode                                      = 0;                                                                            // mode of fileoperation (read,write)
307
                file->filesize                          = 0;                                                                            // the size of the opend file in bytes.
308
                file->fileposition                      = 0;                                                                            // pointer to a character within the file 0 < fileposition < filesize
309
                file->sector_in_buffer          = 0;                                                                            // the last sector read, wich is still in the sectorbuffer.
310
                file->directory_sector          = 0;                                                                            // the sectorposition where the directoryentry has been made.
311
                file->directory_index           = 0;                                                                            // the index to the directoryentry within the specified sector.
312
                file->attribute                         = 0;                                                                            // the attribute of the file opened.
313
        }
314
}
315
 
316
//________________________________________________________________________________________________________________________________________
317
// Funtion:     s32 fread_(void *buffer, s32 size, s32 count, File *file);
318
// 
319
// Description: This function reads count objects of the specified size from the actual position of the file to the specified buffer.
320
//                              
321
// Returnvalue: The function returns the number of objects (not bytes) read from the file.      
322
//                              
323
//________________________________________________________________________________________________________________________________________
324
 
325
u32 fread_(void *buffer, u32 size, u32 count, File *file)
326
{
327
        u32 object_cnt  = 0;                                                                                                            // count the number of objects read from the file.
328
        u32 object_size         = 0;                                                                                                            // count the number of bytes read from the actual object.
329
        u8 *buff_pnt    = 0;                                                                                                            // a pointer to the actual bufferposition.
330
        u8 success      = 1;                                                                                                            // no error occured during read operation to the file.
331
 
332
        buff_pnt = (u8 *) buffer;                                                                                                       // cast the void pointer to an u8 *
333
 
334
        while((object_cnt < count) && success)
335
        {
336
                object_size = size;
337
                while((size > 0) && success)
338
                {
339
                        *buff_pnt = (u8) fgetchar_(file);                                                                       // read a byte from the buffer to the opened file.
340
                        buff_pnt++;
341
                        size--;
342
                }
343
                if(success) object_cnt++;
344
        }              
345
 
346
        return(object_cnt);                                                                                                                                     // return the number of objects succesfully read from the file
347
}
348
 
349
//________________________________________________________________________________________________________________________________________
350
// Funtion:     s32 fwrite_(void *buffer, s32 size, s32 count, File *file);
351
// 
352
// Description: This function writes count objects of the specified size from the buffer to the actual positon within the file.
353
//                              
354
// Returnvalue: The function returns the number of objects (not bytes) written to the file.     
355
//                              
356
//________________________________________________________________________________________________________________________________________
357
 
358
u32 fwrite_(void *buffer, u32 size, u32 count, File *file)
359
{
360
        u32 object_cnt  = 0;                                                                                                            // count the number of objects written to the file.
361
        u32 object_size         = 0;                                                                                                            // count the number of bytes written from the actual object.
362
        u8 *buff_pnt    = 0;                                                                                                            // a pointer to the actual bufferposition.
363
        u8 success      = 1;                                                                                                            // no error occured during write operation to the file.
364
 
365
        buff_pnt = (u8 *) buffer;                                                                                                       // cast the void pointer to an u8 *
366
 
367
        while((object_cnt < count) && success)
368
        {
369
                object_size = size;
370
                while((size > 0) && success)
371
                {
372
                        success = fputchar_(file, *buff_pnt);                                                                                   // write a byte from the buffer to the opened file.
373
                        buff_pnt++;
374
                        size--;
375
                }
376
                if(success) object_cnt++;
377
        }              
378
 
379
        return(object_cnt);                                                                                                                                     // return the number of objects succesfully written to the file
380
}                                                                                                                                                                                       // (!!!!! objects and not bytes !!!!)
381
 
382
//________________________________________________________________________________________________________________________________________
383
// Funtion:     s16 fseek_(File *, s32, s16)
384
// 
385
// Description: This function sets the pointer of the stream relative to the position 
386
//                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END). 
387
//                              
388
//________________________________________________________________________________________________________________________________________
389
 
390
s16 fseek_(File *file, s32 offset, s16 origin)
391
{
392
        s32                     fposition       = 0;
393
        s16                     retvalue        = 1;
394
        u32     temp            = 0;
395
 
396
//......................................................
397
        if(origin == SEEK_SET)                                                                                          // Fileposition relative to the beginning of the file.
398
        {
399
                fposition = 0;
400
        }      
401
//......................................................
402
        else if(origin == SEEK_END)                                                                             // Fileposition relative to the end of the file.
403
        {
404
                fposition  = (s32) file->filesize;
405
        }      
406
//......................................................
407
        else if(origin == SEEK_CUR)                                                                             // Fileposition relative to the current position of the file.
408
        {
409
                fposition = file->fileposition;
410
        }      
411
 
412
        fposition += offset;
413
 
414
        if((fposition >= 0) && (fposition <= (s32)file->filesize))              // is the pointer still within the file?
415
        {
416
                retvalue                                = 0;
417
                file->sector_index              = 0;
418
                file->byte_index                = 0;
419
                file->fileposition              = 0;
420
                file->cluster_pointer   = file->start_cluster;
421
 
422
                while(file->fileposition < fposition)
423
                {
424
                        file->fileposition++;                                                                          
425
                        if(file->byte_index < 511)                                                                     
426
                        {
427
                                file->byte_index++;
428
                        }
429
                        else
430
                        {
431
                                file->byte_index=0;                                                                             // reading at the beginning of new sector.
432
                                file->sector_index++;                                                                   // continue reading in next sector
433
                                if(file->sector_index >= SectorsPerCluster)                     // When end of cluster is reached, the next datacluster has to be searched in the FAT.
434
                                {
435
                                        if(file->fileposition < fposition)
436
                                        {
437
                                                file->sector_index = 0;                                                 // start reading new cluster at first sector of the cluster.
438
                                                GetNextCluster(file);                                                   // Sets the clusterpointer of the file to the next datacluster.
439
                                        }
440
                                }
441
                        }      
442
                }
443
                if(file->byte_index)                           
444
                {
445
                        temp = (u32)((u32)file->cluster_pointer + (u32)file->sector_index);                    
446
                        SDC_GetSector((u32)temp,file->buffer);          // FileBuffer will be written at once at the end of the cluster and has to be updated.                                          
447
                }
448
        }      
449
        return(retvalue);
450
}
451
 
452
//________________________________________________________________________________________________________________________________________
453
// Funtion:     fgetchar_(File *file);
454
// 
455
// Description: This function reads and returns one character from the specified file. Is the end of the actual sector reached the
456
//                              next sector of the cluster is read. Is the last sector of the cluster read the next cluster will be searched in FAT.
457
// Returnvalue: The function returns the character read from the specified memorylocation as u8 casted to s16 or EOF.
458
//________________________________________________________________________________________________________________________________________
459
 
460
s16 fgetchar_(File *file)
461
{      
462
        s16 c = EOF;
463
        u32 temp1;
464
 
465
        if(file->filesize > 0)                                                                                                          // wen the end of the file is not reached, get the next character.
466
        {
467
                temp1  = (u32)file->cluster_pointer;                                            // calculate the adress of the next character to be read.
468
                temp1 += (u32)file->sector_index;                      
469
 
470
                if(file->sector_in_buffer != temp1)                                                                     // Has the content of the buffer been modified and has to be updated?
471
                {
472
                        SDC_GetSector((u32)temp1,file->buffer);                                 // Read the calculated cluster.                 
473
                        file->sector_in_buffer = (u32)temp1;
474
                }      
475
                c = (s16) file->buffer[file->byte_index];
476
                file->filesize--;                                                                                                               // decrement the number of characters available.
477
 
478
                if(file->byte_index < 511)                                                                                              // continue reading from this sector until the end of the sector is reached.
479
                {
480
                        file->byte_index++;
481
                }
482
                else                                                                                                                                    // has the end of an sector been reached->
483
                {
484
                        file->byte_index=0;                                                                                                     // continue reading at the beginning -
485
                        file->sector_index++;                                                                                           // of new sector.
486
                        if(file->sector_index >= SectorsPerCluster)                                             // When the end of an cluster is reached, the next datacluster has to be searched in the FAT.
487
                        {
488
                                file->sector_index = 0;                                                                                 // start reading new cluster at first sector of the cluster.
489
                                GetNextCluster(file);                                                                                   // Sets the clusterpointer of the file to the next datacluster.
490
                        }
491
                }
492
        }
493
        return(c);
494
}
495
 
496
//________________________________________________________________________________________________________________________________________
497
// Funtion:     fputchar_(File *file);
498
// 
499
// Description: This function writes a byte to the specified file and takes care of writing the necessary FAT- Entries. 
500
//                              
501
// Returnvalue: The function returns a value of 0 if the data could not be written.
502
//________________________________________________________________________________________________________________________________________
503
 
504
u8 fputchar_(File *file,s8 c)
505
{      
506
        u32 ul_temp  = 0;
507
        u8 retvalue = 1;
508
 
509
    if(file->sector_index >= SectorsPerCluster)                                                                         // if end of the cluster is reached, find next free cluster
510
        {
511
                file->sector_index = 0;
512
                if(!AppendCluster(file)) retvalue = 0;                                                                                  // append a new and free cluster at the end of the file.
513
        }
514
 
515
        file->buffer[file->byte_index] = c;                                                                                                     // write databyte into the buffer. The byte will be written to the device at once
516
        if(file->filesize == file->fileposition) file->filesize++;                                                      // a character has been written to the file so the size is inkremented but only when the character has been added at the end of the file.
517
        file->fileposition++;                                                                                                                           // the actual positon within the file. 
518
                                                                                                                                                                                // if the buffer contains the complete sectordata.
519
        if(file->byte_index < 511)                                                                                                                      // if the end of this sector is not reached yet
520
        {
521
                file->byte_index++;                                                                                                                             // the next byte will be written to the next byteposition in this sector.
522
        }
523
        else                                                                                                                                                            // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected.
524
        {
525
                ul_temp  = (u32)file->cluster_pointer;
526
                ul_temp += (u32)file->sector_index;
527
 
528
                SDC_PutSector((u32)ul_temp,file->buffer);
529
                file->byte_index=0;                                                                                                                             // and the next byte will be written at the beginning of this new sector.
530
                file->sector_index++;
531
                if(file->sector_index >= SectorsPerCluster)                                                                     // if end of the cluster is reached, find next free cluster
532
                {
533
                        file->sector_index = 0;
534
                        if(!AppendCluster(file)) retvalue = 0;                                                                          // append a new and free cluster at the end of the file.
535
                }
536
        }
537
        return(retvalue);
538
}
539
 
540
//________________________________________________________________________________________________________________________________________
541
// Funtion:     fputs_(File *file);
542
// 
543
// Description: This function writes a string to the specified file.
544
//                              
545
//________________________________________________________________________________________________________________________________________
546
 
547
u8 fputs_(File *file,s8 * string)
548
{
549
        u8 i=0;
550
 
551
        while(string[i] != 0)
552
        {
553
                fputchar_(file,string[i]);
554
                i++;
555
        }
556
        return(0);
557
}
558
 
559
//________________________________________________________________________________________________________________________________________
560
// Funtion:     fgets_(File *file);
561
// 
562
// Description: This function reads a string from the file to the specifies string.
563
//              
564
// Returnvalue: A pointer to the string written from the file.
565
//________________________________________________________________________________________________________________________________________
566
 
567
s8 * fgets_(s8 *string, s16 count, File *file)
568
{
569
        s16 buff_pnt = 0;
570
        s16 buff_tmp = 0;
571
        u8 state = 0;                                                                                                                   // Variable used for a statemachine to recognize the end of a line.
572
 
573
        while(count > 1)                                                                                                                                        // read the count-1 characters from the file to the string.
574
        {
575
                buff_tmp = fgetchar_(file);                                                                                                             // read a character from the opened file.
576
                switch(state)
577
                {
578
                        case 0:
579
                                if(buff_tmp == 0x0A)// state++;                                                                                 
580
                                {
581
                                        count = 1;
582
                                }
583
                                state = 0;     
584
                        break;
585
 
586
                        case 1:
587
                                if(buff_tmp == 0x0A)
588
                                {
589
                                        count = 1;
590
                                }
591
                                state = 0;     
592
                        break;
593
                }
594
                if(buff_tmp == EOF) {buff_tmp = 0; count = 1;}                                                                  // is the end of the file reached, terminate the string with zero.
595
                string[buff_pnt] = (s8) buff_tmp;
596
                count--;
597
                buff_pnt++;
598
        }
599
        string[buff_pnt] = 0;
600
        return(string);
601
}
602
 
603
//________________________________________________________________________________________________________________________________________
604
// Funtion:     u8 fexist_(u8*, File *file);
605
// 
606
// Description: This function searches the specified file and returns 0 if the file was not found.
607
//                              
608
//
609
//      Return:         0 = file does not exist
610
//                              1 = file exists
611
//________________________________________________________________________________________________________________________________________
612
 
613
u8 fexist_(u8 *fname)
614
{
615
        File *file;
616
 
617
        if((file = fopen_(fname,'r')) != 0)
618
        {
619
                fclose_(file);
620
                return(1);
621
        }
622
        else
623
        {
624
                return(0);
625
        }
626
}
627
 
628
//________________________________________________________________________________________________________________________________________
629
// Funtion:     GetNextCluster(File *file);
630
// 
631
// Description: This function finds the next datacluster of the file specified with File *file. 
632
//                              
633
// Returnvalue: The function returns "0" if the last cluster has already been reached.
634
//________________________________________________________________________________________________________________________________________
635
 
636
u16 GetNextCluster(File *file)
637
{
638
        u32 fat_pointer                 =       0;
639
        u32 fat_sector_offset   =       0;
640
        u32 ul_tmp                              =       0;
641
        u8 retvalue                             =       0;                                                                              // no new cluster found yet.
642
 
643
 
644
        if((file->cluster_pointer >= RootDirectory) && (file->cluster_pointer < (RootDirectory + 31)))
645
        {                                                                                                                                                               // Is the next cluster searched within the rootdirectory and available?
646
                file->cluster_pointer++;                                                                                                        // the rootdirectory is a linear adress space of 32 clusters.
647
                retvalue = 1;                                                                                                                           // and the next cluster has been found.
648
        }
649
        else if(file->cluster_pointer > (RootDirectory + 31))                                                   // The specified cluster is within the FAT.
650
        {
651
                fat_sector_offset   = ((file->cluster_pointer) - (FirstDataCluster));           // Calculate index of actual cluster within the FAT.
652
                fat_sector_offset  /= SectorsPerCluster;                                                                        // calculate the index of the actual sector within the FAT.                                     
653
                fat_sector_offset  += 2;                                                                                                        // In Fat16 clusterpositions have an offset of two.     
654
                fat_pointer = (fat_sector_offset%0x100);                                                                        // Calculate the sector within the cluster.                                                                                                                             
655
                fat_sector_offset   = (fat_sector_offset>>8);                                                           // and the position within the sector.
656
 
657
                SDC_GetSector((u32)(FileAllocationTable + fat_sector_offset),file->buffer);    
658
                file->sector_in_buffer = (FileAllocationTable + fat_sector_offset);                     // Mark that new sector has been read.
659
 
660
                ul_tmp  = (u32)file->buffer[((fat_pointer << 1)+1)];                            // Read next sector information from calculated clusterposition.
661
                ul_tmp  = (ul_tmp << 8);
662
                ul_tmp |= (u32)file->buffer[(fat_pointer << 1)];    
663
                ul_tmp -=2;                                                                                                                                     // next datacluster is clusterposition in fat - 2.
664
                ul_tmp *= SectorsPerCluster;                                                                                            // calculate sectorposition of new cluster
665
                ul_tmp += FirstDataCluster;                                                                                                     // in relation to first datacluster of the disk.
666
 
667
                if(ul_tmp < 0xfff7)                                                                                                                     // has a new cluster been read or was the end of the fat reached?
668
                {
669
                        file->cluster_pointer = (u32) ul_tmp;                                           // continue reading the file at the beginning of new datacluster.
670
                        retvalue = 1;                                                                                                                   // a new cluster was found.
671
                }      
672
        }
673
        return(retvalue);
674
}
675
 
676
//________________________________________________________________________________________________________________________________________
677
// Funtion:     u16 FindNextFreeCluster(void)
678
// 
679
// Description: This function looks in the FAT to find the next free datacluster
680
//                              
681
// Returnvalue: The function returns the adress of the next free cluster found within the fAT.
682
//________________________________________________________________________________________________________________________________________
683
 
684
u16 FindNextFreeCluster(File *file)
685
{
686
        u32 fat_pointer                 =       0;                                                      // Pointer to the first sector of the FAT.
687
        u32 ul_tmp                              =       0;                                                      // temporary variable used to calculate a sectornumber.
688
        u16  fat_sector_offset  =       0;                                                      // index to a sector within the FAT.
689
        u16  fat_entry                  =       0;                                                      // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
690
        u16  free_cluster                       =       0;                                                      // a pointer to the first sector of the next free cluster.
691
 
692
        fat_pointer = (u32) FileAllocationTable;                                        // start searching for empty cluster at the beginning of the fat.
693
                                                                                                                                                // if the end of the fat is not reached yet and no free cluster has been found
694
        while((fat_sector_offset < SectorsPerFat) && (!free_cluster))  
695
        {
696
                ul_tmp = (u32) ((u32)fat_pointer + (u32)fat_sector_offset);
697
                SDC_GetSector((u32)ul_tmp,file->buffer);                                // read next sector of FAT.
698
                file->sector_in_buffer = ul_tmp;                                                                // remember the number of the sector in FileBuffer.
699
                Fat = (struct FatEntry *)file->buffer;
700
                for(fat_entry=0;fat_entry<256;fat_entry++)                                              // look for an free cluster at all entries in this sector of the fat. 
701
                {
702
                        if(Fat[fat_entry].next_cluster == 0x0000)                                       // empty cluster found!!
703
                        {                              
704
                                Fat[fat_entry].next_cluster = 0xffff;                                   // mark this fat-entry as used and save it to the device.
705
                                SDC_PutSector((u32)file->sector_in_buffer,file->buffer);
706
                                free_cluster  = fat_entry;                                                              // the relative position of the free cluster found in this sector of the FAT.
707
                                free_cluster += (fat_sector_offset << 8);                               // calculate the absolute position of the free cluster in the FAT;
708
                                fat_entry = 256;                                                                                // terminate the search for a free cluster in this sector.
709
                        }
710
                }
711
                fat_sector_offset++;                                                                   
712
        }      
713
return(free_cluster);
714
}
715
 
716
//________________________________________________________________________________________________________________________________________
717
// Funtion:     u16 AppendCluster(File *file);
718
// 
719
// Description: This function finds the next free datacluster on the disk and appends it to the specified file.
720
//                              
721
// Returnvalue: This funktion returns 1 if a cluster was appended to the specified file.
722
//________________________________________________________________________________________________________________________________________
723
 
724
u8 AppendCluster(File *file)
725
{
726
        u16  free_cluster = 0;                                                                                                         
727
        u32 fat_pointer = 0;
728
        u8 retvalue     = 0;
729
 
730
        free_cluster = FindNextFreeCluster(file);                                                                                               // the next free cluster found on the disk.
731
        if(free_cluster) retvalue = 1;                                                                                                                  // A free cluster was found and can be added to the end of the file. 
732
        fat_pointer  = FileAllocationTable;                                                                                                             // Set Pointer to the beginnig of the FAT.
733
        fat_pointer += (u32)((u32)GetFatClusterOffset(file) >> 8);              // find the sector in the FAT with 256 entries per sector.
734
 
735
    SDC_GetSector(fat_pointer,file->buffer);                                            
736
        Fat = (struct FatEntry *)file->buffer;
737
        Fat[GetFatSectorIndex(file)].next_cluster = free_cluster;                                                               // append the free cluster to the end of the file in the FAT.
738
        SDC_PutSector((u32)fat_pointer,file->buffer);                                                   // save the modified sector to the FAT.
739
 
740
        fat_pointer  = (u32)free_cluster;
741
        fat_pointer -= 2;
742
        fat_pointer *= SectorsPerCluster;
743
        fat_pointer += FirstDataCluster;
744
 
745
        file->cluster_pointer = fat_pointer;                                                                                                    // continue wrtiting to the file in the new and free datacluster.
746
        return(retvalue);                                                                                                                                               // return 1 when a new cluster was appended to the file
747
}
748
 
749
//________________________________________________________________________________________________________________________________________
750
// Funtion:     u16 GetFatClusterIndex(File *file);
751
// 
752
// Description: This function returns the clusterindex of the cluster specified by file->cluster_pointer of the specified file.
753
//                              
754
//________________________________________________________________________________________________________________________________________
755
 
756
u16 GetFatClusterOffset(File *file)
757
{
758
        u32 fat_sector_offset   =       0;
759
 
760
        fat_sector_offset   = ((file->cluster_pointer) - (FirstDataCluster));                           // Calculate index of actual cluster in FAT.
761
        fat_sector_offset  /= SectorsPerCluster;                                                                                                               
762
        fat_sector_offset  += 2;                                                                                                                        // In Fat16 clusterpositions have an offset of two.                                                             
763
 
764
        return((u16)fat_sector_offset);
765
}
766
 
767
//________________________________________________________________________________________________________________________________________
768
// Funtion:     u16 GetFatSectorIndex(File *file);
769
// 
770
// Description: This function returns the sectorindex of the cluster specified by file->cluster_pointer of the specified file.
771
//                              
772
//________________________________________________________________________________________________________________________________________
773
 
774
u16 GetFatSectorIndex(File *file)
775
{
776
        u16 fat_pointer                 =       0;
777
 
778
        fat_pointer = GetFatClusterOffset(file);
779
        fat_pointer = fat_pointer % 0x100;                                                                                                      // Calculate the clusterposition in the fat                                                                                                                             
780
 
781
        return(fat_pointer);
782
}
783
 
784
//________________________________________________________________________________________________________________________________________
785
// Funtion:     u16 CreateDirectoryEntry(u8 *, u16, u8 attrib)
786
// 
787
// Description: This function looks for the next free position in the directory and creates an entry. The type of an directoryentry is
788
//                              specified by the attribute. 
789
//                              bit0:   unused
790
//                              bit1:   archive
791
//                              bit2:   read_only
792
//                              bit3:   system  
793
//                              bit4:   directory
794
//                              bit5:   volume
795
//________________________________________________________________________________________________________________________________________
796
 
797
u8 CreateDirectoryEntry(u8 *fname, u16 cluster, File *file,u8 attrib)
798
{
799
        u16     rootentry       = 0;                                                                                                    // index to an entry in the rootdirectory.
800
        u16     cnt_enries_searched = 0;                                                                                        // count the number of rootentries which have been searched already.
801
        u8      i = 0;
802
        u16     sector_offset = 0;                                                                                                      // index to the sector of the Rootentry which is searched momentarily
803
        u8      retvalue = 0;
804
 
805
                                                                                                                                                                                // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
806
        do
807
        {                                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
808
                rootentry=0;                                                                   
809
                SDC_GetSector((u32)(RootDirectory + sector_offset),file->buffer);       // Read the Rootdirectory.
810
                DirectoryEntry = (struct DirEntry *)file->buffer;
811
                while((rootentry<16) && (!retvalue))
812
                {
813
                        if((DirectoryEntry[rootentry].attribute == 0) || (DirectoryEntry[rootentry].attribute == 0xE5)) // empty directory entry found
814
                        {
815
                                for(i=0;i<11;i++) DirectoryEntry[rootentry].name[i] = fname[i];         // Kopie the filename and the file extension to the directoryentry.
816
                                DirectoryEntry[rootentry].attribute    = attrib;                                                // Set the fileattribute to archive to reserve the directoryentry.
817
                                DirectoryEntry[rootentry].startcluster = cluster;                                               // copy the location of the first datacluster to the directoryentry.
818
                                DirectoryEntry[rootentry].size     = 0;                                                                 // the new createted file has no content yet.
819
                                file->directory_sector = (u32) (RootDirectory + sector_offset);
820
                                file->directory_index  = (u8) rootentry;
821
                                retvalue = 1;
822
                                SDC_PutSector((u32)(RootDirectory + sector_offset),file->buffer);                              
823
                        }                      
824
                        rootentry++;
825
                        cnt_enries_searched++;
826
                }
827
                if(!retvalue)                                                                                                                                   // file not found in this sector so take next sector.
828
                {
829
                        rootentry = 0;
830
                        sector_offset++;
831
                }
832
        }
833
        while((cnt_enries_searched< PossibleRootEntries) && (!retvalue));
834
 
835
        return(retvalue);                                                                                                                                       // return 1 if file has been created otherwise return 0.
836
}
837
 
838
//________________________________________________________________________________________________________________________________________
839
// Funtion:     u16 SeekDirectoryEntry(u8*, File *, u8)
840
// 
841
// Description: this function searches all possible rootentries until the file or directory is found or the end of the rootdirectory is reached
842
//                              
843
// Returnvalue: This function returns 1 if the directoryentry specified was found.
844
//________________________________________________________________________________________________________________________________________
845
 
846
u8 SeekDirectoryEntry(u8 *fname, File *file)
847
{
848
        u16     rootentry=0;
849
        u16     end_of_directory_not_reached = 0;               // the directory has been read completely without a result.
850
        u8      i=0;
851
        u8      retvalue = 0;
852
        u32     cluster_temp = 0;
853
        u16     cnt=0;
854
 
855
                                                                                                                        // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
856
        do
857
        {                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.
858
                rootentry=0;                                                                   
859
                SDC_GetSector((u32) file->cluster_pointer,file->buffer);                // Read the Rootdirectory.
860
                DirectoryEntry = (struct DirEntry *)file->buffer;
861
 
862
                while((!retvalue)&&(rootentry<16))
863
                {
864
                cnt++;
865
 
866
                        i=0;
867
                        while((i<10)&&(DirectoryEntry[rootentry].name[i] == fname[i]))
868
                        {
869
                                i++;
870
                        }
871
                        if((i==10) && (DirectoryEntry[rootentry].attribute == file->attribute))         // entry found!! -> reading startcluster of entry from offset 26.
872
                        {
873
                                cluster_temp = (u32)DirectoryEntry[rootentry].startcluster;                                                    
874
                                cluster_temp -=2;                                                                                                                       // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
875
                                cluster_temp *= (u32)SectorsPerCluster;                                                 // Calculate positon of first cluster.
876
                                file->start_cluster   = (FirstDataCluster + cluster_temp);
877
                                file->directory_sector = (u32) file->cluster_pointer;
878
                                file->cluster_pointer = file->start_cluster;                                                            // start reading the file with the first cluster.
879
                                file->filesize = (u32) DirectoryEntry[rootentry].size;
880
                                file->directory_index  = (u8) rootentry;
881
                                retvalue = 1;
882
                        }
883
                        rootentry++;
884
                }
885
                if(!retvalue)                                                                                   // file not found in this sector so take next sector.
886
                {
887
                        end_of_directory_not_reached = GetNextCluster(file);
888
                }
889
        }
890
        while((end_of_directory_not_reached) && (!retvalue));
891
        return(retvalue);
892
}
893
 
894
//________________________________________________________________________________________________________________________________________
895
// Funtion:     void ScanSubDirectories(u8*, File *file);
896
// 
897
// Description: This function scans the filename for subdirectories and changes the directory until the last directory is reached. 
898
//                              here the specified file is searched. 
899
//                              
900
// Returnvalue:
901
//________________________________________________________________________________________________________________________________________
902
 
903
u8 ScanSubDirectories(u8 *fname, File *file)
904
{
905
        u8 readpointer  = 0;                                            // pointer to read a character within the filepath.
906
        u8 writepointer = 0;                                            // pointer to write a character into the string dirname.
907
        u8 dircnt               = 0;                                            // the number of subdirectories found in filepath.
908
        u8 dirname[11];                                                         // temporary variable containing the name of a directory within the filepath.
909
        u8 retvalue     = 1;                                            // no error opening a subdirectory occured yet. 
910
        u8 cnt                  = 0;                                            // maximun number of characters in a path is 256;
911
 
912
 
913
        while((fname[readpointer]!=0) &&  (cnt < 255))          // search the string until the end is reached.  
914
        {
915
                cnt++;
916
                if((fname[readpointer] == '/') && readpointer)          // subdirectory found. ignore first "/" as directory. 
917
                {
918
                        dircnt++;                                                                               // count the number of subdirectories found within the filepath.                
919
                }
920
                readpointer++;
921
        }
922
 
923
        for(writepointer=0;writepointer<10;writepointer++) dirname[writepointer] = ' ';
924
        writepointer = 0;
925
        readpointer = 0;                                                                                // start scanning the string at the beginning.
926
 
927
        file->cluster_pointer = RootDirectory;                                  // always start searching in the rootdirectory.
928
        file->attribute = _DIRECTORY;                                                   // the attribute of the item to be searched in the specified directory. 
929
 
930
        while(dircnt && retvalue)                                                               // scan all subdirectories found before.
931
        {
932
                if(fname[readpointer] != '/')                                           // is the end of the subdirectory entry not reached yet?
933
                {
934
                        if((fname[readpointer]>96) && (fname[readpointer]<123))
935
                        {                                                                                               // all characters must be upper case.
936
                                dirname[writepointer]=(fname[readpointer] - 32);                                       
937
                        }
938
                        else
939
                        {
940
                                dirname[writepointer]=fname[readpointer];
941
                        }      
942
                        writepointer++;
943
                }      
944
                else                                                                                           
945
                {                      
946
                        dircnt--;
947
                        if(!(SeekDirectoryEntry(dirname, file)))                // was the seperated subdirectory not found?
948
                        {
949
                                retvalue = 0;                                                           // leave the function with return(0) otherwise continue with the next subdirectory until all directories have been searched.
950
                        }
951
                        for(writepointer=0;writepointer<10;writepointer++) dirname[writepointer] = ' ';
952
                        writepointer = 0;
953
                }
954
                readpointer++;
955
        }
956
        file->attribute = _FILE;                                                                // All subdirectories have been searched. the next thing to find is the specified file.
957
        return(retvalue);
958
}
959
 
960
//________________________________________________________________________________________________________________________________________
961
// Funtion:     void SeperateFileName(u8*);
962
// 
963
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST    TXT');
964
//                              
965
//________________________________________________________________________________________________________________________________________
966
 
967
void SeperateFileName(u8 *fname, u8 *name)
968
{
969
        u8 readpointer  = 0;
970
        u8 writepointer = 0;
971
        u8 dircnt               = 0;                                            // the number of subdirectories found in filepath.
972
        u8 fileindex    = 0;                                            // the position in the filenamestring where the last "/" is found.
973
 
974
        while(fname[readpointer]!=0)                                                    // search the string until the end is reached.  
975
        {
976
                if((fname[readpointer] == '/') && readpointer)          // subdirectory found. ignore first "/" as directory. 
977
                {
978
                        dircnt++;                                                                               // subdirectory entry found.            
979
                        fileindex = (readpointer + 1);                                          // store the index of the last slash found as the beginning of the filename.
980
                }
981
                readpointer++;
982
        }
983
        readpointer = fileindex;                                                                // start seperating the filename from the directory at the stored position.
984
        dircnt = 0;
985
 
986
        while((writepointer<=10) && (fname[readpointer]!=0))    // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute.
987
        {                                                                                                               // the filename in the rootdirectory is in the format "TEST    TXT" without the dot.
988
                if(fname[readpointer]=='.')                                             // seperating filename and attribute.
989
                {
990
                        readpointer++;
991
                        writepointer=8;                
992
                }
993
                else
994
                {
995
                        if((fname[readpointer]>96) && (fname[readpointer]<123))
996
                        {
997
                                name[writepointer]=(fname[readpointer] - 32);                                   // all characters must be upper case.
998
                        }
999
                        else
1000
                        {
1001
                                name[writepointer]=fname[readpointer];
1002
                        }      
1003
                        readpointer++;
1004
                        writepointer++;
1005
                }
1006
        }      
1007
}