Subversion Repositories NaviCtrl

Rev

Rev 1 | Rev 41 | Go to most recent revision | 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
6
// + Nur für den privaten Gebrauch
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
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28
// + Die PORTIERUNG der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur 
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 
43
// +   * PORTING this software (or part of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
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
24 StephanB 63
// Last Modifikation:   21.04.2008
64
// Version:                             1.28
1 ingob 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);                
24 StephanB 70
//                                              u8                      fopen_(s8 *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                      fgets_(s8 *string, s16 count, File *file);
1 ingob 76
//                                              u8                      fputchar_(File *file,s8 c);
77
//                                              u8                      fputs_(File *file,s8 *string);
24 StephanB 78
//                                              s8 *            fgets(s8 *, s16, File);
79
//                                              u8                      fexist_(u8*);
80
//                                              u8                      mkdir__(s8 *name);
81
//                                              u8                      chdir__(s8 *name);
82
//                                              u8                      findfirst_(s8 *fname, Find *item, u8 attribute);
83
//                                              u8                      findnext_(Find *item);
84
//                                              u8                      fdelete_(s8 *fname)
85
//                                              u8                      rmdir_(s8 *dname)
86
//                                              u16                     feof_(File);
1 ingob 87
//........................................................................................................................................
88
// ext. functions:              extern u8 SDC_GetSector  (u32,u8 *);            
89
//                                              extern u8 SDC_PutSector (u32,u8 *);
90
//........................................................................................................................................
91
//
92
// URL:                                 www.Mikro-Control.de
93
// mailto:                              stephan.busker@mikro-control.de
94
//________________________________________________________________________________________________________________________________________
95
 
96
 
97
 
98
//________________________________________________________________________________________________________________________________________
99
// 
100
// Global variables needed for read- or write-acces to the FAT16- filesystem.
101
//                              
102
//________________________________________________________________________________________________________________________________________
103
 
24 StephanB 104
u8              SectorsPerCluster               = 0;                                                                                    // how many sectors does a cluster contain?
105
u8              FatCopies                               = 0;                                                                                    // Numbers of copies of the FAT
106
u16             PossibleRootEntries     = 0;                                                                                    // Possible number of entries in the root directory.
107
u16             SectorsPerFat                   = 0;                                                                                    // how many sectors does a fat16 contain?
108
u32             ReservedSectors                 = 0;                                                                                    // Sectors reserved by the filesystem.
109
u32             FirstPartitionSector    = 0;                                                                                    // Distance in sectors between the first partition and the master bootrecord.
110
u32             FileAllocationTable     = 0;                                                                                    // pointer to the first FAT
111
u32             RootDirectory                   = 0;                                                                                    // Pointer to the rootdirectory of the first partition.
112
u32             FirstDataCluster                = 0;                                                                                    // Pointer to the first cluster containing data (cluster0).
113
u32             CWD                                             = 0;                                                                                    // Pointer startcluster to the current working directory
1 ingob 114
 
115
 
24 StephanB 116
struct DirEntry         *DirectoryEntry;                                                                                        // Pointer to an entry of the directory.
117
struct FatEntry         *Fat;                                                                                                           // Pointer to an entry of the fat (next clusterposition).
1 ingob 118
 
24 StephanB 119
File FilePointer[__MAX_FILES_USED];                                                                                             // Allocate Memmoryspace for each filepointer used.
1 ingob 120
 
121
 
122
//________________________________________________________________________________________________________________________________________
123
// Funtion:     InitFat16(void);
124
// 
125
// Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdirectory
126
//                              and stores the information in global variables.
127
//
24 StephanB 128
// Returnvalue: The function returns "0" if the filesystem could not be initialized because no partition was found on the volume. 
1 ingob 129
//________________________________________________________________________________________________________________________________________
130
 
131
u8 InitFat16(void)
132
{      
133
        u8 retvalue = 0;
134
    u8  cnt     = 0;
24 StephanB 135
        struct VBR_Entry *VBR;                                                                                                          // Pointer to the VolumeBootRecord.
136
        struct MBR_Entry *MBR;                                                                                                          // Pointer to the masterbootrecord.     
1 ingob 137
        File *file;
138
 
139
        for(cnt=0;cnt<__MAX_FILES_USED;cnt++)
140
        {
24 StephanB 141
                FilePointer[cnt].state = _UNUSED;                                                                               // declare the filepointers as unused.
1 ingob 142
        }
143
 
144
        file = &FilePointer[0];
145
 
24 StephanB 146
        SerialPutString("\n\rFAT16 init...");
147
        while((SDC_Init() != SD_SUCCESS) && (cnt++<100));
148
 
149
        if(cnt <100)                                                                                                                            // sdcard initialised succesfully
1 ingob 150
        {
24 StephanB 151
                SDC_GetSector((u32)_MBR_SECTOR,file->buffer);                                                   // Read the MasterBootRecord from mmc.
1 ingob 152
                MBR = (struct MBR_Entry *) file->buffer;
153
                FirstPartitionSector = MBR->PartitionEntry1.NoSectorsBeforePartition;
24 StephanB 154
                if((MBR->PartitionEntry1.Type == _FAT16_32_MB_BIOS_Extension) ||
155
                   (MBR->PartitionEntry1.Type == _FAT16_ST_32_MB) ||
156
                   (MBR->PartitionEntry1.Type == _FAT16_LT_32_MB))
157
                {
158
                        SDC_GetSector(FirstPartitionSector,file->buffer);                                       // Read the volume bootrecord from mmc. 
1 ingob 159
 
24 StephanB 160
                        VBR = (struct VBR_Entry *) file->buffer;                                                        // Enter the VBR using the structure VBR_Entry.
161
                        SectorsPerCluster       = VBR->SectorsPerCluster;                                               // Number of sectors per cluster. Depends on the memorysize of the sd-card.
162
                        FatCopies                       = VBR->NoFATCopies;                                                             // Number of fatcopies.
163
                        PossibleRootEntries = VBR->MaxRootEntries;                                                      // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
164
                        SectorsPerFat           = VBR->SectorsPerFAT;                                                   // The number of sectors per FAT.
165
                        ReservedSectors         = VBR->ReservedSectors;                                                 // calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster.
1 ingob 166
 
24 StephanB 167
                        FileAllocationTable     =   (u32)(FirstPartitionSector + (u32)ReservedSectors);                                                 // Calculate the position of the FileAllocationTable.
168
                        RootDirectory           =   (u32)((u32)FileAllocationTable + (u32)((u32)SectorsPerFat*(u32)FatCopies)); // Calculate the position of the Rootdirectory.
169
                        FirstDataCluster        =   (u32)((u32)RootDirectory + ((u32)(PossibleRootEntries>>4)));                                        // Calculate the position of the first datacluster.
170
                        CWD                                     =       RootDirectory;                                                                                                                                  // The actual directory is the rootdirectory.
1 ingob 171
                        retvalue = 1;
24 StephanB 172
                        SerialPutString("\n\rfilesystem ok");                                  
173
                        str_Volume.state = INITIALIZED;
1 ingob 174
                }
24 StephanB 175
                else
176
                {
177
                        str_Volume.state = NOT_INITIALIZED;
178
                        SerialPutString("\n\rfilesystem nok");         
179
                }
1 ingob 180
        }
181
        return(retvalue);      
182
}
183
 
184
//________________________________________________________________________________________________________________________________________
24 StephanB 185
// Funtion:     File * fopen_(u8*, u8 *);
1 ingob 186
// 
24 StephanB 187
// Description: This function looks for the file to be opened in the directory specified by the variable "CWD" of the drive. 
188
//                              If the file was found this function returns a filepoiner to the opened file otherwise NULL//                            
1 ingob 189
//
24 StephanB 190
//      Return:         Pointer to the opened file or NULL
191
//                              
1 ingob 192
//________________________________________________________________________________________________________________________________________
193
 
24 StephanB 194
File * fopen_(s8 *fname, s8 mode)
1 ingob 195
{
196
        File *file;
197
 
24 StephanB 198
        file = ReserveFilePointer();                                                                                                    // reserve a filepointer.       
199
 
200
        if(file != NULL)                                                                                                                                // A free filepointer was found.
1 ingob 201
        {
24 StephanB 202
                file->mode      = mode;                                                                                                                 // mode of fileoperation (read,write)
1 ingob 203
 
24 StephanB 204
                if(SeekFileInDirectory(fname, file))                                                                            // if file was found
1 ingob 205
                {
24 StephanB 206
                        SerialPutString("ok");
1 ingob 207
                        if(mode == 'a')                                                                                                                 // open existing file for writing (append data at the end of the file)
208
                        {      
209
                                fseek_(file, 0, SEEK_END);                                                                                      // fseek points to the end of the file
210
                        }
24 StephanB 211
                }              
1 ingob 212
                else
213
                {
214
                        if((mode == 'a') || (mode == 'w'))                                                                              // specified file doesn't exist so create new file for writing data.
215
                        {      
24 StephanB 216
                                if(CreateFileInDirectory(fname,file))                                                           // Could an entry for the new file in the rootdirectory be created?
1 ingob 217
                                {
24 StephanB 218
                                        return(file);
219
                                }      
220
                                else
221
                                {
222
                                        FreeFilePointer(file);                                                                              // free the filepointer.
223
                                        file = NULL;
224
                                }
1 ingob 225
                        }
24 StephanB 226
            else                                                                    // file with mode 'r' not found
227
            {
228
                FreeFilePointer(file);                                                                                          // free the filepointer.
229
                file = NULL;                                                        // file not found
230
            }
1 ingob 231
                }
232
        }
24 StephanB 233
        return(file);
1 ingob 234
}
235
 
24 StephanB 236
 
237
 
1 ingob 238
//________________________________________________________________________________________________________________________________________
239
// Funtion:     fflush_(File *file);
240
// 
241
// Description: This function writes the data already in the buffer but not yet written to the file. 
242
//                              
243
//________________________________________________________________________________________________________________________________________
244
 
245
s16     fflush_(File *file)
246
{
247
        u16 time=0;
248
        u16 date=0;
249
 
24 StephanB 250
 
251
        if(file && ((file->mode =='a') || (file->mode =='w')))
1 ingob 252
        {
253
                if(file->byte_index > 0)                                                                                                                        // has data been added to the file?             
254
                {
24 StephanB 255
                        SDC_PutSector((u32)(file->cluster_pointer + file->sector_index),file->buffer);// save the data still in the buffer      
1 ingob 256
                }      
24 StephanB 257
                SDC_GetSector((u32)file->directory_sector,file->buffer);                                                        // read the directoryentry for this file.
1 ingob 258
                DirectoryEntry = (struct DirEntry *)file->buffer;
259
                DirectoryEntry[file->directory_index].size = (u32) file->filesize;
260
                DirectoryEntry[file->directory_index].time = (u16) time;
261
                DirectoryEntry[file->directory_index].date = (u16) date;
262
                SDC_PutSector((u32)file->directory_sector,file->buffer);
263
        }
264
        return(0);
265
}
266
 
267
//________________________________________________________________________________________________________________________________________
268
// Funtion:     fclose_(File *file);
269
// 
270
// Description: This function closes the open file by writing the remaining data from the buffer to the device and entering the filesize 
271
//                              in the directory entry.
272
//________________________________________________________________________________________________________________________________________
273
 
274
void fclose_(File *file)
275
{
24 StephanB 276
 
277
        if(file != NULL)
1 ingob 278
        {
24 StephanB 279
                fflush_(file);                                                                                                                                          // save buffered data to the disk
1 ingob 280
        }
24 StephanB 281
        FreeFilePointer(file);                                                                                                                                  // and free the filepointer.
1 ingob 282
}
283
 
284
//________________________________________________________________________________________________________________________________________
24 StephanB 285
// Funtion:     u32 fread_(void *buffer, s32 size, s32 count, File *file);
1 ingob 286
// 
287
// Description: This function reads count objects of the specified size from the actual position of the file to the specified buffer.
288
//                              
289
// Returnvalue: The function returns the number of objects (not bytes) read from the file.      
290
//                              
291
//________________________________________________________________________________________________________________________________________
292
 
293
u32 fread_(void *buffer, u32 size, u32 count, File *file)
294
{
24 StephanB 295
        u32 object_cnt  = 0;                                                                                                                    // count the number of objects read from the file.
1 ingob 296
        u32 object_size         = 0;                                                                                                            // count the number of bytes read from the actual object.
24 StephanB 297
        u8 *buff_pnt    = 0;                                                                                                                    // a pointer to the actual bufferposition.
298
        u8 success      = 1;                                                                                                                    // no error occured during read operation to the file.
1 ingob 299
 
24 StephanB 300
        buff_pnt = (u8 *) buffer;                                                                                                               // cast the void pointer to an u8 *
1 ingob 301
 
302
        while((object_cnt < count) && success)
303
        {
304
                object_size = size;
305
                while((size > 0) && success)
306
                {
24 StephanB 307
                        *buff_pnt = (u8) fgetchar_(file);                                                                               // read a byte from the buffer to the opened file.
1 ingob 308
                        buff_pnt++;
309
                        size--;
310
                }
311
                if(success) object_cnt++;
312
        }              
313
 
24 StephanB 314
        return(object_cnt);                                                                                                                             // return the number of objects succesfully read from the file
1 ingob 315
}
316
 
317
//________________________________________________________________________________________________________________________________________
24 StephanB 318
// Funtion:     u32 fwrite_(void *buffer, s32 size, s32 count, File *file);
1 ingob 319
// 
320
// Description: This function writes count objects of the specified size from the buffer to the actual positon within the file.
321
//                              
322
// Returnvalue: The function returns the number of objects (not bytes) written to the file.     
323
//                              
324
//________________________________________________________________________________________________________________________________________
325
 
326
u32 fwrite_(void *buffer, u32 size, u32 count, File *file)
327
{
24 StephanB 328
        u32 object_cnt  = 0;                                                                                                                    // count the number of objects written to the file.
1 ingob 329
        u32 object_size         = 0;                                                                                                            // count the number of bytes written from the actual object.
24 StephanB 330
        u8 *buff_pnt    = 0;                                                                                                                    // a pointer to the actual bufferposition.
331
        u8 success      = 1;                                                                                                                    // no error occured during write operation to the file.
1 ingob 332
 
24 StephanB 333
        buff_pnt = (u8 *) buffer;                                                                                                               // cast the void pointer to an u8 *
1 ingob 334
 
335
        while((object_cnt < count) && success)
336
        {
337
                object_size = size;
338
                while((size > 0) && success)
339
                {
24 StephanB 340
                        success = fputchar_(file, *buff_pnt);                                                                   // write a byte from the buffer to the opened file.
1 ingob 341
                        buff_pnt++;
342
                        size--;
343
                }
344
                if(success) object_cnt++;
345
        }              
346
 
24 StephanB 347
        return(object_cnt);                                                                                                                             // return the number of objects succesfully written to the file
348
}                                                                                                                                                                       // (!!!!! objects and not bytes !!!!)
1 ingob 349
 
350
//________________________________________________________________________________________________________________________________________
351
// Funtion:     s16 fseek_(File *, s32, s16)
352
// 
353
// Description: This function sets the pointer of the stream relative to the position 
354
//                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END). 
355
//                              
356
//________________________________________________________________________________________________________________________________________
357
 
358
s16 fseek_(File *file, s32 offset, s16 origin)
359
{
360
        s32                     fposition       = 0;
361
        s16                     retvalue        = 1;
362
        u32     temp            = 0;
363
 
364
//......................................................
24 StephanB 365
        if(origin == SEEK_SET)                                                                                                          // Fileposition relative to the beginning of the file.
1 ingob 366
        {
367
                fposition = 0;
368
        }      
369
//......................................................
24 StephanB 370
        else if(origin == SEEK_END)                                                                                                     // Fileposition relative to the end of the file.
1 ingob 371
        {
372
                fposition  = (s32) file->filesize;
373
        }      
374
//......................................................
24 StephanB 375
        else if(origin == SEEK_CUR)                                                                                                     // Fileposition relative to the current position of the file.
1 ingob 376
        {
377
                fposition = file->fileposition;
378
        }      
379
 
380
        fposition += offset;
381
 
24 StephanB 382
        if((fposition >= 0) && (fposition <= (s32)file->filesize))                              // is the pointer still within the file?
1 ingob 383
        {
384
                retvalue                                = 0;
385
                file->sector_index              = 0;
386
                file->byte_index                = 0;
387
                file->fileposition              = 0;
388
                file->cluster_pointer   = file->start_cluster;
389
 
390
                while(file->fileposition < fposition)
391
                {
392
                        file->fileposition++;                                                                          
393
                        if(file->byte_index < 511)                                                                     
394
                        {
395
                                file->byte_index++;
396
                        }
397
                        else
398
                        {
24 StephanB 399
                                file->byte_index=0;                                                                                             // reading at the beginning of new sector.
400
                                file->sector_index++;                                                                                   // continue reading in next sector
401
                                if(file->sector_index >= SectorsPerCluster)                                     // When end of cluster is reached, the next datacluster has to be searched in the FAT.
1 ingob 402
                                {
403
                                        if(file->fileposition < fposition)
404
                                        {
24 StephanB 405
                                                file->sector_index = 0;                                                                 // start reading new cluster at first sector of the cluster.
406
                                                GetNextCluster(file);                                                                   // Sets the clusterpointer of the file to the next datacluster.
1 ingob 407
                                        }
408
                                }
409
                        }      
410
                }
411
                if(file->byte_index)                           
412
                {
413
                        temp = (u32)((u32)file->cluster_pointer + (u32)file->sector_index);                    
24 StephanB 414
                        SDC_GetSector((u32)temp,file->buffer);                                                          // FileBuffer will be written at once at the end of the cluster and has to be updated.                                          
1 ingob 415
                }
416
        }      
417
        return(retvalue);
418
}
419
 
420
//________________________________________________________________________________________________________________________________________
421
// Funtion:     fgetchar_(File *file);
422
// 
24 StephanB 423
// Description: This function reads and returns one character from the specified file. 
424
//                              
1 ingob 425
// Returnvalue: The function returns the character read from the specified memorylocation as u8 casted to s16 or EOF.
426
//________________________________________________________________________________________________________________________________________
427
 
428
s16 fgetchar_(File *file)
429
{      
430
        s16 c = EOF;
431
        u32 temp1;
432
 
24 StephanB 433
        if(((file->fileposition)+1) < file->filesize)                                                           // wen the end of the file is not reached, get the next character.
1 ingob 434
        {
24 StephanB 435
                temp1  = (u32)file->cluster_pointer;                                                                    // calculate the adress of the next character to be read.
1 ingob 436
                temp1 += (u32)file->sector_index;                      
437
 
438
                if(file->sector_in_buffer != temp1)                                                                     // Has the content of the buffer been modified and has to be updated?
439
                {
24 StephanB 440
                        SDC_GetSector((u32)temp1,file->buffer);                                                 // Read the calculated cluster.                 
1 ingob 441
                        file->sector_in_buffer = (u32)temp1;
442
                }      
443
                c = (s16) file->buffer[file->byte_index];
24 StephanB 444
                file->fileposition++;
1 ingob 445
 
446
                if(file->byte_index < 511)                                                                                              // continue reading from this sector until the end of the sector is reached.
447
                {
448
                        file->byte_index++;
449
                }
450
                else                                                                                                                                    // has the end of an sector been reached->
451
                {
452
                        file->byte_index=0;                                                                                                     // continue reading at the beginning -
453
                        file->sector_index++;                                                                                           // of new sector.
454
                        if(file->sector_index >= SectorsPerCluster)                                             // When the end of an cluster is reached, the next datacluster has to be searched in the FAT.
455
                        {
456
                                file->sector_index = 0;                                                                                 // start reading new cluster at first sector of the cluster.
457
                                GetNextCluster(file);                                                                                   // Sets the clusterpointer of the file to the next datacluster.
458
                        }
459
                }
460
        }
461
        return(c);
462
}
463
 
464
//________________________________________________________________________________________________________________________________________
24 StephanB 465
// Funtion:     fputchar_(File *file, s8 *);
1 ingob 466
// 
467
// Description: This function writes a byte to the specified file and takes care of writing the necessary FAT- Entries. 
468
//                              
469
// Returnvalue: The function returns a value of 0 if the data could not be written.
470
//________________________________________________________________________________________________________________________________________
471
 
472
u8 fputchar_(File *file,s8 c)
473
{      
474
        u32 ul_temp  = 0;
475
        u8 retvalue = 1;
476
 
24 StephanB 477
    if(file->sector_index >= SectorsPerCluster)                                                         // if end of the cluster is reached, find next free cluster
1 ingob 478
        {
479
                file->sector_index = 0;
24 StephanB 480
                if(!AppendCluster(file)) retvalue = 0;                                                                  // append a new and free cluster at the end of the file.
1 ingob 481
        }
482
 
24 StephanB 483
        file->buffer[file->byte_index] = c;                                                                             // write databyte into the buffer. The byte will be written to the device at once
484
        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.
485
        file->fileposition++;                                                                                                           // the actual positon within the file. 
486
                                                                                                                                                                // if the buffer contains the complete sectordata.
487
        if(file->byte_index < 511)                                                                                                      // if the end of this sector is not reached yet
1 ingob 488
        {
24 StephanB 489
                file->byte_index++;                                                                                                             // the next byte will be written to the next byteposition in this sector.
1 ingob 490
        }
24 StephanB 491
        else                                                                                                                                            // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected.
1 ingob 492
        {
493
                ul_temp  = (u32)file->cluster_pointer;
494
                ul_temp += (u32)file->sector_index;
495
 
496
                SDC_PutSector((u32)ul_temp,file->buffer);
24 StephanB 497
                file->byte_index=0;                                                                                                             // and the next byte will be written at the beginning of this new sector.
1 ingob 498
                file->sector_index++;
24 StephanB 499
                if(file->sector_index >= SectorsPerCluster)                                                     // if end of the cluster is reached, find next free cluster
1 ingob 500
                {
501
                        file->sector_index = 0;
24 StephanB 502
                        if(!AppendCluster(file)) retvalue = 0;                                                          // append a new and free cluster at the end of the file.
1 ingob 503
                }
504
        }
505
        return(retvalue);
506
}
507
 
508
//________________________________________________________________________________________________________________________________________
24 StephanB 509
// Funtion:     fputs_(File *file, s8 *string);
1 ingob 510
// 
24 StephanB 511
// Description: This function writes a zero terminated string to the specified file.
1 ingob 512
//                              
513
//________________________________________________________________________________________________________________________________________
514
 
515
u8 fputs_(File *file,s8 * string)
516
{
517
        u8 i=0;
518
 
519
        while(string[i] != 0)
520
        {
521
                fputchar_(file,string[i]);
522
                i++;
523
        }
524
        return(0);
525
}
526
 
527
//________________________________________________________________________________________________________________________________________
24 StephanB 528
// Funtion:     s8 * fgets_(s8 *string, s16 count, File *file)
1 ingob 529
// 
24 StephanB 530
// Description: This function reads a string from the file to the specifies string until EOF or end of line was detected.. 
1 ingob 531
//              
24 StephanB 532
// Returnvalue: A pointer to the string or NULL if EOF was read from the file with no other characters before.
1 ingob 533
//________________________________________________________________________________________________________________________________________
534
 
535
s8 * fgets_(s8 *string, s16 count, File *file)
536
{
537
        s16 buff_pnt = 0;
538
        s16 buff_tmp = 0;
24 StephanB 539
        s8 *retvalue = 0;
1 ingob 540
 
24 StephanB 541
        retvalue = string;
542
 
543
        while(count > 1)                                                                                                // read the count-1 characters from the file to the string.
1 ingob 544
        {
24 StephanB 545
                buff_tmp = fgetchar_(file);                                                                     // read a character from the opened file.               
546
                if(buff_tmp == EOF)                                                                             // is the end of the file reached, terminate the string with zero.
1 ingob 547
                {
24 StephanB 548
                        if(buff_pnt != 0)                                                                               // are there characters within the string?
549
                        {
550
                                break;
551
                        }
552
                        else
553
                        {
554
                                retvalue = NULL;                                                                        // first character read was EOF -> return(NULL);
555
                                break;
556
                        }
557
                }      
558
                else if(buff_tmp == 0x0A)                                                                       // lf detected.
559
                {              
560
                        string[buff_pnt] = (s8) buff_tmp;                                               // add lf to the string.
561
                        buff_pnt++;
1 ingob 562
                        break;
563
                }
24 StephanB 564
                else
565
                {
566
                        string[buff_pnt] = (s8) buff_tmp;
567
                        count--;
568
                        buff_pnt++;
569
                }
1 ingob 570
        }
24 StephanB 571
        string[buff_pnt] = 0;                                                                                   // terminate string with zero
1 ingob 572
        return(string);
573
}
574
 
575
//________________________________________________________________________________________________________________________________________
24 StephanB 576
// Funtion:     u8 fexist_(u8*);
1 ingob 577
// 
578
// Description: This function searches the specified file and returns 0 if the file was not found.
579
//                              
580
//
581
//      Return:         0 = file does not exist
582
//                              1 = file exists
583
//________________________________________________________________________________________________________________________________________
584
 
24 StephanB 585
u8 fexist_(s8 *fname)
1 ingob 586
{
587
        File *file;
24 StephanB 588
 
589
        file = fopen_(fname,'r');                                                                               // try to open the specified file.
1 ingob 590
 
24 StephanB 591
        if(file != NULL)
1 ingob 592
        {
24 StephanB 593
                FreeFilePointer(file);                                                                          // Free the filepoint                                                                                           // free the filepointer
594
                return(1);                                                                                                      // file was found so return(1);
1 ingob 595
        }
596
        else
597
        {
24 StephanB 598
                return(0);                                                                                                      // file not found return(0);
1 ingob 599
        }
600
}
601
 
602
//________________________________________________________________________________________________________________________________________
603
// Funtion:     GetNextCluster(File *file);
604
// 
605
// Description: This function finds the next datacluster of the file specified with File *file. 
606
//                              
607
// Returnvalue: The function returns "0" if the last cluster has already been reached.
608
//________________________________________________________________________________________________________________________________________
609
 
