Let me see if I can re-explain. And fix a bug. Instead of storing the bytes something like the following (where the # is which byte that bit belongs to, and note that for convienience I've swapped LSB/MSB left-to-right just for visual purposes): LSb MSb 0 0 0 0 0 0 0 0 1 1 1 1 1 1 (Word 0) 1 1 2 2 2 2 2 2 2 2 3 3 3 3 (Word 1) 3 3 3 3 4 4 4 4 4 4 4 4 5 5 (Word 2) 5 5 5 5 5 5 6 6 6 6 6 6 6 6 (Word 3) I'm advocating something like this: 0 0 0 0 0 0 0 0 4 4 4 4 6 6 (Word 0) 1 1 1 1 1 1 1 1 4 4 4 4 6 6 (Word 1) 2 2 2 2 2 2 2 2 5 5 5 5 6 6 (Word 2) 3 3 3 3 3 3 3 3 5 5 5 5 6 6 (Word 3) So the algorithm is: if (address<4) // Bytes 0..3 are in 8 LSb of words 0..3. { return flash[address]&0xff; } elsif (address<6) // bytes 4..5 are in bits 8..11 of words 0..3 { return flash[ (address-4)/2 ]>>8) & 0b00001111 | flash[ (address-4)/2+1 ]>>6 ) &0b11110000; } elsif (address<7) // byte 6 is in bits 12..13 of words 0..3 { return flash[ (address-6)/4 ]>>12) & 0b00000011 | flash[ (address-6)/4+1 ]>>10 ) &0b00001100; | flash[ (address-6)/4+1 ]>>8 ) &0b00110000; | flash[ (address-6)/4+1 ]>>6 ) &0b11000000; } The bug was forgetting to subtract the "offset" from the address. The joys of coding without compiling or using the code... If you need to store 14 words, then just use 8,12,14 where you see 4, 6 and 7 above... and so on. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist