I haven't tested it, but looks correct at first glance.
I'd write it slightly differently, to:
1) try to force the compiler to do the right thing - we don't want it to optimize (x/16)*2 to (x/8);
2) eliminate usage of the non-portable GCC extension known as "void pointer arithmetics" (it's not your fault for unwittingly using it, it's the compiler designers' and implementers' fault for making it possible...);
3) to simplify the way the last test is written. In fact, the 3 last statements could be combined.
Also, I took the liberty to make x and y unsigned.
- Code: Tout sélectionner
short isBit(void* buffer, unsigned short x, unsigned short y){
// 32 wide start block * 2 size
unsigned char * base = (unsigned char *)buffer + (y<<5) + ((x>>4) +(x>>4));
unsigned short offset = x&15;//Offset from start of base block
unsigned short val = *((unsigned short*)base);
//Number that gets ANDed with the block to test.
unsigned short test = 1<<offset;
return (val&test);
}
EDIT: thinking about it again... given that the btst instruction works with byte-sized memory operands, maybe the whole function could attempt to perform bit tests on bytes, which would yield something along the lines of (untested):
- Code: Tout sélectionner
short isBit(void* buffer, unsigned short x, unsigned short y){
// 32 wide start block * 2 size
unsigned char * base = (unsigned char *)buffer + (y<<5) + (x>>3);
return (*base & (1 << (x&7)));
}
EDIT2: wrapped y<<5 into parentheses, per your later post.