610
u16 GetNextCluster(File *file)
611
{
612
        u32 fat_pointer                 =       0;
613
        u32 fat_sector_offset   =       0;
614
        u32 ul_tmp                              =       0;
24 StephanB 615
        u8 retvalue                             =       0;                                                                                                      // no new cluster found yet.
1 ingob 616
 
617
 
618
        if((file->cluster_pointer >= RootDirectory) && (file->cluster_pointer < (RootDirectory + 31)))
619
        {                                                                                                                                                               // Is the next cluster searched within the rootdirectory and available?
620
                file->cluster_pointer++;                                                                                                        // the rootdirectory is a linear adress space of 32 clusters.
621
                retvalue = 1;                                                                                                                           // and the next cluster has been found.
622
        }
623
        else if(file->cluster_pointer > (RootDirectory + 31))                                                   // The specified cluster is within the FAT.
624
        {
625
                fat_sector_offset   = ((file->cluster_pointer) - (FirstDataCluster));           // Calculate index of actual cluster within the FAT.
626
                fat_sector_offset  /= SectorsPerCluster;                                                                        // calculate the index of the actual sector within the FAT.                                     
627
                fat_sector_offset  += 2;                                                                                                        // In Fat16 clusterpositions have an offset of two.     
628
                fat_pointer = (fat_sector_offset%0x100);                                                                        // Calculate the sector within the cluster.                                                                                                                             
629
                fat_sector_offset   = (fat_sector_offset>>8);                                                           // and the position within the sector.
630
 
631
                SDC_GetSector((u32)(FileAllocationTable + fat_sector_offset),file->buffer);    
24 StephanB 632
                file->sector_in_buffer = (FileAllocationTable + fat_sector_offset);             // Mark that new sector has been read.
1 ingob 633
 
24 StephanB 634
                ul_tmp  = (u32)file->buffer[((fat_pointer << 1)+1)];                                            // Read next sector information from calculated clusterposition.
1 ingob 635
                ul_tmp  = (ul_tmp << 8);
636
                ul_tmp |= (u32)file->buffer[(fat_pointer << 1)];    
637
                ul_tmp -=2;                                                                                                                                     // next datacluster is clusterposition in fat - 2.
638
                ul_tmp *= SectorsPerCluster;                                                                                            // calculate sectorposition of new cluster
639
                ul_tmp += FirstDataCluster;                                                                                                     // in relation to first datacluster of the disk.
640
 
641
                if(ul_tmp < 0xfff7)                                                                                                                     // has a new cluster been read or was the end of the fat reached?
642
                {
24 StephanB 643
                        file->cluster_pointer = (u32) ul_tmp;                                                                   // continue reading the file at the beginning of new datacluster.
1 ingob 644
                        retvalue = 1;                                                                                                                   // a new cluster was found.
645
                }      
646
        }
647
        return(retvalue);
648
}
649
 
650
//________________________________________________________________________________________________________________________________________
651
// Funtion:     u16 FindNextFreeCluster(void)
652
// 
653
// Description: This function looks in the FAT to find the next free datacluster
654
//                              
655
// Returnvalue: The function returns the adress of the next free cluster found within the fAT.
656
//________________________________________________________________________________________________________________________________________
657
 
658
u16 FindNextFreeCluster(File *file)
659
{
24 StephanB 660
        u32 fat_pointer                 =       0;                                                                                                      // Pointer to the first sector of the FAT.
661
        u32 ul_tmp                              =       0;                                                                                                      // temporary variable used to calculate a sectornumber.
662
        u16  fat_sector_offset  =       0;                                                                                                      // index to a sector within the FAT.
663
        u16  fat_entry                  =       0;                                                                                                      // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
664
        u16  free_cluster                       =       0;                                                                                              // a pointer to the first sector of the next free cluster.
1 ingob 665
 
24 StephanB 666
        fat_pointer = (u32) FileAllocationTable;                                                                                // start searching for empty cluster at the beginning of the fat.
667
                                                                                                                                                                        // if the end of the fat is not reached yet and no free cluster has been found
1 ingob 668
        while((fat_sector_offset < SectorsPerFat) && (!free_cluster))  
669
        {
670
                ul_tmp = (u32) ((u32)fat_pointer + (u32)fat_sector_offset);
24 StephanB 671
                SDC_GetSector((u32)ul_tmp,file->buffer);                                                                        // read next sector of FAT.
672
                file->sector_in_buffer = ul_tmp;                                                                                        // remember the number of the sector in FileBuffer.
1 ingob 673
                Fat = (struct FatEntry *)file->buffer;
24 StephanB 674
                for(fat_entry=0;fat_entry<256;fat_entry++)                                                                      // look for an free cluster at all entries in this sector of the fat. 
1 ingob 675
                {
24 StephanB 676
                        if(Fat[fat_entry].next_cluster == 0x0000)                                                               // empty cluster found!!
1 ingob 677
                        {                              
24 StephanB 678
                                Fat[fat_entry].next_cluster = 0xffff;                                                           // mark this fat-entry as used and save it to the device.
1 ingob 679
                                SDC_PutSector((u32)file->sector_in_buffer,file->buffer);
24 StephanB 680
                                free_cluster  = fat_entry;                                                                                      // the relative position of the free cluster found in this sector of the FAT.
681
                                free_cluster += (fat_sector_offset << 8);                                                       // calculate the absolute position of the free cluster in the FAT;
682
                                fat_entry = 256;                                                                                                        // terminate the search for a free cluster in this sector.
1 ingob 683
                        }
684
                }
685
                fat_sector_offset++;                                                                   
686
        }      
687
return(free_cluster);
688
}
689
 
690
//________________________________________________________________________________________________________________________________________
691
// Funtion:     u16 AppendCluster(File *file);
692
// 
693
// Description: This function finds the next free datacluster on the disk and appends it to the specified file.
694
//                              
695
// Returnvalue: This funktion returns 1 if a cluster was appended to the specified file.
696
//________________________________________________________________________________________________________________________________________
697
 
698
u8 AppendCluster(File *file)
699
{
700
        u16  free_cluster = 0;                                                                                                         
701
        u32 fat_pointer = 0;
702
        u8 retvalue     = 0;
703
 
24 StephanB 704
        free_cluster = FindNextFreeCluster(file);                                                                               // the next free cluster found on the disk.
705
        if(free_cluster) retvalue = 1;                                                                                                  // A free cluster was found and can be added to the end of the file. 
706
        fat_pointer  = FileAllocationTable;                                                                                             // Set Pointer to the beginnig of the FAT.
707
        fat_pointer += (u32)((u32)GetFatClusterOffset(file) >> 8);                                              // find the sector in the FAT with 256 entries per sector.
1 ingob 708
 
709
    SDC_GetSector(fat_pointer,file->buffer);                                            
710
        Fat = (struct FatEntry *)file->buffer;
24 StephanB 711
        Fat[GetFatSectorIndex(file)].next_cluster = free_cluster;                                               // append the free cluster to the end of the file in the FAT.
712
        SDC_PutSector((u32)fat_pointer,file->buffer);                                                                   // save the modified sector to the FAT.
1 ingob 713
 
714
        fat_pointer  = (u32)free_cluster;
715
        fat_pointer -= 2;
716
        fat_pointer *= SectorsPerCluster;
717
        fat_pointer += FirstDataCluster;
718
 
24 StephanB 719
        file->cluster_pointer = fat_pointer;                                                                                    // continue wrtiting to the file in the new and free datacluster.
720
        return(retvalue);                                                                                                                               // return 1 when a new cluster was appended to the file
1 ingob 721
}
722
 
24 StephanB 723
 
1 ingob 724
//________________________________________________________________________________________________________________________________________
24 StephanB 725
// Funtion:     void DeleteClusterChain(u16 startcluster);
726
// 
727
// Description: This function frees all the clusters used for file from the fat.
728
//                              
729
// Returnvalue: none
730
//________________________________________________________________________________________________________________________________________
731
 
732
void DeleteClusterChain(u16 startcluster)
733
{
734
        u16 fat_index                   =       0;
735
        u16 fat_sector_offset   =       0;
736
        u32 sector_in_buffer    =       0;     
737
        u32 ul_temp                             =       0;
738
        u8 buffer[512];
739
 
740
        fat_index = (startcluster % 0x100);                                                                                             // Calculate the sector within the cluster.                                                                                                                             
741
        fat_sector_offset = (startcluster >> 8);                                                                                // and the position within the sector.
742
        ul_temp = (u32)(FileAllocationTable + fat_sector_offset);
743
 
744
 
745
        do
746
        {
747
                if(sector_in_buffer != ul_temp)
748
                {
749
                        sector_in_buffer = ul_temp;
750
                        SDC_GetSector(ul_temp,buffer); 
751
                }
752
                Fat = (struct FatEntry *)buffer;
753
 
754
                startcluster = Fat[fat_index].next_cluster;
755
                Fat[fat_index].next_cluster = 0x0000;                                                                           // free the cluster within the fat.
756
 
757
                fat_index = (startcluster % 0x100);                                                                                     // Calculate the sector within the cluster.                                                                                                                             
758
                fat_sector_offset = (startcluster >> 8);                                                                        // and the position within the sector.
759
                ul_temp = (u32)(FileAllocationTable + fat_sector_offset);
760
                if((sector_in_buffer != ul_temp) || (startcluster == 0xffff))
761
                {
762
                        SDC_PutSector(sector_in_buffer,buffer);
763
                }
764
        }
765
        while(startcluster != 0xffff);                                                                                                  // last cluster has been deleted.
766
}
767
 
768
 
769
//________________________________________________________________________________________________________________________________________
1 ingob 770
// Funtion:     u16 GetFatClusterIndex(File *file);
771
// 
772
// Description: This function returns the clusterindex of the cluster specified by file->cluster_pointer of the specified file.
773
//                              
774
//________________________________________________________________________________________________________________________________________
775
 
776
u16 GetFatClusterOffset(File *file)
777
{
778
        u32 fat_sector_offset   =       0;
779
 
24 StephanB 780
        fat_sector_offset   = ((file->cluster_pointer) - (FirstDataCluster));                   // Calculate index of actual cluster in FAT.
1 ingob 781
        fat_sector_offset  /= SectorsPerCluster;                                                                                                               
24 StephanB 782
        fat_sector_offset  += 2;                                                                                                                // In Fat16 clusterpositions have an offset of two.                                                             
1 ingob 783
 
784
        return((u16)fat_sector_offset);
785
}
786
 
787
//________________________________________________________________________________________________________________________________________
788
// Funtion:     u16 GetFatSectorIndex(File *file);
789
// 
790
// Description: This function returns the sectorindex of the cluster specified by file->cluster_pointer of the specified file.
791
//                              
792
//________________________________________________________________________________________________________________________________________
793
 
794
u16 GetFatSectorIndex(File *file)
795
{
796
        u16 fat_pointer                 =       0;
797
 
798
        fat_pointer = GetFatClusterOffset(file);
24 StephanB 799
        fat_pointer = fat_pointer % 0x100;                                                                                              // Calculate the clusterposition in the fat                                                                                                                             
1 ingob 800
 
801
        return(fat_pointer);
802
}
803
 
804
//________________________________________________________________________________________________________________________________________
24 StephanB 805
// Funtion:     u16 CreateFileInDirectory(u8 *, File *)
1 ingob 806
// 
807
// Description: This function looks for the next free position in the directory and creates an entry. The type of an directoryentry is
808
//                              specified by the attribute. 
809
//                              bit0:   unused
810
//                              bit1:   archive
811
//                              bit2:   read_only
812
//                              bit3:   system  
813
//                              bit4:   directory
814
//                              bit5:   volume
815
//________________________________________________________________________________________________________________________________________
816
 
24 StephanB 817
u8 CreateFileInDirectory(s8 *fname, File *file)
1 ingob 818
{
24 StephanB 819
        u16     rootentry       = 0;                                                                                                            // index to an entry in the rootdirectory.
820
        u16     cnt_enries_searched = 0;                                                                                                // count the number of rootentries which have been searched already.
821
        u8              i = 0;
822
        u16     sector_offset = 0;                                                                                                              // index to the sector of the Rootentry which is searched momentarily
823
        u8              retvalue = 0;
824
        u32             cluster_temp = 0;
825
        u16             cluster = 0;
826
        s8 name[11]     = "           ";                       
827
 
828
        SeperateFileName(fname,name);
829
 
830
        cluster_temp = (u32)FindNextFreeCluster(file);                                                                  // the next free cluster on the disk.
1 ingob 831
 
24 StephanB 832
        if(cluster_temp)                                                                                                                                // if a free cluster is available:
833
        {
834
                cluster = (u16)cluster_temp;                                                                                            // remember the index of the free datacluster found for the directory entry.
835
                cluster_temp -=2;                                                                                                                       // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
836
                cluster_temp *= SectorsPerCluster;                                                                                      // Calculate relative sectorindex of first datacluster.
837
                file->start_cluster   = (FirstDataCluster + cluster_temp);                                      // Calculate absolute sectorposition of first datacluster.
838
                file->cluster_pointer = file->start_cluster;                                                            // start reading the file with the first sector of the first datacluster.
839
 
840
                                                                                                                                                                        // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
841
                do
842
                {                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
843
                        rootentry=0;                                                                   
844
                        SDC_GetSector((u32)(CWD + sector_offset),file->buffer);                         // Read the Rootdirectory.
845
                        DirectoryEntry = (struct DirEntry *)file->buffer;
846
                        while((rootentry<16) && (!retvalue))
1 ingob 847
                        {
24 StephanB 848
                                if((DirectoryEntry[rootentry].attribute == 0) || (DirectoryEntry[rootentry].attribute == 0xE5)) // empty directory entry found
849
                                {
850
                                        for(i=0;i<11;i++) DirectoryEntry[rootentry].name[i] = name[i];// Kopie the filename and the file extension to the directoryentry.
851
                                        DirectoryEntry[rootentry].attribute    = _FILE;                                 // Set the fileattribute to archive to reserve the directoryentry.
852
                                        DirectoryEntry[rootentry].startcluster = cluster;                               // copy the location of the first datacluster to the directoryentry.
853
                                        DirectoryEntry[rootentry].size     = 0;                                                 // the new createted file has no content yet.
854
                                        file->directory_sector = (u32) (CWD + sector_offset);
855
                                        file->directory_index  = (u8) rootentry;
856
                                        retvalue = 1;
857
                                        SDC_PutSector((u32)(CWD + sector_offset),file->buffer);                        
858
                                }                      
859
                                rootentry++;
860
                                cnt_enries_searched++;
861
                        }
862
                        if(!retvalue)                                                                                                                   // file not found in this sector so take next sector.
863
                        {
864
                                rootentry = 0;
865
                                sector_offset++;
866
                        }
1 ingob 867
                }
24 StephanB 868
                while((cnt_enries_searched< PossibleRootEntries) && (!retvalue));
869
 
1 ingob 870
        }
24 StephanB 871
        return(retvalue);                                                                                                                               // return 1 if file has been created otherwise return 0.
1 ingob 872
}
873
 
874
//________________________________________________________________________________________________________________________________________
24 StephanB 875
// Funtion:     u16 SeekFileInDirectory(s8 *fname, File *)
1 ingob 876
// 
24 StephanB 877
// Description: this function searches all possible entries withint the actual directory for the specified object.
1 ingob 878
//                              
879
// Returnvalue: This function returns 1 if the directoryentry specified was found.
880
//________________________________________________________________________________________________________________________________________
881
 
24 StephanB 882
u8 SeekFileInDirectory(s8 *fname, File *file)
1 ingob 883
{
884
        u16     rootentry=0;
24 StephanB 885
        u16     end_of_directory_not_reached = 0;                                                                               // the directory has been read completely without a result.
886
        u8              i=0;
1 ingob 887
        u8      retvalue = 0;
888
        u32     cluster_temp = 0;
24 StephanB 889
        s8 name[11]     = "           ";                       
890
 
891
        SeperateFileName(fname,name);
892
 
893
        file->cluster_pointer = CWD;                                                                                                    // start looking for the file in the actual directory.
1 ingob 894
 
24 StephanB 895
                                                                                                                                                                        // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
1 ingob 896
        do
24 StephanB 897
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.
1 ingob 898
                rootentry=0;                                                                   
24 StephanB 899
                SDC_GetSector((u32) file->cluster_pointer,file->buffer);                                        // Read the Rootdirectory.
1 ingob 900
                DirectoryEntry = (struct DirEntry *)file->buffer;
901
 
902
                while((!retvalue)&&(rootentry<16))
903
                {
904
                        i=0;
24 StephanB 905
                        if(DirectoryEntry[rootentry].name[0] != 0xe5)                                                   // ignore deleted items.
1 ingob 906
                        {
24 StephanB 907
                                while((i<=10)&&(DirectoryEntry[rootentry].name[i] == name[i]))
908
                                {
909
                                        i++;
910
                                }
1 ingob 911
                        }
24 StephanB 912
 
913
                        if((i==11) && (DirectoryEntry[rootentry].attribute & _FILE))                    // entry found!! -> reading startcluster of entry from offset 26.
1 ingob 914
                        {
915
                                cluster_temp = (u32)DirectoryEntry[rootentry].startcluster;                                                    
24 StephanB 916
                                cluster_temp -=2;                                                                                                       // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
917
                                cluster_temp *= (u32)SectorsPerCluster;                                                         // Calculate positon of first cluster.
1 ingob 918
                                file->start_cluster   = (FirstDataCluster + cluster_temp);
919
                                file->directory_sector = (u32) file->cluster_pointer;
24 StephanB 920
                                file->cluster_pointer = file->start_cluster;                                            // start reading the file with the first cluster.
1 ingob 921
                                file->filesize = (u32) DirectoryEntry[rootentry].size;
922
                                file->directory_index  = (u8) rootentry;
923
                                retvalue = 1;
924
                        }
925
                        rootentry++;
926
                }
24 StephanB 927
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
1 ingob 928
                {
929
                        end_of_directory_not_reached = GetNextCluster(file);
930
                }
931
        }
