Thread: Bitwise operation; flag look up

  1. #1
    Registered User
    Join Date
    Aug 2010
    Posts
    7

    Bitwise operation; flag look up

    Hi, I'm new here and am having trouble getting bitwise operations to work.

    I have a typedef struct called typebs, I initialize the stuct variable as typebs bs.

    I'm trying to read the first four bits (eventually the entire 28 bits in the field) using the following piece of code:

    Code:
        bs.mouse = periphrials[0] & (1 << 0);
        bs.keyboard = periphrials[0] & (1 << 1);
        bs.gun = periphrials[0] & (1 << 2);
        bs.expand_analog_vert = periphrials[0] & (1 << 3);
    The variables mouse, keyboard, gun and expand_analog_vert are all int types. The variable periphrials is a char array that holds a hex number -- in my current case this number is E019010.

    What I'm expecting is either a 1 or 0 (on or off) put into the int variables, what I'm getting is 1, 0, 4, 0.

    What am I missing and how can I properly implement this?

  2. #2
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    Maybe:

    Code:
        
        bs.mouse = ((periphrials[0] & 0x1) != 0) ;
        bs.keyboard = ((periphrials[0] & 0x2) != 0);
        bs.gun = ((periphrials[0] & 0x4) != 0);
        bs.expand_analog_vert = ((periphrials[0] & 0x8) != 0);
    That should work.
    Last edited by Syscal; 08-31-2010 at 07:12 PM.

  3. #3
    Registered User
    Join Date
    Aug 2010
    Posts
    7
    Not really. If more than one flag's set it returns bogus results.

    Code:
        bs.expand_analog_vert = ((periphrials[0] & 0x1) != 0);
        bs.keyboard = ((periphrials[0] & 0x2) != 0);
        bs.gun = ((periphrials[0] & 0x4) != 0);
        bs.mouse = ((periphrials[0] & 0x8) != 0) ;
    With mouse and keyboard on, expand_analog_vert is on.
    With mouse and gun on, keyboard and expand_analog_vert is on.
    With mouse keyboard and gun on, gun and expand_analog_vert is on.

    Only problems when mouse is set...

    Note I had to change mouse to 0x8 and expand_analog_vert to 0x1.
    Last edited by emptythought; 08-31-2010 at 08:51 PM.

  4. #4
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    Does too work!

    Code:
    #include <stdio.h>
    
    int main(){
    
        int a = 0xE019019;
    
        printf("%i%i%i%i\n",(a & 8)!=0, (a & 4)!= 0, (a & 2)!= 0, (a & 1)!= 0);
    
    
        return 0;
    }
    I made a small change to your number though because the "nibble" was all zeros. This prints the individual bits from the least significant nibble.

  5. #5
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    Code:
    void set(int* arg, int FLAG){
        *arg |= FLAG;
    }
    void clear(int* arg, int FLAG){
        *arg &= ~FLAG;
    }
    bool check(int* arg, int FLAG){
        return (*arg & FLAG) != 0;
    }
    
    void toggle(int* arg, int FLAG){
        *arg ^= FLAG
    }
    Last edited by Syscal; 09-01-2010 at 05:36 AM.

  6. #6
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by emptythought View Post
    Hi, I'm new here and am having trouble getting bitwise operations to work.

    I have a typedef struct called typebs, I initialize the stuct variable as typebs bs.

    I'm trying to read the first four bits (eventually the entire 28 bits in the field) using the following piece of code:

    Code:
        bs.mouse = periphrials[0] & (1 << 0);
        bs.keyboard = periphrials[0] & (1 << 1);
        bs.gun = periphrials[0] & (1 << 2);
        bs.expand_analog_vert = periphrials[0] & (1 << 3);
    The variables mouse, keyboard, gun and expand_analog_vert are all int types. The variable periphrials is a char array that holds a hex number -- in my current case this number is E019010.

    What I'm expecting is either a 1 or 0 (on or off) put into the int variables, what I'm getting is 1, 0, 4, 0.

    What am I missing and how can I properly implement this?
    What is the type of your periphrials[ ]?

    Looking at your source material at the link given, it appears that the mouse bit is the most significant bit in the 28bit field. This is definitely not the (1<<0) bit. What it should be depends on the type of periphrials[ ]. Instead of an array, if perihrials was a 32-bit quantity (unsigned long in some implementations), the mouse bit would either be (1<<31) or (1<<27) depending on where the 28 bits were positioned in the 32 bit field.

  7. #7
    Registered User
    Join Date
    Aug 2010
    Posts
    7
    Quote Originally Posted by Syscal View Post
    Does too work!

    ...

    I made a small change to your number though because the "nibble" was all zeros. This prints the individual bits from the least significant nibble.
    As I mentioned below the peripherals (thanks spell check for the typo!) variable is type character. How can I convert that hex digit into say, an unsigned long when sscanf_s is only available to Windows?

    Quote Originally Posted by Syscal View Post
    Code:
    int check(int *arg, int FLAG){
        return (*arg & FLAG) != 0;
    }
    Here's an example I just finished that shows the first issue your code gave me.

    Code:
    #include <stdio.h>
    
    int check(int *arg, int FLAG)	{
        return(*arg & FLAG) != 0;
    }
    
    int main(void)	{
        char a[] = "B000010";
    
        printf("%i%i%i%i\n", check(a, 0x1), check(a, 0x2), check(a, 0x4),
              check(a, 0x8));
    
        return 0 ;
    }
    mouse, keyboard and expand_ananlog_vert are set and it reports 0100.

    Quote Originally Posted by pheininger View Post
    What is the type of your periphrials[ ]?

    Looking at your source material at the link given, it appears that the mouse bit is the most significant bit in the 28bit field. This is definitely not the (1<<0) bit. What it should be depends on the type of periphrials[ ]. Instead of an array, if perihrials was a 32-bit quantity (unsigned long in some implementations), the mouse bit would either be (1<<31) or (1<<27) depending on where the 28 bits were positioned in the 32 bit field.
    It is a character with 8 elements.

    main.c\cpp - C | #include <stdio.h> #include - Etdcdev - gzJhpnh6 - Pastebin.com
    main.h - C | #define MR_MAX_COLORS 127 # - Etdcdev - XgZr9uLr - Pastebin.com

    Thanks.

  8. #8
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    Quote Originally Posted by emptythought View Post
    As I mentioned below the peripherals (thanks spell check for the typo!) variable is type character. How can I convert that hex digit into say, an unsigned long when sscanf_s is only available to Windows?


    Here's an example I just finished that shows the first issue your code gave me.

    Code:
    #include <stdio.h>
    
    int check(int *arg, int FLAG)	{
        return(*arg & FLAG) != 0;
    }
    
    int main(void)	{
        char a[] = "B000010";
    
        printf("%i%i%i%i\n", check(a, 0x1), check(a, 0x2), check(a, 0x4),
              check(a, 0x8));
    
        return 0 ;
    }
    mouse, keyboard and expand_ananlog_vert are set and it reports 0100.



    It is a character with 8 elements.

    main.c\cpp - C | #include <stdio.h> #include - Etdcdev - gzJhpnh6 - Pastebin.com
    main.h - C | #define MR_MAX_COLORS 127 # - Etdcdev - XgZr9uLr - Pastebin.com

    Thanks.
    Well you should probably pass it one of the elements of the array. Keep in mind that I'm talking in terms of on the bit level.
    Last edited by Syscal; 09-01-2010 at 01:21 PM.

  9. #9
    Registered User
    Join Date
    Aug 2010
    Posts
    7
    I did. It just returns 0010...

  10. #10
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    You want this to be interpreted as hex right? Why cant you just use an int? I'm pressed for time right now so I could help when I get back. Tonight. But I did just realize that you wanted the FIRST four bits checked. That would appear to be 56, 55,54, and 53.
    Last edited by Syscal; 09-01-2010 at 01:34 PM.

  11. #11
    Registered User
    Join Date
    Aug 2010
    Posts
    7
    Quote Originally Posted by Syscal View Post
    ...

    I made a small change to your number though because the "nibble" was all zeros. This prints the individual bits from the least significant nibble.
    Reading over this again; I don't get what you meant by this? I noticed the change; how would a change from a 0 to a 9 change the way the individual bits are printed?

    Quote Originally Posted by Syscal View Post
    You want this to be interpreted as hex right? Why cant you just use an int?
    How can I convert that hex digit into say, an unsigned long when sscanf_s is only available to Windows?

  12. #12
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by emptythought View Post
    Your source infomation tells you that you have a field of 64-bits (8 8-bit bytes) for a data field that is 28-bits long. They do not indicate where those 28-bits are within the 64-bit field. You have to determine where the 28-bits are located. If you have a known good sample that you could look at, you could use this to determine where these bits are located. It would not suprise me if those its were left justified in the 64-bit field. If I am right, then the most significant bit is the mouse bit. Do you know for sure where the 28-bits are located?

    It is not clear what you are going to do with this information, but remember that trying to break copy protection schemes may be a violation of the Digital Millenium Copyright Act in the USA
    Last edited by pheininger; 09-01-2010 at 02:00 PM.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Given this from your linked page ...
    Code:
    <A><-------B------> <C->
    0000 0000 0000 0000 0000 0000 0000
    ^^^^ ^^^^ ^^^^ ^^^^ ^^^^    ^    ^
    |||| |||| |||| |||| ||||    |    |
    |||| |||| |||| |||| ||||    |    +----- Uses Windows CE
    |||| |||| |||| |||| ||||    |
    |||| |||| |||| |||| ||||    +-----  VGA box support
    |||| |||| |||| |||| ||||
    |||| |||| |||| |||| |||+----- Other expansions
    |||| |||| |||| |||| ||+----- Puru Puru pack
    |||| |||| |||| |||| |+----- Mike device
    |||| |||| |||| |||| +----- Memory card
    |||| |||| |||| |||+------ Start + A + B + Directions
    |||| |||| |||| ||+------ C button
    |||| |||| |||| |+------ D button
    |||| |||| |||| +------ X button
    |||| |||| |||+------- Y button
    |||| |||| ||+------- Z button
    |||| |||| |+------- Expanded direction buttons
    |||| |||| +------- Analog R trigger
    |||| |||+-------- Analog L trigger
    |||| ||+-------- Analog horizontal controller
    |||| |+-------- Analog vertical controller
    |||| +-------- Expanded analog horizontal
    |||+--------- Expanded analog vertical
    ||+--------- Gun
    |+--------- Keyboard
    +--------- Mouse
    This is roughage just to give an idea... it is 100% untested...
    Code:
     
    typedef union tBits
       { unsigned long  Peripherals;
          unsigned long Other : 1,
                                  Puru  : 1,
                                  Mike  : 1,
                                  Card  : 1,
                                  SAB   : 1,
                                  Cbtn  : 1,
                                  Dbtn  : 1,
                                  Xbtn  : 1,
                                  Ybtn  : 1,
                                  Zbtn  : 1, 
                                  EBtn  : 1,
                                  ART    : 1,
                                  ALT    : 1 ,
                                  AHC   : 1,
                                  AVC   : 1,
                                  EAH   : 1,
                                  EAV   : 1,
                                  Gun  : 1,
                                  Kbd  : 1,
                                  Mse  : 1; }  BITS, *pBITS;
    
    BITS  bs;
    
    BS.Peripherals = Peripherals[0];
    
    If (bs.Kbd)
      puts("Well lookie there");
    The union should allow you to write in a DWord and read it as bits...

  14. #14
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by CommonTater View Post
    ...
    This is roughage just to give an idea... it is 100% untested...
    Code:
     
    typedef union tBits
       { unsigned long  Peripherals;
          unsigned long Other : 1,
                                  Puru  : 1,
                                  Mike  : 1,
                                  Card  : 1,
                                  SAB   : 1,
                                  Cbtn  : 1,
                                  Dbtn  : 1,
                                  Xbtn  : 1,
                                  Ybtn  : 1,
                                  Zbtn  : 1, 
                                  EBtn  : 1,
                                  ART    : 1,
                                  ALT    : 1 ,
                                  AHC   : 1,
                                  AVC   : 1,
                                  EAH   : 1,
                                  EAV   : 1,
                                  Gun  : 1,
                                  Kbd  : 1,
                                  Mse  : 1; }  BITS, *pBITS;
    
    BITS  bs;
    
    BS.Peripherals = Peripherals[0];
    
    If (bs.Kbd)
      puts("Well lookie there");
    The union should allow you to write in a DWord and read it as bits...
    I realize you gave a warning about it be a "roughage to give an idea". I agree that it does a good job of accomplishing this. This is a good place and time to give some of the warnings about using bit-fields.

    In C99, the only types which are required by an implementation to implement bit-fields are signed int, unsigned int, and _Bool. (6.7.2.1) An implementation is allowed to define other types such as unsigned long.

    In C99, "the order of allocation of bit-fields within a unit" is implementation defined (6.7.2.1) so there is no way to know if these bit-fields will align with the ones given in the documentation. Or stay aligned if using a different compiler or different version of the same compiler.

    This list gives 20 bits of the first 5 nibbles (4-bit), but does not define next 2 nibbles. The documentation does not define where the 7 nibbles (28-bits) are within the 8-bytes (64-bits) of the peripherals field.
    Last edited by pheininger; 09-01-2010 at 06:35 PM. Reason: changed spelling of bit field

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    I agree bitfields operating on externally defined values can be a bit dodgy and appreciate the warnings given... but, in my own defense I did say I was just thinking out loud...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  2. Replies: 5
    Last Post: 12-04-2008, 08:15 PM
  3. Bitwise operation problem
    By cunnus88 in forum C++ Programming
    Replies: 9
    Last Post: 10-25-2008, 01:49 PM
  4. can some one please tell me the cause of the error ?
    By broli86 in forum C Programming
    Replies: 8
    Last Post: 06-26-2008, 08:36 PM
  5. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM