Page 1 of 1

Creating a Bitmap?

Posted: Fri Apr 20, 2007 2:42 am
by pcmattman
Can anyone help me out? I need to somehow put the top 4 bits of an unsigned char into bits 8-11 of a short, and the bottom 4 into bits 0-3.

I can get the bits out of the char, but I don't know how to put them into the short.

Re: Creating a Bitmap?

Posted: Fri Apr 20, 2007 2:58 am
by pjt
pcmattman wrote:Can anyone help me out? I need to somehow put the top 4 bits of an unsigned char into bits 8-11 of a short, and the bottom 4 into bits 0-3.

I can get the bits out of the char, but I don't know how to put them into the short.
First step: s |= ((short)(uc & 0xf0)) << 4
Second step: s|= (uc & 0xf)

Cheers.

Posted: Fri Apr 20, 2007 3:03 am
by pcmattman
Hmmm... still doesn't get what I need.

I need to create a bit field that I can use in the EEPROM command register (3Com 3C90xC) from a unsigned char for the register and opcode. And it needs to be a short.

Posted: Fri Apr 20, 2007 3:48 am
by omin0us
I dont see why pjt's method wont work for you?
but you can also create a struct that uses only certain amounts of bits for each member of the struct.

Code: Select all

struct shortVariable
{
        unsigned bits0to3 : 4;
        unsigned bits4to7 : 4;
        unsigned bits8to11 : 4;
        unsigned bits12-15 : 4;
};

struct shortVariable sv;
unsigned char data;
...

sv.bits0to3 = data & 0x0f;
sv.bits8to11 = (data & 0xf0) << 4;
and then you can cast the struct to a short. I dunno if the struct members will get aligned in memory wierd with that struct. I wouldn't think so, since it is 2 bytes even. But if it does, you can always use __attribute__((packed)) with struct definition.

Posted: Fri Apr 20, 2007 5:04 am
by pjt
Just one nitpick:

Code: Select all

sv.bits8to11 = (data & 0xf0) >> 4; 
For creating a short from a stuct the easiest way is to put them both in a union.

Posted: Fri Apr 20, 2007 5:59 am
by pcmattman
I'll have to try that. Thanks for your help, I tried the struct but forgot about the packed attribute :shock: ...

Posted: Fri Apr 20, 2007 7:27 am
by os64dev
I have created this template class for this purpose.

Code: Select all

//-[ BitField<T> ]--------------------------------------------------------------
template <typename T>
class                   BitField {
    T                       bits;

  public:
    BitField(void) : bits(0) {}
    BitField(T data) : bits(data) {}
    BitField(voidp addr) : bits(*(T *)addr) {}

    T                       get(int16u, int16u);
    void                    set(int16u, int16u, T);

} __attribute__((packed));
//--------------------------------------------------------------[ BitField<T> ]-


//-[ BitField<T>::get ]---------------------------------------------------------
template <class T> T
  BitField<T>::get
  ( int16u                  base,                    //- first bit of data field
    int16u                  size                     //- number of bits to fetch
  )
{   const T                 mask = (((T)1 << size) - (T)1);
    return((bits >> base) & mask);
}
//---------------------------------------------------------[ BitField<T>::get ]-


//-[ BitField<T>::set ]---------------------------------------------------------
template <class T> void
  BitField<T>::set
  ( int16u                  base,                    //- first bit of data field
    int16u                  size,                    //- number of bits to store
    T                       data                     //- value to store in field
  )
{   const T                 mask = (((T)1 << size) - (T)1) << base;
    bits = (bits & ~mask) | ((data << base) & mask);
}
//---------------------------------------------------------[ BitField<T>::set ]-
Can anyone help me out? I need to somehow put the top 4 bits of an unsigned char into bits 8-11 of a short, and the bottom 4 into bits 0-3.

I can get the bits out of the char, but I don't know how to put them into the short.
You can use it like:

Code: Select all

BitField<char>    byte(/*value*/);
BitField<short>    word(/*value*/);

word.set(8, 4/*bit 8-11*/, byte.get(0,4/*bit 0-3*/));

Posted: Fri Apr 20, 2007 4:03 pm
by pcmattman
Maybe I should switch to C++ as my OSdevving langauge. It looks so much easier to work with... Classes are my thing :D

Edit: got it... I just had to put the struct into a union with an unsigned short and it now works perfectly. Thankyou everyone :D