did you checked the FAT was read correctly (i suggest you implement a small HEXDUMP feature and check your memory image of the FAT is what you expected)? what kind of FAT is it ? 12 , 16 or 32. If 12, did you check the bytes were read correctly ?
from a 16-bits word, you could have
let's consider the fat as a list of 3-bytes entries, given cluster nr X, the entry will be X/4.
Code: Select all
struct fat_entry { unsigned short data[3]};
struct fat_entry FAT[fat_size];
[X X X y] [y y Z Z] [Z u u u]
entry=&(FAT[index/4])
X.index % 4 = 0 --> val = entry[0]&0xfff;
y.index % 4 = 1 --> val = (entry[0]>>12) | ((entry[1]<<4)&0xfff);
etc.
now it looks like your code does something very similar ... maybe i could need some more coffee ...
However, i'm wondering if using "unsigned short" rather than "short" couldn't help you ... i remember it's hard to know whether x>>N will be sign-extended or not in C with signed numbers ... maybe it just doesn't care because of that "&0xFFF" operation. I think it could be wiser and cleaner not to do bit operations on signed numbers anyway ...