Putting mutiple booleans into an unsigned char? - c++

Currently I'm working on an NES emulator and I'm working on the CPU core. I've searched all over the internet, but I can't find the right keywords find the answer to my question, so I thought I'd ask it here. What I have is seven booleans that act as my processor status flags. The current opcode I'm working on wants me to push the processor status flags to the stack. My stack is of the unsigned char datatype. I thought I would be able to smash the booleans together like this:
bool C, Z, I, D, B, V, N;
unsigned char example;
example = {C, Z, I, D, B, V, N, 0};
That didn't work, so how do I go about putting all of my boolean processor status flags into an unsigned char datatype so I can push the flags onto my stack?

enum { C=0x01, Z=0x02, I=0x04, D=0x08,
B=0x10, V=0x20, N=0x40 };
unsigned char flags = 0;
This works because only one bit is set in each constant. To determine whether the flag is set, use (flags & FLAGNAME) like (flags & C) to determine if it is set. Be careful not to get the bitwise AND (&) I used confused with the Boolean/logical AND (&&). The && operator won't work in place of the & operator. To set a flag, use (flags |= FLAGNAME) and to unset it, use flags &= ~FLAGNAME;. Adjust the constants for the correct order, so the NES instruction can properly check the flags. After all, if they're not in the correct order, the wrong flag values may be used, which obviously would be a problem.
Also, don't forget the parentheses. The bitwise operators have very low precedence, so parentheses around the expression are essential.
If you don't know about the bitwise operators, they are worth reading up on.
Edit
A handy set of macros for you:
#define FLAG_ISSET(x) (flags & (x))
#define FLAG_SET(x) (flags |= (x))
#define FLAG_CLEAR(x) (flags &= ~(x))
...
if (FLAG_ISSET(C))
...
FLAG_SET(V);
FLAG_CLEAR(Z);

Try std::bitset. http://en.cppreference.com/w/cpp/utility/bitset I couldn't find a way to construct it using initializer lists, but you can always use the operator[] or set() to set each bit, and use to_ulong() to convert it to a number (then you can convert the unsigned long to an unsigned char trivially).
#include <stdio.h>
#include <bitset>
using namespace std;
int main()
{
bitset<7> reg;
bool C = true, Z = false, I = false, D = false, B = true, V = true, N = false;
reg[6] = C;
reg[5] = Z;
reg[4] = I;
reg[3] = D;
reg[2] = B;
reg[1] = V;
reg[0] = N;
unsigned char example = static_cast<unsigned char>(reg.to_ulong());
printf("0x%x\n", example);
return 0;
}

try this:
bool C, Z, I, D, B, V, N;
unsigned char example = 0;
if(C)
example |= (1 << 7)
if(Z)
example |= (1 << 6)
if(I)
example |= (1 << 5)
if(D)
example |= (1 << 4)
if(B)
example |= (1 << 3)
if(V)
example |= (1 << 2)
if(N)
example |= (1 << 1)

Let's say int status is your CPU status register.
You could create some defines like these:
#define CPU_REG_STATUS_C 0x00000040
#define CPU_REG_STATUS_Z 0x00000020
#define CPU_REG_STATUS_I 0x00000010
#define CPU_REG_STATUS_D 0x00000008
#define CPU_REG_STATUS_B 0x00000004
#define CPU_REG_STATUS_V 0x00000002
#define CPU_REG_STATUS_N 0x00000001
and then set/unset the flags indipendently from each other by using the bitwise binary operators & and |
example1: setting the ZERO flag
status |= CPU_REG_STATUS_Z;
example2: checking the value of the ZERO flag:
if(status & CPU_REG_STATUS_Z)
{
//zero flag is set
}
else
{
//zero flag is unset
}
however, there are plenty of CPU core source codes out there, especially for the 6502 CPU (Commodore C64, Nintendo NES and many others) so you have to bother only with the emulation of the console.
http://www.6502.org/tools/emu/

This may be a bit heavy to be putting in an emulator, but why not convert each boolean value into a bit in the character, then decode the character once you need to pull it off your stack.
unsigned char encodeBits(bool bools[8]) {
unsigned char retval = 0;
for(int i = 0; i < 8; i++) {
retval += (bools[i] ? 1 : 0);
retval = (i < 7 ? retval << 1 : retval);
}
return retval;
}
This code basically just shifts the boolean value into a character.
Then to decode, pass an empty array by reference,
void decodeBits(bool (&bools)[8], unsigned char input) {
for(int i = 0; i < 8; i++) {
bools[i] = (input & 0x00000001 ? true : false);
input = (i < 7 ? input >> 1 : input);
}
}
This code should compare the first bit of the character, then shift it etc. etc.
This can be done without arrays but for simplicity's sake I used arrays.
Edit: A working example: http://ideone.com/hQ47nn

