3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33 static unsigned char tolower (char c
)
35 return ((c
>= 'A' && c
<= 'Z') ? c
+ 32: c
);
38 static void dec2bin (long decimal
, char *binary
)
45 // take care of negative input
51 decimal
= decimal
/ 2; // whittle down decimal
52 temp
[k
++] = remain
+ 0x30; // makes characters 0 or 1
53 } while (decimal
> 0);
56 temp
[k
++] = '-'; // add back - sign
58 temp
[k
++] = ' '; // or space
61 binary
[n
++] = temp
[-- k
]; // reverse spelling
63 binary
[n
- 1] = 0; // end with NULL
66 static void parse_attr (char* binary
,int y
)
71 0x04 000100 System file
74 0x20 100000 Binary which stands for Archive
87 for (i
= strlen (binary
) - 1; i
>= 0; i
--) {
88 if(binary
[i
] == '1') {
90 case 0: dir
[y
].read
=1; break;
91 case 1: dir
[y
].hidden
=1; break;
92 case 2: dir
[y
].system
=1; break;
93 case 3: dir
[y
].volume
=1; break;
94 case 4: dir
[y
].dir
=1; break;
95 case 5: dir
[y
].bin
=1; break;
102 static int fat_read (unsigned int byte
, unsigned int byte2
)
106 unsigned char *buf
= text
;
109 unsigned int start
= -1;
110 unsigned int next
= 0;
111 unsigned int test
= 0;
112 unsigned int pom
= 0;
114 if (!read_block (1, text
, 1))
118 for(x
= 0; x
< 512; x
++) {
119 //if (i>byte-3 && i<byte+3)
120 //kprintf("%x",*buf);
124 if (i
== byte2
&& start
!= -1) {
125 if (start
== 0xf0 && *buf
== 0xff)
128 next
= ((*buf
<< 8 | start
) >> 4);
129 test
= (*buf
<< 8 | start
);
132 next
= (*buf
<< 8 | start
) & 0x0FFF;
136 //kprintf("\nnext=%x %d start=%x end=%x byte=%d byte1=%d cele=%d test=%x\n",next,next,start,*buf,byte,byte2,cele,test);
149 static int fat_nextsector (int i
)
151 cele
= (i
* 150) % 100;
152 return (i
* 150) / 100;
155 static void read_f (unsigned int cluster
)
157 static BYTE text1
[512] = "";
160 // kprintf("\n*** %d\n",cluster);
161 read_block (33 + cluster
, text1
, 1);
163 //text1[strlen(text1)-4]='\0';
167 /* FIXME: lot of work with elf */
168 //file_cache = (unsigned char *) krealloc ((void *) file_cache, file_cache_id+len);
170 cache_add (text1
, len
);
172 // kprintf ("file_cache: %d\n", file_cache_id);
175 // 33 sector = open space
176 static unsigned long read_file (int aa
, vfs_content_t
*content
)
184 cache_t
*cache
= cache_create (0, 0, 0);
189 //kprintf("name=%s start=%d fat=%d\n",dir[aa].name,dir[aa].start,next);
190 next
= fat_nextsector (dir
[aa
].start
);
191 sect
= fat_read (next
,next
+1);
193 next
= fat_nextsector (sect
);
194 read_f (dir
[aa
].start
-2);
195 // file_cache[strlen(file_cache)-4]='\0';
197 for (i
= 0; i
< 2000; i
++) {
198 //DPRINT (DBG_DRIVER | DBG_FS, "next: %d sect: %d", next, sect);
200 if (sect
< 0 || sect
== 4095)
202 //file_cache[strlen (file_cache)-4] = '\0';
204 sect
= fat_read (next
, next
+1);
205 next
= fat_nextsector (sect
);
208 content
->ptr
= (char *) &cache
->data
;
209 content
->len
= cache
->limit
;
214 unsigned read_dir (int aa
)
216 static BYTE text
[512];
217 unsigned char *buf
= text
;
224 /* vymazeme nazvy vsech souboru */
225 for(x
= 0; x
< 223; x
++)
226 dir
[x
].name
[0] = '\0';
229 if (!read_block (19, text
, 1))
231 //printf ("ret: %d\n", ret);
233 if (!read_block (33+dir
[aa
].start
-2, text
, 1))
239 for (x
= 0; x
< 512; x
++) {
249 if (i
== 27 && label
== 0)
250 dir
[y
].start
= (*buf
<< 8 | start
);
252 if (i
== 11 && (*buf
== 0x0f || *buf
== 0x00)) {
253 strcpy (dir
[y
].name
, "");
257 if (i
== 11 && *buf
!= 0x0f && *buf
!= 0x00) {
261 if (i
<= 10 && i
>= 0)
262 dir
[y
].name
[i
] = tolower (*buf
);
276 static void write_f (unsigned int cluster
, char *text1
)
278 if (!write_block (33 + cluster
, text1
, 1)) {
279 printf ("error -> FAT12 -> !floppy write\n");
283 DPRINT (DBG_DRIVER
| DBG_FS
, "FAT12 -> write_f (): OK");
286 // 33 sector = open space
287 static void write_file (int aa
, char *buf
)
295 //kprintf("name=%s start=%d fat=%d\n",dir[aa].name,dir[aa].start,next);
297 next
= fat_nextsector (dir
[aa
].start
);
298 sect
= fat_read (next
, next
+1);
300 next
= fat_nextsector (sect
);
301 read_f (dir
[aa
].start
-2);
303 for(i
= 0; i
< 100; i
++) {
304 //DPRINT (DBG_DRIVER | DBG_FS, "next: %d sect: %d", next, sect);
306 if (sect
< 0 || sect
== 4095)
309 write_f (sect
-2, buf
);
310 sect
= fat_read (next
, next
+1);
311 next
= fat_nextsector (sect
);
315 /* TODO: in development */
316 static void write_dir (int aa
)
318 static BYTE text
[512];
319 unsigned char *buf
= text
;
326 /* vymazeme nazvy vsech souboru */
327 for(x
= 0; x
< 223; x
++)
328 dir
[x
].name
[0] = '\0';
331 write_block (19, text
, 1);
333 write_block (33+dir
[aa
].start
-2, text
, 1);
337 for (x
= 0; x
< 512; x
++) {
347 if (i
== 27 && label
== 0)
348 dir
[y
].start
= (*buf
<< 8 | start
);
350 if (i
== 11 && (*buf
== 0x0f || *buf
== 0x00)) {
351 strcpy (dir
[y
].name
, "");
355 if (i
== 11 && *buf
!= 0x0f && *buf
!= 0x00) {
359 if (i
<= 10 && i
>= 0)
360 dir
[y
].name
[i
] = tolower (*buf
);
367 bool fat_handler (unsigned act
, char *block
, unsigned n
, unsigned long l
)
378 l
= read_file (n
, (vfs_content_t
*) block
);
389 char *buf
= (char *) kmalloc (sizeof (char) * (y
+1));
392 DPRINT (DBG_DRIVER
| DBG_FS
, "ERROR -> FAT WRITE : out of memory");
397 memcpy (buf
, block
, l
);
401 for (i
= 0; i
< (y
/512); i
++);
402 write_file (n
, buf
+(i
*512));