gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > grabbing 1 bit out of an 8 bit word

#15443 - slboytoy - Thu Jan 22, 2004 8:56 pm

How would I grab one bit at a time, out of say '0XAA'

For each 1, out of that, i want to display a line.
And for each 0, I want to display a different color line.

I tried using the >> 1 to shift, but I can't seem to get the code right.

#15444 - frag - Thu Jan 22, 2004 8:59 pm

Unless I'm mistaken 0xAA is a 16 bit halfword not a byte...

#15447 - DekuTree64 - Thu Jan 22, 2004 9:20 pm

Nope, that's a byte. Each hex digit is only 4 bits (0-15).
Anyway, calling the first bit 0, then to check if, say, bit5 is set, you would do something like
Code:
if(val & (1 << 5))
{
   //do stuff
}

Or you could do (val >> 5) & 1. For a 'set or unset' check, either way will work, because it will be either zero or not zero, and those are the only states an if recognizes. The first is a tiny bit faster though, becuase 1<<5 = 32, so the compiler can change that to if(val & 32), which is only one instruction, instead of two.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#15448 - slboytoy - Thu Jan 22, 2004 9:21 pm

Well 0xAA

isn't it
1010 1010?

So how can I grab just 1 value at a time?

#15450 - johnny_north - Thu Jan 22, 2004 9:32 pm

Assuming unsigned data

u8 theNumber = 0xAA;
bool bitOn;

for(int i=1; i<8;i++){
bitOn = (theNumber << 7) >> 7); //strip off the top seven bits
if(bitON) //do what ever
else //do whatever
theNumber = theNumber>>i;//roll the bits by one bit
}

#15451 - sajiimori - Thu Jan 22, 2004 9:38 pm