This should be what you are looking for:
bool C, Z, I, D, B, V, N;
unsigned char example = 0;
const unsigned char mask = 0x01;
if(N)
example |= mask << 1;
if(V)
example |= mask << 2;
//...
if(C)
example |= mask << 7;

Related

c++: how to put relevant bits from uint32 into uint8?

I have a uint32 that I've flagged some bits on:
uint32 i = 0;
i |= (1 << 0);
i |= (1 << 5);
i |= (1 << 13);
i |= (1 << 19);
...
I want to convert it to a uint8 (by getting the state of its first 8 bits and disregarding the rest). Obviously I could do this:
uint8 j = 0;
for (int q = 0; q < 8; q++)
{
if (i & (1 << q))
{
j |= (1 << q);
}
}
But is there a fancy bitwise operation I can use to transfer the bits over in one fell swoop, without a loop?
You can achieve the same result by simply assigning the uint32 value to uint8.
int main()
{
unsigned int i = 0x00000888;
unsigned char j = i;
cout<<hex<<i<<endl;
cout<<hex<<+j<<endl;
return 0;
}
output:
888
88
Why not just mask those last 8 bits instead of running a loop over to see if individual bits are set?
const unsigned char bitMask = 0xFF;
j = (i & bitMask);
Note that C++ 14 though allows you to define binary literals right away
const unsigned char bitMask = 0b1111'1111;
The above is all you need. Just in case, if you need to get the subsequent byte positions, use the same mask 0xFF and make sure to right shift back the result to get the desired byte value.

Compact a hex number

