summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorAlan Korr <alkorr@rockbox.org>2002-04-19 12:16:19 +0000
committerAlan Korr <alkorr@rockbox.org>2002-04-19 12:16:19 +0000
commit6dd637f44c0523958012f3c28068c631a73b0569 (patch)
tree73f926f81d05617869da14a40f9613909e7f2dee /firmware
parentb41596560eed4f805d19931eec3d37b3bad06e61 (diff)
downloadrockbox-6dd637f44c0523958012f3c28068c631a73b0569.tar.gz
rockbox-6dd637f44c0523958012f3c28068c631a73b0569.zip
adding files... nothin working... a lot of thing missing
not speaking about possible drastic changes... git-svn-id: svn://svn.rockbox.org/rockbox/trunk@144 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/test/fat/fat-bpb_sector.h211
-rw-r--r--firmware/test/fat/fat-fsi_sector.c105
-rw-r--r--firmware/test/fat/fat-fsi_sector.h80
-rw-r--r--firmware/test/fat/fat-mbr_sector.c65
-rw-r--r--firmware/test/fat/fat-mbr_sector.h69
-rw-r--r--firmware/test/fat/fat-partition.h161
-rw-r--r--firmware/test/fat/fat-volume.c355
-rw-r--r--firmware/test/fat/inlines.h1
-rw-r--r--firmware/test/fat/makefile19
-rw-r--r--firmware/test/fat/return_values.h7
-rw-r--r--firmware/test/fat/types.h19
11 files changed, 1083 insertions, 9 deletions
diff --git a/firmware/test/fat/fat-bpb_sector.h b/firmware/test/fat/fat-bpb_sector.h
new file mode 100644
index 0000000000..247f53115c
--- /dev/null
+++ b/firmware/test/fat/fat-bpb_sector.h
@@ -0,0 +1,211 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef __LIBRARY_FAT_BPB_SECTOR_H__
20#define __LIBRARY_FAT_BPB_SECTOR_H__
21
22// [Alan]:
23// I would like to draw your attention about the fact that SH1
24// cannot use misaligned address access so you must be very cautious
25// with structures stored in FAT32 partition because they come from
26// PC world where misaligned address accesses are usual and not
27// problematic. To avoid such a trouble, I decide to use special
28// structures where fields are moved in such a way they can be
29// accessed by SH1. It is possible thanks to the callback mechanism
30// I use for reading or writing from/to an ATA device in ata.h/c.
31// So don't be puzzled if those structures seem odd compared
32// with the usual ones from PC world. I use this mechanism for structures
33// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
34// not for structure 'bpb_sector' which is too much complex to handle
35// that way, I think.
36// By the way, SH1 is big endian, not little endian as PC is.
37
38///////////////////////////////////////////////////////////////////////////////////
39// BPB SECTOR :
40///////////////
41//
42//
43
44struct __fat_bpb_sector /* Bios Parameters Block Sector */
45 {
46 // jmp_boot has two valid ways to look like in a FAT BPB.
47 // Either EBXX90 or E9XXXX.
48 // Not used by Rockbox.
49 unsigned char
50 jmp_boot[3];
51
52 // Creator system of the fat-drive.
53 // Usually looks like "MSWIN4.x".
54 char
55 oem_name[8];
56
57 // It should be 512 if you don't want any trouble
58 // with Rockbox firmware.
59 unsigned char
60 bytes_per_sector[2];
61
62 // Must be a power of two.
63 unsigned char
64 sectors_per_cluster[1];
65
66 // Number of reserved sectors in the reserved region of the volume
67 // starting at the first sector of the volume.
68 // Usually 32 for FAT32.
69 unsigned char
70 reserved_sectors[2];
71
72 // Number of FAT structures.
73 // This value should always be 2.
74 unsigned char
75 number_of_fats[1];
76
77 // For FAT32, this field must be set to zero.
78 // Not used by Rockbox.
79 unsigned char
80 number_of_root_entries[2];
81
82 // Must be zero for FAT32, since the real value
83 // can be found in total_sectors.
84 // Not used by Rockbox.
85 unsigned char
86 total_sectors_16[2];
87
88 // Not used by Rockbox.
89 unsigned char
90 media[1];
91
92 // In FAT32 this must be zero.
93 // Not used by Rockbox.
94 unsigned char
95 sectors_per_fat_16[2];
96
97 // Sectors per track used on this media.
98 // Not used by Rockbox.
99 unsigned char
100 sectors_per_track[2];
101
102 // Number of heads used on this media.
103 // Not used by Rockbox.
104 unsigned char
105 number_of_heads[2];
106
107 // Number of hidden sectors.
108 // Not used by Rockbox.
109 unsigned char
110 hidden_sectors[4];
111
112 // Number of total sectors.
113 // For FAT32 volumes, this must be specified.
114 unsigned char
115 total_sectors[4];
116
117 // Here follows FAT12/16 or FAT32 specific data. */
118
119 // This is the number of sectors for one FAT.
120 unsigned char
121 sectors_per_fat[4];
122
123 // Extended FAT32 flags follow.
124 unsigned char
125 flags[2];
126 // bits 15-8: reserved
127 // mirroring, bit 7:
128 // 0 -> FAT is mirrored at runtime into all FATs.
129 // 1 -> only the one specified in the following field
130 // is active.
131 // Rockbox always sets it.
132 // bits 7-4 : reserved
133 // active_fat, bits 3-0:
134 // this specifies the "active" FAT mentioned previously.
135
136 // This specifies the file system version.
137 // High byte is major number, low byte is minor.
138 // The current version is 0.0.
139 unsigned char
140 filesystem_version[2];
141
142 // This is set to the cluster number of the first cluster
143 // of the root directory. Usually 2, but not required.
144 unsigned char
145 root_cluster[4];
146
147 // This specifies the sector number of the 'FSINFO' structure
148 // in the reserved area.
149 unsigned char
150 filesystem_info[2];
151
152 // If zero, this specifies where the backup of bpb
153 // can be found.
154 // Usually 6.
155 // No value other than 6 is recommended by Microsoft.
156 unsigned char
157 backup_bpb[2];
158
159 // The following area should always be set to zero
160 // when the volume is initialised.
161 unsigned char
162 zeros[12];
163
164 // Drive number for BIOS.
165 // Not used by Rockbox.
166 unsigned char
167 drive_number[0];
168
169 // Reserved for Windows NT.
170 // Should always be set to 0.
171 unsigned char
172 reserved_for_nt[0];
173
174 // Extended boot signature.
175 // If this is 0x29, the following three fields are present.
176 unsigned char
177 boot_signature[0];
178
179 // Volume serial number.
180 unsigned char
181 volume_id[4];
182
183 // Volume label.
184 // This field must be updated when the volume label
185 // in the root directory is updated.
186 char
187 volume_label[11];
188
189 // One of the strings "FAT12", "FAT16" or "FAT32".
190 // This can not be used to determine the type of the FAT,
191 // but it should be updated when creating file systems.
192 char
193 filesystem_type[8];
194
195 char
196 reserved[420];
197
198 long
199 signature;
200 };
201
202static inline int __fat_get_bpb_sector (unsigned long partition_start,unsigned long lba,struct __fat_bpb_sector *bpb_sector)
203 { return ata_read_sectors (partition_start + lba,1,bpb_sector,0); }
204
205static inline int __fat_put_bpb_sector (unsigned long partition_start,unsigned long lba,struct __fat_bpb_sector *bpb_sector)
206 { return FAT_RETURN_SUCCESS && ata_write_sectors (partition_start + lba,1,bpb_sector,0); }
207
208//
209///////////////////////////////////////////////////////////////////////////////////
210
211#endif \ No newline at end of file
diff --git a/firmware/test/fat/fat-fsi_sector.c b/firmware/test/fat/fat-fsi_sector.c
new file mode 100644
index 0000000000..54863dc2a4
--- /dev/null
+++ b/firmware/test/fat/fat-fsi_sector.c
@@ -0,0 +1,105 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <fat.h>
20#include "fat-fsi_sector.h"
21
22// [Alan]:
23// I would like to draw your attention about the fact that SH1
24// cannot use misaligned address access so you must be very cautious
25// with structures stored in FAT32 partition because they come from
26// PC world where misaligned address accesses are usual and not
27// problematic. To avoid such a trouble, I decide to use special
28// structures where fields are moved in such a way they can be
29// accessed by SH1. It is possible thanks to the callback mechanism
30// I use for reading or writing from/to an ATA device in ata.h/c.
31// So don't be puzzled if those structures seem odd compared
32// with the usual ones from PC world. I use this mechanism for structures
33// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
34// not for structure 'bpb_sector' which is too much complex to handle
35// that way, I think.
36// By the way, SH1 is big endian, not little endian as PC is.
37
38///////////////////////////////////////////////////////////////////////////////////
39// FSI SECTOR :
40///////////////
41//
42//
43
44int __fat_get_fsi_sector_callback (struct __fat_fsi_sector *fsi_sector)
45 {
46 short *data = fsi_sector->data,*end;
47 union { unsigned long si[2]; unsigned short hi[4]; unsigned char qi[8]; } words;
48 for (end = fsi_sector->end0; data < end; ++data)
49 *data = ata_get_word (0);
50#ifdef __little__
51 words.hi[0] = ata_get_word (0);
52 words.hi[1] = ata_get_word (0);
53 words.hi[2] = ata_get_word (0);
54 words.hi[3] = ata_get_word (0);
55#else
56 words.hi[1] = ata_get_word (0);
57 words.hi[0] = ata_get_word (0);
58 words.hi[3] = ata_get_word (0);
59 words.hi[2] = ata_get_word (0);
60#endif
61 for (end = fsi_sector->end1; data < end; ++data)
62 *data = ata_get_word (0);
63#ifdef __little__
64 fsi_sector->left_free_clusters = words.si[0];
65 fsi_sector->next_free_cluster = words.si[1];
66#else
67 fsi_sector->left_free_clusters = swawSI (words.si[0]);
68 fsi_sector->next_free_cluster = swawSI (words.si[1]);
69#endif
70 return ATA_RETURN_SUCCESS;
71 }
72
73int __fat_put_fsi_sector_callback (struct __fat_fsi_sector *fsi_sector)
74 {
75 short *data = fsi_sector->data,*end;
76 union { unsigned long si[2]; unsigned short hi[4]; unsigned char qi[8]; } words;
77#ifdef __little__
78 words.si[0] = swawSI (fsi_sector->left_free_clusters);
79 words.si[1] = swawSI (fsi_sector->next_free_cluster);
80#else
81 words.si[0] = swawSI (fsi_sector->left_free_clusters);
82 words.si[1] = swawSI (fsi_sector->next_free_cluster);
83#endif
84 for (end = fsi_sector->end0; data < end;)
85 ata_put_word (*data++);
86#ifdef __little__
87 ata_put_word (words.hi[0],0);
88 ata_put_word (words.hi[1],0);
89 ata_put_word (words.hi[2],0);
90 ata_put_word (words.hi[3],0);
91#else
92 ata_put_word (words.hi[1],0);
93 ata_put_word (words.hi[0],0);
94 ata_put_word (words.hi[3],0);
95 ata_put_word (words.hi[2],0);
96#endif
97 for (end = fsi_sector->end1; data < end;)
98 ata_put_word (*data++);
99 return ATA_RETURN_SUCCESS;
100 }
101
102//
103///////////////////////////////////////////////////////////////////////////////////
104
105#endif \ No newline at end of file
diff --git a/firmware/test/fat/fat-fsi_sector.h b/firmware/test/fat/fat-fsi_sector.h
new file mode 100644
index 0000000000..c329148bfa
--- /dev/null
+++ b/firmware/test/fat/fat-fsi_sector.h
@@ -0,0 +1,80 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef __LIBRARY_FAT_FSI_SECTOR_H__
20#define __LIBRARY_FAT_FSI_SECTOR_H__
21
22// [Alan]:
23// I would like to draw your attention about the fact that SH1
24// cannot use misaligned address access so you must be very cautious
25// with structures stored in FAT32 partition because they come from
26// PC world where misaligned address accesses are usual and not
27// problematic. To avoid such a trouble, I decide to use special
28// structures where fields are moved in such a way they can be
29// accessed by SH1. It is possible thanks to the callback mechanism
30// I use for reading or writing from/to an ATA device in ata.h/c.
31// So don't be puzzled if those structures seem odd compared
32// with the usual ones from PC world. I use this mechanism for structures
33// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
34// not for structure 'bpb_sector' which is too much complex to handle
35// that way, I think.
36// By the way, SH1 is big endian, not little endian as PC is.
37
38///////////////////////////////////////////////////////////////////////////////////
39// FSI SECTOR :
40///////////////
41//
42//
43
44struct __fat_fsi_sector /* File System Info Sector */
45 {
46 unsigned long
47 left_free_clusters;
48 unsigned long
49 next_free_cluster;
50 short
51 data[0];
52 long /* 0x61415252 - aARR */
53 fsi_signature0;
54 char
55 reserved0[480];
56 long /* 0x41617272 - Aarr */
57 fsi_signature1;
58 short
59 end0[0];
60 char
61 reserved1[12];
62 long /* 0x000055AA */
63 signature;
64 short
65 end1[0];
66 };
67
68int __fat_get_fsi_sector_callback (struct __fat_fsi_sector *fsi_sector);
69int __fat_put_fsi_sector_callback (struct __fat_fsi_sector *fsi_sector);
70
71static inline int __fat_get_fsi_sector (unsigned long partition_start,unsigned long lba,struct __fat_fsi_sector *fsi_sector)
72 { return ata_read_sectors (partition_start + lba,1,fsi_sector,(int(*)(void *))get_fsi_sector_callback); }
73
74static inline int __fat_put_fsi_sector (unsigned long partition_start,unsigned long lba,struct __fat_fsi_sector *fsi_sector)
75 { return ata_write_sectors (partition_start + lba,1,fsi_sector,(int(*)(void *))put_fsi_sector_callback); }
76
77//
78///////////////////////////////////////////////////////////////////////////////////
79
80#endif \ No newline at end of file
diff --git a/firmware/test/fat/fat-mbr_sector.c b/firmware/test/fat/fat-mbr_sector.c
new file mode 100644
index 0000000000..f6b510cea5
--- /dev/null
+++ b/firmware/test/fat/fat-mbr_sector.c
@@ -0,0 +1,65 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <fat.h>
20#include "fat-mbr_sector.h"
21
22// [Alan]:
23// I would like to draw your attention about the fact that SH1
24// cannot use misaligned address access so you must be very cautious
25// with structures stored in FAT32 partition because they come from
26// PC world where misaligned address accesses are usual and not
27// problematic. To avoid such a trouble, I decide to use special
28// structures where fields are moved in such a way they can be
29// accessed by SH1. It is possible thanks to the callback mechanism
30// I use for reading or writing from/to an ATA device in ata.h/c.
31// So don't be puzzled if those structures seem odd compared
32// with the usual ones from PC world. I use this mechanism for structures
33// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
34// not for structure 'bpb_sector' which is too much complex to handle
35// that way, I think.
36// By the way, SH1 is big endian, not little endian as PC is.
37
38///////////////////////////////////////////////////////////////////////////////////
39// MBR SECTOR :
40///////////////
41//
42//
43
44int __fat_get_mbr_sector_callback (struct __fat_mbr_sector *mbr_sector)
45 {
46 short *data = mbr_sector->data,*end;
47 for (end = mbr_sector->end; data < end; ++data)
48 *data = ata_get_word (0);
49 __fat_get_partition_table (mbr_sector->partition_table);
50 mbr_sector->signature = HI(ATAR_DATA);
51 return FAT_RETURN_SUCCESS;
52 }
53
54int __fat_put_mbr_sector_callback (struct __fat_mbr_sector *mbr_sector)
55 {
56 short const *data = mbr_sector->data,*end;
57 for (end = mbr_sector->end; data < end;)
58 HI(ATAR_DATA) = *data++;
59 __fat_put_partition_table (mbr_sector->partition_table);
60 ata_put_word (mbr_sector->signature,0);
61 return FAT_RETURN_SUCCESS;
62 }
63
64//
65///////////////////////////////////////////////////////////////////////////////////
diff --git a/firmware/test/fat/fat-mbr_sector.h b/firmware/test/fat/fat-mbr_sector.h
new file mode 100644
index 0000000000..11f131e440
--- /dev/null
+++ b/firmware/test/fat/fat-mbr_sector.h
@@ -0,0 +1,69 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef __LIBRARY_FAT_MBR_SECTOR_H__
20#define __LIBRARY_FAT_MBR_SECTOR_H__
21#include "fat-partition.h"
22
23// [Alan]:
24// I would like to draw your attention about the fact that SH1
25// cannot use misaligned address access so you must be very cautious
26// with structures stored in FAT32 partition because they come from
27// PC world where misaligned address accesses are usual and not
28// problematic. To avoid such a trouble, I decide to use special
29// structures where fields are moved in such a way they can be
30// accessed by SH1. It is possible thanks to the callback mechanism
31// I use for reading or writing from/to an ATA device in ata.h/c.
32// So don't be puzzled if those structures seem odd compared
33// with the usual ones from PC world. I use this mechanism for structures
34// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
35// not for structure 'bpb_sector' which is too much complex to handle
36// that way, I think.
37// By the way, SH1 is big endian, not little endian as PC is.
38
39///////////////////////////////////////////////////////////////////////////////////
40// MBR SECTOR :
41///////////////
42//
43//
44
45struct __fat_mbr_sector /* Master Boot Record Sector */
46 {
47 struct
48 __fat_partition_info partition_table[4];
49 short
50 data[0x1BE/2];
51 short
52 end[0];
53 short
54 signature;
55 };
56
57int __fat_get_mbr_sector_callback (struct __fat_mbr_sector *mbr_sector);
58int __fat_put_mbr_sector_callback (struct __fat_mbr_sector *mbr_sector);
59
60static inline int __fat_get_mbr_sector (struct mbr_sector *__fat_mbr_sector)
61 { return ata_read_sectors (0,1,mbr_sector,(int(*)(void *))__fat_get_mbr_sector_callback); }
62
63static inline int __fat_put_mbr_sector (struct mbr_sector *__fat_mbr_sector)
64 { return ata_write_sectors (0,1,mbr_sector,(int(*)(void *))__fat_put_mbr_sector_callback); }
65
66//
67///////////////////////////////////////////////////////////////////////////////////
68
69#endif \ No newline at end of file
diff --git a/firmware/test/fat/fat-partition.h b/firmware/test/fat/fat-partition.h
new file mode 100644
index 0000000000..1b0e363efb
--- /dev/null
+++ b/firmware/test/fat/fat-partition.h
@@ -0,0 +1,161 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef __LIBRARY_FAT_PARTITION_H__
20#define __LIBRARY_FAT_PARTITION_H__
21#include <ata/ata.h>
22
23// [Alan]:
24// I would like to draw your attention about the fact that SH1
25// cannot use misaligned address access so you must be very cautious
26// with structures stored in FAT32 partition because they come from
27// PC world where misaligned address accesses are usual and not
28// problematic. To avoid such a trouble, I decide to use special
29// structures where fields are moved in such a way they can be
30// accessed by SH1. It is possible thanks to the callback mechanism
31// I use for reading or writing from/to an ATA device in ata.h/c.
32// So don't be puzzled if those structures seem odd compared
33// with the usual ones from PC world. I use this mechanism for structures
34// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
35// not for structure 'bpb_sector' which is too much complex to handle
36// that way, I think.
37// By the way, SH1 is big endian, not little endian as PC is.
38
39///////////////////////////////////////////////////////////////////////////////////
40// PARTITION INFO :
41///////////////////
42//
43//
44
45struct __fat_partition_info
46 {
47 // Absolute start sector in this partition :
48 // start = start_cylinder * heads * sectors + start_head * sectors + start_sector - 1
49 unsigned long
50 start;
51
52 // Number of sectors in this partition :
53 // sectors = end_cylinder * heads * sectors + end_head * sectors + end_sector - start_sector
54 unsigned long
55 sectors;
56
57 // File system type.
58 // Must be a FAT32 file system type (0x0B or 0x0C)
59 // for Rockbox.
60 char
61 filesystem_type;
62
63 // Is this partition bootable ?
64 // Not used by Rockbox.
65 char
66 bootable;
67
68 // Not used by Rockbox.
69 unsigned char
70 start_head;
71
72 // Not used by Rockbox.
73 unsigned char
74 start_cylinder;
75
76 // Not used by Rockbox.
77 unsigned char
78 start_sector;
79
80 // Not used by Rockbox.
81 unsigned char
82 end_head;
83
84 // Not used by Rockbox.
85 unsigned char
86 end_cylinder;
87
88 // Not used by Rockbox.
89 unsigned char
90 end_sector;
91 };
92
93
94// load partition info into memory
95static inline void __fat_get_partition_info (struct partition_info *__fat_partition_info)
96 {
97 //
98 union { unsigned long si[4]; unsigned short hi[8]; unsigned char qi[16]; } words;
99 short *data = words.hi,*end;
100 for (end = data + 8; data < end; ++data)
101 *data = HI(ATAR_DATA);
102 partition_info->start = swawSI(words.si[2]);
103 partition_info->sectors = swawSI(words.si[3]);
104 partition_info->bootable = words.qi[1];
105 partition_info->filesystem_type = words.qi[5];
106 partition_info->start_head = words.qi[0];
107 partition_info->start_cylinder = words.qi[3];
108 partition_info->start_sector = words.qi[2];
109 partition_info->end_head = words.qi[4];
110 partition_info->end_cylinder = words.qi[7];
111 partition_info->end_sector = words.qi[6];
112 }
113
114// store partition info into harddisk
115static inline void __fat_put_partition_info (struct partition_info *__fat_partition_info)
116 {
117 union { unsigned long si[4]; short hi[8]; unsigned char qi[16]; } words;
118 short *data = words.hi,*end;
119 words.si[2] = swawSI(partition_info->start);
120 words.si[3] = swawSI(partition_info->sectors);
121 words.qi[1] = partition_info->bootable;
122 words.qi[5] = partition_info->filesystem_type;
123 words.qi[0] = partition_info->start_head;
124 words.qi[3] = partition_info->start_cylinder;
125 words.qi[2] = partition_info->start_sector;
126 words.qi[4] = partition_info->end_head;
127 words.qi[7] = partition_info->end_cylinder;
128 words.qi[6] = partition_info->end_sector;
129 for (end = data + 8; data < end;)
130 HI(ATAR_DATA) = *data++;
131 }
132
133//
134///////////////////////////////////////////////////////////////////////////////////
135
136///////////////////////////////////////////////////////////////////////////////////
137// PARTITION TABLE :
138////////////////////
139//
140//
141
142// load the partition table from a mbr sector
143static inline void __fat_get_partition_table (struct partition_info table[4])
144 {
145 struct partition_info *last;
146 for (last = table + 4; table < last;)
147 __fat_get_partition_info (table++);
148 }
149
150// store the partition table into a mbr sector
151static inline void __fat_put_partition_table (struct partition_info const table[4])
152 {
153 struct partition_info const *last;
154 for (last = table + 4; table < last;)
155 __fat_put_partition_info (table++);
156 }
157
158//
159///////////////////////////////////////////////////////////////////////////////////
160
161#endif \ No newline at end of file
diff --git a/firmware/test/fat/fat-volume.c b/firmware/test/fat/fat-volume.c
new file mode 100644
index 0000000000..dada78c4e6
--- /dev/null
+++ b/firmware/test/fat/fat-volume.c
@@ -0,0 +1,355 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#define __LIBRARY_FAT_VOLUME_C__
20
21#include <fat.h>
22#include "fat-mbr_sector.h"
23#include "fat-bpb_sector.h"
24#include "fat-fsi_sector.h"
25
26///////////////////////////////////////////////////////////////////////////////////
27// FAT VOLUME :
28///////////////
29//
30//
31
32// check fsi sector integrity
33static int __fat_check_fsi_sector (struct fat_volume *volume,struct __fat_fsi_sector *fsi_sector,unsigned long lba)
34 {
35 int error;
36 if (!lba)
37 // no FSI sector
38 {
39 volume->next_free_cluster = 2;
40 return FAT_RETURN_SUCCESS;
41 }
42 if ((error = __fat_get_fsi_sector (volume->partition_start,lba,fsi_sector)) > 0)
43 {
44 if ((fsi_sector->signature != 0x0000AA55) ||
45 (fsi_sector->fsi_signature0 != 0x52524161) ||
46 (fsi_sector->fsi_signature1 != 0x72726141))
47 {
48 return FAT_RETURN_BAD_FSI;
49 }
50 if (fsi_sector->left_free_clusters == -1)
51 fsi_sector->next_free_cluster = 2;
52 else if (fsi_sector->next_free_cluster >= volume->sectors_per_fat)
53 return FAT_RETURN_BAD_FSI;
54 volume->next_free_cluster = fsi_sector->next_free_cluster;
55 fsi_sector->left_free_clusters = -1;
56 fsi_sector->next_free_cluster = 2;
57 error = __fat_put_fsi_sector (volume->partition_start,lba,fsi_sector)));
58 }
59 return error;
60 }
61
62static inline int bit_in_range (int value,int min,int max)
63 {
64 for (;min < max; min <<= 1)
65 if (value == min)
66 return 1;
67 return 0;
68 }
69
70// check bpb sector integrity
71static int __fat_check_bpb_sector (struct fat_volume *volume,struct __fat_bpb_sector *bpb_sector,struct __fat_fsi_sector *fsi_sector)
72 {
73 long unsigned bpb_lba = 0,fsi_lba;
74 long unsigned sectors_per_cluster,sectors_per_fat,sectors,reserved_sectors,total_sectors;
75 long unsigned first_cluster_of_root,first_sector_of_fat,first_sector_of_data;
76 long unsigned clusters_per_fat,bytes_per_sector;
77 int error,backup;
78 for (backup = 0; !backup ; backup = 1)
79 {
80 if ((error = __fat_get_bpb_sector (volume->partition_start,bpb_lba,bpb_sector)) > 0)
81 {
82 bytes_per_sector = peekHI (bpb_sector->bytes_per_sector );
83 sectors_per_cluster = peekQI (bpb_sector->sectors_per_cluster);
84 sectors_per_fat = peekSI (bpb_sector->sectors_per_fat );
85 sectors = peekQI (bpb_sector->number_of_fats ) * sectors_per_fat;
86 reserved_sectors = peekHI (bpb_sector->reserved_sectors );
87 total_sectors = peekSI (bpb_sector->total_sectors );
88 first_cluster_of_root = peekSI (bpb_sector->root_cluster );
89 first_sector_of_fat = reserved_sectors + volume->partition_start;
90 first_sector_of_data = first_sector_of_fat + sectors;
91 clusters_per_fat = (total_sectors - first_sector_of_data) / sectors_per_cluster;
92
93 if (!bpb_lba)
94 {
95 bpb_lba = peekHI(bpb_sector->backup_bpb);
96 if (bpb_lba == -1)
97 bpb_lba = 0;
98 }
99
100 if ((bpb_lba >= reserved_sectors) ||
101 (bpb_sector->signature != 0x000055AA) ||
102 (clusters_per_fat < 65525) ||
103 (bytes_per_sector != 512) ||
104 (!bit_in_range (sectors_per_cluster,1,128)) ||
105 (bytes_per_sector * sectors_per_cluster >= 32 KB) ||
106 (peekHI (bpb_sector->total_sectors_16)) ||
107 (peekHI (bpb_sector->sectors_per_fat_16)) ||
108 (peekHI (bpb_sector->number_of_root_entries)) ||
109 ((bpb_sector->media[0] != 0xF0) && (bpb_sector->media[0] < 0xF8)))
110 {
111 error = FAT_RETURN_BAD_BPB;
112 if (bpb_lba) // try with backup BPB sector ?
113 continue;
114 return error;
115 }
116 if ((signed char)bpb_sector->flags[0] >= 0)
117 {
118 bpb_sector->flags[0] = 0x80;
119 if (!backup && (error = __fat_put_bpb_sector (volume->partition_start,0,bpb_sector)) <= 0)
120 return error;
121 if ((error = __fat_put_bpb_sector (volume->partition_start,bpb_lba,bpb_sector)) <= 0)
122 return error;
123 }
124
125 volume->sectors_per_cluster = sectors_per_cluster;
126 volume->sectors_per_fat = sectors_per_fat;
127 volume->first_cluster_of_root = first_cluster_of_root;
128 volume->first_sector_of_fat = first_sector_of_fat;
129 volume->first_sector_of_data = first_sector_of_data;
130 volume->clusters_per_fat = clusters_per_fat;
131
132 fsi_lba = ((long)peekHI(bpb_sector->filesystem_info));
133 if (fsi_lba == -1)
134 fsi_lba = 0;
135 else if (fsi_lba >= reserved_sectors)
136 {
137 error = FAT_RETURN_BAD_FSI;
138 if (bpb_lba) // try with backup BPB sector ?
139 continue;
140 return error;
141 }
142
143 if (((error = __fat_check_fsi_sector (volume,fsi_sector,fsi_lba + (backup ? 0 : bpb_lba))) <= 0) && bpb_lba)
144 continue;
145
146 if (backup)
147 {
148 error = __fat_put_bpb_sector (volume,0,bpb_sector)) <= 0);
149 if (!error)
150 error = __fat_put_fsi_sector (volume,fsi_lba,fsi_sector)) <= 0);
151 }
152
153 break;
154 }
155 }
156 return error;
157 }
158
159static inline int __fat_compare_volume_name (char const *name,struct fat_volume *volume)
160 {
161 return !name ? -1 : strncpy (name,volume->name,11);
162 }
163
164static struct fat_volume *__fat_splay_volume (struct fat_volume *root,char const *name)
165 {
166 struct fat_volume *down;
167 struct fat_volume *less;
168 struct fat_volume *more;
169 struct fat_volume *head[2];
170 ((struct fat_volume *)head)->less =
171 ((struct fat_volume *)head)->more = 0;
172 less =
173 more = head;
174 while (1)
175 {
176 int sign = __fat_compare_volume_name (name,root);
177 if (sign < 0)
178 {
179 if ((down = root->less))
180 {
181 sign = __fat_compare_volume_name (name,down);
182 if (sign < 0)
183 {
184 root->less = down->more;
185 down->more = root;
186 root = down;
187 if (!root->less)
188 break;
189 }
190 more->less = root;
191 more = root;
192 root = root->less;
193 continue;
194 }
195 break;
196 }
197 if (0 < sign)
198 {
199 if ((down = root->more))
200 {
201 sign = __fat_compare_volume_name (name,down);
202 if (0 < sign)
203 {
204 root->more = down->less;
205 down->less = root;
206 root = down;
207 if (!root->more)
208 break;
209 }
210 less->more = root;
211 less = root;
212 root = root->more;
213 continue;
214 }
215 }
216 break;
217 }
218 less->more = root->less;
219 more->less = root->more;
220 root->less = ((struct fat_volume *)head)->more;
221 root->more = ((struct fat_volume *)head)->less;
222 return root;
223 }
224
225static inline struct fat_volume *__fat_insert_volume (struct fat_volume *root,struct fat_volume *node)
226 {
227 if (!root)
228 {
229 node->less =
230 node->more = 0;
231 }
232 else if (node < (root = __fat_splay_volume (root,node->name)))
233 {
234 node->less = root->less;
235 node->more = root;
236 root->less = 0;
237 }
238 else if
239 {
240 node->less = root;
241 node->more = root->more;
242 node->more = 0;
243 }
244 return node;
245 }
246
247#if 0
248static inline struct fat_volume *__fat_remove_volume (struct fat_volume *root,struct memory_free_page *node)
249 {
250 root = __fat_splay_volume (root,node->name);
251 if (root->less)
252 {
253 node = __fat_splay_volume (root->less,node->name);
254 node->more = root->more;
255 }
256 else
257 node = root->more;
258 return node;
259 }
260#endif
261
262static inline struct fat_volume *__fat_lookup_volume (struct fat_volume *root,char const *name)
263 {
264 return __fat_splay_volume (root,0);
265 }
266
267static struct fat_volume *__fat_first_volume (struct fat_volume *root)
268 {
269 struct fat_volume *down;
270 struct fat_volume *less;
271 struct fat_volume *more;
272 struct fat_volume *head[2];
273 ((struct fat_volume *)head)->less =
274 ((struct fat_volume *)head)->more = 0;
275 less =
276 more = &head;
277 if (root)
278 while (1)
279 {
280 if ((down = root->less))
281 {
282 root->less = down->more;
283 down->more = root;
284 root = down;
285 if (!root->less)
286 break;
287 more->less = root;
288 more = root;
289 root = root->less;
290 continue;
291 }
292 break;
293 }
294 less->more = root->less;
295 more->less = root->more;
296 root->less = ((struct fat_volume *)head)->more;
297 root->more = ((struct fat_volume *)head)->less;
298 return root;
299 }
300
301static inline struct fat_volume *__fat_scan_volume (struct fat_volume *root,int next)
302 {
303 return __fat_first_volume (next ? root->more : root,0);
304 }
305
306static int __fat_build_volume_tree (struct fat_volume *root)
307 {
308 struct fat_volume *volume;
309 int number = 4;
310 struct __fat_partition_info *partition_info;
311 struct __fat_mbr_sector mbr_sector;
312 struct __fat_bpb_sector bpb_sector;
313 struct __fat_fsi_sector fsi_sector;
314 if (__fat_get_mbr_sector (&mbr_sector) <= 0)
315 return 0;
316 partition_info = mbr_sector.partition_table;
317 for (;number-- > 0; ++partition_info)
318 {
319 switch (partition_info->filesystem_type)
320 {
321 case 0x05: // extended partition - handle it as well
322 {
323 if (!__fat_build_volume_list (list))
324 return 0;
325 break;
326 }
327 case 0x0B: // FAT32 partitions
328 case 0x0C:
329 {
330 if (!(volume = memory_allocate_page (0)))
331 return 0;
332 volume->next = 0;
333 volume->partition_start = partition_info->start;
334 volume->partition_sectors = partition_info->sectors;
335 if (__fat_check_bpb_sector (volume,&mbr_sector,&fsi_sector) > 0)
336 {
337 dump_volume (volume);
338 *root = volume;
339 list = &volume->next;
340 break;
341 }
342 else
343 memory_release_page (volume,0);
344 }
345 }
346 }
347 return 1;
348 }
349
350static struct fat_volume *__fat_volume_root;
351
352void fat_setup (void)
353 {
354 //build_volume_list (&root);
355 }
diff --git a/firmware/test/fat/inlines.h b/firmware/test/fat/inlines.h
index 02242bb4cb..eb776e9792 100644
--- a/firmware/test/fat/inlines.h
+++ b/firmware/test/fat/inlines.h
@@ -23,4 +23,5 @@
23#define __LIBRARY_FAT_INLINES_H__ 23#define __LIBRARY_FAT_INLINES_H__
24 24
25 25
26
26#endif \ No newline at end of file 27#endif \ No newline at end of file
diff --git a/firmware/test/fat/makefile b/firmware/test/fat/makefile
index 90a8964d40..1cd259b52f 100644
--- a/firmware/test/fat/makefile
+++ b/firmware/test/fat/makefile
@@ -1,20 +1,21 @@
1############################################################################# 1##############################################################################
2## __________ __ ___. 2## __________ __ ___.
3## Open \______ \ ____ ____ | | _\_ |__ _______ ___ 3## Open \______ \ ____ ____ | | _\_ |__ _______ ___
4## Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 4## Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5## Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5## Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6## Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6## Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7## \/ \/ \/ \/ \/ 7## \/ \/ \/ \/ \/
8## Copyright Alan Korr, 2002. All rights reserved. 8## $Id:
9## 9##
10## Permission to use, copy, modify, and distribute this software for any 10## Copyright (C) 2002 by Alan Korr
11## purpose is hereby granted without fee, provided that this copyright and
12## permissions notice appear in all copies and derivatives, and that no
13## charge may be made for the software and its documentation except to cover
14## cost of distribution.
15## 11##
16## This software is provided "as is" without express or implied warranty. 12## All files in this archive are subject to the GNU General Public License.
17############################################################################# 13## See the file COPYING in the source tree root for full license agreement.
14##
15## This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16## KIND, either express or implied.
17##
18##############################################################################
18ARCH = test 19ARCH = test
19PACKAGE = fat 20PACKAGE = fat
20VERSION = 0.0.0 21VERSION = 0.0.0
diff --git a/firmware/test/fat/return_values.h b/firmware/test/fat/return_values.h
index 114a0abb5f..67747ffc36 100644
--- a/firmware/test/fat/return_values.h
+++ b/firmware/test/fat/return_values.h
@@ -21,4 +21,11 @@
21#endif 21#endif
22#ifndef __LIBRARY_FAT_RETURN_VALUES_H__ 22#ifndef __LIBRARY_FAT_RETURN_VALUES_H__
23# define __LIBRARY_FAT_RETURN_VALUES_H__ 23# define __LIBRARY_FAT_RETURN_VALUES_H__
24
25enum
26 {
27 FAT_RETURN_SUCCESS = 1,
28 FAT_RETURN_FAILURE = 0
29 };
30
24#endif \ No newline at end of file 31#endif \ No newline at end of file
diff --git a/firmware/test/fat/types.h b/firmware/test/fat/types.h
index 3a84aa3e97..d83de9e2c1 100644
--- a/firmware/test/fat/types.h
+++ b/firmware/test/fat/types.h
@@ -21,4 +21,23 @@
21#endif 21#endif
22#ifndef __LIBRARY_FAT_TYPES_H__ 22#ifndef __LIBRARY_FAT_TYPES_H__
23# define __LIBRARY_FAT_TYPES_H__ 23# define __LIBRARY_FAT_TYPES_H__
24
25// [Alan]:
26// I would like to draw your attention about the fact that SH1
27// cannot use misaligned address access so you must be very cautious
28// with structures stored in FAT32 partition because they come from
29// PC world where misaligned address accesses are usual and not
30// problematic. To avoid such a trouble, I decide to use special
31// structures where fields are moved in such a way they can be
32// accessed by SH1. It is possible thanks to the callback mechanism
33// I use for reading or writing from/to an ATA device in ata.h/c.
34// So don't be puzzled if those structures seem odd compared
35// with the usual ones from PC world. I use this mechanism for structures
36// 'partition_info', 'mbr_sector' and 'fsi_sector' for instance, but
37// not for structure 'bpb_sector' which is too much complex to handle
38// that way, I think.
39// By the way, SH1 is big endian, not little endian as PC is.
40
41
42
24#endif \ No newline at end of file 43#endif \ No newline at end of file