slboytoy, if you want to get individual bits, DekuTree64 has already shown you how to do that (johnny_north's way is overcomplicated).

#15462 - YopYop - Thu Jan 22, 2004 10:35 pm

If you want to do this for all bits:

here is a way to do

For(x=1 ;x<0xFF ;x<<1)
if( va l& x )
{
//here do stuff
}

#15468 - sajiimori - Thu Jan 22, 2004 11:02 pm

YopYop, your code has several bugs. That isn't a problem when we're discussing conceptual issues with people who are already fluent in C, but you're likely to cause confusion when the people involved may not be experts.

#15473 - Miked0801 - Thu Jan 22, 2004 11:13 pm

#define NUM_BITS 8

s32 i;
u8 data = 0xAA;

for(i=0; i<NUM_BITS; i++)
{
if(data & (1 << i))
{
printf("Bit Set\n");
}
else
{
printf("Bit Clear\n");
}
}

#15479 - YopYop - Thu Jan 22, 2004 11:46 pm

excuse me I forgot the x=x<<1 in for loop

we all here to learn from each others so he will surch or ask what does all this stuff mean and he will learn.
for my part I begin like that

#15482 - slboytoy - Fri Jan 23, 2004 1:04 am

DekuTree64's way was what I was looking for.

Thank you guys for your quick help. This is for a college project, so all my team-mates will have the name "slboytoy". Our levels of C will be all different.

#15687 - slboytoy - Wed Jan 28, 2004 12:08 am

OK here's another question about bit shifting....

Is there a way to read in a 8bit value

Data = LoadByte(0);

And then take the LSB and make into a new value?

DataCh1 = Data << 0;

So then if I scroll ahead in memory (move the offset forwars), it will keep on adding new values to DataCh1, and then if I move back in memory (move the offset backwards), it will add new values on the end of DataCh1?

I basically want to move through memory back and forth, and the current spot in memory will be the center of my waveform.

#15693 - poslundc - Wed Jan 28, 2004 12:53 am

Are you asking if it's possible to make a series of bits that spans some arbitrary memory location that isn't byte-aligned?

The answer is yes, you can. You can do just about anything by masking, shifting and or-ing. Whether or not you need to, though, is another matter. You must access a minimum of a byte at a time from memory, and while you can get around this restriction using bit-arithmetic, it's likely to be an ill-conceived design if your application needs data spanning parts of two separate bytes.

Anyway, here's some code:

Code:
u8      *p = (u8 *)(some-location-in-memory);
u8      n;

n = *p << 3;
n |= (*(p + 1) >> 5);


Here, the value of n is the bottom 5 bits of the first byte in memory followed by the top 3 bits of the next byte in memory.

Dan.

#15699 - sajiimori - Wed Jan 28, 2004 2:44 am

Quote:

Is there a way to read in a 8bit value...And then take the LSB and make into a new value?

LSB stands for Least Significant Byte, which doesn't make any sense when you're talking about a single byte value.
Code:

DataCh1 = Data << 0;

"<< 0" doesn't do anything.
Quote:

...scroll ahead...move the offset...adding new values...waveform...

These things don't mean anything to me unless you describe what you're doing in more detail, and using plain C terms if possible.

#15701 - tepples - Wed Jan 28, 2004 3:25 am

poslundc wrote:
it's likely to be an ill-conceived design if your application needs data spanning parts of two separate bytes.

The obvious exception: data compression and decompression. Right?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#15706 - slboytoy - Wed Jan 28, 2004 5:22 am

Ok here is what I mean.......


Memory spot 1 = 0101 0101
Memory spot 2 = 1001 0101
Memory spot 3 = 0101 1101
Memory spot 4 = 1011 0101
Memory spot 5 = 0111 0110
Memory spot 6 = 1101 0101
Memory spot 7 = 0101 0111
Memory spot 8 = 1011 0101

So I grabbed that from memory, now I want to take each colum and put into 8 different variables.

So the first one would be 11110111
So the second would be 00001010
etc......


I am making a portable logic analyzer. So I will have 8 channels (PODS), storing a 1 or 0, in memory. One memory location will hold all 8 spots. Now when I want to display this waveform on the GBA.. Channel 1 will only be the LSB of each memory spot. Channel 2 will be every 2nd spot in memory, etc...

So I want to be able to read one memory spot and show all 8 channels on the GBA. (one waveform each). Now if I move ahead one memory spot, I will have the next series of 8 waveforms. (Which I'll have 2 waveforms now on the screen for each channel)

I will try to explain things more clear, if you guys don't understand what I'm trying to get at here. Thanks for understanding.

#15710 - sajiimori - Wed Jan 28, 2004 10:11 am

Ah, I see. You're converting x number of n-bit values to n number of x-bit values. As long as x is less than or equal to 32 (it sounds like it's 8 for you), it's easy because the resulting values can fit in single words.

If your source and destination addresses are arranged linearly (i.e. in arrays), it would keep things simple. If x and n are both 8:
Code:

// untested
void remap_bits(u8* src, u8* dst)
{
  int i, b;

  for(i = 0; i < 8; ++i)
  {
    dst[i] = 0;

    for(b = 0; b < 8; ++b)
      if(src[b] & (1 << i))
        dst[i] |= 1 << b;
  }
}

#15712 - YopYop - Wed Jan 28, 2004 10:42 am

sajiimori there's a bug in your code ;)

your code will return 11101111 but he want 11110111 for the 1st value


void remap_bits(u8* src, u8* dst)
{
int i, b;

for(i = 0; i < 8; ++i)
{
dst[i] = 0;

for(b = 0; b < 8; ++b)
if(src[b] & (1 << i)) //this test is not usefull you can replace this 2 lines by
dst[i] |= 1 << (7-b); //dest[i]|=(src[i]&(b+1))<<(7-b)
}
}

#15713 - YopYop - Wed Jan 28, 2004 10:45 am

I made a mistake to
it' s 'b' not 'i' in dest[i]|=(src[i]&(b+1))<<(7-b) so you may write
dest[i]|=(src[b]&(b+1))<<(7-b)

as I say in french "autant pour moi" :)

#15715 - YopYop - Wed Jan 28, 2004 11:40 am

this one may be good

Code:

void remap_bits(u8* src, u8* dst)
{
  int i, b;

  for(i = 0; i < 8; ++i)
  {
    dst[i] = 0;

    for(b = 0; b < 8; ++b)
          dest[i]|=(src[b]&(1<<i))<<(7-b)
  }
}

in the last post I made mistake with 'b' and 'i' sorry

#15728 - slboytoy - Wed Jan 28, 2004 5:26 pm

Ok I I do it this way....... I get....

Code:
void SortChannels()
{
   u8* src;
   u8* dst;
   int i, b;

   for(i=0; i < 8; i++)
   {
      dst[i] = 11;

      for(b=0; b<8; b++)
         dst[i]|=(src[b]&(1<<i))<<(7-b);
   }

      Display(dst[0], 10, 20);

      Display(dst[1], 40, 50);

      Display(dst[2], 70, 80);
         
      Display(dst[3], 100, 110);
}


_____________________

-------------|___________

----|___|----|________|---

--------------|________|---


No matter what I change dst[?] to anything, even if I put in src[?] It still comes up with the same waveform.

Code:

Data = 0xFF;
Display(Data], 100, 110);


That works fine, and I get what I want..[/code]

#15729 - YopYop - Wed Jan 28, 2004 5:36 pm

why did you put Dst[i]=11;
we initialise it to zero because we do a or on it.you must not change it to have a good output in funtion of your input(src)

may be you want to do Src[i]=11;

#15730 - YopYop - Wed Jan 28, 2004 5:39 pm

and you declare u8 * src, * dst
and you don't allow memory to this var

#15732 - slboytoy - Wed Jan 28, 2004 6:02 pm

Sorry you beat me to it before I relized I made a mistake in posting that code....

Code:

   u8 src[8] = {0};
   u8 dst[8] = {0};
   int i, b;
               
                //Dummy Data
   src[0] = 0xAA;
   src[1] = 0x00;
   src[2] = 0xFF;
   src[3] = 0x55;
   src[4] = 0x11;
   src[5] = 0x88;
   src[6] = 0x00;
   src[7] = 0xFF;

   for(i=0; i < 8; i++)
   {
      for(b=0; b<8; b++)
         dst[i]|=(src[b] & (1<<i)) << (7-b);
   }

      Display(dst[0], 0, 10);
      Display(dst[1], 15, 25);
      Display(dst[2], 30, 40);
      Display(dst[3], 45, 55);
      Display(dst[4], 60, 70);
      Display(dst[5], 75, 85);
      Display(dst[6], 90, 100);
      Display(dst[7], 105, 115);
}


Ok I'll try to explain what is going on.

10101010 AA
00000000 00
11111111 FF
01010101 55
00010001 11
10001000 88
00000000 00
11111111 FF

Now the first line is displays fine. 001111001
But the second wave form, the first value gets cut off (1). so it's 0100001 (and it adds an extra 0 at the end).
Now the third wave form, cuts off the first two values (00), so it's 110001 (and adds an extra two 0s at the end).
And the 4th, cuts off the first 3.. etc.....

So the code works fine for the first waveform. Everything in BOLD does not show up. It just needs some fine tuning.. Thanks for the great start though.

#15737 - YopYop - Wed Jan 28, 2004 8:21 pm

tested and it work
Code:

   for(i=0; i < 8; i++)
   {
      dst[i]=0;
      for(b=0; b<8; b++)
     {
         dst[i]|= ((src[b] & (1<<i)) >>i)  <<  (7-b);
     }
     printf("%d\n",dst[i]);
   }


but whith all this shifting sajiimori test must be more efficient
so you may write

not tested
Code:

void remap_bits(u8* src, u8* dst)
{
int i, b;

for(i = 0; i < 8; ++i)
{
dst[i] = 0;

for(b = 0; b < 8; ++b)
if(src[b] & (1 << i)) 
dst[i] |= 1 << (7-b); 
}
}

#15738 - slboytoy - Wed Jan 28, 2004 8:30 pm

Yes the non-tested worked for my Project... Thanks again guys.

#15740 - sajiimori - Wed Jan 28, 2004 8:51 pm

YopYop, you were so anxious to find my error that you made several of your own, corrected over the course of 6(!) posts, and ending up with almost exactly what I posted, except changing b to 7-b to reverse the results.

If you're going to contradict somebody, make sure you're right!