Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I'm currently writing a FAT12 driver, which is giving me some problems. I'm a bit confused about how to read the FAT entries, and finding the next cluster in chain. The weird problem is that a small file ( 1 or 2 clusters ) starting at an even cluster works just fine, but big files jump over all the place. I'm thinking about it, but I can't get the math straigt. As I've read over and over, odd clusters shift 4 to the right, even clusters mask with 0x0FFF. But what I don't get, if I use this method, some bytes will be missing. Because we use ?r the first 12 bits of a word, or the upper 12 bits. I.e. every FAT entry starts at bit 0 or bit 4 of a word. But as far as I can imagine, FAT entries can also start at bit 8 or 12 right? Or am I thinking to complicated?
... some BPB reading here...
int cluster = (block[(c*32)+26] ) + ( block[(c*32)+27] * 0xFF ) ; // Starting cluster from dir entry
int next_cluster=0, fat_offset=0;
BYTE FAT[0x1200];
fd_read_block(1,FAT, 9); // read the FAt, I know this is not the right way to go ;)
while(cluster < 0x0FF8) {
double fat_entry = (cluster * 3)/2;
fat_offset = FAT[(int)fat_entry] + (FAT[(int)fat_entry + 1] * 0xFF);
if(floor(fat_entry) == fat_entry){
next_cluster = fat_offset >> 4;
} else {
next_cluster = (fat_offset & 0x0FFF);
}
show_sector(cluster); // This function displays the contect of cluster x
cluster = next_cluster;
}
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
The 0xFF - 0x100 mistake was rather dumb, but I've experimented with this code so many times it's all f*cked up. So now I have a freshly written loop but the problem remains. I've some output, the loop is:
Welcome to ProtOS.
fd:test
fat_offset: 975 next_cluster: 60 cluster: 59
fat_offset: 57405 next_cluster: 3587 cluster: 60
fat_offset: 26190 next_cluster: 1636 cluster: 3587
fat_offset: 0 next_cluster: 0 cluster: 1636
fat_offset: 65520 next_cluster: 4095 cluster: 0
fd:ls
KERNEL BIN 28672 A cluster:2
CHANGE~1TXT 297 A cluster:58
LICENSE TXT 18009 A cluster:59
README TXT 782 HA cluster:95
TEST D cluster:97
fd:
I've read some raw sectors and I know the file is located at cluster 59-60-61-62-63-etc... ( I limited the results to 5 )
The shift 4 part is working OK, I'm guessing that the masking is going all wrong... Taking a piece of paper and writing it all in binary, but the results make no sense. I end up with a FAT entry which starts at bit 12 of a word... ??
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
MrASCII wrote:
The 0xFF - 0x100 mistake was rather dumb, but I've experimented with this code so many times it's all f*cked up.
I urgently suggest you use some kind of version tracking system. RCS could suffice for local use and is easy to set up / administrate. CVS or Subversion are more complete solutions.
You just voiced the best reason yourself: You tend to edit your code to death otherwise, and the clean-up after such a trial-and-error session becomes much easier if you have a revision history on file.
Every good solution is obvious once you've found it.