932
        while((end_of_directory_not_reached) && (!retvalue));
933
        return(retvalue);
934
}
935
 
24 StephanB 936
 
937
 
1 ingob 938
//________________________________________________________________________________________________________________________________________
24 StephanB 939
// Funtion:     void SeperateFileName(u8*);
1 ingob 940
// 
24 StephanB 941
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST    TXT');
1 ingob 942
//                              
943
//________________________________________________________________________________________________________________________________________
944
 
24 StephanB 945
void SeperateFileName(s8 *fname, s8 *name)
1 ingob 946
{
24 StephanB 947
        u8 readpointer  = 0;
948
        u8 writepointer = 0;
949
        u8 attribute    = 1;
950
        u8 i = 0;
1 ingob 951
 
24 StephanB 952
 
953
        while((writepointer<=10) && (fname[readpointer]!=0))                                                    // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute.
954
        {                                                                                                                                                               // the filename in the rootdirectory is in the format "TEST    TXT" without the dot.
955
                if(fname[readpointer]=='.')                                                                                             // seperating filename and attribute.
956
                {
957
                        if(attribute)                                                                                                                   // is the filename "." or ".." ?
958
                        {
959
                                name[writepointer] = fname[readpointer];
960
                                readpointer++;
961
                                writepointer++;                
962
                        }
963
                        else
964
                        {
965
                                if(fname[(readpointer-1)] != '*')
966
                                {
967
                                        for(i=writepointer;i<8;i++)
968
                                        {
969
                                                name[i] = ' ';
970
                                        }
971
                                }
972
                                readpointer++;
973
                                writepointer = 8;
974
                        }
975
                }
976
                else if(fname[readpointer] == '*')                                                                                      // wildcard found within the filename + extension.
977
                {
978
                        if(writepointer < 8)                                                                                                    // in extension.
979
                        {
980
                                readpointer++;
981
                                writepointer = 8;                                      
982
                        }
983
                        else                                                                                                                                    // in filename.
984
                        {
985
                                writepointer = 11;                                                                                                      // jump to the end of the string to terminate this function.
986
                        }
987
                        attribute = 0;
988
                }
989
                else
990
                {
991
                        if((fname[readpointer]>96) && (fname[readpointer]<123))
992
                        {
993
                                name[writepointer]=(fname[readpointer] - 32);                                           // all characters must be upper case.
994
                        }
995
                        else
996
                        {
997
                                name[writepointer]=fname[readpointer];
998
                        }      
999
                        readpointer++;
1000
                        writepointer++;
1001
                        attribute = 0;
1002
                }
1003
        }      
1004
}
1 ingob 1005
 
24 StephanB 1006
//________________________________________________________________________________________________________________________________________
1007
// Funtion:     File * ReserveFilePointer_(void);
1008
// 
1009
// Description: This function looks for a free filepointer and reserves it.
1010
//                              
1011
//
1012
//      Return:         NULL = faild to reserve a filepointer
1013
//                              otherwise filepointer
1014
//________________________________________________________________________________________________________________________________________
1015
 
1016
File * ReserveFilePointer(void)
1017
{
1018
        File *file;
1019
        file = NULL;
1020
        u8      temp;
1021
 
1022
        for(temp = 0;temp<__MAX_FILES_USED;temp++)
1 ingob 1023
        {
24 StephanB 1024
                if(FilePointer[temp].state == _UNUSED)                                                                          // free filepointer found?
1 ingob 1025
                {
24 StephanB 1026
                        file = &FilePointer[temp];
1027
                        FilePointer[temp].state                                 = _USED;                                                // mark as used.
1028
                        FilePointer[temp].mode                                  = 0;                                                    // type of access (read/write) not defined yet.
1029
                        FilePointer[temp].start_cluster                 = 0;                                                    // Sectorpointer to the first sector of the first datacluster of the file. 
1030
                        FilePointer[temp].cluster_pointer               = 0;                                                    // Pointer to the cluster which is edited at the moment.
1031
                        FilePointer[temp].sector_index                  = 0;                                                    // The sector which is edited at the moment (cluster_pointer + sector_index).
1032
                        FilePointer[temp].byte_index                    = 0;                                                    // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
1033
                        FilePointer[temp].filesize                              = 0;                                                    // the size of the opend file in bytes.
1034
                        FilePointer[temp].fileposition                  = 0;                                                    // pointer to a character within the file 0 < fileposition < filesize
1035
                        FilePointer[temp].sector_in_buffer              = 0;                                                    // the last sector read, wich is still in the sectorbuffer.
1036
                        FilePointer[temp].directory_sector              = 0;                                                    // the sectorposition where the directoryentry has been made.
1037
                        FilePointer[temp].directory_index               = 0;                                                    // the index to the directoryentry within the specified sector.
1038
                        FilePointer[temp].attribute                     = 0;                                                    // the attribute of the file opened.
1039
                        break;
1 ingob 1040
                }
1041
        }
24 StephanB 1042
        return(file);
1043
}
1044
 
1045
 
1046
//________________________________________________________________________________________________________________________________________
1047
// Funtion:     void FreeFilePointer_(File *);
1048
// 
1049
// Description: This function free's the filepointer by marking it as unused.
1050
//                              
1051
//
1052
//      Return:         none
1053
//                              
1054
//________________________________________________________________________________________________________________________________________
1055
 
1056
void FreeFilePointer(File *file)
1057
{
1058
        u8 cnt = 0;
1 ingob 1059
 
24 StephanB 1060
        for(cnt=0;cnt<__MAX_FILES_USED;cnt++)                                                                                   // Is the filepointeradress vaild?
1061
        {
1062
                if(&FilePointer[cnt] == file)                                                                                           // filepointer found therefore it must be valid
1063
                {
1064
                        FilePointer[cnt].state = _UNUSED;                                                                               // and can be marked as unused.
1065
                }
1066
        }
1067
}
1 ingob 1068
 
24 StephanB 1069
 
1070
//________________________________________________________________________________________________________________________________________
1071
// Funtion:     void DelteDirectoryEntry(Find *)
1072
// 
1073
// Description: This function deletes the directoryentry of the specified item.
1074
//                              
1075
//                              
1076
// returnvalue: 1 if the directory could be created.
1077
//________________________________________________________________________________________________________________________________________
1078
 
1079
void DeleteDirectoryEntry(Find *item)
1080
{
1081
        u8 buffer[512];
1 ingob 1082
 
24 StephanB 1083
 
1084
        SDC_GetSector((u32) item->cluster_pointer,buffer);                                                              // Read the Rootdirectory.
1085
        DirectoryEntry = (struct DirEntry *)buffer;
1086
 
1087
        DirectoryEntry[(item->directory_index)-1].attribute = 0;                                                // free the directoryentry.
1088
        DirectoryEntry[(item->directory_index)-1].name[0] = 0xE5;                                               // free the directoryentry.
1089
        SDC_PutSector((u32) item->cluster_pointer,buffer);                                                              // Read the Rootdirectory.
1090
}
1091
 
1092
 
1093
 
1094
 
1095
//________________________________________________________________________________________________________________________________________
1096
// Funtion:     u8 CreateSubDirectory(u8 *)
1097
// 
1098
// Description: This function creates an directory within the directory specified by CWD
1099
//                              
1100
//                              
1101
// returnvalue: 1 if the directory could be created.
1102
//________________________________________________________________________________________________________________________________________
1103
 