Is there a clever (ie: branchless) way to "compact" a hex number. Basically move all the 0s all to one side?
eg:
0x10302040 -> 0x13240000
or
0x10302040 -> 0x00001324
I looked on Bit Twiddling Hacks but didn't see anything.
It's for a SSE numerical pivoting algorithm. I need to remove any pivots that become 0. I can use _mm_cmpgt_ps to find good pivots, _mm_movemask_ps to convert that in to a mask, and then bit hacks to get something like the above. The hex value gets munged in to a mask for a _mm_shuffle_ps instruction to perform a permutation on the SSE 128 bit register.
To compute mask for _pext:
mask = arg;
mask |= (mask << 1) & 0xAAAAAAAA | (mask >> 1) & 0x55555555;
mask |= (mask << 2) & 0xCCCCCCCC | (mask >> 2) & 0x33333333;
First do bit-or on pairs of bits, then on quads. Masks prevent shifted values from overflowing to other digits.
After computing mask this way or harold's way (which is probably faster) you don't need the full power of _pext, so if targeted hardware doesn't support it you can replace it with this:
for(int i = 0; i < 7; i++) {
stay_mask = mask & (~mask - 1);
arg = arg & stay_mask | (arg >> 4) & ~stay_mask;
mask = stay_mask | (mask >> 4);
}
Each iteration moves all nibbles one digit to the right if there is some space. stay_mask marks bits that are in their final positions. This uses somewhat less operations than Hacker's Delight solution, but might still benefit from branching.
Supposing we can use _pext_u32, the issue then is computing a mask that has an F for every nibble that isn't zero. I'm not sure what the best approach is, but you can compute the OR of the 4 bits of the nibble and then "spread" it back out to F's like this:
// calculate horizontal OR of every nibble
x |= x >> 1;
x |= x >> 2;
// clean up junk
x &= 0x11111111;
// spread
x *= 0xF;
Then use that as the mask of _pext_u32.
_pext_u32 can be emulated by this (taken from Hacker's Delight, figure 7.6)
unsigned compress(unsigned x, unsigned m) {
unsigned mk, mp, mv, t;
int i;
x = x & m; // Clear irrelevant bits.
mk = ~m << 1; // We will count 0's to right.
for (i = 0; i < 5; i++) {
mp = mk ^ (mk << 1); // Parallel prefix.
mp = mp ^ (mp << 2);
mp = mp ^ (mp << 4);
mp = mp ^ (mp << 8);
mp = mp ^ (mp << 16);
mv = mp & m; // Bits to move.
m = m ^ mv | (mv >> (1 << i)); // Compress m.
t = x & mv;
x = x ^ t | (t >> (1 << i)); // Compress x.
mk = mk & ~mp;
}
return x;
}
But that's a bit of a disaster. It's probably better to just resort to branching code then.
uint32_t fun(uint32_t val) {
uint32_t retVal(0x00);
uint32_t sa(28);
for (int sb(28); sb >= 0; sb -= 4) {
if (val & (0x0F << sb)) {
retVal |= (0x0F << sb) << (sa - sb)
sa -= 4;
}
}
return retVal;
}
I think this (or something similar) is what you're looking for. Eliminating the 0 nibbles within a number. I've not debugged it, and it would only works on one side atm.
If your processor supports conditional instruction execution, you may get a benefit from this algorithm:
uint32_t compact(uint32_t orig_value)
{
uint32_t mask = 0xF0000000u; // Mask for isolating a hex digit.
uint32_t new_value = 0u;
for (unsigned int i = 0; i < 8; ++i) // 8 hex digits
{
if (orig_value & mask == 0u)
{
orig_value = orig_value << 4; // Shift the original value by 1 digit
}
new_value |= orig_value & mask;
mask = mask >> 4; // next digit
}
return new_value;
}
This looks like a good candidate for loop unrolling.
The algorithm assumes that when the original value is shifted left, zeros are shifted in, filling in the "empty" bits.
Edit 1:
On a processor that supports conditional execution of instructions, the shifting of the original value would be conditionally executed depending on the result of the ANDing of the original value and the mask. Thus no branching, only ignored instructions.
I came up with the following solution. Please take a look, maybe it will help you.
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
class IsZero
{
public:
bool operator ()(char c)
{
return '0' == c;
}
};
int main()
{
int a = 0x01020334; //IMPUT
ostringstream my_sstream;
my_sstream << hex << a;
string str = my_sstream.str();
int base_str_length = str.size();
cout << "Input hex: " << str << endl;
str.insert(remove_if(begin(str), end(str), IsZero()), count_if(begin(str), end(str), IsZero()), '0');
str.replace(begin(str) + base_str_length, end(str), "");
cout << "Processed hex: " << str << endl;
return 0;
}
Output:
Input hex: 1020334
Processed hex: 1233400

How to check certain bits of a variable in C++? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C/C++ check if one bit is set in, i.e. int variable
e.g. if I had a integer and i wanted to check what the value of bits 20-25 were, or if i just wanted to check if one of the bits is 0 or 1, how would i do that?
Use standard logic operations such as logical ANDs, ORs, XORs and combine that with bit shifts. This should give you some ideas: http://en.wikipedia.org/wiki/Bit_manipulation
Hope that helps
You would use the bitwise-AND operator between the integer and a "mask" value, which ignores all the other bits. So something like this:
const int BIT_4 = 0x8;
// ....
int val = /* ... */;
if ((val & BIT_4) != 0)
; // Bit 4 is ON!
else
; // Bit 4 is OFF
You can do it by using bitwise AND operator.
int x = SOME_VALUE;
// check 20-25 bits
if ( x & 0x3F00000 ) {
// any of bits on
}
int bitsToInt(int value, int s, int e) {
int mask = ((1 << (e - s + 1)) - 1) << s;
return (value & mask) >> s;
}
bitsToInt(7, 2, 3) returns 1
thinking about it a bit more, if what you want is to stuff several values into one int you can be better off doing bitfields and have compiler worry about masks and shifts.
uint32_t
get_bits_20_to_24(uint32_t i_)
{
union {
struct
{
uint32_t bits1 : 20;
uint32_t bits2 : 5;
uint32_t bits3 : 7;
} s;
uint32_t i;
};
i = i_;
return s.bits2;
}

Converting a set of booleans to a number

This is the code I am going to use to take a set of three booleans and convert it into an int for a switch statement:
int bits = 0;
bool a = true, b = false, c = true; // 101 = 5
bits = bits | a << 2;
bits = bits | b << 1;
bits = bits | c;
cout << bits;
I have eight cases based on the combined state of these three booleans. Am I doing this right?
Right, not in the sense of the syntax although if there are any problems there please advise. More right in the sense of "Is this the best way to solve this problem?"
If you are using C++, you could use bitset<N>.
You're doing it right. You could make the code a little more succinct though:
bits |= (a<<2) | (b<<1) | (c<<0);
Just be aware that the Standard doesn't enforce any size constraint on bool. Pragmatically speaking there shouldn't be a problem with three bits, but the Standard doesn't back you here.
$ cat ttt.c
//example of C solution
#include <stdio.h>
int main() {
union {
unsigned int val;
struct {
unsigned a : 1;
unsigned b : 1;
unsigned c : 1;
//unsigned d : 1;
//e, f, g, h...
} flags;
} bits;
bits.val=0;
bits.flags.a = 1;
bits.flags.c = 1;
printf("val: %d\n",bits.val);
return 0;
}
~$ ./ttt
val: 5
I would do it as:
bits = (bits << 1) | a;
bits = (bits << 1) | b;
bits = (bits << 1) | c;
which would require less maintenance work if you needed to add or to remove a flag.
However, doing this so that you can use it for a switch sounds like it might be a bad idea. Adding a flag would double the number of states you'd need to handle, and the case values would be fragile and hard to read.
But if you really must, here's another approach:
enum
{
c_bit_offset,
b_bit_offset,
a_bit_offset
};
unsigned int bits = (a << a_bit_offset)
| (b << b_bit_offset)
| (c << c_bit_offset);
switch (bits)
{
case 0:
/* Do something. */
break;
case (1 << a_bit_offset):
/* Do something. */
break;
case (1 << a_bit_offset) | (1 << b_bit_offset):
/* Do something. */
break;
...
}
By the way, you probably should use unsigned int instead of int.
You can make some defines to make easy to work with bits
#define BitSet(arg,bit) ((arg) |= (1<<bit))
#define BitClr(arg,bit) ((arg) &= ~(1<<bit))
#define BitFlp(arg,bit) ((arg) ^= (1<<bit))
#define BitTst(arg,bit) ((arg) & (1<<bit))
Then you can use only one char
keys = 0b00000101;
BitSet (keys,1);
This an common way to work in embedded systems.
You can always do the conversion explicitly:
bits = bits | (a ? 1 : 0) << 2;
However I believe C/C++ will handle it implicitly, once you're using the bit-shift operator.
You should define constants for each flag, giving a name to the bit you are setting:
const int a_flag = 2;
bits = bits | (a ? 1 : 0) << a_flag;
Edit:
As you can see from the comments on my answer, most C/C++ programmers prefer to learn implicit conversions and operator precedence. Therefore your original code is "most correct".
Edit 2:
Except, you should use the |= operator:
const int a_flag = 2;
bits |= a << a_flag;

Big Endian and Little Endian for Files in C++

I am trying to write some processor independent code to write some files in big endian. I have a sample of code below and I can't understand why it doesn't work. All it is supposed to do is let byte store each byte of data one by one in big endian order. In my actual program I would then write the individual byte out to a file, so I get the same byte order in the file regardless of processor architecture.
#include <iostream>
int main (int argc, char * const argv[]) {
long data = 0x12345678;
long bitmask = (0xFF << (sizeof(long) - 1) * 8);
char byte = 0;
for(long i = 0; i < sizeof(long); i++) {
byte = data & bitmask;
data <<= 8;
}
return 0;
}
For some reason byte always has the value of 0. This confuses me, I am looking at the debugger and see this:
data = 00010010001101000101011001111000
bitmask = 11111111000000000000000000000000
I would think that data & mask would give 00010010, but it just makes byte 00000000 every time! How can his be? I have written some code for the little endian order and this works great, see below:
#include <iostream>
int main (int argc, char * const argv[]) {
long data = 0x12345678;
long bitmask = 0xFF;
char byte = 0;
for(long i = 0; i < sizeof(long); i++) {
byte = data & bitmask;
data >>= 8;
}
return 0;
}
Why does the little endian one work and the big endian not? Thanks for any help :-)
You should use the standard functions ntohl() and kin for this. They operate on explicit sized variables (i.e. uint16_t and uin32_t) rather than compiler-specific long, which necessary for portability.
Some platforms provide 64-bit versions in <endian.h>
In your example, data is 0x12345678.
Your first assignment to byte is therefore:
byte = 0x12000000;
which won't fit in a byte, so it gets truncated to zero.
try:
byte = (data & bitmask) >> (sizeof(long) - 1) * 8);
You're getting the shifting all wrong.
#include <iostream>
int main (int argc, char * const argv[]) {
long data = 0x12345678;
int shift = (sizeof(long) - 1) * 8
const unsigned long mask = 0xff;
char byte = 0;
for (long i = 0; i < sizeof(long); i++, shift -= 8) {
byte = (data & (mask << shift)) >> shift;
}
return 0;
}
Now, I wouldn't recommend you do things this way. I would recommend instead writing some nice conversion functions. Many compilers have these as builtins. So you can write your functions to do it the hard way, then switch them to just forward to the compiler builtin when you figure out what it is.
#include <tr1/cstdint> // To get uint16_t, uint32_t and so on.
inline uint16_t to_bigendian(uint16_t val, char bytes[2])
{
bytes[0] = (val >> 8) & 0xffu;
bytes[1] = val & 0xffu;
}
inline uint32_t to_bigendian(uint32_t val, char bytes[4])
{
bytes[0] = (val >> 24) & 0xffu;
bytes[1] = (val >> 16) & 0xffu;
bytes[2] = (val >> 8) & 0xffu;
bytes[3] = val & 0xffu;
}
This code is simpler and easier to understand than your loop. It's also faster. And lastly, it is recognized by some compilers and automatically turned into the single byte swap operation that would be required on most CPUs.
because you are masking off the top byte from an integer and then not shifting it back down 24 bits ...
Change your loop to:
for(long i = 0; i < sizeof(long); i++) {
byte = (data & bitmask) >> 24;
data <<= 8;
}