1104
u8 CreateSubDirectory(s8 *fname)
1105
{
1106
        u16     index   = 0;                                                                                                                    // index to an entry in the rootdirectory.
1107
        u16     cnt_entries_searched = 0;                                                                                               // count the number of rootentries which have been searched already.
1108
        u16             i = 0;
1109
        u16     sector_offset = 0;                                                                                                              // index to the sector of the entry which is searched momentarily
1110
        u8              retvalue = 0;
1111
        u32             cluster_temp = 0;
1112
        u16             cluster = 0;
1113
        File    file;
1114
        s8              name[11] = {"           "};
1115
 
1116
        SeperateFileName(fname,name);
1117
        cluster_temp = (u32)FindNextFreeCluster(&file);                                                         // the next free cluster on the disk.
1118
 
1119
        if(cluster_temp)                                                                                                                                // if a free cluster is available:
1 ingob 1120
        {
24 StephanB 1121
                cluster = (u16)cluster_temp;                                                                                            // remember the index of the free datacluster found for the directory entry.
1122
                cluster_temp -=2;                                                                                                                       // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
1123
                cluster_temp *= SectorsPerCluster;                                                                                      // Calculate relative sectorindex of first datacluster.
1124
                file.start_cluster   = (FirstDataCluster + cluster_temp);                                       // Calculate absolute sectorposition of first datacluster.
1125
                file.cluster_pointer = file.start_cluster;                                                                      // start reading the file with the first sector of the first datacluster.
1126
 
1127
// -Initialise new cluster to zero--------------------------------------------------------
1128
                for(i=0;i<512;i++)
1 ingob 1129
                {
24 StephanB 1130
                        file.buffer[i] = 0;                                                                                                             // initialise buffer to zero
1131
                }
1132
                for(sector_offset=0;sector_offset<SectorsPerCluster;sector_offset++)            // initialise all sectors of new cluster with buffer.
1133
                {
1134
                        SDC_PutSector((u32)(file.start_cluster + sector_offset),file.buffer);   // save the initialised sector to the card.     
1135
                }
1136
// -Create directoryentry "." -------------------------------------------------------------
1137
                DirectoryEntry = (struct DirEntry *)file.buffer;
1138
                DirectoryEntry[0].name[0] = '.';                                                                       
1139
                DirectoryEntry[0].attribute = _DIRECTORY;                                                      
1140
                DirectoryEntry[0].startcluster = cluster;                                                                      
1141
// -Create directoryentry "." -------------------------------------------------------------
1142
                DirectoryEntry[1].name[0] = '.';                                                                       
1143
                DirectoryEntry[1].name[1] = '.';                                                                       
1144
                DirectoryEntry[1].attribute = _DIRECTORY;                                                      
1145
                if(CWD == RootDirectory)
1146
                {
1147
                        DirectoryEntry[1].startcluster = 0;                                                                                    
1148
                }
1149
                else
1150
                {
1151
                        cluster_temp = (CWD - FirstDataCluster);
1152
                        cluster_temp /= SectorsPerCluster;
1153
                        cluster_temp -= 2;
1154
                        DirectoryEntry[1].startcluster = (u16) cluster_temp;                                                                                                   
1155
                }
1156
                SDC_PutSector((u32) file.start_cluster,file.buffer);                                            // save the initialised sector to the card.     
1157
// -create directoryentry within the cwd --------------------------------------------------
1158
                sector_offset = 0;
1159
                cnt_entries_searched = 0;
1160
                do
1161
                {                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
1162
                        index=0;                                                                       
1163
                        SDC_GetSector((u32)(CWD + sector_offset),file.buffer);                                  // Read the actual directory.
1164
                        DirectoryEntry = (struct DirEntry *)file.buffer;
1165
                        while((index<16) && (!retvalue))
1166
                        {
1167
                                if((DirectoryEntry[index].attribute == 0) || (DirectoryEntry[index].attribute == 0xE5)) // empty directory entry found
1168
                                {
1169
                                        for(i=0;i<11;i++) DirectoryEntry[index].name[i] = name[i];      // Kopie the filename and the file extension to the directoryentry.
1170
                                        DirectoryEntry[index].attribute    = _DIRECTORY;                                // Set the fileattribute to archive to reserve the directoryentry.
1171
                                        DirectoryEntry[index].startcluster = cluster;                                   // copy the location of the first datacluster to the directoryentry.
1172
                                        DirectoryEntry[index].size     = 0;                                                             // the new createted file has no content yet.
1173
                                        file.directory_sector = (u32) (CWD + sector_offset);
1174
                                        file.directory_index  = (u8) index;
1175
                                        retvalue = 1;
1176
                                        SDC_PutSector((u32)(CWD + sector_offset),file.buffer);                         
1177
                                }                      
1178
                                index++;
1179
                                cnt_entries_searched++;
1 ingob 1180
                        }
24 StephanB 1181
                        if(!retvalue)                                                                                                                   // file not found in this sector so take next sector.
1 ingob 1182
                        {
24 StephanB 1183
                                index = 0;
1184
                                sector_offset++;
1185
                        }
1186
                }
1187
                while((cnt_entries_searched< PossibleRootEntries) && (!retvalue));
1188
 
1189
        }
1190
        return(retvalue);                                                                                                                               // return 1 if file has been created otherwise return 0.
1191
}
1192
 
1193
 
1194
//________________________________________________________________________________________________________________________________________
1195
// Funtion:     u16 SeekSubDirectory(s8 *fname)
1196
// 
1197
// Description: looks for the specified directory within the CWD.
1198
//                              
1199
// Returnvalue: If the specified directory was found the startcluster is returned. otherwise 0.
1200
//________________________________________________________________________________________________________________________________________
1201
 
1202
u16 SeekSubDirectory(s8 *fname)
1203
{
1204
        u16     index = 0;
1205
        u16     end_of_directory_not_reached = 0;                                                                               // the directory has been read completely without a result.
1206
        u8              i = 0;
1207
        u16     cluster_temp = 0;
1208
        s8 name[11]     = "           ";                       
1209
        File    file;
1210
 
1211
        SeperateFileName(fname,name);
1212
 
1213
        file.cluster_pointer = CWD;                                                                                                             // start looking for the file in the actual directory.
1214
        file.start_cluster   = CWD;                                                                                                             // start looking for the file in the actual directory.
1215
 
1216
                                                                                                                                                                        // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
1217
        do
1218
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.          
1219
                index=0;                                                                       
1220
                SDC_GetSector((u32) file.cluster_pointer,file.buffer);                                          // Read the Rootdirectory.
1221
                DirectoryEntry = (struct DirEntry *)file.buffer;
1222
 
1223
                while((!cluster_temp)&&(index<16))
1224
                {
1225
                        i=0;
1226
                        if(DirectoryEntry[index].name[0] != 0xe5)                                                               // ignore deleted items.
1 ingob 1227
                        {
24 StephanB 1228
                                while((i<=10)&&(DirectoryEntry[index].name[i] == name[i]))
1229
                                {
1230
                                        i++;
1231
                                }
1 ingob 1232
                        }
24 StephanB 1233
 
1234
                        if((i==11) && (DirectoryEntry[index].attribute & _DIRECTORY))                   // entry found!! -> reading startcluster of entry from offset 26.
1235
                        {
1236
                                cluster_temp = (u16)DirectoryEntry[index].startcluster;                                                        
1237
                        }
1238
                        index++;
1 ingob 1239
                }
24 StephanB 1240
                if(!cluster_temp)                                                                                                                       // file not found in this sector so take next sector.
1241
                {
1242
                        end_of_directory_not_reached = GetNextCluster(&file);
1243
                }
1 ingob 1244
        }
24 StephanB 1245
        while((end_of_directory_not_reached) && (!cluster_temp));
1246
        return(cluster_temp);
1247
}
1248
 
1249
 
1250
 
1251
//________________________________________________________________________________________________________________________________________
1252
// Funtion:     u8 mkdir_(u8 *)
1253
// 
1254
// Description: This function checks if the directory to be created already exists. If not the directory will be created.
1255
//                              
1256
//                              
1257
// returnvalue: 1 if the directory could be created.
1258
//________________________________________________________________________________________________________________________________________
1259
 
1260
u8      mkdir_(s8 *fname)
1261
{
1262
        u8 retvalue = 0;
1263
 
1264
        retvalue = SeekSubDirectory(fname);                                                                                             // check wether the specified directory already exists.
1265
 
1266
        if(!retvalue)
1267
        {
1268
                CreateSubDirectory(fname);                                                                                                      // if directory doesn't exist, create it.
1269
                retvalue = 1;
1270
        }
1271
        else
1272
        {
1273
                retvalue = 0;
1274
        }
1275
 
1 ingob 1276
        return(retvalue);
1277
}
1278
 
24 StephanB 1279
 
1 ingob 1280
//________________________________________________________________________________________________________________________________________
24 StephanB 1281
// Funtion:     u8 chdir_(u8 *)
1 ingob 1282
// 
24 StephanB 1283
// Description: This function changes the CWD to the directory specified.
1 ingob 1284
//                              
24 StephanB 1285
//                              
1286
// returnvalue: 1 if the directory could be changed.
1 ingob 1287
//________________________________________________________________________________________________________________________________________
1288
 
24 StephanB 1289
u8      chdir_(s8 *fname)
1 ingob 1290
{
24 StephanB 1291
        u8      retvalue = 0;
1292
        s8  name[11] = {"           "};
1 ingob 1293
 
24 StephanB 1294
        u32 ultemp = 0;
1295
 
1296
        SeperateFileName(fname,name);  
1297
 
1298
        ultemp = (u32)SeekSubDirectory(name);
1299
        if(ultemp >= 2)
1 ingob 1300
        {
24 StephanB 1301
                ultemp -=2;                                                                                                                                     // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
1302
                ultemp *= SectorsPerCluster;                                                                                            // Calculate relative sectorindex of first datacluster.
1303
                ultemp += FirstDataCluster;
1304
                CWD = ultemp;
1305
                retvalue = 1;
1306
        }
1307
        else
1308
        {
1309
                CWD = RootDirectory;
1310
                retvalue = 1;
1311
        }
1312
 
1313
        return(retvalue);
1314
}
1315
 
1316
 
1317
//________________________________________________________________________________________________________________________________________
1318
// Funtion:     u8 FindItem(s8 *fname, Find *)
1319
// 
1320
// Description: finds an item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
1321
//                              
1322
// Returnvalue: If an item was found this function returns '1' else '0'.
1323
//________________________________________________________________________________________________________________________________________
1324
 
1325
u8 FindItem(Find *item)
1326
{
1327
        u16     index = 0;
1328
        u16     end_of_directory_not_reached = 0;                                                                               // the directory has been read completely without a result.
1329
        u8              i = 0;
1330
        u8              readpointer = 0;
1331
        u8              writepointer = 0;
1332
        u8              retvalue = 0;
1333
        File    file;
1334
 
1335
 
1336
        file.cluster_pointer = item->cluster_pointer;
1337
        file.start_cluster   = item->cluster_pointer;                                  
1338
        index                            = item->directory_index;
1339
                                                                                                                                                                        // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
1340
        do
1341
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.          
1342
                SDC_GetSector((u32) file.cluster_pointer,file.buffer);                                          // Read the Rootdirectory.
1343
                DirectoryEntry = (struct DirEntry *)file.buffer;
1344
 
1345
                while((!retvalue)&&(index<16))
1 ingob 1346
                {
24 StephanB 1347
                        i=0;                   
1348
                        if(DirectoryEntry[index].name[0] != 0xe5)                                                               // ignore deleted items.
1349
                        {
1350
                                while((i<=10)&&((DirectoryEntry[index].name[i] == item->searchstring[i]) || (item->searchstring[i]=='*') || item->searchstring[i]=='?'))
1351
                                {
1352
                                        i++;
1353
                                }
1354
                        }
1355
 
1356
                        if((i==11) && (DirectoryEntry[index].attribute & item->attribute))
1357
                        {
1358
                                for(readpointer=0;readpointer<=10;readpointer++)
1359
                                {
1360
                                        if(DirectoryEntry[index].name[readpointer] != ' ')
1361
                                        {
1362
                                                item->name[writepointer] = DirectoryEntry[index].name[readpointer];     // copy the name of the item found to the find_structure.
1363
                                                writepointer++;
1364
                                        }
1365
                                        else if((readpointer==7) && (DirectoryEntry[index].attribute == _FILE)) // if the item found is a file
1366
                                        {
1367
                                                if(DirectoryEntry[index].name[readpointer] != ' ')
1368
                                                {
1369
                                                        item->name[writepointer] = DirectoryEntry[index].name[readpointer];     // copy the name of the item found to the find_structure.
1370
                                                        writepointer++;
1371
                                                }
1372
                                                item->name[writepointer] = '.';                                                 // then seperate the name and the extension by a '.' at index 8.                                                
1373
                                                writepointer++;
1374
                                        }
1375
                                }
1376
                                item->startcluster = (u16)DirectoryEntry[index].startcluster;                                                  
1377
                                item->directory_index = ++index;
1378
                                item->cluster_pointer = file.cluster_pointer;
1379
                                retvalue = 1;
1380
                        }
1381
                        index++;
1 ingob 1382
                }
24 StephanB 1383
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
1384
                {
1385
                        end_of_directory_not_reached = GetNextCluster(&file);
1386
                }
1387
                index = 0;
1 ingob 1388
        }
24 StephanB 1389
        while((end_of_directory_not_reached) && (!retvalue));
1390
 
1391
        return(retvalue);      
1392
}
1 ingob 1393
 
24 StephanB 1394
 
1395
//________________________________________________________________________________________________________________________________________
1396
// Funtion:     u8 findfirst(s8 *fname, Find *)
1397
// 
1398
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
1399
//                              
1400
// Returnvalue: If an item was found this function returns '1' else '0'.
1401
//________________________________________________________________________________________________________________________________________
1402
 
1403
u8 findfirst_(s8 *fname, Find *item, u8 attribute)
1404
{
1405
        u8 retvalue = 0;
1406
        u8 i = 0;
1407
 
1408
        for(i=0;i<=11;i++)
1409
        {
1410
                item->searchstring[i] = '*';                                                                                            // initialise the searchstring with wildcards.
1411
                item->name[i] = 0;
1412
        }
1413
 
1414
        SeperateFileName(fname,item->searchstring);
1415
 
1416
        item->cluster_pointer = CWD;                                                                                                    // findfirst_ starts at the beginning of the cwd.
1417
        item->directory_index = 0;
1418
        item->attribute = attribute;
1419
 
1420
        retvalue = FindItem(item);
1421
 
1422
        return(retvalue);      
1423
}
1424
 
1425
 
1426
//________________________________________________________________________________________________________________________________________
1427
// Funtion:     u8 findnext(Find *)
1428
// 
1429
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
1430
//                              
1431
// Returnvalue: If an item was found this function returns '1' else '0'.
1432
//________________________________________________________________________________________________________________________________________
1433
 
1434
u8 findnext_(Find *item)
1435
{
1436
        u8 retvalue = 0;
1437
        u8 i = 0;
1438
 
1439
        for(i=0;i<=11;i++)                                                                                                                              // copy the name of the searched item to the findstructure.
1440
        {
1441
                item->name[i] = 0;
1442
        }
1443
 
1444
        retvalue = FindItem(item);                                                                                                              // search the item.
1445
 
1446
        return(retvalue);      
1447
}
1448
 
1449
 
1450
 
1451
//________________________________________________________________________________________________________________________________________
1452
// Funtion:     u8 fdelete(s8 *fname)
1453
// 
1454
// Description: Deletes the file specified by fname.
1455
//                              
1456
// Returnvalue: 
1457
//________________________________________________________________________________________________________________________________________
1458
 
1459
u8 fdelete_(s8 *fname)
1460
{
1461
        u8 retvalue = 0;
1462
        Find item;
1463
 
1464
        retvalue = findfirst_(fname,&item, _FILE);                                                                              // look for the item to be deleted.
1465
 
1466
        if(retvalue);                                                                                                                                   // item found?
1467
        {
1468
                DeleteClusterChain(item.startcluster);                                                                          // delete all fatentries of the item. 
1469
                DeleteDirectoryEntry(&item);                                                                                            // free the directoryentry.
1470
 
1471
                do
1 ingob 1472
                {
24 StephanB 1473
                        retvalue = findnext_(&item);
1474
                        if(retvalue)
1475
                        {
1476
                                DeleteClusterChain(item.startcluster);                                                          // delete all fatentries of the item. 
1477
                                DeleteDirectoryEntry(&item);                                                                            // free the directoryentry.                             
1478
                        }
1 ingob 1479
                }
24 StephanB 1480
                while(retvalue);       
1481
        }
1482
 
1483
        return(retvalue);      
1484
}
1485
 
1486
 
1487
//________________________________________________________________________________________________________________________________________
1488
// Funtion:     u8 rmdir(s8 *fname)
1489
// 
1490
// Description: Deletes the directory specified by dname.
1491
//                              
1492
// Returnvalue: 
1493
//________________________________________________________________________________________________________________________________________
1494
 
1495
u8 rmdir_(s8 *dname)
1496
{
1497
        u8 retvalue = 0;
1498
        Find item;
1499
 
1500
        retvalue = findfirst_(dname,&item, _DIRECTORY);                                                                 // look for the item to be deleted.
1501
 
1502
        if(retvalue);                                                                                                                                           // item found?
1503
        {
1504
                DeleteClusterChain(item.startcluster);                                                                                  // delete all fatentries of the item. 
1505
                DeleteDirectoryEntry(&item);                                                                                                    // free the directoryentry.
1506
 
1507
                do
1 ingob 1508
                {
24 StephanB 1509
                        retvalue = findnext_(&item);
1510
                        if(retvalue)
1 ingob 1511
                        {
24 StephanB 1512
                                DeleteClusterChain(item.startcluster);                                                                  // delete all fatentries of the item. 
1513
                                DeleteDirectoryEntry(&item);                                                                                    // free the directoryentry.                             
1 ingob 1514
                        }
1515
                }
24 StephanB 1516
                while(retvalue);       
1517
        }
1518
 
1519
        return(retvalue);      
1 ingob 1520
}
24 StephanB 1521
 
1522
 
1523
//________________________________________________________________________________________________________________________________________
1524
// Funtion:     u16 feof_(File *file)
1525
// 
1526
// Description: This function checks wether the end of the file has been reached.
1527
//                              
1528
// Returnvalue: 0 if the end of the file was not reached otherwise 1. 
1529
//________________________________________________________________________________________________________________________________________
1530
 
1531
u16 feof_(File *file)
1532
{      
1533
        if(((file->fileposition)+1) < (file->filesize))
1534
        {
1535
                return(0);
1536
        }
1537
        else
1538
        {
1539
                return(1);     
1540
        }
1541
}